git ssb

0+

wanderer🌟 / bls-lib



Tree: dd9d879f2923aa9578ec24749c24fc658a74ff0b

Files: dd9d879f2923aa9578ec24749c24fc658a74ff0b / index.js

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