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