Skip to content
Snippets Groups Projects
secrets.js 2.73 KiB
Newer Older
  • Learn to ignore specific revisions
  • import secrets from "../lib/secrets";
    
    import { encryptMessage } from "./signingUtilities";
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
    import { encodeResponse } from "./appUtility";
    
    import { getSliceRange } from "./numberUtilities";
    
    import { THRESHOLD } from "../constants/secrets";
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
    
    
    /** Initialize
     */
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
    export const initSecrets = (bits, rngType) => secrets.init(bits, rngType);
    
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
    export const setRNG = rngType => secrets.setRNG(rngType);
    export const getSecretsConfig = () => secrets.getConfig();
    
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
    /**
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
     * Function generates a random bits length string, and output it in hexadecimal format
     *
     * @param {number} bits
    
     * @returns {string} hex
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
     */
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
    export const generateSecret = bits => secrets.random(bits);
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
    
    /**
     * Divide a secret expressed in hexadecimal form into numShares number of shares, requiring that threshold number of shares be present for reconstructing the secret
     *
     * @param {string} secret
     * @param {number} numShares
     * @param {number} threshold
     * @param {number} [padLength=128]
    
     * @returns {array}
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
     */
    export const divideSecretToShares = (
      secret,
      numShares,
      threshold,
      padLength = 128
    ) => secrets.share(secret, numShares, threshold, padLength);
    
    /**
     * Reconstructs a secret from shares
     *
     * @param {array} shares
    
     * @returns {string}
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
     */
    export const combineSecret = shares => secrets.combine(shares);
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
    
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
    export const encryptShare = async (share, publicKey) =>
      await encryptMessage(share, publicKey, "secretPart");
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
    
    /** Account Recovery key management */
    
    export const generateRecoveryKey = () => {
      const recoveryKey = generateSecret(512);
      return recoveryKey;
    };
    
    export const getRecoveryKeyShares = (recoveryKey, sharesNumber) => {
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
      return divideSecretToShares(recoveryKey, sharesNumber, THRESHOLD);
    
    function getSecretSliceRange(max) {
      const { beginIndex, endIndex } = getSliceRange(max);
      if (endIndex - beginIndex < THRESHOLD) {
        return getSecretSliceRange(max);
      }
    
      return { beginIndex, endIndex };
    }
    
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
    export const checkRecoveryKeyCombine = (recoveryKey, recoveryKeyShares) => {
      let checkKey;
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
    
    
      const { beginIndex, endIndex } = getSecretSliceRange(
        recoveryKeyShares.length + 1
      );
      console.log({ beginIndex, endIndex });
      checkKey = combineSecret(recoveryKeyShares.slice(beginIndex, endIndex));
      if (checkKey !== recoveryKey) {
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
        return encodeResponse(
          "400",
          "",
          "Sanity check with required number of shares failed"
        );
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
      checkKey = combineSecret(recoveryKeyShares.slice(0, 1));
    
      if (checkKey === recoveryKey) {
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
        return encodeResponse(
          "400",
          "",
          "Sanity check with less than required shares failed"
        );
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
      }
      checkKey = combineSecret(recoveryKeyShares);
      if (checkKey !== recoveryKey) {
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
        return encodeResponse("400", "", "Sanity check with all shares failed");
    
    Sasha Ilieva's avatar
    Sasha Ilieva committed
      }
    
      return encodeResponse("200", "", "Check passed");
    };