git ssb

0+

wanderer🌟 / bls-lib



Tree: b278e082117e8d0f58457f4e41e9c7b7adfbf9f1

Files: b278e082117e8d0f58457f4e41e9c7b7adfbf9f1 / index.js

12161 bytesRaw
1let initCb = require('nop')
2const Buffer = require('safe-buffer').Buffer
3const mod = require('./build/bls_lib.js')
4const crypto = require('crypto')
5crypto.getRandomValues = crypto.randomFillSync
6
7let init = false
8
9exports.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 */
15exports.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 */
27exports.MCLBN_CURVE_FP254BNB = 0
28
29/**
30 * The FP382_1 curve
31 */
32exports.MCLBN_CURVE_FP382_1 = 1
33
34/**
35 * The FP382_2 curve
36 */
37exports.MCLBN_CURVE_FP382_2 = 2
38
39/**
40 * The BLS12-381 curve
41 */
42exports.MCL_BLS12_381 = 5
43
44const MCLBN_FP_UNIT_SIZE = 6
45const FR_SIZE = MCLBN_FP_UNIT_SIZE * 8
46const ID_SIZE = FR_SIZE
47const G1_SIZE = FR_SIZE * 3
48const G2_SIZE = FR_SIZE * 3 * 2
49
50mod.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
321function returnBool (func) {
322 return function () {
323 return func.apply(null, arguments) === 1
324 }
325}
326
327function 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
343function 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
353function 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
363function memcpy (dst, src, size) {
364 for (let i = 0; i < size; i++) {
365 mod.HEAP8[dst + i] = mod.HEAP8[src + i]
366 }
367}
368
369function 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
382function 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