-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathindex.js
147 lines (128 loc) · 4.23 KB
/
index.js
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
/**
* generates a members contribution to the DKG
* @param {Object} bls - an instance of [bls-wasm](https://github.com/herumi/bls-wasm)
* @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 = new bls.SecretKey()
sk.setByCSPRNG()
svec.push(sk)
const pk = sk.getPublicKey()
vvec.push(pk)
}
// generate key shares
for (const id of ids) {
const sk = new bls.SecretKey()
sk.share(svec, id)
skContribution.push(sk)
}
svec.forEach(s => s.clear())
return {
verificationVector: vvec,
secretKeyContribution: skContribution
}
}
/**
* generates a members contribution to the DKG, ensuring the secret is null
* @param {Object} bls - an instance of [bls-wasm](https://github.com/herumi/bls-wasm)
* @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 = new bls.SecretKey()
zeroSK.deserialize(zeroArray)
svec.push(zeroSK)
const zeroPK = zeroSK.getPublicKey()
vvec.push(zeroPK)
// generate a sk and vvec
for (let i = 1; i < threshold; i++) {
const sk = new bls.SecretKey()
sk.setByCSPRNG()
svec.push(sk)
const pk = sk.getPublicKey()
vvec.push(pk)
}
// generate key shares
for (const id of ids) {
const sk = new bls.SecretKey()
sk.share(svec, id)
skContribution.push(sk)
}
svec.forEach(s => s.clear())
return {
verificationVector: vvec,
secretKeyContribution: skContribution
}
}
/**
* Adds secret key contribution together to produce a single secret key
* @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 (secretKeyShares) {
const first = secretKeyShares.pop()
secretKeyShares.forEach(sk => {
first.add(sk)
sk.clear()
})
return first
}
/**
* Verifies a contribution share
* @param {Object} bls - an instance of [bls-wasm](https://github.com/herumi/bls-wasm)
* @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 = new bls.PublicKey()
pk1.share(vvec, id)
const pk2 = contribution.getPublicKey()
const isEqual = pk1.isEqual(pk2)
pk1.clear()
pk2.clear()
return Boolean(isEqual)
}
/**
* Adds an array of verification vectors together to produce the groups verification vector
* @param {Array<Array<Number>>} vvecs - an array containing all the groups verifciation vectors
*/
exports.addVerificationVectors = function (vvecs) {
const groupsVvec = []
vvecs.forEach(vvec => {
vvec.forEach((pk2, i) => {
let pk1 = groupsVvec[i]
if (!pk1) {
groupsVvec[i] = pk2
} else {
pk1.add(pk2)
pk2.clear()
}
})
})
return groupsVvec
}