All files index.js

65.67% Statements 44/67
100% Branches 2/2
80% Functions 8/10
66.15% Lines 43/65
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153                  2x   14x   14x   14x   14x 56x 56x 56x   56x 56x 56x       14x 98x 98x 98x     56x   14x                             2x                                                                                               2x 14x 14x 84x 84x   14x                       2x 98x 98x   98x 98x   98x   98x 98x   98x               2x 2x 2x 14x 56x 56x 8x   48x 48x       2x    
/**
 * generates a members contribution to the DKG
 * @param {Object} bls - an instance of [bls-lib](https://github.com/wanderer/bls-lib)
 * @param {Array<Number>} ids - an array of pointers containing the ids of the members of the groups
 * @param {Number} threshold - the threshold number of members needed to sign on a message to
 * produce the groups signature
 * @returns {Object} the object contains `verificationVector` which is an array of public key pointers
 * and `secretKeyContribution` which is an array of secret key pointers
 */
exports.generateContribution = function (bls, ids, threshold) {
  // this id's verification vector
  const vvec = []
  // this id's secret keys
  const svec = []
  // this id's sk contributions shares
  const skContribution = []
  // generate a sk and vvec
  for (let i = 0; i < threshold; i++) {
    const sk = bls.secretKey()
    bls.secretKeySetByCSPRNG(sk)
    svec.push(sk)
 
    const pk = bls.publicKey()
    bls.getPublicKey(pk, sk)
    vvec.push(pk)
  }
 
  // generate key shares
  for (const id of ids) {
    const sk = bls.secretKey()
    bls.secretKeyShare(sk, svec, id)
    skContribution.push(sk)
  }
 
  svec.forEach(s => bls.free(s))
 
  return {
    verificationVector: vvec,
    secretKeyContribution: skContribution
  }
}
 
/**
 * generates a members contribution to the DKG, ensuring the secret is null
 * @param {Object} bls - an instance of [bls-lib](https://github.com/wanderer/bls-lib)
 * @param {Array<Number>} ids - an array of pointers containing the ids of the members of the groups
 * @param {Number} threshold - the threshold number of members needed to sign on a message to
 * produce the groups signature
 * @returns {Object} the object contains `verificationVector` which is an array of public key pointers
 * and `secretKeyContribution` which is an array of secret key pointers
 */
exports.generateZeroContribution = function (bls, ids, threshold) {
  // this id's verification vector
  const vvec = []
  // this id's secret keys
  const svec = []
  // this id's sk contributions shares
  const skContribution = []
 
  const zeroArray = Buffer.alloc(32)
  const zeroSK = bls.secretKeyImport(zeroArray)
  svec.push(zeroSK)
 
  const zeroPK = bls.publicKey()
  bls.getPublicKey(zeroPK, zeroSK)
  vvec.push(zeroPK)
 
  // generate a sk and vvec
  for (let i = 1; i < threshold; i++) {
    const sk = bls.secretKey()
    bls.secretKeySetByCSPRNG(sk)
    svec.push(sk)
 
    const pk = bls.publicKey()
    bls.getPublicKey(pk, sk)
    vvec.push(pk)
  }
 
  // generate key shares
  for (const id of ids) {
    const sk = bls.secretKey()
    bls.secretKeyShare(sk, svec, id)
    skContribution.push(sk)
  }
 
  svec.forEach(s => bls.free(s))
 
  return {
    verificationVector: vvec,
    secretKeyContribution: skContribution
  }
}
 
/**
 * Adds secret key contribution together to produce a single secret key
 * @param {Object} bls - an instance of [bls-lib](https://github.com/wanderer/bls-lib)
 * @param {Array<Number>} secretKeyShares - an array of pointer to secret keys to add
 * @returns {Number} a pointer to the resulting secret key
 */
exports.addContributionShares = function (bls, secretKeyShares) {
  const first = secretKeyShares.pop()
  secretKeyShares.forEach(sk => {
    bls.secretKeyAdd(first, sk)
    bls.free(sk)
  })
  return first
}
 
/**
 * Verifies a contribution share
 * @param {Object} bls - an instance of [bls-lib](https://github.com/wanderer/bls-lib)
 * @param {Number} id - a pointer to the id of the member verifiing the contribution
 * @param {Number} contribution - a pointer to the secret key contribution
 * @param {Array<Number>} vvec - an array of pointers to public keys which is
 * the verification vector of the sender of the contribution
 * @returns {Boolean}
 */
exports.verifyContributionShare = function (bls, id, contribution, vvec) {
  const pk1 = bls.publicKey()
  bls.publicKeyShare(pk1, vvec, id)
 
  const pk2 = bls.publicKey()
  bls.getPublicKey(pk2, contribution)
 
  const isEqual = bls.publicKeyIsEqual(pk1, pk2)
 
  bls.free(pk1)
  bls.free(pk2)
 
  return Boolean(isEqual)
}
 
/**
 * Adds an array of verification vectors together to produce the groups verification vector
 * @param {Object} bls - an instance of [bls-lib](https://github.com/wanderer/bls-lib)
 * @param {Array<Array<Number>>} vvecs - an array containing all the groups verifciation vectors
 */
exports.addVerificationVectors = function (bls, vvecs) {
  const groupsVvec = []
  vvecs.forEach(vvec => {
    vvec.forEach((pk2, i) => {
      let pk1 = groupsVvec[i]
      if (!pk1) {
        groupsVvec[i] = pk2
      } else {
        bls.publicKeyAdd(pk1, pk2)
        bls.free(pk2)
      }
    })
  })
  return groupsVvec
}