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