Files: b278e082117e8d0f58457f4e41e9c7b7adfbf9f1 / index.js
12161 bytesRaw
1 | let initCb = require('nop') |
2 | const Buffer = require('safe-buffer').Buffer |
3 | const mod = require('./build/bls_lib.js') |
4 | const crypto = require('crypto') |
5 | crypto.getRandomValues = crypto.randomFillSync |
6 | |
7 | let init = false |
8 | |
9 | exports.mod = mod |
10 | |
11 | /** |
12 | * Takes a callback that is called once the module is setup |
13 | * @params {Function} cb - the callback to be called once the module is initialized |
14 | */ |
15 | exports.onModuleInit = function (cb) { |
16 | if (init) { |
17 | cb() |
18 | } else { |
19 | init = true |
20 | initCb = cb |
21 | } |
22 | } |
23 | |
24 | /** |
25 | * The FP254BNB curve |
26 | */ |
27 | exports.MCLBN_CURVE_FP254BNB = 0 |
28 | |
29 | /** |
30 | * The FP382_1 curve |
31 | */ |
32 | exports.MCLBN_CURVE_FP382_1 = 1 |
33 | |
34 | /** |
35 | * The FP382_2 curve |
36 | */ |
37 | exports.MCLBN_CURVE_FP382_2 = 2 |
38 | |
39 | /** |
40 | * The BLS12-381 curve |
41 | */ |
42 | exports.MCL_BLS12_381 = 5 |
43 | |
44 | const MCLBN_FP_UNIT_SIZE = 6 |
45 | const FR_SIZE = MCLBN_FP_UNIT_SIZE * 8 |
46 | const ID_SIZE = FR_SIZE |
47 | const G1_SIZE = FR_SIZE * 3 |
48 | const G2_SIZE = FR_SIZE * 3 * 2 |
49 | |
50 | mod.onRuntimeInitialized = function () { |
51 | /** |
52 | * Initializes the library to use a given curve |
53 | * @param {number} curve - the curves that can be used are MCLBN_CURVE_FP254BNB, MCLBN_CURVE_FP382_1 or MCLBN_CURVE_FP382_2 |
54 | */ |
55 | exports.init = function (curve = exports.MCLBN_CURVE_FP254BNB) { |
56 | return mod._blsInit(curve, MCLBN_FP_UNIT_SIZE) |
57 | } |
58 | |
59 | /** |
60 | * Allocates a secret key |
61 | * @returns {number} the pointer to the key |
62 | */ |
63 | exports.secretKey = function () { |
64 | return mod._malloc(FR_SIZE) |
65 | } |
66 | |
67 | /** |
68 | * Allocates a secret key |
69 | * @returns {number} the pointer to the key |
70 | */ |
71 | exports.publicKey = function () { |
72 | return mod._malloc(G2_SIZE) |
73 | } |
74 | |
75 | /** |
76 | * Allocates a signature |
77 | * @returns {number} the pointer to the signature |
78 | */ |
79 | exports.signature = function () { |
80 | return mod._malloc(G1_SIZE) |
81 | } |
82 | |
83 | /** |
84 | * Frees a pointer |
85 | */ |
86 | exports.free = function (x) { |
87 | mod._free(x) |
88 | } |
89 | |
90 | /** |
91 | * Frees an array of pointers |
92 | */ |
93 | exports.freeArray = function (a) { |
94 | a.forEach(el => mod._free(el)) |
95 | } |
96 | |
97 | /** |
98 | * Creates an ID from an int to use with threshold groups |
99 | * @param {number} sk - a pointer to the secret key, secret key struct is used to hold the id |
100 | * @param {number} n - a int representing the ID. n cannot be zero. |
101 | */ |
102 | exports.idSetInt = function (sk, n) { |
103 | if (n === 0) { |
104 | throw new Error('id cannot be zero') |
105 | } |
106 | mod._blsIdSetInt(sk, n) |
107 | } |
108 | |
109 | /** |
110 | * Creates an ID from an int and returns a pointer to it |
111 | * @param {number} n - a int representing the ID. n cannot be zero. |
112 | * @return {number} |
113 | */ |
114 | exports.idImportFromInt = function (n) { |
115 | const sk = exports.secretKey() |
116 | exports.idSetInt(sk, n) |
117 | return sk |
118 | } |
119 | |
120 | /** |
121 | * Creates an ID from an int and returns a pointer to it |
122 | * @param {number} n - a int representing the ID. n cannot be zero. |
123 | * @return {number} |
124 | */ |
125 | exports.idImport = function (n) { |
126 | if (Number.isInteger(n)) { |
127 | return exports.idImportFromInt(n) |
128 | } else { |
129 | const sk = exports.secretKey() |
130 | mod._blsHashToSecretKey(sk, n) |
131 | return sk |
132 | } |
133 | } |
134 | |
135 | /** |
136 | * Signs a message |
137 | * @param {number} sig - a pointer to the a signature |
138 | * @param {number} sk - a pointer to the secret key |
139 | * @param {TypedArray|String} msg - the message to sign |
140 | */ |
141 | exports.sign = wrapInput(mod._blsSign) |
142 | |
143 | /** |
144 | * Verifies a signature |
145 | * @param {number} sig - a pointer to the a signature |
146 | * @param {number} pk - a pointer to the secret key |
147 | * @param {TypedArray|String} msg - the message that was signed |
148 | * @returns {Boolean} |
149 | */ |
150 | exports.verify = returnBool(wrapInput(mod._blsVerify)) |
151 | |
152 | /** |
153 | * Given a pointer to a public key, this returns a 64 byte Int8Array containing the key |
154 | * @param {number} pk - a pointer to the secret key |
155 | * @return {TypedArray} |
156 | */ |
157 | exports.publicKeyExport = wrapOutput(mod._blsPublicKeySerialize, 64) |
158 | |
159 | /** |
160 | * Given a pointer to a secret key, this returns a 32 byte Int8Array containing the key |
161 | * @param {number} pk - a pointer to the secret key |
162 | * @return {TypedArray} |
163 | */ |
164 | exports.secretKeyExport = wrapOutput(mod._blsSecretKeySerialize, 32) |
165 | |
166 | /** |
167 | * Given a pointer to a signature, this returns a 32 byte Int8Array containing the signature |
168 | * @param {number} pk - a pointer to the secret key |
169 | * @return {TypedArray} |
170 | */ |
171 | exports.signatureExport = wrapOutput(mod._blsSignatureSerialize, 32) |
172 | |
173 | /** |
174 | * Generates a secret key given a seed phrase |
175 | * @param {number} sk - a pointer to a secret key |
176 | * @param {String|TypedArray} seed - the seed phrase |
177 | */ |
178 | exports.hashToSecretKey = wrapInput(mod._blsHashToSecretKey) |
179 | |
180 | /** |
181 | * Writes a secretKey to memory |
182 | * @param {number} sk - a pointer to a secret key |
183 | * @param {TypedArray} array - the secret key as a 32 byte TypedArray |
184 | */ |
185 | exports.secretKeyDeserialize = wrapDeserialize(mod._blsSecretKeyDeserialize) |
186 | |
187 | /** |
188 | * Writes a secretKey to memory and returns a pointer to it |
189 | * @param {number} sk - a pointer to a secret key |
190 | * @param {TypedArray} array - the secret key as a 32 byte TypedArray |
191 | * @return {Number} |
192 | */ |
193 | exports.secretKeyImport = function (buf) { |
194 | const sk = exports.secretKey() |
195 | exports.secretKeyDeserialize(sk, buf) |
196 | return sk |
197 | } |
198 | |
199 | /** |
200 | * Writes a publicKey to memory |
201 | * @param {number} sk - a pointer to a public key |
202 | * @param {TypedArray} array - the secret key as a 64 byte TypedArray |
203 | */ |
204 | exports.publicKeyDeserialize = wrapDeserialize(mod._blsPublicKeyDeserialize) |
205 | |
206 | /** |
207 | * Writes a publicKey to memory and returns a pointer to it |
208 | * @param {TypedArray} array - the secret key as a 64 byte TypedArray |
209 | * @return {Number} |
210 | */ |
211 | exports.publicKeyImport = function (buf) { |
212 | const pk = exports.publicKey() |
213 | exports.publicKeyDeserialize(pk, buf) |
214 | return pk |
215 | } |
216 | |
217 | /** |
218 | * Writes a signature to memory |
219 | * @param {number} sig - a pointer to a signature |
220 | * @param {TypedArray} array - the signature as a 32 byte TypedArray |
221 | */ |
222 | exports.signatureDeserialize = wrapDeserialize(mod._blsSignatureDeserialize) |
223 | |
224 | /** |
225 | * Writes a signature to memory and returns a pointer to it |
226 | * @param {TypedArray} array - the signature as a 32 byte TypedArray |
227 | * @return {Number} |
228 | */ |
229 | exports.signatureImport = function (buf) { |
230 | const sig = exports.signature() |
231 | exports.signatureDeserialize(sig, buf) |
232 | return sig |
233 | } |
234 | |
235 | /** |
236 | * Initializes a secret key by a Cryptographically Secure Pseudo Random Number Generator |
237 | * @param {TypedArray} array - the secret key as a TypedArray |
238 | */ |
239 | exports.secretKeySetByCSPRNG = mod._blsSecretKeySetByCSPRNG |
240 | |
241 | /** |
242 | * Creates a public key from the secret key |
243 | * @param {TypedArray} array - the public key as a TypedArray |
244 | * @param {TypedArray} array - the secret key as a TypedArray |
245 | */ |
246 | exports.getPublicKey = mod._blsGetPublicKey |
247 | |
248 | /** |
249 | * Recovers a secret key for a group given the groups secret keys shares and the groups ids |
250 | * @param {number} sk - a pointer to a secret key that will be generated |
251 | * @param {Array<number>} sksArray - an array of pointers to the groups secret key shares. The length of the array should be the threshold number for the group |
252 | * @param {Array<numbers>} idArrah - an array of pointers to ids in the groups. The length of the array should be the threshold number for the group |
253 | */ |
254 | exports.secretKeyRecover = wrapRecover(mod._blsSecretKeyRecover, FR_SIZE, ID_SIZE) |
255 | |
256 | /** |
257 | * Recovers a public key for a group given the groups public keys shares and the groups ids |
258 | * @param {number} pk - a pointer to a public key that will be generated |
259 | * @param {Array<number>} pksArray - an array of pointers to the groups public key shares. The length of the array should be the threshold number for the group |
260 | * @param {Array<numbers>} idArrah - an array of pointers to ids in the groups. The length of the array should be the threshold number for the group |
261 | */ |
262 | exports.publicKeyRecover = wrapRecover(mod._blsPublicKeyRecover, G2_SIZE, ID_SIZE) |
263 | |
264 | /** |
265 | * Recovers a signature for a group given the groups public keys shares and the groups ids |
266 | * @param {number} sig - a pointer to the signature that will be generated |
267 | * @param {Array<number>} sigArray - an array of pointers to signature shares. The length of the array should be the threshold number for the group |
268 | * @param {Array<numbers>} idArrah - an array of pointers to ids in the groups. The length of the array should be the threshold number for the group |
269 | */ |
270 | exports.signatureRecover = wrapRecover(mod._blsSignatureRecover, G1_SIZE, ID_SIZE) |
271 | |
272 | /** |
273 | * Creates a secret key share for a group member given the groups members id (which is the secret key) and array of master secret keys |
274 | * @param {number} skshare - a pointer to a secret key that will be generated |
275 | * @param {Array<number>} msk - an array of master secret keys. The number of keys is the threshold of the group. |
276 | * @param {number} id - the id of the member |
277 | */ |
278 | exports.secretKeyShare = wrapKeyShare(mod._blsSecretKeyShare, FR_SIZE) |
279 | |
280 | /** |
281 | * Creates a public key share for a group member given the groups members id (which is a the secret key) and array of master public keys |
282 | * @param {number} pkshare - a pointer to a secret key that will be generated |
283 | * @param {Array<number>} mpk - an array of master public keys. The number of keys is the threshold of the group. |
284 | * @param {number} id - the id of the member |
285 | */ |
286 | exports.publicKeyShare = wrapKeyShare(mod._blsPublicKeyShare, G2_SIZE) |
287 | |
288 | /** |
289 | * Takes two publicKeys and adds them together. pubkey1 = pubkey1 + pubkey2 |
290 | * @param {number} pubkey1 - a pointer to a public key |
291 | * @param {number} pubkey2 - a pointer to a public key |
292 | */ |
293 | exports.publicKeyAdd = mod._blsPublicKeyAdd |
294 | |
295 | /** |
296 | * Takes two secretKeys and adds them together. seckey1 = seckey1 + seckey2 |
297 | * @param {number} seckey1 - a pointer to a secret key |
298 | * @param {number} seckey2 - a pointer to a secret key |
299 | */ |
300 | exports.secretKeyAdd = mod._blsSecretKeyAdd |
301 | |
302 | /** |
303 | * Takes two publicKeys and tests their equality |
304 | * @param {number} pubkey1 - a pointer to a public key |
305 | * @param {number} pubkey2 - a pointer to a public key |
306 | * return {Boolean} |
307 | */ |
308 | exports.publicKeyIsEqual = returnBool(mod._blsPublicKeyIsEqual) |
309 | |
310 | /** |
311 | * Does Diffie–Hellman key exchange |
312 | * @param {number} sharedSecretKey - a pointer to a secretKey that will be populated with the shared secret |
313 | * @param {number} secretKey - a pointer to a secret key |
314 | * @param {number} pubkey - a pointer to a public key |
315 | */ |
316 | exports.dhKeyExchange = mod._blsDHKeyExchange |
317 | |
318 | initCb() |
319 | } |
320 | |
321 | function returnBool (func) { |
322 | return function () { |
323 | return func.apply(null, arguments) === 1 |
324 | } |
325 | } |
326 | |
327 | function wrapInput (func) { |
328 | return function () { |
329 | const args = [...arguments] |
330 | let buf = args.pop() |
331 | if (typeof buf === 'string') { |
332 | buf = Buffer.from(buf) |
333 | } |
334 | const pos = mod._malloc(buf.length) |
335 | |
336 | mod.HEAP8.set(buf, pos) |
337 | let r = func(...args, pos, buf.length) |
338 | mod._free(pos) |
339 | return r |
340 | } |
341 | } |
342 | |
343 | function wrapDeserialize (func) { |
344 | func = wrapInput(func) |
345 | return function (p, buf) { |
346 | const r = func(p, buf) |
347 | if (r === 0) { |
348 | throw new Error('Deserialize err') |
349 | } |
350 | } |
351 | } |
352 | |
353 | function wrapOutput (func, size) { |
354 | return function (x) { |
355 | const pos = mod._malloc(size) |
356 | const n = func(pos, size, x) |
357 | const a = mod.HEAP8.slice(pos, pos + n) |
358 | mod._free(pos) |
359 | return a |
360 | } |
361 | } |
362 | |
363 | function memcpy (dst, src, size) { |
364 | for (let i = 0; i < size; i++) { |
365 | mod.HEAP8[dst + i] = mod.HEAP8[src + i] |
366 | } |
367 | } |
368 | |
369 | function wrapKeyShare (func, dataSize) { |
370 | return function (x, vec, id) { |
371 | const k = vec.length |
372 | const p = mod._malloc(dataSize * k) |
373 | for (let i = 0; i < k; i++) { |
374 | memcpy(p + i * dataSize, vec[i], dataSize) |
375 | } |
376 | const r = func(x, p, k, id) |
377 | mod._free(p) |
378 | return r |
379 | } |
380 | } |
381 | |
382 | function wrapRecover (func, dataSize, idDataSize) { |
383 | return function (x, vec, idVec) { |
384 | const n = vec.length |
385 | const p = mod._malloc(dataSize * n) |
386 | const q = mod._malloc(idDataSize * n) |
387 | for (let i = 0; i < n; i++) { |
388 | memcpy(p + i * dataSize, vec[i], dataSize) |
389 | memcpy(q + i * idDataSize, idVec[i], idDataSize) |
390 | } |
391 | const r = func(x, p, q, n) |
392 | mod._free(q) |
393 | mod._free(p) |
394 | return r |
395 | } |
396 | } |
397 |
Built with git-ssb-web