Files: 22bf66e454af3c3430bd9354d73620173cf52426 / index.js
9795 bytesRaw
1 | const nop = require('nop') |
2 | const mod = require('./build/bls_lib.js') |
3 | const exportedFuncs = require('./exportedFuncs.json') |
4 | |
5 | exports.mod = mod |
6 | |
7 | let init = false |
8 | let initCb = nop |
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 | exportedFuncs.forEach(func => { |
46 | exports[func.exportName] = mod.cwrap(func.name, func.returns, func.args) |
47 | }) |
48 | |
49 | /** |
50 | * intailizes the libary to use a given curve |
51 | * @param {number} curve - the curves that can be used are MCLBN_CURVE_FP254BNB, MCLBN_CURVE_FP382_1 or MCLBN_CURVE_FP382_2 |
52 | */ |
53 | exports.init = function (curve = exports.MCLBN_CURVE_FP254BNB) { |
54 | return exports._init(curve, MCLBN_FP_UNIT_SIZE) |
55 | } |
56 | |
57 | /** |
58 | * allocates a secret key |
59 | * @returns {number} the pointer to the key |
60 | */ |
61 | exports.secretKey = function () { |
62 | return mod._malloc(FR_SIZE) |
63 | } |
64 | |
65 | /** |
66 | * allocates a secret key |
67 | * @returns {number} the pointer to the key |
68 | */ |
69 | exports.publicKey = function () { |
70 | return mod._malloc(G2_SIZE) |
71 | } |
72 | |
73 | /** |
74 | * allocates a signature |
75 | * @returns {number} the pointer to the signture |
76 | */ |
77 | exports.signature = function () { |
78 | return mod._malloc(G1_SIZE) |
79 | } |
80 | |
81 | /** |
82 | * frees a pointer |
83 | */ |
84 | exports.free = function (x) { |
85 | mod._free(x) |
86 | } |
87 | |
88 | /** |
89 | * frees an array of pointers |
90 | */ |
91 | exports.freeArray = function (a) { |
92 | a.forEach(el => mod._free(el)) |
93 | } |
94 | |
95 | /** |
96 | * creates an ID from an int to use in with threshold groups |
97 | * @param {number} sk - a pointer to the secret key, secret key stuct is used to hold the id |
98 | * @param {number} n - a int repsenting the ID. n cannot be zero. |
99 | */ |
100 | exports.idSetInt = function (sk, n) { |
101 | if (n === 0) { |
102 | throw new Error('id cannot be zero') |
103 | } |
104 | exports._idSetInt(sk, n) |
105 | } |
106 | |
107 | /** |
108 | * creates an ID from an int and returns a pointer to it |
109 | * @param {number} n - a int repsenting the ID. n cannot be zero. |
110 | * @return {number} |
111 | */ |
112 | exports.idImportFromInt = function (n) { |
113 | const sk = exports.secretKey() |
114 | exports.idSetInt(sk, n) |
115 | return sk |
116 | } |
117 | |
118 | /** |
119 | * signs a message |
120 | * @param {number} sig - a pointer to the a signature |
121 | * @param {number} sk - a pointer to the secret key |
122 | * @param {TypedArray|String} msg - the message to sign |
123 | */ |
124 | exports.sign = wrapInput(exports._sign) |
125 | |
126 | /** |
127 | * verifies a signature |
128 | * @param {number} sig - a pointer to the a signature |
129 | * @param {number} pk - a pointer to the secret key |
130 | * @param {TypedArray|String} msg - the message that was signed |
131 | */ |
132 | exports.verify = wrapInput(exports._verify, true) |
133 | |
134 | /** |
135 | * given a pointer to a public key this returns 64 byte Int8Array containing the key |
136 | * @param {number} pk - a pointer to the secret key |
137 | * @return {TypedArray} |
138 | */ |
139 | exports.publicKeyExport = wrapOutput(exports._publicKeySerialize, 64) |
140 | |
141 | /** |
142 | * given a pointer to a secret key this returns 32 byte Int8Array containing the key |
143 | * @param {number} pk - a pointer to the secret key |
144 | * @return {TypedArray} |
145 | */ |
146 | exports.secretKeyExport = wrapOutput(exports._secretKeySerialize, 32) |
147 | |
148 | /** |
149 | * given a pointer to a signature this returns 32 byte Int8Array containing the signature |
150 | * @param {number} pk - a pointer to the secret key |
151 | * @return {TypedArray} |
152 | */ |
153 | exports.signatureExport = wrapOutput(exports._signatureSerialize, 32) |
154 | |
155 | /** |
156 | * generates a secret key given a seed phrase. |
157 | * @param {number} sk - a pointer to a secret key |
158 | * @param {String|TypedArray} seed - the seed phrase |
159 | */ |
160 | exports.hashToSecretKey = wrapInput(exports._hashToSecretKey, true) |
161 | |
162 | /** |
163 | * write a secretKey to memory |
164 | * @param {number} sk - a pointer to a secret key |
165 | * @param {TypedArray} array - the secret key as a 32 byte TypedArray |
166 | */ |
167 | exports.secretKeyDeserialize = wrapInput(exports._secretKeyDeserialize, true) |
168 | |
169 | /** |
170 | * write a secretKey to memory and returns a pointer to it |
171 | * @param {number} sk - a pointer to a secret key |
172 | * @param {TypedArray} array - the secret key as a 32 byte TypedArray |
173 | * @return {Number} |
174 | */ |
175 | exports.secretKeyImport = function (buf) { |
176 | const sk = exports.secretKey() |
177 | exports.secretKeyDeserialize(sk, buf) |
178 | return sk |
179 | } |
180 | |
181 | /** |
182 | * write a publicKey to memory |
183 | * @param {number} sk - a pointer to a public key |
184 | * @param {TypedArray} array - the secret key as a 64 byte TypedArray |
185 | */ |
186 | exports.publicKeyDeserialize = wrapInput(exports._publicKeyDeserialize, true) |
187 | |
188 | /** |
189 | * write a publicKey to memory and returns a pointer to it |
190 | * @param {TypedArray} array - the secret key as a 64 byte TypedArray |
191 | * @return {Number} |
192 | */ |
193 | exports.publicKeyImport = function (buf) { |
194 | const pk = exports.publicKey() |
195 | exports.publicKeyDeserialize(pk, buf) |
196 | return pk |
197 | } |
198 | |
199 | /** |
200 | * write a signature to memory |
201 | * @param {number} sig - a pointer to a signature |
202 | * @param {TypedArray} array - the signature as a 32 byte TypedArray |
203 | */ |
204 | exports.signatureDeserialize = wrapInput(exports._signatureDeserialize) |
205 | |
206 | /** |
207 | * write a signature to memory and returns a pointer to it |
208 | * @param {TypedArray} array - the signature as a 32 byte TypedArray |
209 | * @return {Number} |
210 | */ |
211 | exports.signatureImport = function (buf) { |
212 | const sig = exports.signature() |
213 | exports.signatureDeserialize(sig, buf) |
214 | return sig |
215 | } |
216 | |
217 | /** |
218 | * Recovers a secret key for a group given the groups secret keys shares and the groups ids |
219 | * @param {number} sk - a pointer to a secret key that will be generated |
220 | * @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 |
221 | * @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 |
222 | */ |
223 | exports.secretKeyRecover = wrapRecover(exports._secretKeyRecover, FR_SIZE, ID_SIZE) |
224 | |
225 | /** |
226 | * Recovers a public key for a group given the groups public keys shares and the groups ids |
227 | * @param {number} pk - a pointer to a secret key that will be generated |
228 | * @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 |
229 | * @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 |
230 | */ |
231 | exports.publicKeyRecover = wrapRecover(exports._publicKeyRecover, G2_SIZE, ID_SIZE) |
232 | |
233 | /** |
234 | * Recovers a signature for a group given the groups public keys shares and the groups ids |
235 | * @param {number} sig - a pointer to the signature that will be generated |
236 | * @param {Array<number>} sigArray - an array of pointers to signature shares. The length of the array should be the threshold number for the group |
237 | * @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 |
238 | */ |
239 | exports.signatureRecover = wrapRecover(exports._signatureRecover, G1_SIZE, ID_SIZE) |
240 | |
241 | /** |
242 | * 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 |
243 | * @param {number} skshare - a pointer to a secret key that will be generated |
244 | * @param {Array<number>} msk - an array of master secret keys. The number of keys is the threshould of the group. |
245 | * @param {number} id - the id of the member |
246 | */ |
247 | exports.secretKeyShare = wrapKeyShare(exports._secretKeyShare, FR_SIZE) |
248 | |
249 | /** |
250 | * 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 |
251 | * @param {number} pkshare - a pointer to a secret key that will be generated |
252 | * @param {Array<number>} mpk - an array of master public keys. The number of keys is the threshould of the group. |
253 | * @param {number} id - the id of the member |
254 | */ |
255 | exports.publicKeyShare = wrapKeyShare(exports._publicKeyShare, G2_SIZE) |
256 | |
257 | initCb() |
258 | } |
259 | |
260 | function wrapInput (func) { |
261 | return function () { |
262 | const args = [...arguments] |
263 | let buf = args.pop() |
264 | if (typeof buf === 'string') { |
265 | buf = Buffer.from(buf) |
266 | } |
267 | const pos = mod._malloc(buf.length) |
268 | |
269 | mod.HEAP8.set(buf, pos) |
270 | let r = func(...args, pos, buf.length) |
271 | mod._free(pos) |
272 | return r |
273 | } |
274 | } |
275 | |
276 | function wrapOutput (func, size) { |
277 | return function (x) { |
278 | const pos = mod._malloc(size) |
279 | const n = func(pos, size, x) |
280 | const a = mod.HEAP8.slice(pos, pos + n) |
281 | mod._free(pos) |
282 | return a |
283 | } |
284 | } |
285 | |
286 | function wrapKeyShare (func, dataSize) { |
287 | return function (x, vec, id) { |
288 | const k = vec.length |
289 | const p = mod._malloc(dataSize * k) |
290 | for (let i = 0; i < k; i++) { |
291 | mod._memcpy(p + i * dataSize, vec[i], dataSize) |
292 | } |
293 | const r = func(x, p, k, id) |
294 | mod._free(p) |
295 | return r |
296 | } |
297 | } |
298 | |
299 | function wrapRecover (func, dataSize, idDataSize) { |
300 | return function (x, vec, idVec) { |
301 | const n = vec.length |
302 | const p = mod._malloc(dataSize * n) |
303 | const q = mod._malloc(idDataSize * n) |
304 | for (let i = 0; i < n; i++) { |
305 | mod._memcpy(p + i * dataSize, vec[i], dataSize) |
306 | mod._memcpy(q + i * idDataSize, idVec[i], idDataSize) |
307 | } |
308 | const r = func(x, p, q, n) |
309 | mod._free(q) |
310 | mod._free(p) |
311 | return r |
312 | } |
313 | } |
314 |
Built with git-ssb-web