websnark/example/main.js
example/main.jsRaw
1(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2module.exports.buildF1 = require("./src/f1.js");
3module.exports.buildBn128 = require("./src/bn128.js");
4module.exports.buildGroth16 = require("./src/groth16.js");
5
6},{"./src/bn128.js":3,"./src/f1.js":15,"./src/groth16.js":16}],2:[function(require,module,exports){
7var bigInt = (function (undefined) {
8 "use strict";
9
10 var BASE = 1e7,
11 LOG_BASE = 7,
12 MAX_INT = 9007199254740992,
13 MAX_INT_ARR = smallToArray(MAX_INT),
14 DEFAULT_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
15
16 var supportsNativeBigInt = typeof BigInt === "function";
17
18 function Integer(v, radix, alphabet, caseSensitive) {
19 if (typeof v === "undefined") return Integer[0];
20 if (typeof radix !== "undefined") return +radix === 10 && !alphabet ? parseValue(v) : parseBase(v, radix, alphabet, caseSensitive);
21 return parseValue(v);
22 }
23
24 function BigInteger(value, sign) {
25 this.value = value;
26 this.sign = sign;
27 this.isSmall = false;
28 }
29 BigInteger.prototype = Object.create(Integer.prototype);
30
31 function SmallInteger(value) {
32 this.value = value;
33 this.sign = value < 0;
34 this.isSmall = true;
35 }
36 SmallInteger.prototype = Object.create(Integer.prototype);
37
38 function NativeBigInt(value) {
39 this.value = value;
40 }
41 NativeBigInt.prototype = Object.create(Integer.prototype);
42
43 function isPrecise(n) {
44 return -MAX_INT < n && n < MAX_INT;
45 }
46
47 function smallToArray(n) { // For performance reasons doesn't reference BASE, need to change this function if BASE changes
48 if (n < 1e7)
49 return [n];
50 if (n < 1e14)
51 return [n % 1e7, Math.floor(n / 1e7)];
52 return [n % 1e7, Math.floor(n / 1e7) % 1e7, Math.floor(n / 1e14)];
53 }
54
55 function arrayToSmall(arr) { // If BASE changes this function may need to change
56 trim(arr);
57 var length = arr.length;
58 if (length < 4 && compareAbs(arr, MAX_INT_ARR) < 0) {
59 switch (length) {
60 case 0: return 0;
61 case 1: return arr[0];
62 case 2: return arr[0] + arr[1] * BASE;
63 default: return arr[0] + (arr[1] + arr[2] * BASE) * BASE;
64 }
65 }
66 return arr;
67 }
68
69 function trim(v) {
70 var i = v.length;
71 while (v[--i] === 0);
72 v.length = i + 1;
73 }
74
75 function createArray(length) { // function shamelessly stolen from Yaffle's library https://github.com/Yaffle/BigInteger
76 var x = new Array(length);
77 var i = -1;
78 while (++i < length) {
79 x[i] = 0;
80 }
81 return x;
82 }
83
84 function truncate(n) {
85 if (n > 0) return Math.floor(n);
86 return Math.ceil(n);
87 }
88
89 function add(a, b) { // assumes a and b are arrays with a.length >= b.length
90 var l_a = a.length,
91 l_b = b.length,
92 r = new Array(l_a),
93 carry = 0,
94 base = BASE,
95 sum, i;
96 for (i = 0; i < l_b; i++) {
97 sum = a[i] + b[i] + carry;
98 carry = sum >= base ? 1 : 0;
99 r[i] = sum - carry * base;
100 }
101 while (i < l_a) {
102 sum = a[i] + carry;
103 carry = sum === base ? 1 : 0;
104 r[i++] = sum - carry * base;
105 }
106 if (carry > 0) r.push(carry);
107 return r;
108 }
109
110 function addAny(a, b) {
111 if (a.length >= b.length) return add(a, b);
112 return add(b, a);
113 }
114
115 function addSmall(a, carry) { // assumes a is array, carry is number with 0 <= carry < MAX_INT
116 var l = a.length,
117 r = new Array(l),
118 base = BASE,
119 sum, i;
120 for (i = 0; i < l; i++) {
121 sum = a[i] - base + carry;
122 carry = Math.floor(sum / base);
123 r[i] = sum - carry * base;
124 carry += 1;
125 }
126 while (carry > 0) {
127 r[i++] = carry % base;
128 carry = Math.floor(carry / base);
129 }
130 return r;
131 }
132
133 BigInteger.prototype.add = function (v) {
134 var n = parseValue(v);
135 if (this.sign !== n.sign) {
136 return this.subtract(n.negate());
137 }
138 var a = this.value, b = n.value;
139 if (n.isSmall) {
140 return new BigInteger(addSmall(a, Math.abs(b)), this.sign);
141 }
142 return new BigInteger(addAny(a, b), this.sign);
143 };
144 BigInteger.prototype.plus = BigInteger.prototype.add;
145
146 SmallInteger.prototype.add = function (v) {
147 var n = parseValue(v);
148 var a = this.value;
149 if (a < 0 !== n.sign) {
150 return this.subtract(n.negate());
151 }
152 var b = n.value;
153 if (n.isSmall) {
154 if (isPrecise(a + b)) return new SmallInteger(a + b);
155 b = smallToArray(Math.abs(b));
156 }
157 return new BigInteger(addSmall(b, Math.abs(a)), a < 0);
158 };
159 SmallInteger.prototype.plus = SmallInteger.prototype.add;
160
161 NativeBigInt.prototype.add = function (v) {
162 return new NativeBigInt(this.value + parseValue(v).value);
163 }
164 NativeBigInt.prototype.plus = NativeBigInt.prototype.add;
165
166 function subtract(a, b) { // assumes a and b are arrays with a >= b
167 var a_l = a.length,
168 b_l = b.length,
169 r = new Array(a_l),
170 borrow = 0,
171 base = BASE,
172 i, difference;
173 for (i = 0; i < b_l; i++) {
174 difference = a[i] - borrow - b[i];
175 if (difference < 0) {
176 difference += base;
177 borrow = 1;
178 } else borrow = 0;
179 r[i] = difference;
180 }
181 for (i = b_l; i < a_l; i++) {
182 difference = a[i] - borrow;
183 if (difference < 0) difference += base;
184 else {
185 r[i++] = difference;
186 break;
187 }
188 r[i] = difference;
189 }
190 for (; i < a_l; i++) {
191 r[i] = a[i];
192 }
193 trim(r);
194 return r;
195 }
196
197 function subtractAny(a, b, sign) {
198 var value;
199 if (compareAbs(a, b) >= 0) {
200 value = subtract(a, b);
201 } else {
202 value = subtract(b, a);
203 sign = !sign;
204 }
205 value = arrayToSmall(value);
206 if (typeof value === "number") {
207 if (sign) value = -value;
208 return new SmallInteger(value);
209 }
210 return new BigInteger(value, sign);
211 }
212
213 function subtractSmall(a, b, sign) { // assumes a is array, b is number with 0 <= b < MAX_INT
214 var l = a.length,
215 r = new Array(l),
216 carry = -b,
217 base = BASE,
218 i, difference;
219 for (i = 0; i < l; i++) {
220 difference = a[i] + carry;
221 carry = Math.floor(difference / base);
222 difference %= base;
223 r[i] = difference < 0 ? difference + base : difference;
224 }
225 r = arrayToSmall(r);
226 if (typeof r === "number") {
227 if (sign) r = -r;
228 return new SmallInteger(r);
229 } return new BigInteger(r, sign);
230 }
231
232 BigInteger.prototype.subtract = function (v) {
233 var n = parseValue(v);
234 if (this.sign !== n.sign) {
235 return this.add(n.negate());
236 }
237 var a = this.value, b = n.value;
238 if (n.isSmall)
239 return subtractSmall(a, Math.abs(b), this.sign);
240 return subtractAny(a, b, this.sign);
241 };
242 BigInteger.prototype.minus = BigInteger.prototype.subtract;
243
244 SmallInteger.prototype.subtract = function (v) {
245 var n = parseValue(v);
246 var a = this.value;
247 if (a < 0 !== n.sign) {
248 return this.add(n.negate());
249 }
250 var b = n.value;
251 if (n.isSmall) {
252 return new SmallInteger(a - b);
253 }
254 return subtractSmall(b, Math.abs(a), a >= 0);
255 };
256 SmallInteger.prototype.minus = SmallInteger.prototype.subtract;
257
258 NativeBigInt.prototype.subtract = function (v) {
259 return new NativeBigInt(this.value - parseValue(v).value);
260 }
261 NativeBigInt.prototype.minus = NativeBigInt.prototype.subtract;
262
263 BigInteger.prototype.negate = function () {
264 return new BigInteger(this.value, !this.sign);
265 };
266 SmallInteger.prototype.negate = function () {
267 var sign = this.sign;
268 var small = new SmallInteger(-this.value);
269 small.sign = !sign;
270 return small;
271 };
272 NativeBigInt.prototype.negate = function () {
273 return new NativeBigInt(-this.value);
274 }
275
276 BigInteger.prototype.abs = function () {
277 return new BigInteger(this.value, false);
278 };
279 SmallInteger.prototype.abs = function () {
280 return new SmallInteger(Math.abs(this.value));
281 };
282 NativeBigInt.prototype.abs = function () {
283 return new NativeBigInt(this.value >= 0 ? this.value : -this.value);
284 }
285
286
287 function multiplyLong(a, b) {
288 var a_l = a.length,
289 b_l = b.length,
290 l = a_l + b_l,
291 r = createArray(l),
292 base = BASE,
293 product, carry, i, a_i, b_j;
294 for (i = 0; i < a_l; ++i) {
295 a_i = a[i];
296 for (var j = 0; j < b_l; ++j) {
297 b_j = b[j];
298 product = a_i * b_j + r[i + j];
299 carry = Math.floor(product / base);
300 r[i + j] = product - carry * base;
301 r[i + j + 1] += carry;
302 }
303 }
304 trim(r);
305 return r;
306 }
307
308 function multiplySmall(a, b) { // assumes a is array, b is number with |b| < BASE
309 var l = a.length,
310 r = new Array(l),
311 base = BASE,
312 carry = 0,
313 product, i;
314 for (i = 0; i < l; i++) {
315 product = a[i] * b + carry;
316 carry = Math.floor(product / base);
317 r[i] = product - carry * base;
318 }
319 while (carry > 0) {
320 r[i++] = carry % base;
321 carry = Math.floor(carry / base);
322 }
323 return r;
324 }
325
326 function shiftLeft(x, n) {
327 var r = [];
328 while (n-- > 0) r.push(0);
329 return r.concat(x);
330 }
331
332 function multiplyKaratsuba(x, y) {
333 var n = Math.max(x.length, y.length);
334
335 if (n <= 30) return multiplyLong(x, y);
336 n = Math.ceil(n / 2);
337
338 var b = x.slice(n),
339 a = x.slice(0, n),
340 d = y.slice(n),
341 c = y.slice(0, n);
342
343 var ac = multiplyKaratsuba(a, c),
344 bd = multiplyKaratsuba(b, d),
345 abcd = multiplyKaratsuba(addAny(a, b), addAny(c, d));
346
347 var product = addAny(addAny(ac, shiftLeft(subtract(subtract(abcd, ac), bd), n)), shiftLeft(bd, 2 * n));
348 trim(product);
349 return product;
350 }
351
352 // The following function is derived from a surface fit of a graph plotting the performance difference
353 // between long multiplication and karatsuba multiplication versus the lengths of the two arrays.
354 function useKaratsuba(l1, l2) {
355 return -0.012 * l1 - 0.012 * l2 + 0.000015 * l1 * l2 > 0;
356 }
357
358 BigInteger.prototype.multiply = function (v) {
359 var n = parseValue(v),
360 a = this.value, b = n.value,
361 sign = this.sign !== n.sign,
362 abs;
363 if (n.isSmall) {
364 if (b === 0) return Integer[0];
365 if (b === 1) return this;
366 if (b === -1) return this.negate();
367 abs = Math.abs(b);
368 if (abs < BASE) {
369 return new BigInteger(multiplySmall(a, abs), sign);
370 }
371 b = smallToArray(abs);
372 }
373 if (useKaratsuba(a.length, b.length)) // Karatsuba is only faster for certain array sizes
374 return new BigInteger(multiplyKaratsuba(a, b), sign);
375 return new BigInteger(multiplyLong(a, b), sign);
376 };
377
378 BigInteger.prototype.times = BigInteger.prototype.multiply;
379
380 function multiplySmallAndArray(a, b, sign) { // a >= 0
381 if (a < BASE) {
382 return new BigInteger(multiplySmall(b, a), sign);
383 }
384 return new BigInteger(multiplyLong(b, smallToArray(a)), sign);
385 }
386 SmallInteger.prototype._multiplyBySmall = function (a) {
387 if (isPrecise(a.value * this.value)) {
388 return new SmallInteger(a.value * this.value);
389 }
390 return multiplySmallAndArray(Math.abs(a.value), smallToArray(Math.abs(this.value)), this.sign !== a.sign);
391 };
392 BigInteger.prototype._multiplyBySmall = function (a) {
393 if (a.value === 0) return Integer[0];
394 if (a.value === 1) return this;
395 if (a.value === -1) return this.negate();
396 return multiplySmallAndArray(Math.abs(a.value), this.value, this.sign !== a.sign);
397 };
398 SmallInteger.prototype.multiply = function (v) {
399 return parseValue(v)._multiplyBySmall(this);
400 };
401 SmallInteger.prototype.times = SmallInteger.prototype.multiply;
402
403 NativeBigInt.prototype.multiply = function (v) {
404 return new NativeBigInt(this.value * parseValue(v).value);
405 }
406 NativeBigInt.prototype.times = NativeBigInt.prototype.multiply;
407
408 function square(a) {
409 //console.assert(2 * BASE * BASE < MAX_INT);
410 var l = a.length,
411 r = createArray(l + l),
412 base = BASE,
413 product, carry, i, a_i, a_j;
414 for (i = 0; i < l; i++) {
415 a_i = a[i];
416 carry = 0 - a_i * a_i;
417 for (var j = i; j < l; j++) {
418 a_j = a[j];
419 product = 2 * (a_i * a_j) + r[i + j] + carry;
420 carry = Math.floor(product / base);
421 r[i + j] = product - carry * base;
422 }
423 r[i + l] = carry;
424 }
425 trim(r);
426 return r;
427 }
428
429 BigInteger.prototype.square = function () {
430 return new BigInteger(square(this.value), false);
431 };
432
433 SmallInteger.prototype.square = function () {
434 var value = this.value * this.value;
435 if (isPrecise(value)) return new SmallInteger(value);
436 return new BigInteger(square(smallToArray(Math.abs(this.value))), false);
437 };
438
439 NativeBigInt.prototype.square = function (v) {
440 return new NativeBigInt(this.value * this.value);
441 }
442
443 function divMod1(a, b) { // Left over from previous version. Performs faster than divMod2 on smaller input sizes.
444 var a_l = a.length,
445 b_l = b.length,
446 base = BASE,
447 result = createArray(b.length),
448 divisorMostSignificantDigit = b[b_l - 1],
449 // normalization
450 lambda = Math.ceil(base / (2 * divisorMostSignificantDigit)),
451 remainder = multiplySmall(a, lambda),
452 divisor = multiplySmall(b, lambda),
453 quotientDigit, shift, carry, borrow, i, l, q;
454 if (remainder.length <= a_l) remainder.push(0);
455 divisor.push(0);
456 divisorMostSignificantDigit = divisor[b_l - 1];
457 for (shift = a_l - b_l; shift >= 0; shift--) {
458 quotientDigit = base - 1;
459 if (remainder[shift + b_l] !== divisorMostSignificantDigit) {
460 quotientDigit = Math.floor((remainder[shift + b_l] * base + remainder[shift + b_l - 1]) / divisorMostSignificantDigit);
461 }
462 // quotientDigit <= base - 1
463 carry = 0;
464 borrow = 0;
465 l = divisor.length;
466 for (i = 0; i < l; i++) {
467 carry += quotientDigit * divisor[i];
468 q = Math.floor(carry / base);
469 borrow += remainder[shift + i] - (carry - q * base);
470 carry = q;
471 if (borrow < 0) {
472 remainder[shift + i] = borrow + base;
473 borrow = -1;
474 } else {
475 remainder[shift + i] = borrow;
476 borrow = 0;
477 }
478 }
479 while (borrow !== 0) {
480 quotientDigit -= 1;
481 carry = 0;
482 for (i = 0; i < l; i++) {
483 carry += remainder[shift + i] - base + divisor[i];
484 if (carry < 0) {
485 remainder[shift + i] = carry + base;
486 carry = 0;
487 } else {
488 remainder[shift + i] = carry;
489 carry = 1;
490 }
491 }
492 borrow += carry;
493 }
494 result[shift] = quotientDigit;
495 }
496 // denormalization
497 remainder = divModSmall(remainder, lambda)[0];
498 return [arrayToSmall(result), arrayToSmall(remainder)];
499 }
500
501 function divMod2(a, b) { // Implementation idea shamelessly stolen from Silent Matt's library http://silentmatt.com/biginteger/
502 // Performs faster than divMod1 on larger input sizes.
503 var a_l = a.length,
504 b_l = b.length,
505 result = [],
506 part = [],
507 base = BASE,
508 guess, xlen, highx, highy, check;
509 while (a_l) {
510 part.unshift(a[--a_l]);
511 trim(part);
512 if (compareAbs(part, b) < 0) {
513 result.push(0);
514 continue;
515 }
516 xlen = part.length;
517 highx = part[xlen - 1] * base + part[xlen - 2];
518 highy = b[b_l - 1] * base + b[b_l - 2];
519 if (xlen > b_l) {
520 highx = (highx + 1) * base;
521 }
522 guess = Math.ceil(highx / highy);
523 do {
524 check = multiplySmall(b, guess);
525 if (compareAbs(check, part) <= 0) break;
526 guess--;
527 } while (guess);
528 result.push(guess);
529 part = subtract(part, check);
530 }
531 result.reverse();
532 return [arrayToSmall(result), arrayToSmall(part)];
533 }
534
535 function divModSmall(value, lambda) {
536 var length = value.length,
537 quotient = createArray(length),
538 base = BASE,
539 i, q, remainder, divisor;
540 remainder = 0;
541 for (i = length - 1; i >= 0; --i) {
542 divisor = remainder * base + value[i];
543 q = truncate(divisor / lambda);
544 remainder = divisor - q * lambda;
545 quotient[i] = q | 0;
546 }
547 return [quotient, remainder | 0];
548 }
549
550 function divModAny(self, v) {
551 var value, n = parseValue(v);
552 if (supportsNativeBigInt) {
553 return [new NativeBigInt(self.value / n.value), new NativeBigInt(self.value % n.value)];
554 }
555 var a = self.value, b = n.value;
556 var quotient;
557 if (b === 0) throw new Error("Cannot divide by zero");
558 if (self.isSmall) {
559 if (n.isSmall) {
560 return [new SmallInteger(truncate(a / b)), new SmallInteger(a % b)];
561 }
562 return [Integer[0], self];
563 }
564 if (n.isSmall) {
565 if (b === 1) return [self, Integer[0]];
566 if (b == -1) return [self.negate(), Integer[0]];
567 var abs = Math.abs(b);
568 if (abs < BASE) {
569 value = divModSmall(a, abs);
570 quotient = arrayToSmall(value[0]);
571 var remainder = value[1];
572 if (self.sign) remainder = -remainder;
573 if (typeof quotient === "number") {
574 if (self.sign !== n.sign) quotient = -quotient;
575 return [new SmallInteger(quotient), new SmallInteger(remainder)];
576 }
577 return [new BigInteger(quotient, self.sign !== n.sign), new SmallInteger(remainder)];
578 }
579 b = smallToArray(abs);
580 }
581 var comparison = compareAbs(a, b);
582 if (comparison === -1) return [Integer[0], self];
583 if (comparison === 0) return [Integer[self.sign === n.sign ? 1 : -1], Integer[0]];
584
585 // divMod1 is faster on smaller input sizes
586 if (a.length + b.length <= 200)
587 value = divMod1(a, b);
588 else value = divMod2(a, b);
589
590 quotient = value[0];
591 var qSign = self.sign !== n.sign,
592 mod = value[1],
593 mSign = self.sign;
594 if (typeof quotient === "number") {
595 if (qSign) quotient = -quotient;
596 quotient = new SmallInteger(quotient);
597 } else quotient = new BigInteger(quotient, qSign);
598 if (typeof mod === "number") {
599 if (mSign) mod = -mod;
600 mod = new SmallInteger(mod);
601 } else mod = new BigInteger(mod, mSign);
602 return [quotient, mod];
603 }
604
605 BigInteger.prototype.divmod = function (v) {
606 var result = divModAny(this, v);
607 return {
608 quotient: result[0],
609 remainder: result[1]
610 };
611 };
612 NativeBigInt.prototype.divmod = SmallInteger.prototype.divmod = BigInteger.prototype.divmod;
613
614
615 BigInteger.prototype.divide = function (v) {
616 return divModAny(this, v)[0];
617 };
618 NativeBigInt.prototype.over = NativeBigInt.prototype.divide = function (v) {
619 return new NativeBigInt(this.value / parseValue(v).value);
620 };
621 SmallInteger.prototype.over = SmallInteger.prototype.divide = BigInteger.prototype.over = BigInteger.prototype.divide;
622
623 BigInteger.prototype.mod = function (v) {
624 return divModAny(this, v)[1];
625 };
626 NativeBigInt.prototype.mod = NativeBigInt.prototype.remainder = function (v) {
627 return new NativeBigInt(this.value % parseValue(v).value);
628 };
629 SmallInteger.prototype.remainder = SmallInteger.prototype.mod = BigInteger.prototype.remainder = BigInteger.prototype.mod;
630
631 BigInteger.prototype.pow = function (v) {
632 var n = parseValue(v),
633 a = this.value,
634 b = n.value,
635 value, x, y;
636 if (b === 0) return Integer[1];
637 if (a === 0) return Integer[0];
638 if (a === 1) return Integer[1];
639 if (a === -1) return n.isEven() ? Integer[1] : Integer[-1];
640 if (n.sign) {
641 return Integer[0];
642 }
643 if (!n.isSmall) throw new Error("The exponent " + n.toString() + " is too large.");
644 if (this.isSmall) {
645 if (isPrecise(value = Math.pow(a, b)))
646 return new SmallInteger(truncate(value));
647 }
648 x = this;
649 y = Integer[1];
650 while (true) {
651 if (b & 1 === 1) {
652 y = y.times(x);
653 --b;
654 }
655 if (b === 0) break;
656 b /= 2;
657 x = x.square();
658 }
659 return y;
660 };
661 SmallInteger.prototype.pow = BigInteger.prototype.pow;
662
663 NativeBigInt.prototype.pow = function (v) {
664 var n = parseValue(v);
665 var a = this.value, b = n.value;
666 var _0 = BigInt(0), _1 = BigInt(1), _2 = BigInt(2);
667 if (b === _0) return Integer[1];
668 if (a === _0) return Integer[0];
669 if (a === _1) return Integer[1];
670 if (a === BigInt(-1)) return n.isEven() ? Integer[1] : Integer[-1];
671 if (n.isNegative()) return new NativeBigInt(_0);
672 var x = this;
673 var y = Integer[1];
674 while (true) {
675 if ((b & _1) === _1) {
676 y = y.times(x);
677 --b;
678 }
679 if (b === _0) break;
680 b /= _2;
681 x = x.square();
682 }
683 return y;
684 }
685
686 BigInteger.prototype.modPow = function (exp, mod) {
687 exp = parseValue(exp);
688 mod = parseValue(mod);
689 if (mod.isZero()) throw new Error("Cannot take modPow with modulus 0");
690 var r = Integer[1],
691 base = this.mod(mod);
692 while (exp.isPositive()) {
693 if (base.isZero()) return Integer[0];
694 if (exp.isOdd()) r = r.multiply(base).mod(mod);
695 exp = exp.divide(2);
696 base = base.square().mod(mod);
697 }
698 return r;
699 };
700 NativeBigInt.prototype.modPow = SmallInteger.prototype.modPow = BigInteger.prototype.modPow;
701
702 function compareAbs(a, b) {
703 if (a.length !== b.length) {
704 return a.length > b.length ? 1 : -1;
705 }
706 for (var i = a.length - 1; i >= 0; i--) {
707 if (a[i] !== b[i]) return a[i] > b[i] ? 1 : -1;
708 }
709 return 0;
710 }
711
712 BigInteger.prototype.compareAbs = function (v) {
713 var n = parseValue(v),
714 a = this.value,
715 b = n.value;
716 if (n.isSmall) return 1;
717 return compareAbs(a, b);
718 };
719 SmallInteger.prototype.compareAbs = function (v) {
720 var n = parseValue(v),
721 a = Math.abs(this.value),
722 b = n.value;
723 if (n.isSmall) {
724 b = Math.abs(b);
725 return a === b ? 0 : a > b ? 1 : -1;
726 }
727 return -1;
728 };
729 NativeBigInt.prototype.compareAbs = function (v) {
730 var a = this.value;
731 var b = parseValue(v).value;
732 a = a >= 0 ? a : -a;
733 b = b >= 0 ? b : -b;
734 return a === b ? 0 : a > b ? 1 : -1;
735 }
736
737 BigInteger.prototype.compare = function (v) {
738 // See discussion about comparison with Infinity:
739 // https://github.com/peterolson/BigInteger.js/issues/61
740 if (v === Infinity) {
741 return -1;
742 }
743 if (v === -Infinity) {
744 return 1;
745 }
746
747 var n = parseValue(v),
748 a = this.value,
749 b = n.value;
750 if (this.sign !== n.sign) {
751 return n.sign ? 1 : -1;
752 }
753 if (n.isSmall) {
754 return this.sign ? -1 : 1;
755 }
756 return compareAbs(a, b) * (this.sign ? -1 : 1);
757 };
758 BigInteger.prototype.compareTo = BigInteger.prototype.compare;
759
760 SmallInteger.prototype.compare = function (v) {
761 if (v === Infinity) {
762 return -1;
763 }
764 if (v === -Infinity) {
765 return 1;
766 }
767
768 var n = parseValue(v),
769 a = this.value,
770 b = n.value;
771 if (n.isSmall) {
772 return a == b ? 0 : a > b ? 1 : -1;
773 }
774 if (a < 0 !== n.sign) {
775 return a < 0 ? -1 : 1;
776 }
777 return a < 0 ? 1 : -1;
778 };
779 SmallInteger.prototype.compareTo = SmallInteger.prototype.compare;
780
781 NativeBigInt.prototype.compare = function (v) {
782 if (v === Infinity) {
783 return -1;
784 }
785 if (v === -Infinity) {
786 return 1;
787 }
788 var a = this.value;
789 var b = parseValue(v).value;
790 return a === b ? 0 : a > b ? 1 : -1;
791 }
792 NativeBigInt.prototype.compareTo = NativeBigInt.prototype.compare;
793
794 BigInteger.prototype.equals = function (v) {
795 return this.compare(v) === 0;
796 };
797 NativeBigInt.prototype.eq = NativeBigInt.prototype.equals = SmallInteger.prototype.eq = SmallInteger.prototype.equals = BigInteger.prototype.eq = BigInteger.prototype.equals;
798
799 BigInteger.prototype.notEquals = function (v) {
800 return this.compare(v) !== 0;
801 };
802 NativeBigInt.prototype.neq = NativeBigInt.prototype.notEquals = SmallInteger.prototype.neq = SmallInteger.prototype.notEquals = BigInteger.prototype.neq = BigInteger.prototype.notEquals;
803
804 BigInteger.prototype.greater = function (v) {
805 return this.compare(v) > 0;
806 };
807 NativeBigInt.prototype.gt = NativeBigInt.prototype.greater = SmallInteger.prototype.gt = SmallInteger.prototype.greater = BigInteger.prototype.gt = BigInteger.prototype.greater;
808
809 BigInteger.prototype.lesser = function (v) {
810 return this.compare(v) < 0;
811 };
812 NativeBigInt.prototype.lt = NativeBigInt.prototype.lesser = SmallInteger.prototype.lt = SmallInteger.prototype.lesser = BigInteger.prototype.lt = BigInteger.prototype.lesser;
813
814 BigInteger.prototype.greaterOrEquals = function (v) {
815 return this.compare(v) >= 0;
816 };
817 NativeBigInt.prototype.geq = NativeBigInt.prototype.greaterOrEquals = SmallInteger.prototype.geq = SmallInteger.prototype.greaterOrEquals = BigInteger.prototype.geq = BigInteger.prototype.greaterOrEquals;
818
819 BigInteger.prototype.lesserOrEquals = function (v) {
820 return this.compare(v) <= 0;
821 };
822 NativeBigInt.prototype.leq = NativeBigInt.prototype.lesserOrEquals = SmallInteger.prototype.leq = SmallInteger.prototype.lesserOrEquals = BigInteger.prototype.leq = BigInteger.prototype.lesserOrEquals;
823
824 BigInteger.prototype.isEven = function () {
825 return (this.value[0] & 1) === 0;
826 };
827 SmallInteger.prototype.isEven = function () {
828 return (this.value & 1) === 0;
829 };
830 NativeBigInt.prototype.isEven = function () {
831 return (this.value & BigInt(1)) === BigInt(0);
832 }
833
834 BigInteger.prototype.isOdd = function () {
835 return (this.value[0] & 1) === 1;
836 };
837 SmallInteger.prototype.isOdd = function () {
838 return (this.value & 1) === 1;
839 };
840 NativeBigInt.prototype.isOdd = function () {
841 return (this.value & BigInt(1)) === BigInt(1);
842 }
843
844 BigInteger.prototype.isPositive = function () {
845 return !this.sign;
846 };
847 SmallInteger.prototype.isPositive = function () {
848 return this.value > 0;
849 };
850 NativeBigInt.prototype.isPositive = SmallInteger.prototype.isPositive;
851
852 BigInteger.prototype.isNegative = function () {
853 return this.sign;
854 };
855 SmallInteger.prototype.isNegative = function () {
856 return this.value < 0;
857 };
858 NativeBigInt.prototype.isNegative = SmallInteger.prototype.isNegative;
859
860 BigInteger.prototype.isUnit = function () {
861 return false;
862 };
863 SmallInteger.prototype.isUnit = function () {
864 return Math.abs(this.value) === 1;
865 };
866 NativeBigInt.prototype.isUnit = function () {
867 return this.abs().value === BigInt(1);
868 }
869
870 BigInteger.prototype.isZero = function () {
871 return false;
872 };
873 SmallInteger.prototype.isZero = function () {
874 return this.value === 0;
875 };
876 NativeBigInt.prototype.isZero = function () {
877 return this.value === BigInt(0);
878 }
879
880 BigInteger.prototype.isDivisibleBy = function (v) {
881 var n = parseValue(v);
882 if (n.isZero()) return false;
883 if (n.isUnit()) return true;
884 if (n.compareAbs(2) === 0) return this.isEven();
885 return this.mod(n).isZero();
886 };
887 NativeBigInt.prototype.isDivisibleBy = SmallInteger.prototype.isDivisibleBy = BigInteger.prototype.isDivisibleBy;
888
889 function isBasicPrime(v) {
890 var n = v.abs();
891 if (n.isUnit()) return false;
892 if (n.equals(2) || n.equals(3) || n.equals(5)) return true;
893 if (n.isEven() || n.isDivisibleBy(3) || n.isDivisibleBy(5)) return false;
894 if (n.lesser(49)) return true;
895 // we don't know if it's prime: let the other functions figure it out
896 }
897
898 function millerRabinTest(n, a) {
899 var nPrev = n.prev(),
900 b = nPrev,
901 r = 0,
902 d, t, i, x;
903 while (b.isEven()) b = b.divide(2), r++;
904 next: for (i = 0; i < a.length; i++) {
905 if (n.lesser(a[i])) continue;
906 x = bigInt(a[i]).modPow(b, n);
907 if (x.isUnit() || x.equals(nPrev)) continue;
908 for (d = r - 1; d != 0; d--) {
909 x = x.square().mod(n);
910 if (x.isUnit()) return false;
911 if (x.equals(nPrev)) continue next;
912 }
913 return false;
914 }
915 return true;
916 }
917
918 // Set "strict" to true to force GRH-supported lower bound of 2*log(N)^2
919 BigInteger.prototype.isPrime = function (strict) {
920 var isPrime = isBasicPrime(this);
921 if (isPrime !== undefined) return isPrime;
922 var n = this.abs();
923 var bits = n.bitLength();
924 if (bits <= 64)
925 return millerRabinTest(n, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]);
926 var logN = Math.log(2) * bits.toJSNumber();
927 var t = Math.ceil((strict === true) ? (2 * Math.pow(logN, 2)) : logN);
928 for (var a = [], i = 0; i < t; i++) {
929 a.push(bigInt(i + 2));
930 }
931 return millerRabinTest(n, a);
932 };
933 NativeBigInt.prototype.isPrime = SmallInteger.prototype.isPrime = BigInteger.prototype.isPrime;
934
935 BigInteger.prototype.isProbablePrime = function (iterations) {
936 var isPrime = isBasicPrime(this);
937 if (isPrime !== undefined) return isPrime;
938 var n = this.abs();
939 var t = iterations === undefined ? 5 : iterations;
940 for (var a = [], i = 0; i < t; i++) {
941 a.push(bigInt.randBetween(2, n.minus(2)));
942 }
943 return millerRabinTest(n, a);
944 };
945 NativeBigInt.prototype.isProbablePrime = SmallInteger.prototype.isProbablePrime = BigInteger.prototype.isProbablePrime;
946
947 BigInteger.prototype.modInv = function (n) {
948 var t = bigInt.zero, newT = bigInt.one, r = parseValue(n), newR = this.abs(), q, lastT, lastR;
949 while (!newR.isZero()) {
950 q = r.divide(newR);
951 lastT = t;
952 lastR = r;
953 t = newT;
954 r = newR;
955 newT = lastT.subtract(q.multiply(newT));
956 newR = lastR.subtract(q.multiply(newR));
957 }
958 if (!r.isUnit()) throw new Error(this.toString() + " and " + n.toString() + " are not co-prime");
959 if (t.compare(0) === -1) {
960 t = t.add(n);
961 }
962 if (this.isNegative()) {
963 return t.negate();
964 }
965 return t;
966 };
967
968 NativeBigInt.prototype.modInv = SmallInteger.prototype.modInv = BigInteger.prototype.modInv;
969
970 BigInteger.prototype.next = function () {
971 var value = this.value;
972 if (this.sign) {
973 return subtractSmall(value, 1, this.sign);
974 }
975 return new BigInteger(addSmall(value, 1), this.sign);
976 };
977 SmallInteger.prototype.next = function () {
978 var value = this.value;
979 if (value + 1 < MAX_INT) return new SmallInteger(value + 1);
980 return new BigInteger(MAX_INT_ARR, false);
981 };
982 NativeBigInt.prototype.next = function () {
983 return new NativeBigInt(this.value + BigInt(1));
984 }
985
986 BigInteger.prototype.prev = function () {
987 var value = this.value;
988 if (this.sign) {
989 return new BigInteger(addSmall(value, 1), true);
990 }
991 return subtractSmall(value, 1, this.sign);
992 };
993 SmallInteger.prototype.prev = function () {
994 var value = this.value;
995 if (value - 1 > -MAX_INT) return new SmallInteger(value - 1);
996 return new BigInteger(MAX_INT_ARR, true);
997 };
998 NativeBigInt.prototype.prev = function () {
999 return new NativeBigInt(this.value - BigInt(1));
1000 }
1001
1002 var powersOfTwo = [1];
1003 while (2 * powersOfTwo[powersOfTwo.length - 1] <= BASE) powersOfTwo.push(2 * powersOfTwo[powersOfTwo.length - 1]);
1004 var powers2Length = powersOfTwo.length, highestPower2 = powersOfTwo[powers2Length - 1];
1005
1006 function shift_isSmall(n) {
1007 return Math.abs(n) <= BASE;
1008 }
1009
1010 BigInteger.prototype.shiftLeft = function (v) {
1011 var n = parseValue(v).toJSNumber();
1012 if (!shift_isSmall(n)) {
1013 throw new Error(String(n) + " is too large for shifting.");
1014 }
1015 if (n < 0) return this.shiftRight(-n);
1016 var result = this;
1017 if (result.isZero()) return result;
1018 while (n >= powers2Length) {
1019 result = result.multiply(highestPower2);
1020 n -= powers2Length - 1;
1021 }
1022 return result.multiply(powersOfTwo[n]);
1023 };
1024 NativeBigInt.prototype.shiftLeft = SmallInteger.prototype.shiftLeft = BigInteger.prototype.shiftLeft;
1025
1026 BigInteger.prototype.shiftRight = function (v) {
1027 var remQuo;
1028 var n = parseValue(v).toJSNumber();
1029 if (!shift_isSmall(n)) {
1030 throw new Error(String(n) + " is too large for shifting.");
1031 }
1032 if (n < 0) return this.shiftLeft(-n);
1033 var result = this;
1034 while (n >= powers2Length) {
1035 if (result.isZero() || (result.isNegative() && result.isUnit())) return result;
1036 remQuo = divModAny(result, highestPower2);
1037 result = remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
1038 n -= powers2Length - 1;
1039 }
1040 remQuo = divModAny(result, powersOfTwo[n]);
1041 return remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
1042 };
1043 NativeBigInt.prototype.shiftRight = SmallInteger.prototype.shiftRight = BigInteger.prototype.shiftRight;
1044
1045 function bitwise(x, y, fn) {
1046 y = parseValue(y);
1047 var xSign = x.isNegative(), ySign = y.isNegative();
1048 var xRem = xSign ? x.not() : x,
1049 yRem = ySign ? y.not() : y;
1050 var xDigit = 0, yDigit = 0;
1051 var xDivMod = null, yDivMod = null;
1052 var result = [];
1053 while (!xRem.isZero() || !yRem.isZero()) {
1054 xDivMod = divModAny(xRem, highestPower2);
1055 xDigit = xDivMod[1].toJSNumber();
1056 if (xSign) {
1057 xDigit = highestPower2 - 1 - xDigit; // two's complement for negative numbers
1058 }
1059
1060 yDivMod = divModAny(yRem, highestPower2);
1061 yDigit = yDivMod[1].toJSNumber();
1062 if (ySign) {
1063 yDigit = highestPower2 - 1 - yDigit; // two's complement for negative numbers
1064 }
1065
1066 xRem = xDivMod[0];
1067 yRem = yDivMod[0];
1068 result.push(fn(xDigit, yDigit));
1069 }
1070 var sum = fn(xSign ? 1 : 0, ySign ? 1 : 0) !== 0 ? bigInt(-1) : bigInt(0);
1071 for (var i = result.length - 1; i >= 0; i -= 1) {
1072 sum = sum.multiply(highestPower2).add(bigInt(result[i]));
1073 }
1074 return sum;
1075 }
1076
1077 BigInteger.prototype.not = function () {
1078 return this.negate().prev();
1079 };
1080 NativeBigInt.prototype.not = SmallInteger.prototype.not = BigInteger.prototype.not;
1081
1082 BigInteger.prototype.and = function (n) {
1083 return bitwise(this, n, function (a, b) { return a & b; });
1084 };
1085 NativeBigInt.prototype.and = SmallInteger.prototype.and = BigInteger.prototype.and;
1086
1087 BigInteger.prototype.or = function (n) {
1088 return bitwise(this, n, function (a, b) { return a | b; });
1089 };
1090 NativeBigInt.prototype.or = SmallInteger.prototype.or = BigInteger.prototype.or;
1091
1092 BigInteger.prototype.xor = function (n) {
1093 return bitwise(this, n, function (a, b) { return a ^ b; });
1094 };
1095 NativeBigInt.prototype.xor = SmallInteger.prototype.xor = BigInteger.prototype.xor;
1096
1097 var LOBMASK_I = 1 << 30, LOBMASK_BI = (BASE & -BASE) * (BASE & -BASE) | LOBMASK_I;
1098 function roughLOB(n) { // get lowestOneBit (rough)
1099 // SmallInteger: return Min(lowestOneBit(n), 1 << 30)
1100 // BigInteger: return Min(lowestOneBit(n), 1 << 14) [BASE=1e7]
1101 var v = n.value,
1102 x = typeof v === "number" ? v | LOBMASK_I :
1103 typeof v === "bigint" ? v | BigInt(LOBMASK_I) :
1104 v[0] + v[1] * BASE | LOBMASK_BI;
1105 return x & -x;
1106 }
1107
1108 function integerLogarithm(value, base) {
1109 if (base.compareTo(value) <= 0) {
1110 var tmp = integerLogarithm(value, base.square(base));
1111 var p = tmp.p;
1112 var e = tmp.e;
1113 var t = p.multiply(base);
1114 return t.compareTo(value) <= 0 ? { p: t, e: e * 2 + 1 } : { p: p, e: e * 2 };
1115 }
1116 return { p: bigInt(1), e: 0 };
1117 }
1118
1119 BigInteger.prototype.bitLength = function () {
1120 var n = this;
1121 if (n.compareTo(bigInt(0)) < 0) {
1122 n = n.negate().subtract(bigInt(1));
1123 }
1124 if (n.compareTo(bigInt(0)) === 0) {
1125 return bigInt(0);
1126 }
1127 return bigInt(integerLogarithm(n, bigInt(2)).e).add(bigInt(1));
1128 }
1129 NativeBigInt.prototype.bitLength = SmallInteger.prototype.bitLength = BigInteger.prototype.bitLength;
1130
1131 function max(a, b) {
1132 a = parseValue(a);
1133 b = parseValue(b);
1134 return a.greater(b) ? a : b;
1135 }
1136 function min(a, b) {
1137 a = parseValue(a);
1138 b = parseValue(b);
1139 return a.lesser(b) ? a : b;
1140 }
1141 function gcd(a, b) {
1142 a = parseValue(a).abs();
1143 b = parseValue(b).abs();
1144 if (a.equals(b)) return a;
1145 if (a.isZero()) return b;
1146 if (b.isZero()) return a;
1147 var c = Integer[1], d, t;
1148 while (a.isEven() && b.isEven()) {
1149 d = min(roughLOB(a), roughLOB(b));
1150 a = a.divide(d);
1151 b = b.divide(d);
1152 c = c.multiply(d);
1153 }
1154 while (a.isEven()) {
1155 a = a.divide(roughLOB(a));
1156 }
1157 do {
1158 while (b.isEven()) {
1159 b = b.divide(roughLOB(b));
1160 }
1161 if (a.greater(b)) {
1162 t = b; b = a; a = t;
1163 }
1164 b = b.subtract(a);
1165 } while (!b.isZero());
1166 return c.isUnit() ? a : a.multiply(c);
1167 }
1168 function lcm(a, b) {
1169 a = parseValue(a).abs();
1170 b = parseValue(b).abs();
1171 return a.divide(gcd(a, b)).multiply(b);
1172 }
1173 function randBetween(a, b) {
1174 a = parseValue(a);
1175 b = parseValue(b);
1176 var low = min(a, b), high = max(a, b);
1177 var range = high.subtract(low).add(1);
1178 if (range.isSmall) return low.add(Math.floor(Math.random() * range));
1179 var digits = toBase(range, BASE).value;
1180 var result = [], restricted = true;
1181 for (var i = 0; i < digits.length; i++) {
1182 var top = restricted ? digits[i] : BASE;
1183 var digit = truncate(Math.random() * top);
1184 result.push(digit);
1185 if (digit < top) restricted = false;
1186 }
1187 return low.add(Integer.fromArray(result, BASE, false));
1188 }
1189
1190 var parseBase = function (text, base, alphabet, caseSensitive) {
1191 alphabet = alphabet || DEFAULT_ALPHABET;
1192 text = String(text);
1193 if (!caseSensitive) {
1194 text = text.toLowerCase();
1195 alphabet = alphabet.toLowerCase();
1196 }
1197 var length = text.length;
1198 var i;
1199 var absBase = Math.abs(base);
1200 var alphabetValues = {};
1201 for (i = 0; i < alphabet.length; i++) {
1202 alphabetValues[alphabet[i]] = i;
1203 }
1204 for (i = 0; i < length; i++) {
1205 var c = text[i];
1206 if (c === "-") continue;
1207 if (c in alphabetValues) {
1208 if (alphabetValues[c] >= absBase) {
1209 if (c === "1" && absBase === 1) continue;
1210 throw new Error(c + " is not a valid digit in base " + base + ".");
1211 }
1212 }
1213 }
1214 base = parseValue(base);
1215 var digits = [];
1216 var isNegative = text[0] === "-";
1217 for (i = isNegative ? 1 : 0; i < text.length; i++) {
1218 var c = text[i];
1219 if (c in alphabetValues) digits.push(parseValue(alphabetValues[c]));
1220 else if (c === "<") {
1221 var start = i;
1222 do { i++; } while (text[i] !== ">" && i < text.length);
1223 digits.push(parseValue(text.slice(start + 1, i)));
1224 }
1225 else throw new Error(c + " is not a valid character");
1226 }
1227 return parseBaseFromArray(digits, base, isNegative);
1228 };
1229
1230 function parseBaseFromArray(digits, base, isNegative) {
1231 var val = Integer[0], pow = Integer[1], i;
1232 for (i = digits.length - 1; i >= 0; i--) {
1233 val = val.add(digits[i].times(pow));
1234 pow = pow.times(base);
1235 }
1236 return isNegative ? val.negate() : val;
1237 }
1238
1239 function stringify(digit, alphabet) {
1240 alphabet = alphabet || DEFAULT_ALPHABET;
1241 if (digit < alphabet.length) {
1242 return alphabet[digit];
1243 }
1244 return "<" + digit + ">";
1245 }
1246
1247 function toBase(n, base) {
1248 base = bigInt(base);
1249 if (base.isZero()) {
1250 if (n.isZero()) return { value: [0], isNegative: false };
1251 throw new Error("Cannot convert nonzero numbers to base 0.");
1252 }
1253 if (base.equals(-1)) {
1254 if (n.isZero()) return { value: [0], isNegative: false };
1255 if (n.isNegative())
1256 return {
1257 value: [].concat.apply([], Array.apply(null, Array(-n.toJSNumber()))
1258 .map(Array.prototype.valueOf, [1, 0])
1259 ),
1260 isNegative: false
1261 };
1262
1263 var arr = Array.apply(null, Array(n.toJSNumber() - 1))
1264 .map(Array.prototype.valueOf, [0, 1]);
1265 arr.unshift([1]);
1266 return {
1267 value: [].concat.apply([], arr),
1268 isNegative: false
1269 };
1270 }
1271
1272 var neg = false;
1273 if (n.isNegative() && base.isPositive()) {
1274 neg = true;
1275 n = n.abs();
1276 }
1277 if (base.isUnit()) {
1278 if (n.isZero()) return { value: [0], isNegative: false };
1279
1280 return {
1281 value: Array.apply(null, Array(n.toJSNumber()))
1282 .map(Number.prototype.valueOf, 1),
1283 isNegative: neg
1284 };
1285 }
1286 var out = [];
1287 var left = n, divmod;
1288 while (left.isNegative() || left.compareAbs(base) >= 0) {
1289 divmod = left.divmod(base);
1290 left = divmod.quotient;
1291 var digit = divmod.remainder;
1292 if (digit.isNegative()) {
1293 digit = base.minus(digit).abs();
1294 left = left.next();
1295 }
1296 out.push(digit.toJSNumber());
1297 }
1298 out.push(left.toJSNumber());
1299 return { value: out.reverse(), isNegative: neg };
1300 }
1301
1302 function toBaseString(n, base, alphabet) {
1303 var arr = toBase(n, base);
1304 return (arr.isNegative ? "-" : "") + arr.value.map(function (x) {
1305 return stringify(x, alphabet);
1306 }).join('');
1307 }
1308
1309 BigInteger.prototype.toArray = function (radix) {
1310 return toBase(this, radix);
1311 };
1312
1313 SmallInteger.prototype.toArray = function (radix) {
1314 return toBase(this, radix);
1315 };
1316
1317 NativeBigInt.prototype.toArray = function (radix) {
1318 return toBase(this, radix);
1319 };
1320
1321 BigInteger.prototype.toString = function (radix, alphabet) {
1322 if (radix === undefined) radix = 10;
1323 if (radix !== 10) return toBaseString(this, radix, alphabet);
1324 var v = this.value, l = v.length, str = String(v[--l]), zeros = "0000000", digit;
1325 while (--l >= 0) {
1326 digit = String(v[l]);
1327 str += zeros.slice(digit.length) + digit;
1328 }
1329 var sign = this.sign ? "-" : "";
1330 return sign + str;
1331 };
1332
1333 SmallInteger.prototype.toString = function (radix, alphabet) {
1334 if (radix === undefined) radix = 10;
1335 if (radix != 10) return toBaseString(this, radix, alphabet);
1336 return String(this.value);
1337 };
1338
1339 NativeBigInt.prototype.toString = SmallInteger.prototype.toString;
1340
1341 NativeBigInt.prototype.toJSON = BigInteger.prototype.toJSON = SmallInteger.prototype.toJSON = function () { return this.toString(); }
1342
1343 BigInteger.prototype.valueOf = function () {
1344 return parseInt(this.toString(), 10);
1345 };
1346 BigInteger.prototype.toJSNumber = BigInteger.prototype.valueOf;
1347
1348 SmallInteger.prototype.valueOf = function () {
1349 return this.value;
1350 };
1351 SmallInteger.prototype.toJSNumber = SmallInteger.prototype.valueOf;
1352 NativeBigInt.prototype.valueOf = NativeBigInt.prototype.toJSNumber = function () {
1353 return parseInt(this.toString(), 10);
1354 }
1355
1356 function parseStringValue(v) {
1357 if (isPrecise(+v)) {
1358 var x = +v;
1359 if (x === truncate(x))
1360 return supportsNativeBigInt ? new NativeBigInt(BigInt(x)) : new SmallInteger(x);
1361 throw new Error("Invalid integer: " + v);
1362 }
1363 var sign = v[0] === "-";
1364 if (sign) v = v.slice(1);
1365 var split = v.split(/e/i);
1366 if (split.length > 2) throw new Error("Invalid integer: " + split.join("e"));
1367 if (split.length === 2) {
1368 var exp = split[1];
1369 if (exp[0] === "+") exp = exp.slice(1);
1370 exp = +exp;
1371 if (exp !== truncate(exp) || !isPrecise(exp)) throw new Error("Invalid integer: " + exp + " is not a valid exponent.");
1372 var text = split[0];
1373 var decimalPlace = text.indexOf(".");
1374 if (decimalPlace >= 0) {
1375 exp -= text.length - decimalPlace - 1;
1376 text = text.slice(0, decimalPlace) + text.slice(decimalPlace + 1);
1377 }
1378 if (exp < 0) throw new Error("Cannot include negative exponent part for integers");
1379 text += (new Array(exp + 1)).join("0");
1380 v = text;
1381 }
1382 var isValid = /^([0-9][0-9]*)$/.test(v);
1383 if (!isValid) throw new Error("Invalid integer: " + v);
1384 if (supportsNativeBigInt) {
1385 return new NativeBigInt(BigInt(sign ? "-" + v : v));
1386 }
1387 var r = [], max = v.length, l = LOG_BASE, min = max - l;
1388 while (max > 0) {
1389 r.push(+v.slice(min, max));
1390 min -= l;
1391 if (min < 0) min = 0;
1392 max -= l;
1393 }
1394 trim(r);
1395 return new BigInteger(r, sign);
1396 }
1397
1398 function parseNumberValue(v) {
1399 if (supportsNativeBigInt) {
1400 return new NativeBigInt(BigInt(v));
1401 }
1402 if (isPrecise(v)) {
1403 if (v !== truncate(v)) throw new Error(v + " is not an integer.");
1404 return new SmallInteger(v);
1405 }
1406 return parseStringValue(v.toString());
1407 }
1408
1409 function parseValue(v) {
1410 if (typeof v === "number") {
1411 return parseNumberValue(v);
1412 }
1413 if (typeof v === "string") {
1414 return parseStringValue(v);
1415 }
1416 if (typeof v === "bigint") {
1417 return new NativeBigInt(v);
1418 }
1419 return v;
1420 }
1421 // Pre-define numbers in range [-999,999]
1422 for (var i = 0; i < 1000; i++) {
1423 Integer[i] = parseValue(i);
1424 if (i > 0) Integer[-i] = parseValue(-i);
1425 }
1426 // Backwards compatibility
1427 Integer.one = Integer[1];
1428 Integer.zero = Integer[0];
1429 Integer.minusOne = Integer[-1];
1430 Integer.max = max;
1431 Integer.min = min;
1432 Integer.gcd = gcd;
1433 Integer.lcm = lcm;
1434 Integer.isInstance = function (x) { return x instanceof BigInteger || x instanceof SmallInteger || x instanceof NativeBigInt; };
1435 Integer.randBetween = randBetween;
1436
1437 Integer.fromArray = function (digits, base, isNegative) {
1438 return parseBaseFromArray(digits.map(parseValue), parseValue(base || 10), isNegative);
1439 };
1440
1441 return Integer;
1442})();
1443
1444// Node.js check
1445if (typeof module !== "undefined" && module.hasOwnProperty("exports")) {
1446 module.exports = bigInt;
1447}
1448
1449//amd check
1450if (typeof define === "function" && define.amd) {
1451 define("big-integer", [], function () {
1452 return bigInt;
1453 });
1454}
1455
1456},{}],3:[function(require,module,exports){
1457/* globals WebAssembly */
1458const bigInt = require("big-integer");
1459const ModuleBuilder = require("./wasmbuilder/index.js");
1460const buildF1m = require("./build_f1m.js");
1461const buildF2m = require("./build_f2m.js");
1462const buildF1 = require("./build_f1.js");
1463const buildCurve = require("./build_curve.js");
1464const buildTest = require("./build_testg1");
1465const buildFFT = require("./build_fft");
1466const buildMultiexp = require("./build_multiexp");
1467const buildPol = require("./build_pol");
1468const utils = require("./utils");
1469
1470async function build() {
1471 const bn128 = new Bn128();
1472
1473 bn128.q = bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208583");
1474 bn128.r = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
1475 bn128.n64 = Math.floor((bn128.q.minus(1).bitLength() - 1)/64) +1;
1476 bn128.n32 = bn128.n64*2;
1477 bn128.n8 = bn128.n64*8;
1478
1479 bn128.memory = new WebAssembly.Memory({initial:10000});
1480 bn128.i32 = new Uint32Array(bn128.memory.buffer);
1481
1482 const moduleBuilder = new ModuleBuilder();
1483 moduleBuilder.setMemory(10000);
1484 buildF1m(moduleBuilder, bn128.q, "f1m");
1485 buildF1(moduleBuilder, bn128.r, "fr", "frm");
1486 buildCurve(moduleBuilder, "g1", "f1m");
1487 buildMultiexp(moduleBuilder, "g1", "g1", "f1m", "fr");
1488 buildFFT(moduleBuilder, "fft", "frm");
1489 buildPol(moduleBuilder, "pol", "frm");
1490
1491 const pNonResidueF2 = moduleBuilder.alloc(
1492 utils.bigInt2BytesLE(
1493 bigInt("15537367993719455909907449462855742678907882278146377936676643359958227611562"), // -1 in montgomery
1494 bn128.n8
1495 )
1496 );
1497
1498 buildF2m(moduleBuilder, pNonResidueF2, "f2m", "f1m");
1499 buildCurve(moduleBuilder, "g2", "f2m");
1500 buildMultiexp(moduleBuilder, "g2", "g2", "f2m", "fr");
1501
1502 buildTest(moduleBuilder);
1503
1504 const code = moduleBuilder.build();
1505
1506 const wasmModule = await WebAssembly.compile(code);
1507
1508 bn128.instance = await WebAssembly.instantiate(wasmModule, {
1509 env: {
1510 "memory": bn128.memory
1511 }
1512 });
1513
1514 bn128.pq = moduleBuilder.modules.f1m.pq;
1515 bn128.pr = moduleBuilder.modules.frm.pq;
1516
1517 bn128.pg1 = bn128.g1_allocPoint([bigInt(1), bigInt(2), bigInt(1)]);
1518
1519 Object.assign(bn128, bn128.instance.exports);
1520
1521 return bn128;
1522}
1523
1524class Bn128 {
1525
1526 constructor() {
1527
1528 }
1529
1530 alloc(length) {
1531 while (this.i32[0] & 3) this.i32[0]++; // Return always aligned pointers
1532 const res = this.i32[0];
1533 this.i32[0] += length;
1534 return res;
1535 }
1536
1537 putInt(pos, _a) {
1538 const a = bigInt(_a);
1539 if (pos & 0x7) throw new Error("Pointer must be aligned");
1540 if (a.bitLength > this.n64*64) {
1541 return this.putInt(a.mod(this.q));
1542 }
1543 for (let i=0; i<this.n32; i++) {
1544 this.i32[(pos>>2)+i] = a.shiftRight(i*32).and(0xFFFFFFFF).toJSNumber();
1545 }
1546 }
1547
1548 getInt(pos) {
1549 if (pos & 0x7) throw new Error("Pointer must be aligned");
1550 let acc = bigInt(this.i32[(pos>>2)+this.n32-1]);
1551 for (let i=this.n32-2; i>=0; i--) {
1552 acc = acc.shiftLeft(32);
1553 acc = acc.add(this.i32[(pos>>2)+i]);
1554 }
1555 return acc;
1556 }
1557
1558 allocInt(_a) {
1559 const p = this.alloc(this.n8);
1560 if (_a) this.putInt(p, _a);
1561 return p;
1562 }
1563
1564 putIntF2(pos, a) {
1565 this.putInt(pos, a[0]);
1566 this.putInt(pos+this.n8, a[1]);
1567 }
1568
1569 getIntF2(pos) {
1570 const p = Array(2);
1571 p[0] = this.getInt(pos);
1572 p[1] = this.getInt(pos+this.n8);
1573 return p;
1574 }
1575
1576 allocIntF2(a) {
1577 const pP = this.alloc(this.n8*2);
1578 if (a) {
1579 this.putIntF2(pP, a);
1580 }
1581 return pP;
1582 }
1583
1584 g1_putPoint(pos, p) {
1585 this.putInt(pos, p[0]);
1586 this.putInt(pos+this.n8, p[1]);
1587 if (p.length == 3) {
1588 this.putInt(pos+this.n8*2, p[2]);
1589 } else {
1590 this.putInt(pos+this.n8*2, 1);
1591 }
1592 }
1593
1594 g1_getPoint(pos) {
1595 const p = Array(3);
1596 p[0] = this.getInt(pos);
1597 p[1] = this.getInt(pos+this.n8);
1598 p[2] = this.getInt(pos+this.n8*2);
1599 return p;
1600 }
1601
1602 g1_allocPoint(p) {
1603 const pP = this.alloc(this.n8*3);
1604 if (p) {
1605 this.g1_putPoint(pP, p);
1606 }
1607 return pP;
1608 }
1609
1610
1611 g2_putPoint(pos, p) {
1612 this.putIntF2(pos, p[0]);
1613 this.putIntF2(pos+this.n8*2, p[1]);
1614 if (p.length == 3) {
1615 this.putIntF2(pos+this.n8*4, p[2]);
1616 } else {
1617 this.putIntF2(pos+this.n8*4, 1);
1618 }
1619 }
1620
1621 g2_getPoint(pos) {
1622 const p = Array(3);
1623 p[0] = this.getIntF2(pos);
1624 p[1] = this.getIntF2(pos+this.n8*2);
1625 p[2] = this.getIntF2(pos+this.n8*4);
1626 return p;
1627 }
1628
1629 g2_allocPoint(p) {
1630 const pP = this.alloc(this.n8*6);
1631 if (p) {
1632 this.g2_putPoint(pP, p);
1633 }
1634 return pP;
1635 }
1636
1637 putBin(b) {
1638 const p = this.alloc(b.byteLength);
1639 const s32 = new Uint32Array(b);
1640 this.i32.set(s32, p/4);
1641 return p;
1642 }
1643
1644 test_AddG1(n) {
1645 const start = new Date().getTime();
1646
1647 const pg = this.g1_allocPoint([bigInt(1), bigInt(2), bigInt(1)]);
1648 this.g1_toMontgomery(pg,pg);
1649 const p2 = this.g1_allocPoint();
1650 this.instance.exports.testAddG1(n, pg, p2);
1651 this.g1_fromMontgomery(p2,p2);
1652
1653 const end = new Date().getTime();
1654 const time = end - start;
1655
1656 return time;
1657 }
1658
1659 test_fft(n) {
1660
1661 const N=n;
1662
1663 const p = this.i32[0];
1664 for (let i=0; i<N; i++) {
1665 this.putInt(p+i*32, i);
1666 }
1667
1668 const start = new Date().getTime();
1669 this.fft_ifft(p, N);
1670 const end = new Date().getTime();
1671 const time = end - start;
1672
1673 return time;
1674 }
1675
1676}
1677
1678module.exports = build;
1679
1680},{"./build_curve.js":4,"./build_f1.js":5,"./build_f1m.js":6,"./build_f2m.js":7,"./build_fft":8,"./build_multiexp":10,"./build_pol":11,"./build_testg1":13,"./utils":17,"./wasmbuilder/index.js":20,"big-integer":2}],4:[function(require,module,exports){
1681
1682const buildTimesScalar = require("./build_timesscalar");
1683
1684module.exports = function buildCurve(module, prefix, prefixField) {
1685
1686
1687 const n64 = module.modules[prefixField].n64;
1688 const n8 = n64*8;
1689
1690 if (module.modules[prefix]) return prefix; // already builded
1691 module.modules[prefix] = {
1692 n64: n64*3
1693 };
1694
1695 function buildIsZero() {
1696 const f = module.addFunction(prefix + "_isZero");
1697 f.addParam("p1", "i32");
1698 f.setReturnType("i32");
1699
1700 const c = f.getCodeBuilder();
1701
1702 f.addCode(c.call(
1703 prefixField + "_isZero",
1704 c.i32_add(
1705 c.getLocal("p1"),
1706 c.i32_const(n8*2)
1707 )
1708 ));
1709 }
1710
1711 function buildCopy() {
1712 const f = module.addFunction(prefix + "_copy");
1713 f.addParam("p1", "i32");
1714 f.addParam("pr", "i32");
1715
1716 const c = f.getCodeBuilder();
1717
1718 f.addCode(c.call(
1719 prefixField + "_copy",
1720 c.getLocal("p1"),
1721 c.getLocal("pr")
1722 ));
1723
1724 f.addCode(c.call(
1725 prefixField + "_copy",
1726 c.i32_add(
1727 c.getLocal("p1"),
1728 c.i32_const(n8)
1729 ),
1730 c.i32_add(
1731 c.getLocal("pr"),
1732 c.i32_const(n8)
1733 )
1734 ));
1735
1736 f.addCode(c.call(
1737 prefixField + "_copy",
1738 c.i32_add(
1739 c.getLocal("p1"),
1740 c.i32_const(n8*2)
1741 ),
1742 c.i32_add(
1743 c.getLocal("pr"),
1744 c.i32_const(n8*2)
1745 )
1746 ));
1747 }
1748
1749 function buildZero() {
1750 const f = module.addFunction(prefix + "_zero");
1751 f.addParam("pr", "i32");
1752
1753 const c = f.getCodeBuilder();
1754
1755 f.addCode(c.call(
1756 prefixField + "_zero",
1757 c.getLocal("pr")
1758 ));
1759
1760 f.addCode(c.call(
1761 prefixField + "_one",
1762 c.i32_add(
1763 c.getLocal("pr"),
1764 c.i32_const(n8)
1765 )
1766 ));
1767
1768 f.addCode(c.call(
1769 prefixField + "_zero",
1770 c.i32_add(
1771 c.getLocal("pr"),
1772 c.i32_const(n8*2)
1773 )
1774 ));
1775 }
1776
1777 function buildDouble() {
1778 const f = module.addFunction(prefix + "_double");
1779 f.addParam("p1", "i32");
1780 f.addParam("pr", "i32");
1781
1782 const c = f.getCodeBuilder();
1783
1784 const x = c.getLocal("p1");
1785 const y = c.i32_add(c.getLocal("p1"), c.i32_const(n8));
1786 const z = c.i32_add(c.getLocal("p1"), c.i32_const(n8*2));
1787 const x3 = c.getLocal("pr");
1788 const y3 = c.i32_add(c.getLocal("pr"), c.i32_const(n8));
1789 const z3 = c.i32_add(c.getLocal("pr"), c.i32_const(n8*2));
1790
1791 const A = c.i32_const(module.alloc(n8));
1792 const B = c.i32_const(module.alloc(n8));
1793 const C = c.i32_const(module.alloc(n8));
1794 const D = c.i32_const(module.alloc(n8));
1795 const E = c.i32_const(module.alloc(n8));
1796 const F = c.i32_const(module.alloc(n8));
1797 const G = c.i32_const(module.alloc(n8));
1798 const eightC = c.i32_const(module.alloc(n8));
1799
1800 f.addCode(
1801 c.if(
1802 c.call(prefix + "_isZero", c.getLocal("p1")),
1803 [
1804 ...c.call(prefix + "_copy", c.getLocal("p1"), c.getLocal("pr")),
1805 ...c.ret([])
1806 ]
1807 ),
1808
1809 c.call(prefixField + "_mul", x, x, A),
1810 c.call(prefixField + "_mul", y, y, B),
1811 c.call(prefixField + "_mul", B, B, C),
1812
1813 c.call(prefixField + "_add", x, B, D),
1814 c.call(prefixField + "_mul", D, D, D),
1815 c.call(prefixField + "_sub", D, A, D),
1816 c.call(prefixField + "_sub", D, C, D),
1817 c.call(prefixField + "_add", D, D, D),
1818
1819 c.call(prefixField + "_add", A, A, E),
1820 c.call(prefixField + "_add", E, A, E),
1821 c.call(prefixField + "_mul", E, E, F),
1822
1823 c.call(prefixField + "_mul", y, z, G),
1824
1825 c.call(prefixField + "_add", D, D, x3),
1826 c.call(prefixField + "_sub", F, x3, x3),
1827
1828 c.call(prefixField + "_add", C, C, eightC),
1829 c.call(prefixField + "_add", eightC, eightC, eightC),
1830 c.call(prefixField + "_add", eightC, eightC, eightC),
1831
1832 c.call(prefixField + "_sub", D, x3, y3),
1833 c.call(prefixField + "_mul", y3, E, y3),
1834 c.call(prefixField + "_sub", y3, eightC, y3),
1835
1836 c.call(prefixField + "_add", G, G, z3),
1837 );
1838 }
1839
1840 function buildToMontgomery() {
1841 const f = module.addFunction(prefix + "_toMontgomery");
1842 f.addParam("p1", "i32");
1843 f.addParam("pr", "i32");
1844
1845 const c = f.getCodeBuilder();
1846
1847 f.addCode(c.call(
1848 prefixField + "_toMontgomery",
1849 c.getLocal("p1"),
1850 c.getLocal("pr")
1851 ));
1852 for (let i=1; i<3; i++) {
1853 f.addCode(c.call(
1854 prefixField + "_toMontgomery",
1855 c.i32_add(c.getLocal("p1"), c.i32_const(i*n8)),
1856 c.i32_add(c.getLocal("pr"), c.i32_const(i*n8))
1857 ));
1858 }
1859 }
1860
1861 function buildFromMontgomery() {
1862 const f = module.addFunction(prefix + "_fromMontgomery");
1863 f.addParam("p1", "i32");
1864 f.addParam("pr", "i32");
1865
1866 const c = f.getCodeBuilder();
1867
1868 f.addCode(c.call(
1869 prefixField + "_fromMontgomery",
1870 c.getLocal("p1"),
1871 c.getLocal("pr")
1872 ));
1873 for (let i=1; i<3; i++) {
1874 f.addCode(c.call(
1875 prefixField + "_fromMontgomery",
1876 c.i32_add(c.getLocal("p1"), c.i32_const(i*n8)),
1877 c.i32_add(c.getLocal("pr"), c.i32_const(i*n8))
1878 ));
1879 }
1880 }
1881
1882
1883 function buildAdd() {
1884
1885 const f = module.addFunction(prefix + "_add");
1886 f.addParam("p1", "i32");
1887 f.addParam("p2", "i32");
1888 f.addParam("pr", "i32");
1889 f.addLocal("z1", "i32");
1890 f.addLocal("z2", "i32");
1891
1892 const c = f.getCodeBuilder();
1893
1894 const x1 = c.getLocal("p1");
1895 const y1 = c.i32_add(c.getLocal("p1"), c.i32_const(n8));
1896 f.addCode(c.setLocal("z1", c.i32_add(c.getLocal("p1"), c.i32_const(n8*2))));
1897 const z1 = c.getLocal("z1");
1898 const x2 = c.getLocal("p2");
1899 const y2 = c.i32_add(c.getLocal("p2"), c.i32_const(n8));
1900 f.addCode(c.setLocal("z2", c.i32_add(c.getLocal("p2"), c.i32_const(n8*2))));
1901 const z2 = c.getLocal("z2");
1902 const x3 = c.getLocal("pr");
1903 const y3 = c.i32_add(c.getLocal("pr"), c.i32_const(n8));
1904 const z3 = c.i32_add(c.getLocal("pr"), c.i32_const(n8*2));
1905
1906 const Z1Z1 = c.i32_const(module.alloc(n8));
1907 const Z2Z2 = c.i32_const(module.alloc(n8));
1908 const U1 = c.i32_const(module.alloc(n8));
1909 const U2 = c.i32_const(module.alloc(n8));
1910 const Z1_cubed = c.i32_const(module.alloc(n8));
1911 const Z2_cubed = c.i32_const(module.alloc(n8));
1912 const S1 = c.i32_const(module.alloc(n8));
1913 const S2 = c.i32_const(module.alloc(n8));
1914 const H = c.i32_const(module.alloc(n8));
1915 const S2_minus_S1 = c.i32_const(module.alloc(n8));
1916 const I = c.i32_const(module.alloc(n8));
1917 const J = c.i32_const(module.alloc(n8));
1918 const r = c.i32_const(module.alloc(n8));
1919 const r2 = c.i32_const(module.alloc(n8));
1920 const V = c.i32_const(module.alloc(n8));
1921 const V2 = c.i32_const(module.alloc(n8));
1922 const S1_J2 = c.i32_const(module.alloc(n8));
1923
1924 f.addCode(
1925 c.if(
1926 c.call(prefix + "_isZero", c.getLocal("p1")),
1927 [
1928 ...c.call(prefix + "_copy", c.getLocal("p2"), c.getLocal("pr")),
1929 ...c.ret([])
1930 ]
1931 ),
1932
1933 c.if(
1934 c.call(prefix + "_isZero", c.getLocal("p2")),
1935 [
1936 ...c.call(prefix + "_copy", c.getLocal("p1"), c.getLocal("pr")),
1937 ...c.ret([])
1938 ]
1939 ),
1940
1941 c.call(prefixField + "_mul", z1, z1, Z1Z1),
1942 c.call(prefixField + "_mul", z2, z2, Z2Z2),
1943 c.call(prefixField + "_mul", x1, Z2Z2, U1),
1944 c.call(prefixField + "_mul", x2, Z1Z1, U2),
1945 c.call(prefixField + "_mul", z1, Z1Z1, Z1_cubed),
1946 c.call(prefixField + "_mul", z2, Z2Z2, Z2_cubed),
1947 c.call(prefixField + "_mul", y1, Z2_cubed, S1),
1948 c.call(prefixField + "_mul", y2, Z1_cubed, S2),
1949
1950 c.if(
1951 c.call(prefixField + "_eq", U1, U2),
1952 c.if(
1953 c.call(prefixField + "_eq", S1, S2),
1954 [
1955 ...c.call(prefix + "_double", c.getLocal("p1"), c.getLocal("pr")),
1956 ...c.ret([])
1957 ]
1958 )
1959 ),
1960
1961 c.call(prefixField + "_sub", U2, U1, H),
1962 c.call(prefixField + "_sub", S2, S1, S2_minus_S1),
1963 c.call(prefixField + "_add", H, H, I),
1964 c.call(prefixField + "_mul", I, I, I),
1965 c.call(prefixField + "_mul", H, I, J),
1966 c.call(prefixField + "_add", S2_minus_S1, S2_minus_S1, r),
1967 c.call(prefixField + "_mul", U1, I, V),
1968 c.call(prefixField + "_mul", r, r, r2),
1969 c.call(prefixField + "_add", V, V, V2),
1970
1971 c.call(prefixField + "_sub", r2, J, x3),
1972 c.call(prefixField + "_sub", x3, V2, x3),
1973
1974 c.call(prefixField + "_mul", S1, J, S1_J2),
1975 c.call(prefixField + "_add", S1_J2, S1_J2, S1_J2),
1976
1977 c.call(prefixField + "_sub", V, x3, y3),
1978 c.call(prefixField + "_mul", y3, r, y3),
1979 c.call(prefixField + "_sub", y3, S1_J2, y3),
1980
1981 c.call(prefixField + "_add", z1, z2, z3),
1982 c.call(prefixField + "_mul", z3, z3, z3),
1983 c.call(prefixField + "_sub", z3, Z1Z1, z3),
1984 c.call(prefixField + "_sub", z3, Z2Z2, z3),
1985 c.call(prefixField + "_mul", z3, H, z3),
1986 );
1987
1988 }
1989
1990 function buildNeg() {
1991 const f = module.addFunction(prefix + "_neg");
1992 f.addParam("p1", "i32");
1993 f.addParam("pr", "i32");
1994
1995 const c = f.getCodeBuilder();
1996
1997 const x = c.getLocal("p1");
1998 const y = c.i32_add(c.getLocal("p1"), c.i32_const(n8));
1999 const z = c.i32_add(c.getLocal("p1"), c.i32_const(n8*2));
2000 const x3 = c.getLocal("pr");
2001 const y3 = c.i32_add(c.getLocal("pr"), c.i32_const(n8));
2002 const z3 = c.i32_add(c.getLocal("pr"), c.i32_const(n8*2));
2003
2004 f.addCode(
2005 c.call(prefixField + "_copy", x, x3),
2006 c.call(prefixField + "_neg", y, y3),
2007 c.call(prefixField + "_copy", z, z3)
2008 );
2009 }
2010
2011 function buildSub() {
2012 const f = module.addFunction(prefix + "_sub");
2013 f.addParam("p1", "i32");
2014 f.addParam("p2", "i32");
2015 f.addParam("pr", "i32");
2016
2017 const c = f.getCodeBuilder();
2018
2019 f.addCode(
2020 c.call(prefix + "_neg", c.getLocal("p2"), c.getLocal("pr")),
2021 c.call(prefix + "_add", c.getLocal("p1"), c.getLocal("pr"), c.getLocal("pr")),
2022 );
2023 }
2024
2025
2026 function buildAffine() {
2027 const f = module.addFunction(prefix + "_affine");
2028 f.addParam("p1", "i32");
2029 f.addParam("pr", "i32");
2030
2031 const c = f.getCodeBuilder();
2032
2033 const x = c.getLocal("p1");
2034 const y = c.i32_add(c.getLocal("p1"), c.i32_const(n8));
2035 const z = c.i32_add(c.getLocal("p1"), c.i32_const(n8*2));
2036 const x3 = c.getLocal("pr");
2037 const y3 = c.i32_add(c.getLocal("pr"), c.i32_const(n8));
2038 const z3 = c.i32_add(c.getLocal("pr"), c.i32_const(n8*2));
2039
2040
2041 const Z_inv = c.i32_const(module.alloc(n8));
2042 const Z2_inv = c.i32_const(module.alloc(n8));
2043 const Z3_inv = c.i32_const(module.alloc(n8));
2044
2045 f.addCode(
2046 c.if(
2047 c.call(prefix + "_isZero", c.getLocal("p1")),
2048 c.call(prefix + "_zero", c.getLocal("pr")),
2049 [
2050 ...c.call(prefixField + "_inverse", z, Z_inv),
2051 ...c.call(prefixField + "_mul", Z_inv, Z_inv, Z2_inv),
2052 ...c.call(prefixField + "_mul", Z_inv, Z2_inv, Z3_inv),
2053 ...c.call(prefixField + "_mul", x, Z2_inv, x3),
2054 ...c.call(prefixField + "_mul", y, Z3_inv, y3),
2055 ...c.call(prefixField + "_one", z3)
2056 ]
2057 )
2058 );
2059 }
2060
2061
2062 buildIsZero();
2063 buildZero();
2064 buildCopy();
2065 buildDouble();
2066 buildAdd();
2067 buildNeg();
2068 buildSub();
2069 buildFromMontgomery();
2070 buildToMontgomery();
2071 buildAffine();
2072 buildTimesScalar(
2073 module,
2074 prefix + "_timesScalar",
2075 n8*3,
2076 prefix + "_add",
2077 prefix + "_double",
2078 prefix
2079 );
2080 module.exportFunction(prefix + "_isZero");
2081 module.exportFunction(prefix + "_copy");
2082 module.exportFunction(prefix + "_zero");
2083 module.exportFunction(prefix + "_double");
2084 module.exportFunction(prefix + "_add");
2085 module.exportFunction(prefix + "_neg");
2086 module.exportFunction(prefix + "_sub");
2087 module.exportFunction(prefix + "_fromMontgomery");
2088 module.exportFunction(prefix + "_toMontgomery");
2089 module.exportFunction(prefix + "_affine");
2090 module.exportFunction(prefix + "_timesScalar");
2091
2092 /*
2093 buildG1MulScalar(module, zq);
2094 module.exportFunction("g1MulScalar");
2095 */
2096
2097 return prefix;
2098};
2099
2100},{"./build_timesscalar":14}],5:[function(require,module,exports){
2101
2102const bigInt = require("big-integer");
2103
2104const buildF1m =require("./build_f1m.js");
2105
2106module.exports = function buildF1(module, _q, _prefix, _f1mPrefix, _intPrefix) {
2107
2108 const q = bigInt(_q);
2109 const n64 = Math.floor((q.minus(1).bitLength() - 1)/64) +1;
2110 const n8 = n64*8;
2111
2112 const prefix = _prefix || "f1";
2113 if (module.modules[prefix]) return prefix; // already builded
2114 module.modules[prefix] = {
2115 n64: n64
2116 };
2117
2118 const intPrefix = _intPrefix || "int";
2119 const f1mPrefix = buildF1m(module, q, _f1mPrefix, intPrefix);
2120
2121
2122 const pR2 = module.modules[f1mPrefix].pR2;
2123 const pq = module.modules[f1mPrefix].pq;
2124
2125 function buildMul() {
2126 const pAux1 = module.alloc(n8);
2127
2128 const f = module.addFunction(prefix+ "_mul");
2129 f.addParam("x", "i32");
2130 f.addParam("y", "i32");
2131 f.addParam("r", "i32");
2132
2133 const c = f.getCodeBuilder();
2134 f.addCode(c.call(f1mPrefix + "_mul", c.getLocal("x"), c.getLocal("y"), c.i32_const(pAux1)));
2135 f.addCode(c.call(f1mPrefix + "_mul", c.i32_const(pAux1), c.i32_const(pR2), c.getLocal("r")));
2136 }
2137
2138 function buildInverse() {
2139
2140 const f = module.addFunction(prefix+ "_inverse");
2141 f.addParam("x", "i32");
2142 f.addParam("r", "i32");
2143
2144 const c = f.getCodeBuilder();
2145 f.addCode(c.call(intPrefix + "_inverseMod", c.getLocal("x"), c.i32_const(pq), c.getLocal("r")));
2146 }
2147
2148 buildMul();
2149 buildInverse();
2150 module.exportFunction(f1mPrefix + "_add", prefix + "_add");
2151 module.exportFunction(f1mPrefix + "_sub", prefix + "_sub");
2152 module.exportFunction(f1mPrefix + "_neg", prefix + "_neg");
2153 module.exportFunction(prefix + "_mul");
2154 module.exportFunction(prefix + "_inverse");
2155 module.exportFunction(f1mPrefix + "_copy", prefix+"_copy");
2156 module.exportFunction(f1mPrefix + "_zero", prefix+"_zero");
2157 module.exportFunction(f1mPrefix + "_one", prefix+"_one");
2158 module.exportFunction(f1mPrefix + "_isZero", prefix+"_isZero");
2159 module.exportFunction(f1mPrefix + "_eq", prefix+"_eq");
2160
2161 return prefix;
2162};
2163
2164},{"./build_f1m.js":6,"big-integer":2}],6:[function(require,module,exports){
2165const bigInt = require("big-integer");
2166const buildInt = require("./build_int.js");
2167const utils = require("./utils.js");
2168
2169module.exports = function buildF1m(module, _q, _prefix, _intPrefix) {
2170 const q = bigInt(_q);
2171 const n64 = Math.floor((q.minus(1).bitLength() - 1)/64) +1;
2172 const n32 = n64*2;
2173 const n8 = n64*8;
2174
2175 const prefix = _prefix || "f1m";
2176 if (module.modules[prefix]) return prefix; // already builded
2177
2178 const intPrefix = buildInt(module, n64, _intPrefix);
2179 const pq = module.alloc(n8, utils.bigInt2BytesLE(q, n8));
2180
2181 const pR2 = module.alloc(utils.bigInt2BytesLE(bigInt.one.shiftLeft(n64*64).square().mod(q), n8));
2182 const pOne = module.alloc(utils.bigInt2BytesLE(bigInt.one.shiftLeft(n64*64).mod(q), n8));
2183 const pZero = module.alloc(utils.bigInt2BytesLE(bigInt.zero, n8));
2184 module.modules[prefix] = {
2185 pq: pq,
2186 pR2: pR2,
2187 n64: n64,
2188 q: q,
2189 pOne: pOne,
2190 pZero: pZero
2191 };
2192
2193 function buildOne() {
2194 const f = module.addFunction(prefix+"_one");
2195 f.addParam("pr", "i32");
2196
2197 const c = f.getCodeBuilder();
2198
2199 f.addCode(c.call(prefix + "_copy", c.i32_const(pOne), c.getLocal("pr")));
2200 }
2201
2202 function buildAdd() {
2203 const f = module.addFunction(prefix+"_add");
2204 f.addParam("x", "i32");
2205 f.addParam("y", "i32");
2206 f.addParam("r", "i32");
2207
2208 const c = f.getCodeBuilder();
2209
2210 f.addCode(
2211 c.if(
2212 c.call(intPrefix+"_add", c.getLocal("x"), c.getLocal("y"), c.getLocal("r")),
2213 c.drop(c.call(intPrefix+"_sub", c.getLocal("r"), c.i32_const(pq), c.getLocal("r"))),
2214 c.if(
2215 c.call(intPrefix+"_gte", c.getLocal("r"), c.i32_const(pq) ),
2216 c.drop(c.call(intPrefix+"_sub", c.getLocal("r"), c.i32_const(pq), c.getLocal("r"))),
2217 )
2218 )
2219 );
2220 }
2221
2222 function buildSub() {
2223 const f = module.addFunction(prefix+"_sub");
2224 f.addParam("x", "i32");
2225 f.addParam("y", "i32");
2226 f.addParam("r", "i32");
2227
2228 const c = f.getCodeBuilder();
2229
2230 f.addCode(
2231 c.if(
2232 c.call(intPrefix+"_sub", c.getLocal("x"), c.getLocal("y"), c.getLocal("r")),
2233 c.drop(c.call(intPrefix+"_add", c.getLocal("r"), c.i32_const(pq), c.getLocal("r")))
2234 )
2235 );
2236 }
2237
2238 function buildNeg() {
2239 const f = module.addFunction(prefix+"_neg");
2240 f.addParam("x", "i32");
2241 f.addParam("r", "i32");
2242
2243 const c = f.getCodeBuilder();
2244
2245 f.addCode(
2246 c.if(
2247 c.i32_eqz( c.call(intPrefix + "_isZero", c.getLocal("x"))),
2248 c.drop(c.call(intPrefix+"_sub", c.i32_const(pq), c.getLocal("x"), c.getLocal("r"))),
2249 )
2250 );
2251 }
2252
2253
2254 function buildMReduct() {
2255 const carries = module.alloc(n32*n32*8);
2256
2257 const f = module.addFunction(prefix+"_mReduct");
2258 f.addParam("t", "i32");
2259 f.addParam("r", "i32");
2260 f.addLocal("np32", "i64");
2261 f.addLocal("c", "i64");
2262 f.addLocal("m", "i64");
2263
2264 const c = f.getCodeBuilder();
2265
2266 const np32 = bigInt("100000000",16).minus( q.modInv(bigInt("100000000",16))).toJSNumber();
2267
2268 f.addCode(c.setLocal("np32", c.i64_const(np32)));
2269
2270 for (let i=0; i<n32; i++) {
2271 f.addCode(c.setLocal("c", c.i64_const(0)));
2272
2273 f.addCode(
2274 c.setLocal(
2275 "m",
2276 c.i64_and(
2277 c.i64_mul(
2278 c.i64_load32_u(c.getLocal("t"), i*4),
2279 c.getLocal("np32")
2280 ),
2281 c.i64_const("0xFFFFFFFF")
2282 )
2283 )
2284 );
2285
2286 for (let j=0; j<n32; j++) {
2287
2288 f.addCode(
2289 c.setLocal("c",
2290 c.i64_add(
2291 c.i64_add(
2292 c.i64_load32_u(c.getLocal("t"), (i+j)*4),
2293 c.i64_shr_u(c.getLocal("c"), c.i64_const(32))
2294 ),
2295 c.i64_mul(
2296 c.i64_load32_u(c.i32_const(pq), j*4),
2297 c.getLocal("m")
2298 )
2299 )
2300 )
2301 );
2302
2303 f.addCode(
2304 c.i64_store32(
2305 c.getLocal("t"),
2306 (i+j)*4,
2307 c.getLocal("c")
2308 )
2309 );
2310 }
2311
2312 f.addCode(
2313 c.i64_store32(
2314 c.i32_const(carries),
2315 i*4,
2316 c.i64_shr_u(c.getLocal("c"), c.i64_const(32))
2317 )
2318 );
2319 }
2320
2321 f.addCode(
2322 c.call(
2323 prefix+"_add",
2324 c.i32_const(carries),
2325 c.i32_add(
2326 c.getLocal("t"),
2327 c.i32_const(n32*4)
2328 ),
2329 c.getLocal("r")
2330 )
2331 );
2332 }
2333
2334
2335 function buildMul() {
2336
2337 const pAux2 = module.alloc(n8*2);
2338
2339 const f = module.addFunction(prefix+"_mul");
2340 f.addParam("x", "i32");
2341 f.addParam("y", "i32");
2342 f.addParam("r", "i32");
2343
2344 const c = f.getCodeBuilder();
2345 f.addCode(c.call(intPrefix + "_mul", c.getLocal("x"), c.getLocal("y"), c.i32_const(pAux2) ));
2346 f.addCode(c.call(prefix + "_mReduct", c.i32_const(pAux2), c.getLocal("r")));
2347 }
2348
2349
2350 function buildToMontgomery() {
2351 const f = module.addFunction(prefix+"_toMontgomery");
2352 f.addParam("x", "i32");
2353 f.addParam("r", "i32");
2354
2355 const c = f.getCodeBuilder();
2356 f.addCode(c.call(prefix+"_mul", c.getLocal("x"), c.i32_const(pR2), c.getLocal("r")));
2357 }
2358
2359 function buildFromMontgomery() {
2360
2361 const pAux2 = module.alloc(n8*2);
2362
2363 const f = module.addFunction(prefix+"_fromMontgomery");
2364 f.addParam("x", "i32");
2365 f.addParam("r", "i32");
2366
2367 const c = f.getCodeBuilder();
2368 f.addCode(c.call(intPrefix + "_copy", c.getLocal("x"), c.i32_const(pAux2) ));
2369 f.addCode(c.call(intPrefix + "_zero", c.i32_const(pAux2 + n8) ));
2370 f.addCode(c.call(prefix+"_mReduct", c.i32_const(pAux2), c.getLocal("r")));
2371 }
2372
2373 function buildInverse() {
2374
2375 const f = module.addFunction(prefix+ "_inverse");
2376 f.addParam("x", "i32");
2377 f.addParam("r", "i32");
2378
2379 const c = f.getCodeBuilder();
2380 f.addCode(c.call(prefix + "_fromMontgomery", c.getLocal("x"), c.getLocal("r")));
2381 f.addCode(c.call(intPrefix + "_inverseMod", c.getLocal("r"), c.i32_const(pq), c.getLocal("r")));
2382 f.addCode(c.call(prefix + "_toMontgomery", c.getLocal("r"), c.getLocal("r")));
2383 }
2384
2385 buildAdd();
2386 buildSub();
2387 buildNeg();
2388 buildMReduct();
2389 buildMul();
2390 buildToMontgomery();
2391 buildFromMontgomery();
2392 buildInverse();
2393 module.exportFunction(prefix + "_add");
2394 module.exportFunction(prefix + "_sub");
2395 module.exportFunction(prefix + "_neg");
2396 module.exportFunction(prefix + "_mReduct");
2397 module.exportFunction(prefix + "_mul");
2398 module.exportFunction(prefix + "_fromMontgomery");
2399 module.exportFunction(prefix + "_toMontgomery");
2400 module.exportFunction(prefix + "_inverse");
2401 module.exportFunction(intPrefix + "_copy", prefix+"_copy");
2402 module.exportFunction(intPrefix + "_zero", prefix+"_zero");
2403 module.exportFunction(intPrefix + "_isZero", prefix+"_isZero");
2404 module.exportFunction(intPrefix + "_eq", prefix+"_eq");
2405 buildOne();
2406 module.exportFunction(prefix + "_one");
2407
2408 return prefix;
2409};
2410
2411},{"./build_int.js":9,"./utils.js":17,"big-integer":2}],7:[function(require,module,exports){
2412module.exports = function buildF2m(module, pNonResidue, prefix, f1mPrefix) {
2413
2414 if (module.modules[prefix]) return prefix; // already builded
2415
2416 const f1n8 = module.modules[f1mPrefix].n64*8;
2417 module.modules[prefix] = {
2418 n64: module.modules[f1mPrefix].n64*2
2419 };
2420
2421 function buildAdd() {
2422 const f = module.addFunction(prefix+"_add");
2423 f.addParam("x", "i32");
2424 f.addParam("y", "i32");
2425 f.addParam("r", "i32");
2426
2427 const c = f.getCodeBuilder();
2428
2429 const x0 = c.getLocal("x");
2430 const x1 = c.i32_add(c.getLocal("x"), c.i32_const(f1n8));
2431 const y0 = c.getLocal("y");
2432 const y1 = c.i32_add(c.getLocal("y"), c.i32_const(f1n8));
2433 const r0 = c.getLocal("r");
2434 const r1 = c.i32_add(c.getLocal("r"), c.i32_const(f1n8));
2435
2436 f.addCode(
2437 c.call(f1mPrefix+"_add", x0, y0, r0),
2438 c.call(f1mPrefix+"_add", x1, y1, r1),
2439 );
2440 }
2441
2442 function buildSub() {
2443 const f = module.addFunction(prefix+"_sub");
2444 f.addParam("x", "i32");
2445 f.addParam("y", "i32");
2446 f.addParam("r", "i32");
2447
2448 const c = f.getCodeBuilder();
2449
2450 const x0 = c.getLocal("x");
2451 const x1 = c.i32_add(c.getLocal("x"), c.i32_const(f1n8));
2452 const y0 = c.getLocal("y");
2453 const y1 = c.i32_add(c.getLocal("y"), c.i32_const(f1n8));
2454 const r0 = c.getLocal("r");
2455 const r1 = c.i32_add(c.getLocal("r"), c.i32_const(f1n8));
2456
2457 f.addCode(
2458 c.call(f1mPrefix+"_sub", x0, y0, r0),
2459 c.call(f1mPrefix+"_sub", x1, y1, r1),
2460 );
2461 }
2462
2463 function buildNeg() {
2464 const f = module.addFunction(prefix+"_neg");
2465 f.addParam("x", "i32");
2466 f.addParam("r", "i32");
2467
2468 const c = f.getCodeBuilder();
2469
2470 const x0 = c.getLocal("x");
2471 const x1 = c.i32_add(c.getLocal("x"), c.i32_const(f1n8));
2472 const r0 = c.getLocal("r");
2473 const r1 = c.i32_add(c.getLocal("r"), c.i32_const(f1n8));
2474
2475 f.addCode(
2476 c.call(f1mPrefix+"_neg", x0, r0),
2477 c.call(f1mPrefix+"_neg", x1, r1),
2478 );
2479 }
2480
2481 function buildMul() {
2482 const f = module.addFunction(prefix+"_mul");
2483 f.addParam("x", "i32");
2484 f.addParam("y", "i32");
2485 f.addParam("r", "i32");
2486
2487 const c = f.getCodeBuilder();
2488
2489 const x0 = c.getLocal("x");
2490 const x1 = c.i32_add(c.getLocal("x"), c.i32_const(f1n8));
2491 const y0 = c.getLocal("y");
2492 const y1 = c.i32_add(c.getLocal("y"), c.i32_const(f1n8));
2493 const r0 = c.getLocal("r");
2494 const r1 = c.i32_add(c.getLocal("r"), c.i32_const(f1n8));
2495
2496 const A = c.i32_const(module.alloc(f1n8));
2497 const B = c.i32_const(module.alloc(f1n8));
2498 const C = c.i32_const(module.alloc(f1n8));
2499 const D = c.i32_const(module.alloc(f1n8));
2500
2501
2502 f.addCode(
2503 c.call(f1mPrefix + "_mul", x0, y0, A), // A = x0*y0
2504 c.call(f1mPrefix + "_mul", x1, y1, B), // B = x1*y1
2505
2506 c.call(f1mPrefix + "_add", x0, x1, C), // C = x0 + x1
2507 c.call(f1mPrefix + "_add", y0, y1, D), // D = y0 + y1
2508 c.call(f1mPrefix + "_mul", C, D, C), // C = (x0 + x1)*(y0 + y1) = x0*y0+x0*y1+x1*y0+x1*y1
2509
2510 c.call(f1mPrefix + "_mul", B, c.i32_const(pNonResidue), r0), // r0 = nr*(x1*y1)
2511 c.call(f1mPrefix + "_add", A, r0, r0), // r0 = x0*y0 + nr*(x1*y1)
2512 c.call(f1mPrefix + "_add", A, B, r1), // r1 = x0*y0+x1*y1
2513 c.call(f1mPrefix + "_sub", C, r1, r1) // r1 = x0*y0+x0*y1+x1*y0+x1*y1 - x0*y0+x1*y1 = x0*y1+x1*y0
2514 );
2515
2516 }
2517
2518
2519 function buildToMontgomery() {
2520 const f = module.addFunction(prefix+"_toMontgomery");
2521 f.addParam("x", "i32");
2522 f.addParam("r", "i32");
2523
2524 const c = f.getCodeBuilder();
2525
2526 const x0 = c.getLocal("x");
2527 const x1 = c.i32_add(c.getLocal("x"), c.i32_const(f1n8));
2528 const r0 = c.getLocal("r");
2529 const r1 = c.i32_add(c.getLocal("r"), c.i32_const(f1n8));
2530
2531 f.addCode(
2532 c.call(f1mPrefix+"_toMontgomery", x0, r0),
2533 c.call(f1mPrefix+"_toMontgomery", x1, r1)
2534 );
2535 }
2536
2537 function buildFromMontgomery() {
2538 const f = module.addFunction(prefix+"_fromMontgomery");
2539 f.addParam("x", "i32");
2540 f.addParam("r", "i32");
2541
2542 const c = f.getCodeBuilder();
2543
2544 const x0 = c.getLocal("x");
2545 const x1 = c.i32_add(c.getLocal("x"), c.i32_const(f1n8));
2546 const r0 = c.getLocal("r");
2547 const r1 = c.i32_add(c.getLocal("r"), c.i32_const(f1n8));
2548
2549 f.addCode(
2550 c.call(f1mPrefix+"_fromMontgomery", x0, r0),
2551 c.call(f1mPrefix+"_fromMontgomery", x1, r1)
2552 );
2553 }
2554
2555 function buildCopy() {
2556 const f = module.addFunction(prefix+"_copy");
2557 f.addParam("x", "i32");
2558 f.addParam("r", "i32");
2559
2560 const c = f.getCodeBuilder();
2561
2562 const x0 = c.getLocal("x");
2563 const x1 = c.i32_add(c.getLocal("x"), c.i32_const(f1n8));
2564 const r0 = c.getLocal("r");
2565 const r1 = c.i32_add(c.getLocal("r"), c.i32_const(f1n8));
2566
2567 f.addCode(
2568 c.call(f1mPrefix+"_copy", x0, r0),
2569 c.call(f1mPrefix+"_copy", x1, r1)
2570 );
2571 }
2572
2573 function buildZero() {
2574 const f = module.addFunction(prefix+"_zero");
2575 f.addParam("x", "i32");
2576
2577 const c = f.getCodeBuilder();
2578
2579 const x0 = c.getLocal("x");
2580 const x1 = c.i32_add(c.getLocal("x"), c.i32_const(f1n8));
2581
2582 f.addCode(
2583 c.call(f1mPrefix+"_zero", x0),
2584 c.call(f1mPrefix+"_zero", x1)
2585 );
2586 }
2587
2588 function buildOne() {
2589 const f = module.addFunction(prefix+"_one");
2590 f.addParam("x", "i32");
2591
2592 const c = f.getCodeBuilder();
2593
2594 const x0 = c.getLocal("x");
2595 const x1 = c.i32_add(c.getLocal("x"), c.i32_const(f1n8));
2596
2597 f.addCode(
2598 c.call(f1mPrefix+"_one", x0),
2599 c.call(f1mPrefix+"_zero", x1)
2600 );
2601 }
2602
2603 function buildEq() {
2604 const f = module.addFunction(prefix+"_eq");
2605 f.addParam("x", "i32");
2606 f.addParam("y", "i32");
2607 f.setReturnType("i32");
2608
2609 const c = f.getCodeBuilder();
2610
2611 const x0 = c.getLocal("x");
2612 const x1 = c.i32_add(c.getLocal("x"), c.i32_const(f1n8));
2613 const y0 = c.getLocal("y");
2614 const y1 = c.i32_add(c.getLocal("y"), c.i32_const(f1n8));
2615
2616 f.addCode(
2617 c.i32_and(
2618 c.call(f1mPrefix+"_eq", x0, y0),
2619 c.call(f1mPrefix+"_eq", x1, y1)
2620 )
2621 );
2622 }
2623
2624 function buildIsZero() {
2625 const f = module.addFunction(prefix+"_isZero");
2626 f.addParam("x", "i32");
2627 f.setReturnType("i32");
2628
2629 const c = f.getCodeBuilder();
2630
2631 const x0 = c.getLocal("x");
2632 const x1 = c.i32_add(c.getLocal("x"), c.i32_const(f1n8));
2633
2634 f.addCode(
2635 c.i32_and(
2636 c.call(f1mPrefix+"_isZero", x0),
2637 c.call(f1mPrefix+"_isZero", x1)
2638 )
2639 );
2640 }
2641
2642 function buildInverse() {
2643 const f = module.addFunction(prefix+"_inverse");
2644 f.addParam("x", "i32");
2645 f.addParam("r", "i32");
2646
2647 const c = f.getCodeBuilder();
2648
2649 const x0 = c.getLocal("x");
2650 const x1 = c.i32_add(c.getLocal("x"), c.i32_const(f1n8));
2651 const r0 = c.getLocal("r");
2652 const r1 = c.i32_add(c.getLocal("r"), c.i32_const(f1n8));
2653
2654 const t0 = c.i32_const(module.alloc(f1n8));
2655 const t1 = c.i32_const(module.alloc(f1n8));
2656 const t2 = c.i32_const(module.alloc(f1n8));
2657 const t3 = c.i32_const(module.alloc(f1n8));
2658
2659 f.addCode(
2660 c.call(f1mPrefix+"_mul", x0, x0, t0),
2661 c.call(f1mPrefix+"_mul", x1, x1, t1),
2662 c.call(f1mPrefix+"_mul", t1, c.i32_const(pNonResidue), t2),
2663 c.call(f1mPrefix+"_sub", t0, t2, t2),
2664 c.call(f1mPrefix+"_inverse", t2, t3),
2665
2666 c.call(f1mPrefix+"_mul", x0, t3, r0),
2667 c.call(f1mPrefix+"_mul", x1, t3, r1),
2668 c.call(f1mPrefix+"_neg", r1, r1),
2669 );
2670 }
2671
2672 buildIsZero();
2673 buildZero();
2674 buildOne();
2675 buildCopy();
2676 buildMul();
2677 buildAdd();
2678 buildSub();
2679 buildNeg();
2680 buildToMontgomery();
2681 buildFromMontgomery();
2682 buildEq();
2683 buildInverse();
2684
2685 module.exportFunction(prefix + "_isZero");
2686 module.exportFunction(prefix + "_zero");
2687 module.exportFunction(prefix + "_one");
2688 module.exportFunction(prefix + "_copy");
2689 module.exportFunction(prefix + "_mul");
2690 module.exportFunction(prefix + "_add");
2691 module.exportFunction(prefix + "_sub");
2692 module.exportFunction(prefix + "_neg");
2693 module.exportFunction(prefix + "_fromMontgomery");
2694 module.exportFunction(prefix + "_toMontgomery");
2695 module.exportFunction(prefix + "_eq");
2696 module.exportFunction(prefix + "_inverse");
2697
2698 return prefix;
2699};
2700
2701},{}],8:[function(require,module,exports){
2702const bigInt = require("big-integer");
2703const utils = require("./utils.js");
2704
2705module.exports = function buildFFT(module, prefix, f1mPrefix) {
2706
2707 const n64 = module.modules[f1mPrefix].n64;
2708 const n8 = n64*8;
2709 const q = module.modules[f1mPrefix].q;
2710
2711 let rem = q.minus(bigInt(1));
2712 let maxBits = 0;
2713 while (!rem.isOdd()) {
2714 maxBits ++;
2715 rem = rem.shiftRight(1);
2716 }
2717
2718 let nr = bigInt(2);
2719
2720 while ( nr.modPow(q.shiftRight(1), q).equals(1) ) nr = nr.add(1);
2721
2722 const w = new Array(maxBits+1);
2723 w[maxBits] = nr.modPow(rem, q);
2724
2725 let n=maxBits-1;
2726 while (n>=0) {
2727 w[n] = w[n+1].modPow(2, q);
2728 n--;
2729 }
2730
2731 const bytes = [];
2732 const R = bigInt(1).shiftLeft(n8*8).mod(q);
2733
2734 for (let i=0; i<w.length; i++) {
2735 const m = w[i].times(R).mod(q);
2736 bytes.push(...utils.bigInt2BytesLE(m, n8));
2737 }
2738
2739 const ROOTs = module.alloc(bytes);
2740
2741 const i2 = new Array(maxBits+1);
2742 i2[0] = bigInt(1);
2743
2744 for (let i=1; i<=maxBits; i++) {
2745 i2[i] = i2[i-1].times(2);
2746 }
2747
2748 const bytesi2 =[];
2749 for (let i=0; i<=maxBits; i++) {
2750 const m = i2[i].modInv(q).times(R).mod(q);
2751 bytesi2.push(...utils.bigInt2BytesLE(m, n8));
2752 }
2753
2754 const INV2 = module.alloc(bytesi2);
2755
2756 function rev(x) {
2757 let r=0;
2758 for (let i=0; i<8; i++) {
2759 if (x & (1 << i)) {
2760 r = r | (0x80 >> i);
2761 }
2762 }
2763 return r;
2764 }
2765
2766 const rtable = Array(256);
2767 for (let i=0; i<256; i++) {
2768 rtable[i] = rev(i);
2769 }
2770
2771 const REVTABLE = module.alloc(rtable);
2772
2773
2774 function buildLog2() {
2775 const f = module.addFunction(prefix+"__log2");
2776 f.addParam("n", "i32");
2777 f.setReturnType("i32");
2778 f.addLocal("bits", "i32");
2779 f.addLocal("aux", "i32");
2780
2781 const c = f.getCodeBuilder();
2782
2783 f.addCode(
2784 c.setLocal(
2785 "aux",
2786 c.i32_shr_u(
2787 c.getLocal("n"),
2788 c.i32_const(1)
2789 )
2790 )
2791 );
2792 f.addCode(c.setLocal("bits", c.i32_const(0)));
2793
2794 f.addCode(c.block(c.loop(
2795 c.br_if(
2796 1,
2797 c.i32_eqz(c.getLocal("aux"))
2798 ),
2799
2800 c.setLocal(
2801 "aux",
2802 c.i32_shr_u(
2803 c.getLocal("aux"),
2804 c.i32_const(1)
2805 )
2806 ),
2807
2808 c.setLocal(
2809 "bits",
2810 c.i32_add(
2811 c.getLocal("bits"),
2812 c.i32_const(1)
2813 )
2814 ),
2815
2816 c.br(0)
2817 )));
2818
2819 f.addCode(c.if(
2820 c.i32_ne(
2821 c.getLocal("n"),
2822 c.i32_shl(
2823 c.i32_const(1),
2824 c.getLocal("bits")
2825 )
2826 ),
2827 c.unreachable()
2828 ));
2829
2830 f.addCode(c.if(
2831 c.i32_gt_u(
2832 c.getLocal("bits"),
2833 c.i32_const(maxBits)
2834 ),
2835 c.unreachable()
2836 ));
2837
2838 f.addCode(c.getLocal("bits"));
2839 }
2840
2841 function buildFFT() {
2842 const f = module.addFunction(prefix+"_fft");
2843 f.addParam("px", "i32");
2844 f.addParam("n", "i32");
2845 f.addParam("odd", "i32");
2846
2847 f.addLocal("bits", "i32");
2848
2849 const c = f.getCodeBuilder();
2850
2851 f.addCode(
2852 c.setLocal(
2853 "bits",
2854 c.call(
2855 prefix + "__log2",
2856 c.getLocal("n")
2857 )
2858 )
2859 );
2860
2861
2862 f.addCode(c.call(
2863 prefix+"__rawfft",
2864 c.getLocal("px"),
2865 c.getLocal("bits"),
2866 c.getLocal("odd"),
2867 ));
2868
2869 }
2870
2871 function buildIFFT() {
2872 const f = module.addFunction(prefix+"_ifft");
2873 f.addParam("px", "i32");
2874 f.addParam("n", "i32");
2875 f.addParam("odd", "i32");
2876 f.addLocal("bits", "i32");
2877
2878 const c = f.getCodeBuilder();
2879
2880 f.addCode(
2881 c.setLocal(
2882 "bits",
2883 c.call(
2884 prefix + "__log2",
2885 c.getLocal("n")
2886 )
2887 )
2888 );
2889
2890 f.addCode(c.call(
2891 prefix+"__rawfft",
2892 c.getLocal("px"),
2893 c.getLocal("bits"),
2894 c.getLocal("odd")
2895 ));
2896
2897 f.addCode(c.call(
2898 prefix+"__finalInverse",
2899 c.getLocal("px"),
2900 c.getLocal("bits"),
2901 ));
2902
2903 }
2904
2905 function buildRawFFT() {
2906 const f = module.addFunction(prefix+"__rawfft");
2907 f.addParam("px", "i32");
2908 f.addParam("bits", "i32");
2909 f.addParam("odd", "i32");
2910 f.addLocal("s", "i32");
2911 f.addLocal("k", "i32");
2912 f.addLocal("j", "i32");
2913 f.addLocal("m", "i32");
2914 f.addLocal("mdiv2", "i32");
2915 f.addLocal("n", "i32");
2916 f.addLocal("pwm", "i32");
2917 f.addLocal("idx1", "i32");
2918 f.addLocal("idx2", "i32");
2919
2920 const c = f.getCodeBuilder();
2921
2922 const W = c.i32_const(module.alloc(n8));
2923 const T = c.i32_const(module.alloc(n8));
2924 const U = c.i32_const(module.alloc(n8));
2925
2926 f.addCode(
2927 c.call(prefix + "__reversePermutation", c.getLocal("px"), c.getLocal("bits")),
2928 c.setLocal("n", c.i32_shl(c.i32_const(1), c.getLocal("bits"))),
2929 c.setLocal("s", c.i32_const(1)),
2930 c.block(c.loop(
2931 c.br_if(
2932 1,
2933 c.i32_gt_u(
2934 c.getLocal("s"),
2935 c.getLocal("bits")
2936 )
2937 ),
2938 c.setLocal("m", c.i32_shl(c.i32_const(1), c.getLocal("s"))),
2939 c.setLocal("pwm",
2940 c.i32_add(
2941 c.i32_const(ROOTs),
2942 c.i32_mul(
2943 c.getLocal("s"),
2944 c.i32_const(n8)
2945 )
2946 )
2947 ),
2948 c.setLocal("k", c.i32_const(0)),
2949 c.block(c.loop(
2950 c.br_if(
2951 1,
2952 c.i32_ge_u(
2953 c.getLocal("k"),
2954 c.getLocal("n")
2955 )
2956 ),
2957
2958 c.if(
2959 c.getLocal("odd"),
2960 c.call(
2961 f1mPrefix + "_copy",
2962 c.i32_add(
2963 c.getLocal("pwm"),
2964 c.i32_const(n8)
2965 ),
2966 W
2967 ),
2968 c.call(f1mPrefix + "_one", W)
2969 ),
2970
2971
2972 c.setLocal("mdiv2", c.i32_shr_u(c.getLocal("m"), c.i32_const(1)) ),
2973 c.setLocal("j", c.i32_const(0)),
2974 c.block(c.loop(
2975 c.br_if(
2976 1,
2977 c.i32_ge_u(
2978 c.getLocal("j"),
2979 c.getLocal("mdiv2")
2980 )
2981 ),
2982
2983 c.setLocal(
2984 "idx1",
2985 c.i32_add(
2986 c.getLocal("px"),
2987 c.i32_mul(
2988 c.i32_add(
2989 c.getLocal("k"),
2990 c.getLocal("j")
2991 ),
2992 c.i32_const(n8)
2993 )
2994 )
2995 ),
2996
2997 c.setLocal(
2998 "idx2",
2999 c.i32_add(
3000 c.getLocal("idx1"),
3001 c.i32_mul(
3002 c.getLocal("mdiv2"),
3003 c.i32_const(n8)
3004 )
3005 )
3006 ),
3007
3008 c.call(
3009 f1mPrefix + "_mul",
3010 W,
3011 c.getLocal("idx2"),
3012 T
3013 ),
3014
3015 c.call(
3016 f1mPrefix + "_copy",
3017 c.getLocal("idx1"),
3018 U
3019 ),
3020
3021 c.call(
3022 f1mPrefix + "_add",
3023 U,
3024 T,
3025 c.getLocal("idx1"),
3026 ),
3027
3028 c.call(
3029 f1mPrefix + "_sub",
3030 U,
3031 T,
3032 c.getLocal("idx2"),
3033 ),
3034
3035 c.call(
3036 f1mPrefix + "_mul",
3037 W,
3038 c.getLocal("pwm"),
3039 W,
3040 ),
3041
3042 c.setLocal("j", c.i32_add(c.getLocal("j"), c.i32_const(1))),
3043 c.br(0)
3044 )),
3045
3046 c.setLocal("k", c.i32_add(c.getLocal("k"), c.getLocal("m"))),
3047 c.br(0)
3048 )),
3049
3050 c.setLocal("s", c.i32_add(c.getLocal("s"), c.i32_const(1))),
3051 c.br(0)
3052 ))
3053 );
3054 }
3055
3056 function buildCopyInterleaved() {
3057 const f = module.addFunction(prefix+"_copyNInterleaved");
3058 f.addParam("ps", "i32");
3059 f.addParam("pd", "i32");
3060 f.addParam("n", "i32");
3061 f.addLocal("pi", "i32");
3062 f.addLocal("po", "i32");
3063 f.addLocal("pn", "i32");
3064
3065 const c = f.getCodeBuilder();
3066
3067 f.addCode(
3068 c.setLocal("pi", c.getLocal("ps")),
3069 c.setLocal("po", c.getLocal("pd")),
3070 c.setLocal(
3071 "pn",
3072 c.i32_add(
3073 c.getLocal("ps"),
3074 c.i32_mul(
3075 c.getLocal("n"),
3076 c.i32_const(n8)
3077 )
3078 )
3079 ),
3080 c.block(c.loop(
3081 c.br_if(
3082 1,
3083 c.i32_eq(
3084 c.getLocal("pi"),
3085 c.getLocal("pn")
3086 )
3087 ),
3088
3089 c.call(f1mPrefix + "_copy", c.getLocal("pi"), c.getLocal("po")),
3090
3091 c.setLocal("pi", c.i32_add(c.getLocal("pi"), c.i32_const(n8))),
3092 c.setLocal("po", c.i32_add(c.getLocal("po"), c.i32_const(n8*2))),
3093 c.br(0)
3094 ))
3095 );
3096 }
3097
3098
3099
3100 function buildToMontgomery() {
3101 const f = module.addFunction(prefix+"_toMontgomeryN");
3102 f.addParam("ps", "i32");
3103 f.addParam("pd", "i32");
3104 f.addParam("n", "i32");
3105 f.addLocal("pi", "i32");
3106 f.addLocal("po", "i32");
3107 f.addLocal("pn", "i32");
3108
3109 const c = f.getCodeBuilder();
3110
3111 f.addCode(
3112 c.setLocal("pi", c.getLocal("ps")),
3113 c.setLocal("po", c.getLocal("pd")),
3114 c.setLocal(
3115 "pn",
3116 c.i32_add(
3117 c.getLocal("ps"),
3118 c.i32_mul(
3119 c.getLocal("n"),
3120 c.i32_const(n8)
3121 )
3122 )
3123 ),
3124 c.block(c.loop(
3125 c.br_if(
3126 1,
3127 c.i32_eq(
3128 c.getLocal("pi"),
3129 c.getLocal("pn")
3130 )
3131 ),
3132
3133 c.call(f1mPrefix + "_toMontgomery", c.getLocal("pi"), c.getLocal("po")),
3134
3135 c.setLocal("pi", c.i32_add(c.getLocal("pi"), c.i32_const(n8))),
3136 c.setLocal("po", c.i32_add(c.getLocal("po"), c.i32_const(n8))),
3137 c.br(0)
3138 ))
3139 );
3140 }
3141
3142
3143 function buildMulN() {
3144 const f = module.addFunction(prefix+"_mulN");
3145 f.addParam("px", "i32");
3146 f.addParam("py", "i32");
3147 f.addParam("n", "i32");
3148 f.addParam("pd", "i32");
3149 f.addLocal("pix", "i32");
3150 f.addLocal("piy", "i32");
3151 f.addLocal("po", "i32");
3152 f.addLocal("lastpix", "i32");
3153
3154 const c = f.getCodeBuilder();
3155
3156 f.addCode(
3157 c.setLocal("pix", c.getLocal("px")),
3158 c.setLocal("piy", c.getLocal("py")),
3159 c.setLocal("po", c.getLocal("pd")),
3160 c.setLocal(
3161 "lastpix",
3162 c.i32_add(
3163 c.getLocal("px"),
3164 c.i32_mul(
3165 c.getLocal("n"),
3166 c.i32_const(n8)
3167 )
3168 )
3169 ),
3170 c.block(c.loop(
3171 c.br_if(
3172 1,
3173 c.i32_eq(
3174 c.getLocal("pix"),
3175 c.getLocal("lastpix")
3176 )
3177 ),
3178
3179 c.call(f1mPrefix + "_mul", c.getLocal("pix"), c.getLocal("piy"), c.getLocal("po")),
3180
3181 c.setLocal("pix", c.i32_add(c.getLocal("pix"), c.i32_const(n8))),
3182 c.setLocal("piy", c.i32_add(c.getLocal("piy"), c.i32_const(n8))),
3183 c.setLocal("po", c.i32_add(c.getLocal("po"), c.i32_const(n8))),
3184 c.br(0)
3185 ))
3186 );
3187 }
3188
3189 function buildFromMontgomery() {
3190 const f = module.addFunction(prefix+"_fromMontgomeryN");
3191 f.addParam("ps", "i32");
3192 f.addParam("pd", "i32");
3193 f.addParam("n", "i32");
3194 f.addLocal("pi", "i32");
3195 f.addLocal("po", "i32");
3196 f.addLocal("pn", "i32");
3197
3198 const c = f.getCodeBuilder();
3199
3200 f.addCode(
3201 c.setLocal("pi", c.getLocal("ps")),
3202 c.setLocal("po", c.getLocal("pd")),
3203 c.setLocal(
3204 "pn",
3205 c.i32_add(
3206 c.getLocal("ps"),
3207 c.i32_mul(
3208 c.getLocal("n"),
3209 c.i32_const(n8)
3210 )
3211 )
3212 ),
3213 c.block(c.loop(
3214 c.br_if(
3215 1,
3216 c.i32_eq(
3217 c.getLocal("pi"),
3218 c.getLocal("pn")
3219 )
3220 ),
3221
3222 c.call(f1mPrefix + "_fromMontgomery", c.getLocal("pi"), c.getLocal("po")),
3223
3224 c.setLocal("pi", c.i32_add(c.getLocal("pi"), c.i32_const(n8))),
3225 c.setLocal("po", c.i32_add(c.getLocal("po"), c.i32_const(n8))),
3226 c.br(0)
3227 ))
3228 );
3229 }
3230
3231
3232 function buildFinalInverse() {
3233 const f = module.addFunction(prefix+"__finalInverse");
3234 f.addParam("px", "i32");
3235 f.addParam("bits", "i32");
3236 f.addLocal("n", "i32");
3237 f.addLocal("ndiv2", "i32");
3238 f.addLocal("pInv2", "i32");
3239 f.addLocal("i", "i32");
3240 f.addLocal("mask", "i32");
3241 f.addLocal("idx1", "i32");
3242 f.addLocal("idx2", "i32");
3243
3244 const c = f.getCodeBuilder();
3245
3246 const T = c.i32_const(module.alloc(n8));
3247
3248 f.addCode(
3249 c.setLocal("n", c.i32_shl( c.i32_const(1), c.getLocal("bits"))),
3250
3251 c.setLocal(
3252 "pInv2",
3253 c.i32_add(
3254 c.i32_const(INV2),
3255 c.i32_mul(
3256 c.getLocal("bits"),
3257 c.i32_const(n8)
3258 )
3259 )
3260 ),
3261
3262 c.setLocal("mask", c.i32_sub( c.getLocal("n") , c.i32_const(1))),
3263 c.setLocal("i", c.i32_const(1)),
3264 c.setLocal(
3265 "ndiv2",
3266 c.i32_shr_u(
3267 c.getLocal("n"),
3268 c.i32_const(1)
3269 )
3270 ),
3271 c.block(c.loop(
3272 c.br_if(
3273 1,
3274 c.i32_eq(
3275 c.getLocal("i"),
3276 c.getLocal("ndiv2")
3277 )
3278 ),
3279
3280 c.setLocal("idx1",
3281 c.i32_add(
3282 c.getLocal("px"),
3283 c.i32_mul(
3284 c.getLocal("i"),
3285 c.i32_const(n8)
3286 )
3287 )
3288 ),
3289
3290 c.setLocal("idx2",
3291 c.i32_add(
3292 c.getLocal("px"),
3293 c.i32_mul(
3294 c.i32_sub(
3295 c.getLocal("n"),
3296 c.getLocal("i")
3297 ),
3298 c.i32_const(n8)
3299 )
3300 )
3301 ),
3302
3303 c.call(f1mPrefix + "_copy", c.getLocal("idx1"), T),
3304 c.call(f1mPrefix + "_mul", c.getLocal("idx2") , c.getLocal("pInv2"), c.getLocal("idx1") ),
3305 c.call(f1mPrefix + "_mul", T , c.getLocal("pInv2"), c.getLocal("idx2")),
3306
3307// c.call(f1mPrefix + "_mul", c.getLocal("idx1") , c.getLocal("pInv2"), c.getLocal("idx1") ),
3308// c.call(f1mPrefix + "_mul", c.getLocal("idx2") , c.getLocal("pInv2"), c.getLocal("idx1") ),
3309
3310 c.setLocal("i", c.i32_add(c.getLocal("i"), c.i32_const(1))),
3311
3312 c.br(0)
3313 )),
3314
3315 c.call(f1mPrefix + "_mul", c.getLocal("px") , c.getLocal("pInv2"), c.getLocal("px")),
3316
3317 c.setLocal("idx2",
3318 c.i32_add(
3319 c.getLocal("px"),
3320 c.i32_mul(
3321 c.getLocal("ndiv2"),
3322 c.i32_const(n8)
3323 )
3324 )
3325 ),
3326
3327 c.call(f1mPrefix + "_mul", c.getLocal("idx2"),c.getLocal("pInv2"), c.getLocal("idx2"))
3328
3329 );
3330 }
3331
3332 function buildReversePermutation() {
3333 const f = module.addFunction(prefix+"__reversePermutation");
3334 f.addParam("px", "i32");
3335 f.addParam("bits", "i32");
3336 f.addLocal("n", "i32");
3337 f.addLocal("i", "i32");
3338 f.addLocal("ri", "i32");
3339 f.addLocal("idx1", "i32");
3340 f.addLocal("idx2", "i32");
3341
3342 const c = f.getCodeBuilder();
3343
3344 const T = c.i32_const(module.alloc(n8));
3345
3346 f.addCode(
3347 c.setLocal("n", c.i32_shl( c.i32_const(1), c.getLocal("bits"))),
3348 c.setLocal("i", c.i32_const(0)),
3349 c.block(c.loop(
3350 c.br_if(
3351 1,
3352 c.i32_eq(
3353 c.getLocal("i"),
3354 c.getLocal("n")
3355 )
3356 ),
3357
3358 c.setLocal("idx1",
3359 c.i32_add(
3360 c.getLocal("px"),
3361 c.i32_mul(
3362 c.getLocal("i"),
3363 c.i32_const(n8)
3364 )
3365 )
3366 ),
3367
3368 c.setLocal("ri", c.call(prefix + "__rev", c.getLocal("i"), c.getLocal("bits"))),
3369
3370 c.setLocal("idx2",
3371 c.i32_add(
3372 c.getLocal("px"),
3373 c.i32_mul(
3374 c.getLocal("ri"),
3375 c.i32_const(n8)
3376 )
3377 )
3378 ),
3379
3380 c.if(
3381 c.i32_lt_u(
3382 c.getLocal("i"),
3383 c.getLocal("ri")
3384 ),
3385 [
3386 ...c.call(f1mPrefix + "_copy", c.getLocal("idx1"), T),
3387 ...c.call(f1mPrefix + "_copy", c.getLocal("idx2") , c.getLocal("idx1")),
3388 ...c.call(f1mPrefix + "_copy", T , c.getLocal("idx2"))
3389 ]
3390 ),
3391
3392 c.setLocal("i", c.i32_add(c.getLocal("i"), c.i32_const(1))),
3393
3394 c.br(0)
3395 ))
3396 );
3397 }
3398
3399 function buildRev() {
3400 const f = module.addFunction(prefix+"__rev");
3401 f.addParam("x", "i32");
3402 f.addParam("bits", "i32");
3403 f.setReturnType("i32");
3404
3405 const c = f.getCodeBuilder();
3406
3407 f.addCode(
3408 c.i32_rotl(
3409 c.i32_add(
3410 c.i32_add(
3411 c.i32_shl(
3412 c.i32_load8_u(
3413 c.i32_and(
3414 c.getLocal("x"),
3415 c.i32_const(0xFF)
3416 ),
3417 REVTABLE,
3418 0
3419 ),
3420 c.i32_const(24)
3421 ),
3422 c.i32_shl(
3423 c.i32_load8_u(
3424 c.i32_and(
3425 c.i32_shr_u(
3426 c.getLocal("x"),
3427 c.i32_const(8)
3428 ),
3429 c.i32_const(0xFF)
3430 ),
3431 REVTABLE,
3432 0
3433 ),
3434 c.i32_const(16)
3435 ),
3436 ),
3437 c.i32_add(
3438 c.i32_shl(
3439 c.i32_load8_u(
3440 c.i32_and(
3441 c.i32_shr_u(
3442 c.getLocal("x"),
3443 c.i32_const(16)
3444 ),
3445 c.i32_const(0xFF)
3446 ),
3447 REVTABLE,
3448 0
3449 ),
3450 c.i32_const(8)
3451 ),
3452 c.i32_load8_u(
3453 c.i32_and(
3454 c.i32_shr_u(
3455 c.getLocal("x"),
3456 c.i32_const(24)
3457 ),
3458 c.i32_const(0xFF)
3459 ),
3460 REVTABLE,
3461 0
3462 ),
3463 )
3464 ),
3465 c.getLocal("bits")
3466 )
3467 );
3468 }
3469
3470
3471 buildRev();
3472 buildReversePermutation();
3473 buildRawFFT();
3474 buildCopyInterleaved();
3475 buildFromMontgomery();
3476 buildToMontgomery();
3477 buildFinalInverse();
3478 buildLog2();
3479 buildFFT();
3480 buildIFFT();
3481 buildMulN();
3482
3483 module.exportFunction(prefix+"_fft");
3484 module.exportFunction(prefix+"_ifft");
3485 module.exportFunction(prefix+"_toMontgomeryN");
3486 module.exportFunction(prefix+"_fromMontgomeryN");
3487 module.exportFunction(prefix+"_copyNInterleaved");
3488 module.exportFunction(prefix+"_mulN");
3489
3490};
3491
3492},{"./utils.js":17,"big-integer":2}],9:[function(require,module,exports){
3493
3494const utils = require("./utils.js");
3495
3496module.exports = function buildInt(module, n64, _prefix) {
3497
3498 const prefix = _prefix || "int";
3499 if (module.modules[prefix]) return prefix; // already builded
3500 module.modules[prefix] = {};
3501
3502 const n32 = n64*2;
3503 const n8 = n64*8;
3504
3505 const one = module.alloc(n8, utils.bigInt2BytesLE(1, n8));
3506
3507 function buildCopy() {
3508 const f = module.addFunction(prefix+"_copy");
3509 f.addParam("px", "i32");
3510 f.addParam("pr", "i32");
3511
3512 const c = f.getCodeBuilder();
3513
3514 for (let i=0; i<n64; i++) {
3515 f.addCode(
3516 c.i64_store(
3517 c.getLocal("pr"),
3518 i*8,
3519 c.i64_load(
3520 c.getLocal("px"),
3521 i*8
3522 )
3523 )
3524 );
3525 }
3526 }
3527
3528 function buildZero() {
3529 const f = module.addFunction(prefix+"_zero");
3530 f.addParam("pr", "i32");
3531
3532 const c = f.getCodeBuilder();
3533
3534 for (let i=0; i<n64; i++) {
3535 f.addCode(
3536 c.i64_store(
3537 c.getLocal("pr"),
3538 i*8,
3539 c.i64_const(0)
3540 )
3541 );
3542 }
3543 }
3544
3545 function buildOne() {
3546 const f = module.addFunction(prefix+"_one");
3547 f.addParam("pr", "i32");
3548
3549 const c = f.getCodeBuilder();
3550
3551 f.addCode(
3552 c.i64_store(
3553 c.getLocal("pr"),
3554 0,
3555 c.i64_const(1)
3556 )
3557 );
3558 for (let i=1; i<n64; i++) {
3559 f.addCode(
3560 c.i64_store(
3561 c.getLocal("pr"),
3562 i*8,
3563 c.i64_const(0)
3564 )
3565 );
3566 }
3567 }
3568
3569 function buildIsZero() {
3570 const f = module.addFunction(prefix+"_isZero");
3571 f.addParam("px", "i32");
3572 f.setReturnType("i32");
3573
3574 const c = f.getCodeBuilder();
3575
3576 function getCompCode(n) {
3577 if (n==0) {
3578 return c.ret(c.i64_eqz(
3579 c.i64_load(c.getLocal("px"))
3580 ));
3581 }
3582 return c.if(
3583 c.i64_eqz(
3584 c.i64_load(c.getLocal("px"), n*8 )
3585 ),
3586 getCompCode(n-1),
3587 c.ret(c.i32_const(0))
3588 );
3589 }
3590
3591 f.addCode(getCompCode(n64-1));
3592 f.addCode(c.ret(c.i32_const(0)));
3593 }
3594
3595 function buildEq() {
3596 const f = module.addFunction(prefix+"_eq");
3597 f.addParam("px", "i32");
3598 f.addParam("py", "i32");
3599 f.setReturnType("i32");
3600
3601 const c = f.getCodeBuilder();
3602
3603 function getCompCode(n) {
3604 if (n==0) {
3605 return c.ret(c.i64_eq(
3606 c.i64_load(c.getLocal("px")),
3607 c.i64_load(c.getLocal("py"))
3608 ));
3609 }
3610 return c.if(
3611 c.i64_eq(
3612 c.i64_load(c.getLocal("px"), n*8 ),
3613 c.i64_load(c.getLocal("py"), n*8 )
3614 ),
3615 getCompCode(n-1),
3616 c.ret(c.i32_const(0))
3617 );
3618 }
3619
3620 f.addCode(getCompCode(n64-1));
3621 f.addCode(c.ret(c.i32_const(0)));
3622 }
3623
3624
3625
3626 function buildGte() {
3627 const f = module.addFunction(prefix+"_gte");
3628 f.addParam("px", "i32");
3629 f.addParam("py", "i32");
3630 f.setReturnType("i32");
3631
3632 const c = f.getCodeBuilder();
3633
3634 function getCompCode(n) {
3635 if (n==0) {
3636 return c.ret(c.i64_ge_u(
3637 c.i64_load(c.getLocal("px")),
3638 c.i64_load(c.getLocal("py"))
3639 ));
3640 }
3641 return c.if(
3642 c.i64_lt_u(
3643 c.i64_load(c.getLocal("px"), n*8 ),
3644 c.i64_load(c.getLocal("py"), n*8 )
3645 ),
3646 c.ret(c.i32_const(0)),
3647 c.if(
3648 c.i64_gt_u(
3649 c.i64_load(c.getLocal("px"), n*8 ),
3650 c.i64_load(c.getLocal("py"), n*8 )
3651 ),
3652 c.ret(c.i32_const(1)),
3653 getCompCode(n-1)
3654 )
3655 );
3656 }
3657
3658 f.addCode(getCompCode(n64-1));
3659 f.addCode(c.ret(c.i32_const(0)));
3660 }
3661
3662
3663
3664 function buildAdd() {
3665
3666 const f = module.addFunction(prefix+"_add");
3667 f.addParam("x", "i32");
3668 f.addParam("y", "i32");
3669 f.addParam("r", "i32");
3670 f.setReturnType("i32");
3671 f.addLocal("c", "i64");
3672
3673 const c = f.getCodeBuilder();
3674
3675 f.addCode(c.setLocal(
3676 "c",
3677 c.i64_add(
3678 c.i64_load32_u(c.getLocal("x")),
3679 c.i64_load32_u(c.getLocal("y"))
3680 )
3681 ));
3682
3683 f.addCode(c.i64_store32(
3684 c.getLocal("r"),
3685 c.getLocal("c"),
3686 ));
3687
3688 for (let i=1; i<n32; i++) {
3689 f.addCode(c.setLocal( "c",
3690 c.i64_add(
3691 c.i64_add(
3692 c.i64_load32_u(c.getLocal("x"), 4*i),
3693 c.i64_load32_u(c.getLocal("y"), 4*i)
3694 ),
3695 c.i64_shr_u (c.getLocal("c"), c.i64_const(32))
3696 )
3697 ));
3698
3699 f.addCode(c.i64_store32(
3700 c.getLocal("r"),
3701 i*4,
3702 c.getLocal("c")
3703 ));
3704 }
3705
3706 f.addCode(c.i32_wrap_i64(c.i64_shr_u (c.getLocal("c"), c.i64_const(32))));
3707 }
3708
3709
3710 function buildSub() {
3711
3712 const f = module.addFunction(prefix+"_sub");
3713 f.addParam("x", "i32");
3714 f.addParam("y", "i32");
3715 f.addParam("r", "i32");
3716 f.setReturnType("i32");
3717 f.addLocal("c", "i64");
3718
3719 const c = f.getCodeBuilder();
3720
3721 f.addCode(c.setLocal(
3722 "c",
3723 c.i64_sub(
3724 c.i64_load32_u(c.getLocal("x")),
3725 c.i64_load32_u(c.getLocal("y"))
3726 )
3727 ));
3728
3729 f.addCode(c.i64_store32(
3730 c.getLocal("r"),
3731 c.i64_and(
3732 c.getLocal("c"),
3733 c.i64_const("0xFFFFFFFF")
3734 )
3735 ));
3736
3737 for (let i=1; i<n32; i++) {
3738 f.addCode(c.setLocal( "c",
3739 c.i64_add(
3740 c.i64_sub(
3741 c.i64_load32_u(c.getLocal("x"), 4*i),
3742 c.i64_load32_u(c.getLocal("y"), 4*i)
3743 ),
3744 c.i64_shr_s (c.getLocal("c"), c.i64_const(32))
3745 )
3746 ));
3747
3748 f.addCode(c.i64_store32(
3749 c.getLocal("r"),
3750 i*4,
3751 c.i64_and( c.getLocal("c"), c.i64_const("0xFFFFFFFF"))
3752 ));
3753 }
3754
3755 f.addCode(c.i32_wrap_i64 ( c.i64_shr_s (c.getLocal("c"), c.i64_const(32))));
3756 }
3757
3758
3759 function buildMul() {
3760
3761 const mulBuff = module.alloc(n32*n32*8);
3762
3763 const f = module.addFunction(prefix+"_mul");
3764 f.addParam("x", "i32");
3765 f.addParam("y", "i32");
3766 f.addParam("r", "i32");
3767 f.addLocal("c", "i64");
3768
3769 const c = f.getCodeBuilder();
3770
3771 for (let i=0; i<n32; i++) {
3772 for (let j=0; j<n32; j++) {
3773 f.addCode(c.i64_store(
3774 c.i32_const(mulBuff),
3775 (i*n32+j)*8,
3776 c.i64_mul(
3777 c.i64_load32_u( c.getLocal("x"), i*4),
3778 c.i64_load32_u( c.getLocal("y"), j*4)
3779 )
3780 ));
3781 }
3782 }
3783
3784 for (let i=0; i<n32; i++) {
3785 f.addCode(c.i64_shr_u(c.getLocal("c"), c.i64_const(32)));
3786 for (let j=0; j<i; j++) {
3787 f.addCode(c.i64_add(
3788 [],
3789 c.i64_load32_u(
3790 c.i32_const(mulBuff),
3791 j*(n32*8) + i*8-4 - j*8
3792 )
3793 ));
3794 }
3795 for (let j=0; j<i+1; j++) {
3796 f.addCode(c.i64_add(
3797 [],
3798 c.i64_load32_u(
3799 c.i32_const(mulBuff),
3800 j*(n32*8) + i*8 - j*8
3801 )
3802 ));
3803 }
3804 f.addCode(c.setLocal("c", []));
3805 f.addCode(
3806 c.i64_store32(
3807 c.getLocal("r"),
3808 i*4,
3809 c.getLocal("c")
3810 )
3811 );
3812 }
3813
3814 for (let i=0; i<n32; i++) {
3815 f.addCode(c.i64_shr_u(c.getLocal("c"), c.i64_const(32)));
3816 for (let j=i; j<n32; j++) {
3817 f.addCode(c.i64_add(
3818 [],
3819 c.i64_load32_u(
3820 c.i32_const(mulBuff),
3821 j*(n32*8) + n32*8-4 + i*8- j*8
3822 )
3823 ));
3824 }
3825 for (let j=i+1; j<n32; j++) {
3826 f.addCode(c.i64_add(
3827 [],
3828 c.i64_load32_u(
3829 c.i32_const(mulBuff),
3830 j*(n32*8) + n32*8 + i*8 - j*8
3831 )
3832 ));
3833 }
3834 f.addCode(c.setLocal("c", []));
3835 f.addCode(
3836 c.i64_store32(
3837 c.getLocal("r"),
3838 i*4 + n32*4,
3839 c.getLocal("c")
3840 )
3841 );
3842 }
3843 }
3844
3845 function _buildMul1() {
3846 const f = module.addFunction(prefix+"__mul1");
3847 f.addParam("px", "i32");
3848 f.addParam("y", "i64");
3849 f.addParam("pr", "i32");
3850 f.addLocal("c", "i64");
3851
3852 const c = f.getCodeBuilder();
3853
3854 f.addCode(c.setLocal(
3855 "c",
3856 c.i64_mul(
3857 c.i64_load32_u(c.getLocal("px"), 0, 0),
3858 c.getLocal("y")
3859 )
3860 ));
3861
3862 f.addCode(c.i64_store32(
3863 c.getLocal("pr"),
3864 0,
3865 0,
3866 c.getLocal("c"),
3867 ));
3868
3869 for (let i=1; i<n32; i++) {
3870 f.addCode(c.setLocal( "c",
3871 c.i64_add(
3872 c.i64_mul(
3873 c.i64_load32_u(c.getLocal("px"), 4*i, 0),
3874 c.getLocal("y")
3875 ),
3876 c.i64_shr_u (c.getLocal("c"), c.i64_const(32))
3877 )
3878 ));
3879
3880 f.addCode(c.i64_store32(
3881 c.getLocal("pr"),
3882 i*4,
3883 0,
3884 c.getLocal("c")
3885 ));
3886 }
3887 }
3888
3889 function _buildAdd1() {
3890 const f = module.addFunction(prefix+"__add1");
3891 f.addParam("x", "i32");
3892 f.addParam("y", "i64");
3893 f.addLocal("c", "i64");
3894 f.addLocal("px", "i32");
3895
3896 const c = f.getCodeBuilder();
3897
3898 f.addCode(c.setLocal("px", c.getLocal("x")));
3899
3900 f.addCode(c.setLocal(
3901 "c",
3902 c.i64_add(
3903 c.i64_load32_u(c.getLocal("px"), 0, 0),
3904 c.getLocal("y")
3905 )
3906 ));
3907
3908 f.addCode(c.i64_store32(
3909 c.getLocal("px"),
3910 0,
3911 0,
3912 c.getLocal("c"),
3913 ));
3914
3915 f.addCode(c.setLocal(
3916 "c",
3917 c.i64_shr_u(
3918 c.getLocal("c"),
3919 c.i64_const(32)
3920 )
3921 ));
3922
3923 f.addCode(c.block(c.loop(
3924 c.br_if(
3925 1,
3926 c.i64_eqz(c.getLocal("c"))
3927 ),
3928 c.setLocal(
3929 "px",
3930 c.i32_add(
3931 c.getLocal("px"),
3932 c.i32_const(4)
3933 )
3934 ),
3935
3936 c.setLocal(
3937 "c",
3938 c.i64_add(
3939 c.i64_load32_u(c.getLocal("px"), 0, 0),
3940 c.getLocal("c")
3941 )
3942 ),
3943
3944 c.i64_store32(
3945 c.getLocal("px"),
3946 0,
3947 0,
3948 c.getLocal("c"),
3949 ),
3950
3951 c.setLocal(
3952 "c",
3953 c.i64_shr_u(
3954 c.getLocal("c"),
3955 c.i64_const(32)
3956 )
3957 ),
3958
3959 c.br(0)
3960 )));
3961 }
3962
3963
3964 function buildDiv() {
3965 _buildMul1();
3966 _buildAdd1();
3967
3968 const f = module.addFunction(prefix+"_div");
3969 f.addParam("x", "i32");
3970 f.addParam("y", "i32");
3971 f.addParam("c", "i32");
3972 f.addParam("r", "i32");
3973 f.addLocal("rr", "i32");
3974 f.addLocal("cc", "i32");
3975 f.addLocal("eX", "i32");
3976 f.addLocal("eY", "i32");
3977 f.addLocal("sy", "i64");
3978 f.addLocal("sx", "i64");
3979 f.addLocal("ec", "i32");
3980
3981 const c = f.getCodeBuilder();
3982
3983 const Y = c.i32_const(module.alloc(n8));
3984 const Caux = c.i32_const(module.alloc(n8));
3985 const Raux = c.i32_const(module.alloc(n8));
3986 const C = c.getLocal("cc");
3987 const R = c.getLocal("rr");
3988 const pr1 = module.alloc(n8*2);
3989 const R1 = c.i32_const(pr1);
3990 const R2 = c.i32_const(pr1+n8);
3991
3992 // Ic c is 0 then store it in an auxiliary buffer
3993 f.addCode(c.if(
3994 c.getLocal("c"),
3995 c.setLocal("cc", c.getLocal("c")),
3996 c.setLocal("cc", Caux)
3997 ));
3998
3999 // Ic r is 0 then store it in an auxiliary buffer
4000 f.addCode(c.if(
4001 c.getLocal("r"),
4002 c.setLocal("rr", c.getLocal("r")),
4003 c.setLocal("rr", Raux)
4004 ));
4005
4006 // Copy
4007 f.addCode(c.call(prefix + "_copy", c.getLocal("x"), R));
4008 f.addCode(c.call(prefix + "_copy", c.getLocal("y"), Y));
4009 f.addCode(c.call(prefix + "_zero", C));
4010 f.addCode(c.call(prefix + "_zero", R1));
4011
4012
4013 f.addCode(c.setLocal("eX", c.i32_const(n8-1)));
4014 f.addCode(c.setLocal("eY", c.i32_const(n8-1)));
4015
4016 // while (eY>3)&&(Y[eY]==0) ey--;
4017 f.addCode(c.block(c.loop(
4018 c.br_if(
4019 1,
4020 c.i32_or(
4021 c.i32_load8_u(
4022 c.i32_add(Y , c.getLocal("eY")),
4023 0,
4024 0
4025 ),
4026 c.i32_eq(
4027 c.getLocal("eY"),
4028 c.i32_const(3)
4029 )
4030 )
4031 ),
4032 c.setLocal("eY", c.i32_sub(c.getLocal("eY"), c.i32_const(1))),
4033 c.br(0)
4034 )));
4035
4036 f.addCode(
4037 c.setLocal(
4038 "sy",
4039 c.i64_add(
4040 c.i64_load32_u(
4041 c.i32_sub(
4042 c.i32_add( Y, c.getLocal("eY")),
4043 c.i32_const(3)
4044 ),
4045 0,
4046 0
4047 ),
4048 c.i64_const(1)
4049 )
4050 )
4051 );
4052
4053 // Force a divide by 0 if quotien is 0
4054 f.addCode(
4055 c.if(
4056 c.i64_eq(
4057 c.getLocal("sy"),
4058 c.i64_const(1)
4059 ),
4060 c.drop(c.i64_div_u(c.i64_const(0), c.i64_const(0)))
4061 )
4062 );
4063
4064 f.addCode(c.block(c.loop(
4065
4066 // while (eX>7)&&(Y[eX]==0) ex--;
4067 c.block(c.loop(
4068 c.br_if(
4069 1,
4070 c.i32_or(
4071 c.i32_load8_u(
4072 c.i32_add(R , c.getLocal("eX")),
4073 0,
4074 0
4075 ),
4076 c.i32_eq(
4077 c.getLocal("eX"),
4078 c.i32_const(7)
4079 )
4080 )
4081 ),
4082 c.setLocal("eX", c.i32_sub(c.getLocal("eX"), c.i32_const(1))),
4083 c.br(0)
4084 )),
4085
4086 c.setLocal(
4087 "sx",
4088 c.i64_load(
4089 c.i32_sub(
4090 c.i32_add( R, c.getLocal("eX")),
4091 c.i32_const(7)
4092 ),
4093 0,
4094 0
4095 )
4096 ),
4097
4098 c.setLocal(
4099 "sx",
4100 c.i64_div_u(
4101 c.getLocal("sx"),
4102 c.getLocal("sy")
4103 )
4104 ),
4105 c.setLocal(
4106 "ec",
4107 c.i32_sub(
4108 c.i32_sub(
4109 c.getLocal("eX"),
4110 c.getLocal("eY")
4111 ),
4112 c.i32_const(4)
4113 )
4114 ),
4115
4116 // While greater than 32 bits or ec is neg, shr and inc exp
4117 c.block(c.loop(
4118 c.br_if(
4119 1,
4120 c.i32_and(
4121 c.i64_eqz(
4122 c.i64_and(
4123 c.getLocal("sx"),
4124 c.i64_const("0xFFFFFFFF00000000")
4125 )
4126 ),
4127 c.i32_ge_s(
4128 c.getLocal("ec"),
4129 c.i32_const(0)
4130 )
4131 )
4132 ),
4133
4134 c.setLocal(
4135 "sx",
4136 c.i64_shr_u(
4137 c.getLocal("sx"),
4138 c.i64_const(8)
4139 )
4140 ),
4141
4142 c.setLocal(
4143 "ec",
4144 c.i32_add(
4145 c.getLocal("ec"),
4146 c.i32_const(1)
4147 )
4148 ),
4149 c.br(0)
4150 )),
4151
4152 c.if(
4153 c.i64_eqz(c.getLocal("sx")),
4154 [
4155 ...c.br_if(
4156 2,
4157 c.i32_eqz(c.call(prefix + "_gte", R, Y))
4158 ),
4159 ...c.setLocal("sx", c.i64_const(1)),
4160 ...c.setLocal("ec", c.i32_const(0))
4161 ]
4162 ),
4163
4164 c.call(prefix + "__mul1", Y, c.getLocal("sx"), R2),
4165 c.drop(c.call(
4166 prefix + "_sub",
4167 R,
4168 c.i32_sub(R2, c.getLocal("ec")),
4169 R
4170 )),
4171 c.call(
4172 prefix + "__add1",
4173 c.i32_add(C, c.getLocal("ec")),
4174 c.getLocal("sx")
4175 ),
4176 c.br(0)
4177 )));
4178 }
4179
4180 function buildInverseMod() {
4181
4182 const f = module.addFunction(prefix+"_inverseMod");
4183 f.addParam("px", "i32");
4184 f.addParam("pm", "i32");
4185 f.addParam("pr", "i32");
4186 f.addLocal("t", "i32");
4187 f.addLocal("newt", "i32");
4188 f.addLocal("r", "i32");
4189 f.addLocal("qq", "i32");
4190 f.addLocal("qr", "i32");
4191 f.addLocal("newr", "i32");
4192 f.addLocal("swp", "i32");
4193 f.addLocal("x", "i32");
4194 f.addLocal("signt", "i32");
4195 f.addLocal("signnewt", "i32");
4196 f.addLocal("signx", "i32");
4197
4198 const c = f.getCodeBuilder();
4199
4200 const aux1 = c.i32_const(module.alloc(n8));
4201 const aux2 = c.i32_const(module.alloc(n8));
4202 const aux3 = c.i32_const(module.alloc(n8));
4203 const aux4 = c.i32_const(module.alloc(n8));
4204 const aux5 = c.i32_const(module.alloc(n8));
4205 const aux6 = c.i32_const(module.alloc(n8));
4206 const mulBuff = c.i32_const(module.alloc(n8*2));
4207 const aux7 = c.i32_const(module.alloc(n8));
4208
4209 f.addCode(
4210 c.setLocal("t", aux1),
4211 c.call(prefix + "_zero", aux1),
4212 c.setLocal("signt", c.i32_const(0)),
4213 );
4214
4215 f.addCode(
4216 c.setLocal("r", aux2),
4217 c.call(prefix + "_copy", c.getLocal("pm"), aux2)
4218 );
4219
4220 f.addCode(
4221 c.setLocal("newt", aux3),
4222 c.call(prefix + "_one", aux3),
4223 c.setLocal("signnewt", c.i32_const(0)),
4224 );
4225
4226 f.addCode(
4227 c.setLocal("newr", aux4),
4228 c.call(prefix + "_copy", c.getLocal("px"), aux4)
4229 );
4230
4231
4232
4233
4234 f.addCode(c.setLocal("qq", aux5));
4235 f.addCode(c.setLocal("qr", aux6));
4236 f.addCode(c.setLocal("x", aux7));
4237
4238 f.addCode(c.block(c.loop(
4239 c.br_if(
4240 1,
4241 c.call(prefix + "_isZero", c.getLocal("newr") )
4242 ),
4243 c.call(prefix + "_div", c.getLocal("r"), c.getLocal("newr"), c.getLocal("qq"), c.getLocal("qr")),
4244
4245 c.call(prefix + "_mul", c.getLocal("qq"), c.getLocal("newt"), mulBuff),
4246
4247 c.if(
4248 c.getLocal("signt"),
4249 c.if(
4250 c.getLocal("signnewt"),
4251 c.if (
4252 c.call(prefix + "_gte", mulBuff, c.getLocal("t")),
4253 [
4254 ...c.drop(c.call(prefix + "_sub", mulBuff, c.getLocal("t"), c.getLocal("x"))),
4255 ...c.setLocal("signx", c.i32_const(0))
4256 ],
4257 [
4258 ...c.drop(c.call(prefix + "_sub", c.getLocal("t"), mulBuff, c.getLocal("x"))),
4259 ...c.setLocal("signx", c.i32_const(1))
4260 ],
4261 ),
4262 [
4263 ...c.drop(c.call(prefix + "_add", mulBuff, c.getLocal("t"), c.getLocal("x"))),
4264 ...c.setLocal("signx", c.i32_const(1))
4265 ]
4266 ),
4267 c.if(
4268 c.getLocal("signnewt"),
4269 [
4270 ...c.drop(c.call(prefix + "_add", mulBuff, c.getLocal("t"), c.getLocal("x"))),
4271 ...c.setLocal("signx", c.i32_const(0))
4272 ],
4273 c.if (
4274 c.call(prefix + "_gte", c.getLocal("t"), mulBuff),
4275 [
4276 ...c.drop(c.call(prefix + "_sub", c.getLocal("t"), mulBuff, c.getLocal("x"))),
4277 ...c.setLocal("signx", c.i32_const(0))
4278 ],
4279 [
4280 ...c.drop(c.call(prefix + "_sub", mulBuff, c.getLocal("t"), c.getLocal("x"))),
4281 ...c.setLocal("signx", c.i32_const(1))
4282 ]
4283 )
4284 )
4285 ),
4286
4287 c.setLocal("swp", c.getLocal("t")),
4288 c.setLocal("t", c.getLocal("newt")),
4289 c.setLocal("newt", c.getLocal("x")),
4290 c.setLocal("x", c.getLocal("swp")),
4291
4292 c.setLocal("signt", c.getLocal("signnewt")),
4293 c.setLocal("signnewt", c.getLocal("signx")),
4294
4295 c.setLocal("swp", c.getLocal("r")),
4296 c.setLocal("r", c.getLocal("newr")),
4297 c.setLocal("newr", c.getLocal("qr")),
4298 c.setLocal("qr", c.getLocal("swp")),
4299
4300 c.br(0)
4301 )));
4302
4303 f.addCode(c.if(
4304 c.getLocal("signt"),
4305 c.drop(c.call(prefix + "_sub", c.getLocal("pm"), c.getLocal("t"), c.getLocal("pr"))),
4306 c.call(prefix + "_copy", c.getLocal("t"), c.getLocal("pr"))
4307 ));
4308 }
4309
4310
4311 buildCopy();
4312 buildZero();
4313 buildIsZero();
4314 buildOne();
4315 buildEq();
4316 buildGte();
4317 buildAdd();
4318 buildSub();
4319 buildMul();
4320 buildDiv();
4321 buildInverseMod();
4322 module.exportFunction(prefix+"_copy");
4323 module.exportFunction(prefix+"_zero");
4324 module.exportFunction(prefix+"_one");
4325 module.exportFunction(prefix+"_isZero");
4326 module.exportFunction(prefix+"_eq");
4327 module.exportFunction(prefix+"_gte");
4328 module.exportFunction(prefix+"_add");
4329 module.exportFunction(prefix+"_sub");
4330 module.exportFunction(prefix+"_mul");
4331 module.exportFunction(prefix+"_div");
4332 module.exportFunction(prefix+"_inverseMod");
4333
4334 return prefix;
4335};
4336
4337},{"./utils.js":17}],10:[function(require,module,exports){
4338
4339module.exports = function buildMultiexp(module, prefix, curvePrefix, pointFieldPrefix, scalarPrefix) {
4340
4341 const pointFieldN64 = module.modules[pointFieldPrefix].n64;
4342 const pointFieldN8 = pointFieldN64*8;
4343 const pointN64 = module.modules[curvePrefix].n64;
4344 const pointN8 = pointN64*8;
4345 const scalarN64 = module.modules[scalarPrefix].n64;
4346 const scalarN8 = scalarN64*8;
4347
4348
4349 function buildPackBits() {
4350 const f = module.addFunction(prefix+"__packbits");
4351 f.addParam("pscalars", "i32");
4352 f.addParam("w", "i32"); // 8 max
4353 f.addParam("pr", "i32"); // P to result scalarN8*8 bytes
4354 f.addLocal("i", "i32");
4355 f.addLocal("j", "i32");
4356 f.addLocal("w1", "i64");
4357 f.addLocal("w2", "i64");
4358
4359 const c = f.getCodeBuilder();
4360
4361 f.addCode(c.setLocal("i", c.i32_const(0)));
4362 f.addCode(c.block(c.loop(
4363 c.br_if(
4364 1,
4365 c.i32_eq(
4366 c.getLocal("i"),
4367 c.i32_const(scalarN8)
4368 )
4369 ),
4370
4371 c.setLocal("w2", c.i64_const(0)),
4372
4373 c.setLocal("j", c.i32_const(0)),
4374
4375 c.block(c.loop(
4376 c.br_if(
4377 1,
4378 c.i32_eq(
4379 c.getLocal("j"),
4380 c.getLocal("w")
4381 )
4382 ),
4383
4384 c.setLocal(
4385 "w1",
4386 c.i64_load8_u(
4387 c.i32_add(
4388 c.getLocal("pscalars"),
4389 c.i32_add(
4390 c.i32_mul(
4391 c.getLocal("j"),
4392 c.i32_const(scalarN8)
4393 ),
4394 c.getLocal("i")
4395 )
4396 )
4397 )
4398 ),
4399
4400 c.setLocal(
4401 "w1",
4402 c.i64_and(
4403 c.i64_or(
4404 c.getLocal("w1"),
4405 c.i64_shl(
4406 c.getLocal("w1"),
4407 c.i64_const(28)
4408 )
4409 ),
4410 c.i64_const("0x0000000F0000000F")
4411 )
4412 ),
4413
4414 c.setLocal(
4415 "w1",
4416 c.i64_and(
4417 c.i64_or(
4418 c.getLocal("w1"),
4419 c.i64_shl(
4420 c.getLocal("w1"),
4421 c.i64_const(14)
4422 )
4423 ),
4424 c.i64_const("0x0003000300030003")
4425 )
4426 ),
4427
4428 c.setLocal(
4429 "w1",
4430 c.i64_and(
4431 c.i64_or(
4432 c.getLocal("w1"),
4433 c.i64_shl(
4434 c.getLocal("w1"),
4435 c.i64_const(7)
4436 )
4437 ),
4438 c.i64_const("0x0101010101010101")
4439 )
4440 ),
4441
4442 c.setLocal(
4443 "w2",
4444 c.i64_or(
4445 c.getLocal("w2"),
4446 c.i64_shl(
4447 c.getLocal("w1"),
4448 c.i64_extend_i32_u(c.getLocal("j"))
4449 )
4450 )
4451 ),
4452
4453
4454 c.setLocal("j", c.i32_add(c.getLocal("j"), c.i32_const(1))),
4455 c.br(0)
4456 )),
4457
4458 c.i64_store(
4459 c.i32_add(
4460 c.getLocal("pr"),
4461 c.i32_mul(
4462 c.getLocal("i"),
4463 c.i32_const(8)
4464 )
4465 ),
4466 c.getLocal("w2")
4467 ),
4468
4469 c.setLocal("i", c.i32_add(c.getLocal("i"), c.i32_const(1))),
4470 c.br(0)
4471 )));
4472
4473
4474 }
4475
4476 const c1 = [];
4477 const c2 = [];
4478
4479 function nbits(_b) {
4480 let c=0;
4481 let r=_b;
4482 while(r) {
4483 if (r&1) c++;
4484 r = r>>1;
4485 }
4486 return c;
4487 }
4488
4489 function split(_b) {
4490 const nb1 = nbits(_b) >> 1;
4491 let r = _b;
4492 let c = 0;
4493 if (nb1 == 0) return null;
4494 let mask = 0xFFFFFFFF;
4495 while (c<nb1) {
4496 if (r&1) c++;
4497 mask = mask << 1;
4498 r = r>>1;
4499 }
4500 return [(_b & mask), (_b & (~mask))];
4501 }
4502
4503 for (let i=0; i<256; i++) {
4504 const a = split(i);
4505 if (a) {
4506 c1[i] = a[0];
4507 c2[i] = a[1];
4508 } else {
4509 c1[i] = 0;
4510 c2[i] = 0;
4511 }
4512 }
4513
4514 const ptable = module.alloc(pointN8*256);
4515 const pset = module.alloc(32);
4516 const composite1 = module.alloc(256, c1);
4517 const composite2 = module.alloc(256, c2);
4518
4519
4520 function buildSetSet() {
4521 const f = module.addFunction(prefix+"__set_set");
4522 f.addParam("idx", "i32");
4523 f.addLocal("word", "i32");
4524 f.addLocal("mask", "i32");
4525
4526 const c = f.getCodeBuilder();
4527
4528 f.addCode(
4529 c.setLocal(
4530 "word",
4531 c.i32_shl(
4532 c.i32_shr_u(
4533 c.getLocal("idx"),
4534 c.i32_const(5)
4535 ),
4536 c.i32_const(2)
4537 )
4538 )
4539 );
4540 f.addCode(
4541 c.setLocal(
4542 "mask",
4543 c.i32_shl(
4544 c.i32_const(1),
4545 c.i32_and(
4546 c.getLocal("idx"),
4547 c.i32_const("0x1F")
4548 )
4549 )
4550 )
4551 );
4552 f.addCode(
4553 c.i32_store(
4554 c.getLocal("word"),
4555 pset,
4556 c.i32_or(
4557 c.i32_load(
4558 c.getLocal("word"),
4559 pset
4560 ),
4561 c.getLocal("mask")
4562 )
4563 )
4564 );
4565 }
4566
4567 function buildSetIsSet() {
4568 const f = module.addFunction(prefix+"__set_isSet");
4569 f.addParam("idx", "i32");
4570 f.setReturnType("i32");
4571 f.addLocal("word", "i32");
4572 f.addLocal("mask", "i32");
4573
4574 const c = f.getCodeBuilder();
4575
4576
4577 f.addCode(
4578 c.setLocal(
4579 "word",
4580 c.i32_shl(
4581 c.i32_shr_u(
4582 c.getLocal("idx"),
4583 c.i32_const(5)
4584 ),
4585 c.i32_const(2)
4586 )
4587 )
4588 );
4589 f.addCode(
4590 c.setLocal(
4591 "mask",
4592 c.i32_shl(
4593 c.i32_const(1),
4594 c.i32_and(
4595 c.getLocal("idx"),
4596 c.i32_const("0x1F")
4597 )
4598 )
4599 )
4600 );
4601
4602 f.addCode(
4603 c.i32_and(
4604 c.i32_load(
4605 c.getLocal("word"),
4606 pset
4607 ),
4608 c.getLocal("mask")
4609 )
4610 );
4611 }
4612
4613
4614 function buildPTableReset() {
4615 const f = module.addFunction(prefix+"__ptable_reset");
4616 f.addParam("ppoints", "i32");
4617 f.addParam("w", "i32"); // Window size Max 8
4618 f.addLocal("ps", "i32");
4619 f.addLocal("pd", "i32");
4620 f.addLocal("i", "i32");
4621 f.addLocal("isZero", "i32");
4622
4623 const c = f.getCodeBuilder();
4624
4625 f.addCode(c.setLocal("ps", c.getLocal("ppoints")));
4626
4627 f.addCode(c.call( curvePrefix + "_zero", c.i32_const(ptable) ));
4628
4629 f.addCode(c.setLocal("i", c.i32_const(0)));
4630 f.addCode(c.block(c.loop(
4631 c.br_if(
4632 1,
4633 c.i32_eq(
4634 c.getLocal("i"),
4635 c.getLocal("w")
4636 )
4637 ),
4638
4639 c.setLocal(
4640 "pd",
4641 c.i32_add(
4642 c.i32_const(ptable),
4643 c.i32_mul(
4644 c.i32_shl(
4645 c.i32_const(1),
4646 c.getLocal("i")
4647 ),
4648 c.i32_const(pointN8)
4649 )
4650 )
4651 ),
4652
4653
4654 c.setLocal("isZero", c.call(pointFieldPrefix + "_isZero", c.getLocal("ps"))),
4655
4656 c.call( pointFieldPrefix + "_copy", c.getLocal("ps"), c.getLocal("pd")),
4657 c.setLocal("ps", c.i32_add(c.getLocal("ps"), c.i32_const(pointFieldN8))),
4658 c.setLocal("pd", c.i32_add(c.getLocal("pd"), c.i32_const(pointFieldN8))),
4659
4660 c.call( pointFieldPrefix + "_copy", c.getLocal("ps"), c.getLocal("pd")),
4661 c.setLocal("ps", c.i32_add(c.getLocal("ps"), c.i32_const(pointFieldN8))),
4662 c.setLocal("pd", c.i32_add(c.getLocal("pd"), c.i32_const(pointFieldN8))),
4663
4664 c.if(
4665 c.getLocal("isZero"),
4666 c.call( pointFieldPrefix + "_zero", c.getLocal("pd")),
4667 c.call( pointFieldPrefix + "_one", c.getLocal("pd")),
4668 ),
4669
4670 c.setLocal("i", c.i32_add(c.getLocal("i"), c.i32_const(1))),
4671 c.br(0)
4672 )));
4673
4674 // Reset the set
4675 f.addCode(c.i64_store( c.i32_const(pset ),c.i64_const("0x0000000100010117")));
4676 f.addCode(c.i64_store( c.i32_const(pset+ 8),c.i64_const("0x0000000000000001")));
4677 f.addCode(c.i64_store( c.i32_const(pset+16),c.i64_const("0x0000000000000001")));
4678 f.addCode(c.i64_store( c.i32_const(pset+24),c.i64_const("0x0000000000000000")));
4679
4680
4681 }
4682
4683 function buildPTableGet() {
4684 const f = module.addFunction(prefix+"__ptable_get");
4685 f.addParam("idx", "i32");
4686 f.setReturnType("i32");
4687 f.addLocal("pr", "i32");
4688 f.addLocal("p1", "i32");
4689 f.addLocal("p2", "i32");
4690
4691 const c = f.getCodeBuilder();
4692
4693 f.addCode(
4694 c.setLocal(
4695 "pr",
4696 c.i32_add(
4697 c.i32_const(ptable),
4698 c.i32_mul(
4699 c.getLocal("idx"),
4700 c.i32_const(pointN8)
4701 )
4702 )
4703 )
4704 );
4705
4706 f.addCode(c.if(
4707 c.i32_eqz(
4708 c.call(
4709 prefix + "__set_isSet",
4710 c.getLocal("idx")
4711 ),
4712 ),
4713 [
4714 ...c.setLocal(
4715 "p1",
4716 c.call(
4717 prefix + "__ptable_get",
4718 c.i32_load8_u(
4719 c.getLocal("idx"),
4720 composite1
4721 )
4722 )
4723 ),
4724 ...c.setLocal(
4725 "p2",
4726 c.call(
4727 prefix + "__ptable_get",
4728 c.i32_load8_u(
4729 c.getLocal("idx"),
4730 composite2
4731 )
4732 )
4733 ),
4734 ...c.call(
4735 curvePrefix + "_add",
4736 c.getLocal("p1"),
4737 c.getLocal("p2"),
4738 c.getLocal("pr")
4739 ),
4740 ...c.call(
4741 prefix + "__set_set",
4742 c.getLocal("idx")
4743 )
4744 ]
4745 ));
4746
4747 f.addCode(c.getLocal("pr"));
4748 }
4749
4750 function buildMulw() {
4751 const f = module.addFunction(prefix+"__mulw");
4752 f.addParam("pscalars", "i32");
4753 f.addParam("ppoints", "i32");
4754 f.addParam("w", "i32"); // Window size Max 8
4755 f.addParam("pr", "i32");
4756 f.addLocal("i", "i32");
4757
4758 const c = f.getCodeBuilder();
4759
4760 const psels = module.alloc(scalarN8 * 8);
4761
4762 f.addCode(c.call(
4763 prefix + "__packbits",
4764 c.getLocal("pscalars"),
4765 c.getLocal("w"),
4766 c.i32_const(psels)
4767 ));
4768
4769 f.addCode(c.call(
4770 curvePrefix + "_zero",
4771 c.getLocal("pr"),
4772 ));
4773
4774 f.addCode(c.call(
4775 prefix + "__ptable_reset",
4776 c.getLocal("ppoints"),
4777 c.getLocal("w")
4778 ));
4779
4780
4781 f.addCode(c.setLocal("i", c.i32_const(0)));
4782 f.addCode(c.block(c.loop(
4783 c.br_if(
4784 1,
4785 c.i32_eq(
4786 c.getLocal("i"),
4787 c.i32_const(scalarN8 * 8)
4788 )
4789 ),
4790
4791 c.call(curvePrefix + "_double",
4792 c.getLocal("pr"),
4793 c.getLocal("pr"),
4794 ),
4795 c.call(curvePrefix + "_add",
4796 c.getLocal("pr"),
4797 c.call(
4798 prefix + "__ptable_get",
4799 c.i32_load8_u(
4800 c.i32_sub(
4801 c.i32_const(psels + scalarN8 * 8 -1),
4802 c.getLocal("i")
4803 )
4804 )
4805 ),
4806 c.getLocal("pr"),
4807 ),
4808
4809 c.setLocal("i", c.i32_add(c.getLocal("i"), c.i32_const(1))),
4810 c.br(0)
4811 )));
4812
4813 }
4814
4815
4816 function buildMultiexp() {
4817 const f = module.addFunction(prefix+"_multiexp");
4818 f.addParam("pscalars", "i32");
4819 f.addParam("ppoints", "i32");
4820 f.addParam("n", "i32"); // Number of points
4821 f.addParam("w", "i32"); // Window size Max 8
4822 f.addParam("pr", "i32");
4823 f.addLocal("ps", "i32");
4824 f.addLocal("pp", "i32");
4825 f.addLocal("wf", "i32");
4826 f.addLocal("lastps", "i32");
4827
4828 const c = f.getCodeBuilder();
4829
4830 const aux = c.i32_const(module.alloc(pointN8));
4831
4832 f.addCode(c.setLocal("ps", c.getLocal("pscalars")));
4833 f.addCode(c.setLocal("pp", c.getLocal("ppoints")));
4834
4835 f.addCode(c.setLocal(
4836 "lastps",
4837 c.i32_add(
4838 c.getLocal("ps"),
4839 c.i32_mul(
4840 c.i32_mul(
4841 c.i32_div_u(
4842 c.getLocal("n"),
4843 c.getLocal("w")
4844 ),
4845 c.getLocal("w")
4846 ),
4847 c.i32_const(scalarN8)
4848 )
4849 )
4850 ));
4851
4852 f.addCode(c.block(c.loop(
4853 c.br_if(
4854 1,
4855 c.i32_eq(
4856 c.getLocal("ps"),
4857 c.getLocal("lastps")
4858 )
4859 ),
4860
4861 c.call(prefix + "__mulw", c.getLocal("ps"), c.getLocal("pp"), c.getLocal("w"), aux),
4862 c.call(curvePrefix + "_add", aux, c.getLocal("pr"), c.getLocal("pr")),
4863
4864 c.setLocal(
4865 "ps",
4866 c.i32_add(
4867 c.getLocal("ps"),
4868 c.i32_mul(
4869 c.i32_const(scalarN8),
4870 c.getLocal("w")
4871 )
4872 )
4873 ),
4874
4875 c.setLocal(
4876 "pp",
4877 c.i32_add(
4878 c.getLocal("pp"),
4879 c.i32_mul(
4880 c.i32_const(pointFieldN8*2),
4881 c.getLocal("w")
4882 )
4883 )
4884 ),
4885
4886 c.br(0)
4887 )));
4888
4889 f.addCode(c.setLocal("wf", c.i32_rem_u(c.getLocal("n"), c.getLocal("w"))));
4890
4891 f.addCode(c.if(
4892 c.getLocal("wf"),
4893 [
4894 ...c.call(prefix + "__mulw", c.getLocal("ps"), c.getLocal("pp"), c.getLocal("wf"), aux),
4895 ...c.call(curvePrefix + "_add", aux, c.getLocal("pr"), c.getLocal("pr")),
4896 ]
4897 ));
4898 }
4899
4900 buildSetSet();
4901 buildSetIsSet();
4902 buildPTableReset();
4903 buildPTableGet();
4904 buildPackBits();
4905 buildMulw();
4906 buildMultiexp();
4907 module.exportFunction(prefix+"_multiexp");
4908
4909
4910};
4911
4912},{}],11:[function(require,module,exports){
4913module.exports = function buildPol(module, prefix, prefixField) {
4914
4915 const n64 = module.modules[prefixField].n64;
4916 const n8 = n64*8;
4917
4918
4919 function buildZero() {
4920 const f = module.addFunction(prefix+"_zero");
4921 f.addParam("px", "i32");
4922 f.addParam("n", "i32");
4923 f.addLocal("lastp", "i32");
4924 f.addLocal("p", "i32");
4925
4926 const c = f.getCodeBuilder();
4927
4928 f.addCode(
4929 c.setLocal("p", c.getLocal("px")),
4930 c.setLocal(
4931 "lastp",
4932 c.i32_add(
4933 c.getLocal("px"),
4934 c.i32_mul(
4935 c.getLocal("n"),
4936 c.i32_const(n8)
4937 )
4938 )
4939 ),
4940 c.block(c.loop(
4941 c.br_if(
4942 1,
4943 c.i32_eq(
4944 c.getLocal("p"),
4945 c.getLocal("lastp")
4946 )
4947 ),
4948 c.call(prefixField + "_zero", c.getLocal("p")),
4949 c.setLocal("p", c.i32_add(c.getLocal("p"), c.i32_const(n8))),
4950 c.br(0)
4951 ))
4952 );
4953 }
4954
4955 function buildConstructLC() {
4956 const f = module.addFunction(prefix+"_constructLC");
4957 f.addParam("ppolynomials", "i32");
4958 f.addParam("psignals", "i32");
4959 f.addParam("nSignals", "i32");
4960 f.addParam("pres", "i32");
4961 f.addLocal("i", "i32");
4962 f.addLocal("j", "i32");
4963 f.addLocal("pp", "i32");
4964 f.addLocal("ps", "i32");
4965 f.addLocal("pd", "i32");
4966 f.addLocal("ncoefs", "i32");
4967
4968 const c = f.getCodeBuilder();
4969
4970 const aux = c.i32_const(module.alloc(n8));
4971
4972 f.addCode(
4973 c.setLocal("i", c.i32_const(0)),
4974 c.setLocal("pp", c.getLocal("ppolynomials")),
4975 c.setLocal("ps", c.getLocal("psignals")),
4976 c.block(c.loop(
4977 c.br_if(
4978 1,
4979 c.i32_eq(
4980 c.getLocal("i"),
4981 c.getLocal("nSignals")
4982 )
4983 ),
4984
4985 c.setLocal("ncoefs", c.i32_load(c.getLocal("pp"))),
4986 c.setLocal("pp", c.i32_add(c.getLocal("pp"), c.i32_const(4))),
4987
4988 c.setLocal("j", c.i32_const(0)),
4989 c.block(c.loop(
4990 c.br_if(
4991 1,
4992 c.i32_eq(
4993 c.getLocal("j"),
4994 c.getLocal("ncoefs")
4995 )
4996 ),
4997
4998 c.setLocal(
4999 "pd",
5000 c.i32_add(
5001 c.getLocal("pres"),
5002 c.i32_mul(
5003 c.i32_load(c.getLocal("pp")),
5004 c.i32_const(n8)
5005 )
5006 )
5007 ),
5008
5009 c.setLocal("pp", c.i32_add(c.getLocal("pp"), c.i32_const(4))),
5010
5011
5012 c.call(
5013 prefixField + "_mul",
5014 c.getLocal("ps"),
5015 c.getLocal("pp"),
5016 aux
5017 ),
5018
5019 c.call(
5020 prefixField + "_add",
5021 aux,
5022 c.getLocal("pd"),
5023 c.getLocal("pd")
5024 ),
5025
5026 c.setLocal("pp", c.i32_add(c.getLocal("pp"), c.i32_const(n8))),
5027 c.setLocal("j", c.i32_add(c.getLocal("j"), c.i32_const(1))),
5028 c.br(0)
5029 )),
5030
5031 c.setLocal("ps", c.i32_add(c.getLocal("ps"), c.i32_const(n8))),
5032 c.setLocal("i", c.i32_add(c.getLocal("i"), c.i32_const(1))),
5033 c.br(0)
5034 ))
5035 );
5036
5037 }
5038
5039 buildZero();
5040 buildConstructLC();
5041
5042
5043 module.exportFunction(prefix + "_zero");
5044 module.exportFunction(prefix + "_constructLC");
5045
5046 return prefix;
5047
5048
5049
5050
5051};
5052
5053},{}],12:[function(require,module,exports){
5054const bigInt = require("big-integer");
5055const utils = require("./utils.js");
5056
5057module.exports = function buildTestF1(module) {
5058
5059 const q = bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208583");
5060
5061 const pR2 = module.modules.f1m.pR2;
5062 const n8 = module.modules.f1m.n64*8;
5063
5064 const pR3 = module.alloc(utils.bigInt2BytesLE(bigInt.one.shiftLeft(256).square().mod(q).shiftRight(128), n8));
5065
5066
5067 function buildTestF1() {
5068 const f = module.addFunction("testF1");
5069 f.addParam("n", "i32");
5070 f.addLocal("i", "i32");
5071
5072 const c = f.getCodeBuilder();
5073
5074 const pAux1 = module.alloc(n8);
5075
5076 f.addCode(c.setLocal("i", c.getLocal("n")));
5077 f.addCode(c.block(c.loop(
5078// c.call("f1m_add", c.i32_const(pR2), c.i32_const(pR2), c.i32_const(pAux1)),
5079 c.call("f1m_mul", c.i32_const(pR2), c.i32_const(pR2), c.i32_const(pAux1)),
5080// c.call("int_div", c.i32_const(pR2), c.i32_const(pR3), c.i32_const(pAux1), c.i32_const(0)),
5081 c.setLocal("i", c.i32_sub(c.getLocal("i"), c.i32_const(1))),
5082 c.br_if(1, c.i32_eqz ( c.getLocal("i") )),
5083 c.br(0)
5084 )));
5085 }
5086
5087 buildTestF1();
5088 module.exportFunction("testF1");
5089};
5090
5091},{"./utils.js":17,"big-integer":2}],13:[function(require,module,exports){
5092const bigInt = require("big-integer");
5093
5094module.exports = function buildTestAddG1(module) {
5095
5096 function buildTestAddG1() {
5097 const f = module.addFunction("testAddG1");
5098 f.addParam("n", "i32");
5099 f.addParam("pP", "i32");
5100 f.addParam("pR", "i32");
5101 f.addLocal("i", "i32");
5102
5103 const c = f.getCodeBuilder();
5104
5105 f.addCode(c.call("g1_zero", c.getLocal("pR")));
5106
5107 f.addCode(c.setLocal("i", c.getLocal("n")));
5108 f.addCode(c.block(c.loop(
5109 c.call("g1_add", c.getLocal("pP"), c.getLocal("pR"), c.getLocal("pR")),
5110 c.setLocal("i", c.i32_sub(c.getLocal("i"), c.i32_const(1))),
5111 c.br_if(1, c.i32_eqz ( c.getLocal("i") )),
5112 c.br(0)
5113 )));
5114 }
5115
5116 buildTestAddG1();
5117 module.exportFunction("testAddG1");
5118};
5119
5120
5121},{"big-integer":2}],14:[function(require,module,exports){
5122
5123
5124
5125module.exports = function buildTimesScalar(module, fnName, elementLen, opAB, opAA, fPrefix) {
5126
5127 const f = module.addFunction(fnName);
5128 f.addParam("base", "i32");
5129 f.addParam("scalar", "i32");
5130 f.addParam("scalarLength", "i32");
5131 f.addParam("r", "i32");
5132 f.addLocal("i", "i32");
5133 f.addLocal("b", "i32");
5134
5135 const c = f.getCodeBuilder();
5136
5137 const aux = c.i32_const(module.alloc(elementLen));
5138
5139 f.addCode(c.call(fPrefix + "_copy", c.getLocal("base"), aux));
5140
5141 f.addCode(c.call(fPrefix + "_zero", c.getLocal("r")));
5142
5143 f.addCode(c.setLocal("i", c.getLocal("scalarLength")));
5144 f.addCode(c.block(c.loop(
5145 c.setLocal("i", c.i32_sub(c.getLocal("i"), c.i32_const(1))),
5146
5147 c.setLocal(
5148 "b",
5149 c.i32_load8_u(
5150 c.i32_add(
5151 c.getLocal("scalar"),
5152 c.getLocal("i")
5153 )
5154 )
5155 ),
5156 ...innerLoop(),
5157 c.br_if(1, c.i32_eqz ( c.getLocal("i") )),
5158 c.br(0)
5159 )));
5160
5161
5162 function innerLoop() {
5163 const code = [];
5164 for (let i=0; i<8; i++) {
5165 code.push(
5166 ...c.call(opAA, c.getLocal("r"), c.getLocal("r")),
5167 ...c.if(
5168 c.i32_ge_u( c.getLocal("b"), c.i32_const(0x80 >> i)),
5169 [
5170 ...c.setLocal(
5171 "b",
5172 c.i32_sub(
5173 c.getLocal("b"),
5174 c.i32_const(0x80 >> i)
5175 )
5176 ),
5177 ...c.call(opAB, aux, c.getLocal("r"), c.getLocal("r"))
5178 ]
5179 )
5180 );
5181 }
5182 return code;
5183 }
5184
5185};
5186
5187},{}],15:[function(require,module,exports){
5188/* globals WebAssembly */
5189const bigInt = require("big-integer");
5190const ModuleBuilder = require("./wasmbuilder/index.js");
5191const buildF1 = require("./build_f1.js");
5192const buildTestF1 = require("./build_testf1.js");
5193
5194async function build(q) {
5195 const f1 = new F1(q);
5196
5197 f1.q = bigInt(q);
5198 f1.n64 = Math.floor((f1.q.minus(1).bitLength() - 1)/64) +1;
5199 f1.n32 = f1.n64*2;
5200 f1.n8 = f1.n64*8;
5201
5202 f1.memory = new WebAssembly.Memory({initial:1});
5203 f1.i32 = new Uint32Array(f1.memory.buffer);
5204
5205 const moduleBuilder = new ModuleBuilder();
5206 buildF1(moduleBuilder, f1.q);
5207 buildTestF1(moduleBuilder);
5208
5209 const code = moduleBuilder.build();
5210
5211 const wasmModule = await WebAssembly.compile(code);
5212
5213 f1.instance = await WebAssembly.instantiate(wasmModule, {
5214 env: {
5215 "memory": f1.memory
5216 }
5217 });
5218
5219 Object.assign(f1, f1.instance.exports);
5220
5221 return f1;
5222}
5223
5224class F1 {
5225
5226 constructor() {
5227
5228 }
5229
5230 alloc(length) {
5231 const res = this.i32[0];
5232 this.i32[0] += length;
5233 return res;
5234 }
5235
5236 putInt(pos, _a) {
5237 const a = bigInt(_a);
5238 if (pos & 0x7) throw new Error("Pointer must be aligned");
5239 if (a.bitLength > this.n64*64) {
5240 return this.putInt(a.mod(this.q));
5241 }
5242 for (let i=0; i<this.n32; i++) {
5243 this.i32[(pos>>2)+i] = a.shiftRight(i*32).and(0xFFFFFFFF).toJSNumber();
5244 }
5245 }
5246
5247 allocInt(_a) {
5248 const p = this.alloc(this.n8);
5249 if (_a) this.putInt(p, _a);
5250 return p;
5251 }
5252
5253 putInt2(pos, _a) {
5254 const a = bigInt(_a);
5255 if (pos & 0x7) throw new Error("Pointer must be aligned");
5256 if (a.bitLength > this.n64*64*2) {
5257 return this.putInt(a.mod(this.q));
5258 }
5259 for (let i=0; i<this.n32*2; i++) {
5260 this.i32[(pos>>2)+i] = a.shiftRight(i*32).and(0xFFFFFFFF).toJSNumber();
5261 }
5262 }
5263
5264 getInt(pos) {
5265 if (pos & 0x7) throw new Error("Pointer must be aligned");
5266 let acc = bigInt(this.i32[(pos>>2)+this.n32-1]);
5267 for (let i=this.n32-2; i>=0; i--) {
5268 acc = acc.shiftLeft(32);
5269 acc = acc.add(this.i32[(pos>>2)+i]);
5270 }
5271 return acc;
5272 }
5273
5274 getInt2(pos) {
5275 if (pos & 0x7) throw new Error("Pointer must be aligned");
5276 const last = this.n32*2-1;
5277 let acc = bigInt(this.i32[(pos>>2)+last]);
5278 for (let i=last; i>=0; i--) {
5279 acc = acc.shiftLeft(32);
5280 acc = acc.add(this.i32[(pos>>2)+i]);
5281 }
5282 return acc;
5283 }
5284
5285 allocInt2(_a) {
5286 const p = this.alloc(this.n8*2);
5287 if (_a) this.putInt2(p, _a);
5288 return p;
5289 }
5290
5291 test_F1(n) {
5292 const start = new Date().getTime();
5293
5294 this.instance.exports.testF1(n);
5295
5296 const end = new Date().getTime();
5297 const time = end - start;
5298
5299 return time;
5300 }
5301/*
5302 function test(n) {
5303
5304 const q = 21888242871839275222246405745257275088696311157297823662689037894645226208583n;
5305 let a = (1n << 512n)%q ;
5306 let b = a >> 128n;
5307
5308 let c;
5309
5310 const start = new Date().getTime();
5311 for (let i=0; i<n; i++) c = a+b;
5312
5313 const end = new Date().getTime();
5314 const time = end - start;
5315
5316 console.log(time);
5317 }
5318*/
5319}
5320
5321module.exports = build;
5322
5323},{"./build_f1.js":5,"./build_testf1.js":12,"./wasmbuilder/index.js":20,"big-integer":2}],16:[function(require,module,exports){
5324/* globals WebAssembly, Blob, Worker, navigator, Promise, window */
5325const bigInt = require("big-integer");
5326const ModuleBuilder = require("./wasmbuilder/index.js");
5327const buildF1m = require("./build_f1m.js");
5328const buildF2m = require("./build_f2m.js");
5329const buildF1 = require("./build_f1.js");
5330const buildCurve = require("./build_curve.js");
5331const buildTest = require("./build_testg1");
5332const buildFFT = require("./build_fft");
5333const buildMultiexp = require("./build_multiexp");
5334const buildPol = require("./build_pol");
5335const utils = require("./utils");
5336const assert = require("assert");
5337
5338
5339class Deferred {
5340 constructor() {
5341 this.promise = new Promise((resolve, reject)=> {
5342 this.reject = reject;
5343 this.resolve = resolve;
5344 });
5345 }
5346}
5347
5348/*
5349function delay(ms) {
5350 return new Promise(resolve => setTimeout(resolve, ms));
5351}
5352*/
5353
5354function thread(self) {
5355 let instance;
5356 let memory;
5357 let i32;
5358
5359 async function init(data) {
5360 const code = new Uint8Array(data.code);
5361 const wasmModule = await WebAssembly.compile(code);
5362 memory = new WebAssembly.Memory({initial:data.init});
5363 i32 = new Uint32Array(memory.buffer);
5364
5365 instance = await WebAssembly.instantiate(wasmModule, {
5366 env: {
5367 "memory": memory
5368 }
5369 });
5370 }
5371
5372 function alloc(length) {
5373 while (i32[0] & 3) i32[0]++; // Return always aligned pointers
5374 const res = i32[0];
5375 i32[0] += length;
5376 return res;
5377 }
5378
5379 function putBin(b) {
5380 const p = alloc(b.byteLength);
5381 const s32 = new Uint32Array(b);
5382 i32.set(s32, p/4);
5383 return p;
5384 }
5385
5386 function getBin(p, l) {
5387 return memory.buffer.slice(p, p+l);
5388 }
5389
5390 self.onmessage = function(e) {
5391 if (e.data.command == "INIT") {
5392 init(e.data).then(function() {
5393 self.postMessage(e.data.result);
5394 });
5395 } else if (e.data.command == "G1_MULTIEXP") {
5396
5397 const oldAlloc = i32[0];
5398 const pScalars = putBin(e.data.scalars);
5399 const pPoints = putBin(e.data.points);
5400 const pRes = alloc(96);
5401 instance.exports.g1_zero(pRes);
5402 instance.exports.g1_multiexp(pScalars, pPoints, e.data.n, 5, pRes);
5403
5404 e.data.result = getBin(pRes, 96);
5405 i32[0] = oldAlloc;
5406 self.postMessage(e.data.result, [e.data.result]);
5407 } else if (e.data.command == "G2_MULTIEXP") {
5408
5409 const oldAlloc = i32[0];
5410 const pScalars = putBin(e.data.scalars);
5411 const pPoints = putBin(e.data.points);
5412 const pRes = alloc(192);
5413 instance.exports.g2_zero(pRes);
5414 instance.exports.g2_multiexp(pScalars, pPoints, e.data.n, 5, pRes);
5415
5416 e.data.result = getBin(pRes, 192);
5417 i32[0] = oldAlloc;
5418 self.postMessage(e.data.result, [e.data.result]);
5419 } else if (e.data.command == "CALC_H") {
5420 const oldAlloc = i32[0];
5421 const pSignals = putBin(e.data.signals);
5422 const pPolsA = putBin(e.data.polsA);
5423 const pPolsB = putBin(e.data.polsB);
5424 const nSignals = e.data.nSignals;
5425 const domainSize = e.data.domainSize;
5426 const pSignalsM = alloc(nSignals*32);
5427 const pPolA = alloc(domainSize*32);
5428 const pPolB = alloc(domainSize*32);
5429 const pPolA2 = alloc(domainSize*32*2);
5430 const pPolB2 = alloc(domainSize*32*2);
5431
5432 instance.exports.fft_toMontgomeryN(pSignals, pSignalsM, nSignals);
5433
5434 instance.exports.pol_zero(pPolA, domainSize);
5435 instance.exports.pol_zero(pPolB, domainSize);
5436
5437 instance.exports.pol_constructLC(pPolsA, pSignalsM, nSignals, pPolA);
5438 instance.exports.pol_constructLC(pPolsB, pSignalsM, nSignals, pPolB);
5439
5440 instance.exports.fft_copyNInterleaved(pPolA, pPolA2, domainSize);
5441 instance.exports.fft_copyNInterleaved(pPolB, pPolB2, domainSize);
5442
5443 instance.exports.fft_ifft(pPolA, domainSize, 0);
5444 instance.exports.fft_ifft(pPolB, domainSize, 0);
5445 instance.exports.fft_fft(pPolA, domainSize, 1);
5446 instance.exports.fft_fft(pPolB, domainSize, 1);
5447
5448 instance.exports.fft_copyNInterleaved(pPolA, pPolA2+32, domainSize);
5449 instance.exports.fft_copyNInterleaved(pPolB, pPolB2+32, domainSize);
5450
5451 instance.exports.fft_mulN(pPolA2, pPolB2, domainSize*2, pPolA2);
5452
5453 instance.exports.fft_ifft(pPolA2, domainSize*2, 0);
5454
5455 instance.exports.fft_fromMontgomeryN(pPolA2+domainSize*32, pPolA2+domainSize*32, nSignals);
5456
5457 e.data.result = getBin(pPolA2+domainSize*32, domainSize*32);
5458 i32[0] = oldAlloc;
5459 self.postMessage(e.data.result, [e.data.result]);
5460 }
5461 };
5462}
5463
5464async function build() {
5465
5466 const groth16 = new Groth16();
5467
5468 groth16.q = bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208583");
5469 groth16.r = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
5470 groth16.n64 = Math.floor((groth16.q.minus(1).bitLength() - 1)/64) +1;
5471 groth16.n32 = groth16.n64*2;
5472 groth16.n8 = groth16.n64*8;
5473
5474 groth16.memory = new WebAssembly.Memory({initial:1000});
5475 groth16.i32 = new Uint32Array(groth16.memory.buffer);
5476
5477 const moduleBuilder = new ModuleBuilder();
5478 moduleBuilder.setMemory(1000);
5479 buildF1m(moduleBuilder, groth16.q, "f1m");
5480 buildF1(moduleBuilder, groth16.r, "fr", "frm");
5481 buildCurve(moduleBuilder, "g1", "f1m");
5482 buildMultiexp(moduleBuilder, "g1", "g1", "f1m", "fr");
5483 buildFFT(moduleBuilder, "fft", "frm");
5484 buildPol(moduleBuilder, "pol", "frm");
5485
5486 const pNonResidueF2 = moduleBuilder.alloc(
5487 utils.bigInt2BytesLE(
5488 bigInt("15537367993719455909907449462855742678907882278146377936676643359958227611562"), // -1 in montgomery
5489 groth16.n8
5490 )
5491 );
5492
5493 buildF2m(moduleBuilder, pNonResidueF2, "f2m", "f1m");
5494 buildCurve(moduleBuilder, "g2", "f2m");
5495 buildMultiexp(moduleBuilder, "g2", "g2", "f2m", "fr");
5496
5497 buildTest(moduleBuilder);
5498
5499 const code = moduleBuilder.build();
5500
5501 const wasmModule = await WebAssembly.compile(code);
5502
5503 groth16.instance = await WebAssembly.instantiate(wasmModule, {
5504 env: {
5505 "memory": groth16.memory
5506 }
5507 });
5508
5509 groth16.pq = moduleBuilder.modules.f1m.pq;
5510 groth16.pr = moduleBuilder.modules.frm.pq;
5511
5512 groth16.pr0 = groth16.alloc(192);
5513 groth16.pr1 = groth16.alloc(192);
5514
5515 groth16.workers = [];
5516 groth16.pendingDeferreds = [];
5517 groth16.working = [];
5518
5519 const concurrency = navigator.hardwareConcurrency || 8;
5520
5521 for (let i = 0; i<concurrency+2; i++) {
5522
5523 const blob = new Blob(["(", thread.toString(), ")(self);"], { type: "text/javascript" });
5524 const url = URL.createObjectURL(blob);
5525
5526 groth16.workers[i] = new Worker(url);
5527
5528 groth16.workers[i].onmessage = function(e) {
5529 groth16.working[i]=false;
5530 groth16.pendingDeferreds[i].resolve(e.data);
5531 groth16.processWorks();
5532 };
5533
5534 groth16.working[i]=false;
5535 }
5536
5537 const initPromises = [];
5538 for (let i=0; i<groth16.workers.length;i++) {
5539 const copyCode = code.slice(0).buffer;
5540 initPromises.push(groth16.postAction(i, {
5541 command: "INIT",
5542 init: 1000,
5543 code: copyCode
5544
5545 }, [copyCode]));
5546 }
5547
5548 await Promise.all(initPromises);
5549
5550 return groth16;
5551}
5552
5553class Groth16 {
5554 constructor() {
5555 this.actionQueue = [];
5556 }
5557
5558 postAction(workerId, e, transfers, _deferred) {
5559 assert(this.working[workerId] == false);
5560 this.working[workerId] = true;
5561
5562 this.pendingDeferreds[workerId] = _deferred ? _deferred : new Deferred();
5563 this.workers[workerId].postMessage(e, transfers);
5564
5565 return this.pendingDeferreds[workerId].promise;
5566 }
5567
5568 processWorks() {
5569 for (let i=0; (i<this.workers.length)&&(this.actionQueue.length > 0); i++) {
5570 if (this.working[i] == false) {
5571 const work = this.actionQueue.shift();
5572 this.postAction(i, work.data, work.transfers, work.deferred);
5573 }
5574 }
5575 }
5576
5577 queueAction(actionData, transfers) {
5578 const d = new Deferred();
5579 this.actionQueue.push({
5580 data: actionData,
5581 transfers: transfers,
5582 deferred: d
5583 });
5584 this.processWorks();
5585 return d.promise;
5586 }
5587
5588 alloc(length) {
5589 while (this.i32[0] & 3) this.i32[0]++; // Return always aligned pointers
5590 const res = this.i32[0];
5591 this.i32[0] += length;
5592 return res;
5593 }
5594
5595
5596 putBin(p, b) {
5597 const s32 = new Uint32Array(b);
5598 this.i32.set(s32, p/4);
5599 }
5600
5601 getBin(p, l) {
5602 return this.memory.buffer.slice(p, p+l);
5603 }
5604
5605 bin2int(b) {
5606 const i32 = new Uint32Array(b);
5607 let acc = bigInt(i32[7]);
5608 for (let i=6; i>=0; i--) {
5609 acc = acc.shiftLeft(32);
5610 acc = acc.add(i32[i]);
5611 }
5612 return acc.toString();
5613 }
5614
5615 bin2g1(b) {
5616 return [
5617 this.bin2int(b.slice(0,32)),
5618 this.bin2int(b.slice(32,64)),
5619 this.bin2int(b.slice(64,96)),
5620 ];
5621 }
5622 bin2g2(b) {
5623 return [
5624 [
5625 this.bin2int(b.slice(0,32)),
5626 this.bin2int(b.slice(32,64))
5627 ],
5628 [
5629 this.bin2int(b.slice(64,96)),
5630 this.bin2int(b.slice(96,128))
5631 ],
5632 [
5633 this.bin2int(b.slice(128,160)),
5634 this.bin2int(b.slice(160,192))
5635 ],
5636 ];
5637 }
5638
5639 async g1_multiexp(scalars, points) {
5640 const nPoints = scalars.byteLength /32;
5641 const nPointsPerThread = Math.floor(nPoints / this.workers.length);
5642 const opPromises = [];
5643 for (let i=0; i<this.workers.length; i++) {
5644 const th_nPoints =
5645 i < this.workers.length -1 ?
5646 nPointsPerThread :
5647 nPoints - (nPointsPerThread * (this.workers.length -1));
5648 const scalars_th = scalars.slice(i*nPointsPerThread*32, i*nPointsPerThread*32 + th_nPoints*32);
5649 const points_th = points.slice(i*nPointsPerThread*64, i*nPointsPerThread*64 + th_nPoints*64);
5650 opPromises.push(
5651 this.queueAction({
5652 command: "G1_MULTIEXP",
5653 scalars: scalars_th,
5654 points: points_th,
5655 n: th_nPoints
5656 }, [scalars_th, points_th])
5657 );
5658 }
5659
5660 const results = await Promise.all(opPromises);
5661
5662 this.instance.exports.g1_zero(this.pr0);
5663 for (let i=0; i<results.length; i++) {
5664 this.putBin(this.pr1, results[i]);
5665 this.instance.exports.g1_add(this.pr0, this.pr1, this.pr0);
5666 }
5667
5668 return this.getBin(this.pr0, 96);
5669 }
5670
5671 async g2_multiexp(scalars, points) {
5672 const nPoints = scalars.byteLength /32;
5673 const nPointsPerThread = Math.floor(nPoints / this.workers.length);
5674 const opPromises = [];
5675 for (let i=0; i<this.workers.length; i++) {
5676 const th_nPoints =
5677 i < this.workers.length -1 ?
5678 nPointsPerThread :
5679 nPoints - (nPointsPerThread * (this.workers.length -1));
5680 const scalars_th = scalars.slice(i*nPointsPerThread*32, i*nPointsPerThread*32 + th_nPoints*32);
5681 const points_th = points.slice(i*nPointsPerThread*128, i*nPointsPerThread*128 + th_nPoints*128);
5682 opPromises.push(
5683 this.queueAction({
5684 command: "G2_MULTIEXP",
5685 scalars: scalars_th,
5686 points: points_th,
5687 n: th_nPoints
5688 }, [scalars_th, points_th])
5689 );
5690 }
5691
5692 const results = await Promise.all(opPromises);
5693
5694 this.instance.exports.g2_zero(this.pr0);
5695 for (let i=0; i<results.length; i++) {
5696 this.putBin(this.pr1, results[i]);
5697 this.instance.exports.g2_add(this.pr0, this.pr1, this.pr0);
5698 }
5699
5700 return this.getBin(this.pr0, 192);
5701 }
5702
5703 g1_affine(p) {
5704 this.putBin(this.pr0, p);
5705 this.instance.exports.g1_affine(this.pr0, this.pr0);
5706 return this.getBin(this.pr0, 96);
5707 }
5708
5709 g2_affine(p) {
5710 this.putBin(this.pr0, p);
5711 this.instance.exports.g2_affine(this.pr0, this.pr0);
5712 return this.getBin(this.pr0, 192);
5713 }
5714
5715 g1_fromMontgomery(p) {
5716 this.putBin(this.pr0, p);
5717 this.instance.exports.g1_fromMontgomery(this.pr0, this.pr0);
5718 return this.getBin(this.pr0, 96);
5719 }
5720
5721 g2_fromMontgomery(p) {
5722 this.putBin(this.pr0, p);
5723 this.instance.exports.g2_fromMontgomery(this.pr0, this.pr0);
5724 return this.getBin(this.pr0, 192);
5725 }
5726
5727 loadPoint1(b) {
5728 const p = this.alloc(96);
5729 this.putBin(p, b);
5730 this.instance.exports.f1m_one(p+64);
5731 return p;
5732 }
5733
5734 loadPoint2(b) {
5735 const p = this.alloc(192);
5736 this.putBin(p, b);
5737 this.instance.exports.f2m_one(p+128);
5738 return p;
5739 }
5740
5741
5742 async calcH(signals, polsA, polsB, nSignals, domainSize) {
5743 return this.queueAction({
5744 command: "CALC_H",
5745 signals: signals,
5746 polsA: polsA,
5747 polsB: polsB,
5748 nSignals: nSignals,
5749 domainSize: domainSize
5750 }, [signals, polsA, polsB]);
5751 }
5752
5753 async proof(signals, pkey) {
5754 const pkey32 = new Uint32Array(pkey);
5755 const nSignals = pkey32[0];
5756 const nPublic = pkey32[1];
5757 const domainSize = pkey32[2];
5758 const pPolsA = pkey32[3];
5759 const pPolsB = pkey32[4];
5760 const pPointsA = pkey32[5];
5761 const pPointsB1 = pkey32[6];
5762 const pPointsB2 = pkey32[7];
5763 const pPointsC = pkey32[8];
5764 const pHExps = pkey32[9];
5765 const polsA = pkey.slice(pPolsA, pPolsA + pPolsB);
5766 const polsB = pkey.slice(pPolsB, pPolsB + pPointsA);
5767 const pointsA = pkey.slice(pPointsA, pPointsA + nSignals*64);
5768 const pointsB1 = pkey.slice(pPointsB1, pPointsB1 + nSignals*64);
5769 const pointsB2 = pkey.slice(pPointsB2, pPointsB2 + nSignals*128);
5770 const pointsC = pkey.slice(pPointsC, pPointsC + (nSignals-nPublic-1)*64);
5771 const pointsHExps = pkey.slice(pHExps, pHExps + domainSize*64);
5772
5773 const alfa1 = pkey.slice(10*4, 10*4 + 64);
5774 const beta1 = pkey.slice(10*4 + 64, 10*4 + 128);
5775 const delta1 = pkey.slice(10*4 + 128, 10*4 + 192);
5776 const beta2 = pkey.slice(10*4 + 192, 10*4 + 320);
5777 const delta2 = pkey.slice(10*4 + 320, 10*4 + 448);
5778
5779
5780 const pH = this.calcH(signals.slice(0), polsA, polsB, nSignals, domainSize).then( (h) => {
5781 return this.g1_multiexp(h, pointsHExps);
5782 });
5783
5784 const pA = this.g1_multiexp(signals.slice(0), pointsA);
5785 const pB1 = this.g1_multiexp(signals.slice(0), pointsB1);
5786 const pB2 = this.g2_multiexp(signals.slice(0), pointsB2);
5787 const pC = this.g1_multiexp(signals.slice((nPublic+1)*32), pointsC);
5788
5789 const res = await Promise.all([pA, pB1, pB2, pC, pH]);
5790
5791 const pi_a = this.alloc(96);
5792 const pi_b = this.alloc(192);
5793 const pi_c = this.alloc(96);
5794 const pib1 = this.alloc(96);
5795
5796
5797 this.putBin(pi_a, res[0]);
5798 this.putBin(pib1, res[1]);
5799 this.putBin(pi_b, res[2]);
5800 this.putBin(pi_c, res[3]);
5801
5802 const pAlfa1 = this.loadPoint1(alfa1);
5803 const pBeta1 = this.loadPoint1(beta1);
5804 const pDelta1 = this.loadPoint1(delta1);
5805 const pBeta2 = this.loadPoint2(beta2);
5806 const pDelta2 = this.loadPoint2(delta2);
5807
5808
5809 let rnd = new Uint32Array(8);
5810
5811 const aux1 = this.alloc(96);
5812 const aux2 = this.alloc(192);
5813
5814 window.crypto.getRandomValues(rnd);
5815 const pr = this.alloc(32);
5816 this.putBin(pr, rnd);
5817 // this.instance.exports.frm_normalize(pr);
5818
5819 window.crypto.getRandomValues(rnd);
5820 const ps = this.alloc(32);
5821 this.putBin(ps, rnd);
5822 // this.instance.exports.frm_normalize(ps);
5823
5824//this.instance.exports.frm_zero(pr);
5825//this.instance.exports.frm_zero(ps);
5826
5827
5828 // pi_a = pi_a + Alfa1 + r*Delta1
5829 this.instance.exports.g1_add(pAlfa1, pi_a, pi_a);
5830 // this.instance.exports.g1_mulscalar(pr, pDelta1, 1, 1, aux1);
5831 this.instance.exports.g1_timesScalar(pDelta1, pr, 32, aux1);
5832 this.instance.exports.g1_add(aux1, pi_a, pi_a);
5833
5834 // pi_b = pi_b + Beta2 + s*Delta2
5835 this.instance.exports.g2_add(pBeta2, pi_b, pi_b);
5836 this.instance.exports.g2_timesScalar(pDelta2, ps, 32, aux2);
5837 this.instance.exports.g2_add(aux2, pi_b, pi_b);
5838
5839 // pib1 = pib1 + Beta1 + s*Delta1
5840 this.instance.exports.g1_add(pBeta1, pib1, pib1);
5841 this.instance.exports.g1_timesScalar(pDelta1, ps, 32, aux1);
5842 this.instance.exports.g1_add(aux1, pib1, pib1);
5843
5844
5845 // pi_c = pi_c + pH
5846 this.putBin(aux1, res[4]);
5847 this.instance.exports.g1_add(aux1, pi_c, pi_c);
5848
5849 // pi_c = pi_c + s*pi_a
5850 this.instance.exports.g1_timesScalar(pi_a, ps, 32, aux1);
5851 this.instance.exports.g1_add(aux1, pi_c, pi_c);
5852
5853 // pi_c = pi_c + r*pib1
5854 this.instance.exports.g1_timesScalar(pib1, pr, 32, aux1);
5855 this.instance.exports.g1_add(aux1, pi_c, pi_c);
5856
5857 // pi_c = pi_c - r*s*delta1
5858 const prs = this.alloc(64);
5859 this.instance.exports.int_mul(pr, ps, prs);
5860 this.instance.exports.g1_timesScalar(pDelta1, prs, 64, aux1);
5861 this.instance.exports.g1_neg(aux1, aux1);
5862 this.instance.exports.g1_add(aux1, pi_c, pi_c);
5863
5864 this.instance.exports.g1_affine(pi_a, pi_a);
5865 this.instance.exports.g2_affine(pi_b, pi_b);
5866 this.instance.exports.g1_affine(pi_c, pi_c);
5867
5868 this.instance.exports.g1_fromMontgomery(pi_a, pi_a);
5869 this.instance.exports.g2_fromMontgomery(pi_b, pi_b);
5870 this.instance.exports.g1_fromMontgomery(pi_c, pi_c);
5871
5872 return {
5873 pi_a: this.bin2g1(this.getBin(pi_a, 96)),
5874 pi_b: this.bin2g2(this.getBin(pi_b, 192)),
5875 pi_c: this.bin2g1(this.getBin(pi_c, 96)),
5876 };
5877
5878 }
5879
5880}
5881
5882module.exports = build;
5883
5884},{"./build_curve.js":4,"./build_f1.js":5,"./build_f1m.js":6,"./build_f2m.js":7,"./build_fft":8,"./build_multiexp":10,"./build_pol":11,"./build_testg1":13,"./utils":17,"./wasmbuilder/index.js":20,"assert":24,"big-integer":2}],17:[function(require,module,exports){
5885const bigInt = require("big-integer");
5886
5887exports.bigInt2BytesLE = function bigInt2BytesLE(_a, len) {
5888 const b = Array(len);
5889 let v = bigInt(_a);
5890 for (let i=0; i<len; i++) {
5891 b[i] = v.and(0xFF).toJSNumber();
5892 v = v.shiftRight(8);
5893 }
5894 return b;
5895};
5896
5897exports.bigInt2U32LE = function bigInt2BytesLE(_a, len) {
5898 const b = Array(len);
5899 let v = bigInt(_a);
5900 for (let i=0; i<len; i++) {
5901 b[i] = v.and(0xFFFFFFFF).toJSNumber();
5902 v = v.shiftRight(32);
5903 }
5904 return b;
5905};
5906
5907},{"big-integer":2}],18:[function(require,module,exports){
5908const utils = require("./utils.js");
5909
5910class CodeBuilder {
5911 constructor(func) {
5912 this.func = func;
5913 this.functionName = func.functionName;
5914 this.module = func.module;
5915 }
5916
5917 setLocal(localName, valCode) {
5918 const idx = this.func.localIdxByName[localName];
5919 if (idx === undefined)
5920 throw new Error(`Local Variable not defined: Function: ${this.functionName} local: ${localName} `);
5921 return [...valCode, 0x21, ...utils.varuint32( idx )];
5922 }
5923
5924 teeLocal(localName, valCode) {
5925 const idx = this.func.localIdxByName[localName];
5926 if (idx === undefined)
5927 throw new Error(`Local Variable not defined: Function: ${this.functionName} local: ${localName} `);
5928 return [...valCode, 0x22, ...utils.varuint32( idx )];
5929 }
5930
5931 getLocal(localName) {
5932 const idx = this.func.localIdxByName[localName];
5933 if (idx === undefined)
5934 throw new Error(`Local Variable not defined: Function: ${this.functionName} local: ${localName} `);
5935 return [0x20, ...utils.varuint32( idx )];
5936 }
5937
5938 i64_load8_s(idxCode, _offset, _align) {
5939 const offset = _offset || 0;
5940 const align = (_align === undefined) ? 0 : _align; // 32 bits alignment by default
5941 return [...idxCode, 0x30, align, ...utils.varuint32(offset)];
5942 }
5943
5944 i64_load8_u(idxCode, _offset, _align) {
5945 const offset = _offset || 0;
5946 const align = (_align === undefined) ? 0 : _align; // 32 bits alignment by default
5947 return [...idxCode, 0x31, align, ...utils.varuint32(offset)];
5948 }
5949
5950 i64_load16_s(idxCode, _offset, _align) {
5951 const offset = _offset || 0;
5952 const align = (_align === undefined) ? 1 : _align; // 32 bits alignment by default
5953 return [...idxCode, 0x32, align, ...utils.varuint32(offset)];
5954 }
5955
5956 i64_load16_u(idxCode, _offset, _align) {
5957 const offset = _offset || 0;
5958 const align = (_align === undefined) ? 1 : _align; // 32 bits alignment by default
5959 return [...idxCode, 0x33, align, ...utils.varuint32(offset)];
5960 }
5961
5962 i64_load32_s(idxCode, _offset, _align) {
5963 const offset = _offset || 0;
5964 const align = (_align === undefined) ? 2 : _align; // 32 bits alignment by default
5965 return [...idxCode, 0x34, align, ...utils.varuint32(offset)];
5966 }
5967
5968 i64_load32_u(idxCode, _offset, _align) {
5969 const offset = _offset || 0;
5970 const align = (_align === undefined) ? 2 : _align; // 32 bits alignment by default
5971 return [...idxCode, 0x35, align, ...utils.varuint32(offset)];
5972 }
5973
5974 i64_load(idxCode, _offset, _align) {
5975 const offset = _offset || 0;
5976 const align = (_align === undefined) ? 3 : _align; // 32 bits alignment by default
5977 return [...idxCode, 0x29, align, ...utils.varuint32(offset)];
5978 }
5979
5980 i64_store32(idxCode, _offset, _align, _codeVal) {
5981 let offset, align, codeVal;
5982 if (Array.isArray(_offset)) {
5983 offset = 0;
5984 align = 2;
5985 codeVal = _offset;
5986 } else if (Array.isArray(_align)) {
5987 offset = _offset;
5988 align = 2;
5989 codeVal = _align;
5990 } else if (Array.isArray(_codeVal)) {
5991 offset = _offset;
5992 align = _align;
5993 codeVal = _codeVal;
5994 }
5995 return [...idxCode, ...codeVal, 0x3e, align, ...utils.varuint32(offset)];
5996 }
5997
5998 i64_store(idxCode, _offset, _align, _codeVal) {
5999 let offset, align, codeVal;
6000 if (Array.isArray(_offset)) {
6001 offset = 0;
6002 align = 3;
6003 codeVal = _offset;
6004 } else if (Array.isArray(_align)) {
6005 offset = _offset;
6006 align = 3;
6007 codeVal = _align;
6008 } else if (Array.isArray(_codeVal)) {
6009 offset = _offset;
6010 align = _align;
6011 codeVal = _codeVal;
6012 }
6013 return [...idxCode, ...codeVal, 0x37, align, ...utils.varuint32(offset)];
6014 }
6015
6016 i32_load8_s(idxCode, _offset, _align) {
6017 const offset = _offset || 0;
6018 const align = (_align === undefined) ? 0 : _align; // 32 bits alignment by default
6019 return [...idxCode, 0x2c, align, ...utils.varuint32(offset)];
6020 }
6021
6022 i32_load8_u(idxCode, _offset, _align) {
6023 const offset = _offset || 0;
6024 const align = (_align === undefined) ? 0 : _align; // 32 bits alignment by default
6025 return [...idxCode, 0x2d, align, ...utils.varuint32(offset)];
6026 }
6027
6028 i32_load16_s(idxCode, _offset, _align) {
6029 const offset = _offset || 0;
6030 const align = (_align === undefined) ? 1 : _align; // 32 bits alignment by default
6031 return [...idxCode, 0x2e, align, ...utils.varuint32(offset)];
6032 }
6033
6034 i32_load16_u(idxCode, _offset, _align) {
6035 const offset = _offset || 0;
6036 const align = (_align === undefined) ? 1 : _align; // 32 bits alignment by default
6037 return [...idxCode, 0x2f, align, ...utils.varuint32(offset)];
6038 }
6039
6040 i32_load(idxCode, _offset, _align) {
6041 const offset = _offset || 0;
6042 const align = (_align === undefined) ? 2 : _align; // 32 bits alignment by default
6043 return [...idxCode, 0x28, align, ...utils.varuint32(offset)];
6044 }
6045
6046 i32_store(idxCode, _offset, _align, _codeVal) {
6047 let offset, align, codeVal;
6048 if (Array.isArray(_offset)) {
6049 offset = 0;
6050 align = 2;
6051 codeVal = _offset;
6052 } else if (Array.isArray(_align)) {
6053 offset = _offset;
6054 align = 2;
6055 codeVal = _align;
6056 } else if (Array.isArray(_codeVal)) {
6057 offset = _offset;
6058 align = _align;
6059 codeVal = _codeVal;
6060 }
6061 return [...idxCode, ...codeVal, 0x36, align, ...utils.varuint32(offset)];
6062 }
6063
6064
6065 call(fnName, ...args) {
6066 const idx = this.module.functionIdxByName[fnName];
6067 if (idx === undefined)
6068 throw new Error(`Function not defined: Function: ${fnName}`);
6069 return [...[].concat(...args), 0x10, ...utils.varuint32(idx)];
6070 }
6071
6072 if(condCode, thenCode, elseCode) {
6073 if (elseCode) {
6074 return [...condCode, 0x04, 0x40, ...thenCode, 0x05, ...elseCode, 0x0b];
6075 } else {
6076 return [...condCode, 0x04, 0x40, ...thenCode, 0x0b];
6077 }
6078 }
6079
6080 block(bCode) { return [0x02, 0x40, ...bCode, 0x0b]; }
6081 loop(...args) {
6082 return [0x03, 0x40, ...[].concat(...[...args]), 0x0b];
6083 }
6084 br_if(relPath, condCode) { return [...condCode, 0x0d, ...utils.varuint32(relPath)]; }
6085 br(relPath) { return [0x0c, ...utils.varuint32(relPath)]; }
6086 ret(rCode) { return [...rCode, 0x0f]; }
6087 drop(dCode) { return [...dCode, 0x1a]; }
6088
6089 i64_const(num) { return [0x42, ...utils.varint64(num)]; }
6090 i32_const(num) { return [0x41, ...utils.varint32(num)]; }
6091
6092
6093 i64_eqz(opcode) { return [...opcode, 0x50]; }
6094 i64_eq(op1code, op2code) { return [...op1code, ...op2code, 0x51]; }
6095 i64_ne(op1code, op2code) { return [...op1code, ...op2code, 0x52]; }
6096 i64_lt_s(op1code, op2code) { return [...op1code, ...op2code, 0x53]; }
6097 i64_lt_u(op1code, op2code) { return [...op1code, ...op2code, 0x54]; }
6098 i64_gt_s(op1code, op2code) { return [...op1code, ...op2code, 0x55]; }
6099 i64_gt_u(op1code, op2code) { return [...op1code, ...op2code, 0x56]; }
6100 i64_le_s(op1code, op2code) { return [...op1code, ...op2code, 0x57]; }
6101 i64_le_u(op1code, op2code) { return [...op1code, ...op2code, 0x58]; }
6102 i64_ge_s(op1code, op2code) { return [...op1code, ...op2code, 0x59]; }
6103 i64_ge_u(op1code, op2code) { return [...op1code, ...op2code, 0x5a]; }
6104 i64_add(op1code, op2code) { return [...op1code, ...op2code, 0x7c]; }
6105 i64_sub(op1code, op2code) { return [...op1code, ...op2code, 0x7d]; }
6106 i64_mul(op1code, op2code) { return [...op1code, ...op2code, 0x7e]; }
6107 i64_div_u(op1code, op2code) { return [...op1code, ...op2code, 0x80]; }
6108 i64_and(op1code, op2code) { return [...op1code, ...op2code, 0x83]; }
6109 i64_or(op1code, op2code) { return [...op1code, ...op2code, 0x84]; }
6110 i64_shl(op1code, op2code) { return [...op1code, ...op2code, 0x86]; }
6111 i64_shr_s(op1code, op2code) { return [...op1code, ...op2code, 0x87]; }
6112 i64_shr_u(op1code, op2code) { return [...op1code, ...op2code, 0x88]; }
6113 i64_extend_i32_u(op1code) { return [...op1code, 0xad]; }
6114
6115
6116 i32_eqz(op1code) { return [...op1code, 0x45]; }
6117 i32_eq(op1code, op2code) { return [...op1code, ...op2code, 0x46]; }
6118 i32_ne(op1code, op2code) { return [...op1code, ...op2code, 0x47]; }
6119 i32_lt_s(op1code, op2code) { return [...op1code, ...op2code, 0x48]; }
6120 i32_lt_u(op1code, op2code) { return [...op1code, ...op2code, 0x49]; }
6121 i32_gt_s(op1code, op2code) { return [...op1code, ...op2code, 0x4a]; }
6122 i32_gt_u(op1code, op2code) { return [...op1code, ...op2code, 0x4b]; }
6123 i32_le_s(op1code, op2code) { return [...op1code, ...op2code, 0x4c]; }
6124 i32_le_u(op1code, op2code) { return [...op1code, ...op2code, 0x4d]; }
6125 i32_ge_s(op1code, op2code) { return [...op1code, ...op2code, 0x4e]; }
6126 i32_ge_u(op1code, op2code) { return [...op1code, ...op2code, 0x4f]; }
6127 i32_add(op1code, op2code) { return [...op1code, ...op2code, 0x6a]; }
6128 i32_sub(op1code, op2code) { return [...op1code, ...op2code, 0x6b]; }
6129 i32_mul(op1code, op2code) { return [...op1code, ...op2code, 0x6c]; }
6130 i32_div_s(op1code, op2code) { return [...op1code, ...op2code, 0x6d]; }
6131 i32_div_u(op1code, op2code) { return [...op1code, ...op2code, 0x6e]; }
6132 i32_rem_s(op1code, op2code) { return [...op1code, ...op2code, 0x6f]; }
6133 i32_rem_u(op1code, op2code) { return [...op1code, ...op2code, 0x70]; }
6134 i32_and(op1code, op2code) { return [...op1code, ...op2code, 0x71]; }
6135 i32_or(op1code, op2code) { return [...op1code, ...op2code, 0x72]; }
6136 i32_shl(op1code, op2code) { return [...op1code, ...op2code, 0x74]; }
6137 i32_shr_s(op1code, op2code) { return [...op1code, ...op2code, 0x75]; }
6138 i32_shr_u(op1code, op2code) { return [...op1code, ...op2code, 0x76]; }
6139 i32_rotl(op1code, op2code) { return [...op1code, ...op2code, 0x77]; }
6140 i32_rotr(op1code, op2code) { return [...op1code, ...op2code, 0x78]; }
6141 i32_wrap_i64(op1code) { return [...op1code, 0xa7]; }
6142
6143 unreachable() { return [ 0x0 ]; }
6144
6145}
6146
6147module.exports = CodeBuilder;
6148
6149},{"./utils.js":22}],19:[function(require,module,exports){
6150
6151const CodeBuilder = require("./codebuilder.js");
6152const utils = require("./utils.js");
6153
6154const typeCodes = {
6155 "i32": 0x7f,
6156 "i64": 0x7e,
6157 "f32": 0x7d,
6158 "f64": 0x7c,
6159 "anyfunc": 0x70,
6160 "func": 0x60,
6161 "emptyblock": 0x40
6162};
6163
6164
6165class FunctionBuilder {
6166
6167 constructor (module, fnName, fnType, moduleName, fieldName) {
6168 if (fnType == "import") {
6169 this.fnType = "import";
6170 this.moduleName = moduleName;
6171 this.fieldName = fieldName;
6172 } else if (fnType == "internal") {
6173 this.fnType = "internal";
6174 } else {
6175 throw new Error("Invalid function fnType: " + fnType);
6176 }
6177 this.module = module;
6178 this.fnName = fnName;
6179 this.params = [];
6180 this.locals = [];
6181 this.localIdxByName = {};
6182 this.code = [];
6183 this.returnType = null;
6184 this.nextLocal =0;
6185 }
6186
6187 addParam(paramName, paramType) {
6188 if (this.localIdxByName[paramName])
6189 throw new Error(`param already exists. Function: ${this.fnName}, Param: ${paramName} `);
6190 const idx = this.nextLocal++;
6191 this.localIdxByName[paramName] = idx;
6192 this.params.push({
6193 type: paramType
6194 });
6195 }
6196
6197 addLocal(localName, localType, _length) {
6198 const length = _length || 1;
6199 if (this.localIdxByName[localName])
6200 throw new Error(`local already exists. Function: ${this.fnName}, Param: ${localName} `);
6201 const idx = this.nextLocal++;
6202 this.localIdxByName[localName] = idx;
6203 this.locals.push({
6204 type: localType,
6205 length: length
6206 });
6207 }
6208
6209 setReturnType(returnType) {
6210 if (this.returnType)
6211 throw new Error(`returnType already defined. Function: ${this.fnName}`);
6212 this.returnType = returnType;
6213 }
6214
6215 getSignature() {
6216 const params = [...utils.varuint32(this.params.length), ...this.params.map((p) => typeCodes[p.type])];
6217 const returns = this.returnType ? [0x01, typeCodes[this.returnType]] : [0];
6218 return [0x60, ...params, ...returns];
6219 }
6220
6221 getBody() {
6222 const locals = this.locals.map((l) => [
6223 ...utils.varuint32(l.length),
6224 typeCodes[l.type]
6225 ]);
6226
6227 const body = [
6228 ...utils.varuint32(this.locals.length),
6229 ...[].concat(...locals),
6230 ...this.code,
6231 0x0b
6232 ];
6233 return [
6234 ...utils.varuint32(body.length),
6235 ...body
6236 ];
6237 }
6238
6239 addCode(...code) {
6240 this.code.push(...[].concat(...[...code]));
6241 }
6242
6243 getCodeBuilder() {
6244 return new CodeBuilder(this);
6245 }
6246}
6247
6248module.exports = FunctionBuilder;
6249
6250},{"./codebuilder.js":18,"./utils.js":22}],20:[function(require,module,exports){
6251module.exports = require("./modulebuilder");
6252
6253},{"./modulebuilder":21}],21:[function(require,module,exports){
6254
6255
6256const FunctionBuilder = require("./functionbuilder.js");
6257const utils = require("./utils.js");
6258
6259class ModuleBuilder {
6260
6261 constructor() {
6262 this.functions = [];
6263 this.functionIdxByName = {};
6264 this.nImportFunctions = 0;
6265 this.nInternalFunctions =0;
6266 this.memory = {
6267 pagesSize: 1,
6268 moduleName: "env",
6269 fieldName: "memory"
6270 };
6271 this.free = 8;
6272 this.datas = [];
6273 this.modules = {};
6274 this.exports = [];
6275 }
6276
6277 build() {
6278 this._setSignatures();
6279 return new Uint8Array([
6280 ...utils.u32(0x6d736100),
6281 ...utils.u32(1),
6282 ...this._buildType(),
6283 ...this._buildImport(),
6284 ...this._buildFunctionDeclarations(),
6285 ...this._buildExports(),
6286 ...this._buildCode(),
6287 ...this._buildData()
6288 ]);
6289 }
6290
6291 addFunction(fnName) {
6292 if (typeof(this.functionIdxByName[fnName]) !== "undefined")
6293 throw new Error(`Function already defined: ${fnName}`);
6294
6295 const idx = this.functions.length;
6296 this.functionIdxByName[fnName] = idx;
6297
6298 this.functions.push(new FunctionBuilder(this, fnName, "internal"));
6299
6300 this.nInternalFunctions++;
6301 return this.functions[idx];
6302 }
6303
6304 addIimportFunction(fnName, moduleName, _fieldName) {
6305 if (typeof(this.functionIdxByName[fnName]) !== "undefined")
6306 throw new Error(`Function already defined: ${fnName}`);
6307
6308 if ( (this.functions.length>0)
6309 &&(this.functions[this.functions.length-1].type == "internal"))
6310 throw new Error(`Import functions must be declared before internal: ${fnName}`);
6311
6312 let fieldName = _fieldName || fnName;
6313
6314 const idx = this.functions.length;
6315 this.functionIdxByName[fnName] = idx;
6316
6317 this.functions.push(new FunctionBuilder(this, fnName, "import", moduleName, fieldName));
6318
6319 this.nImportFunctions ++;
6320 return this.functions[idx];
6321 }
6322
6323 setMemory(pagesSize, moduleName, fieldName) {
6324 this.memory = {
6325 pagesSize: pagesSize,
6326 moduleName: moduleName || "env",
6327 fieldName: fieldName || "memory"
6328 };
6329 }
6330
6331 exportFunction(fnName, _exportName) {
6332 const exportName = _exportName || fnName;
6333 if (typeof(this.functionIdxByName[fnName]) === "undefined")
6334 throw new Error(`Function not defined: ${fnName}`);
6335 const idx = this.functionIdxByName[fnName];
6336 if (exportName != fnName) {
6337 this.functionIdxByName[exportName] = idx;
6338 }
6339 this.exports.push({
6340 exportName: exportName,
6341 idx: idx
6342 });
6343 }
6344
6345 addData(offset, bytes) {
6346 this.datas.push({
6347 offset: offset,
6348 bytes: bytes
6349 });
6350 }
6351
6352 alloc(a, b) {
6353 let size;
6354 let bytes;
6355 if (Array.isArray(a) && (typeof(b) === "undefined")) {
6356 size = a.length;
6357 bytes = a;
6358 } else {
6359 size = a;
6360 bytes = b;
6361 }
6362 const p = this.free;
6363 this.free += size;
6364 if (bytes) {
6365 this.addData(p, bytes);
6366 }
6367 return p;
6368 }
6369
6370 _setSignatures() {
6371 this.signatures = [];
6372 const signatureIdxByName = {};
6373 for (let i=0; i<this.functions.length; i++) {
6374 const signature = this.functions[i].getSignature();
6375 const signatureName = "s_"+utils.toHexString(signature);
6376 if (typeof(signatureIdxByName[signatureName]) === "undefined") {
6377 signatureIdxByName[signatureName] = this.signatures.length;
6378 this.signatures.push(signature);
6379 }
6380
6381 this.functions[i].signatureIdx = signatureIdxByName[signatureName];
6382 }
6383
6384 }
6385
6386 _buildSection(sectionType, section) {
6387 return [sectionType, ...utils.varuint32(section.length), ...section];
6388 }
6389
6390 _buildType() {
6391 return this._buildSection(
6392 0x01,
6393 [
6394 ...utils.varuint32(this.signatures.length),
6395 ...[].concat(...this.signatures)
6396 ]
6397 );
6398 }
6399
6400 _buildImport() {
6401 const entries = [];
6402 entries.push([
6403 ...utils.string(this.memory.moduleName),
6404 ...utils.string(this.memory.fieldName),
6405 0x02,
6406 0x00, //Flags no init valua
6407 ...utils.varuint32(this.memory.pagesSize)
6408 ]);
6409 for (let i=0; i< this.nImportFunctions; i++) {
6410 entries.push([
6411 ...utils.string(this.functions[i].moduleName),
6412 ...utils.string(this.functions[i].fieldName),
6413 0x00,
6414 ...utils.varuint32(this.functions[i].signatureIdx)
6415 ]);
6416 }
6417 return this._buildSection(
6418 0x02,
6419 utils.varuint32(entries.length).concat(...entries)
6420 );
6421 }
6422
6423 _buildFunctionDeclarations() {
6424 const entries = [];
6425 for (let i=this.nImportFunctions; i< this.nInternalFunctions; i++) {
6426 entries.push(...utils.varuint32(this.functions[i].signatureIdx));
6427 }
6428 return this._buildSection(
6429 0x03,
6430 [
6431 ...utils.varuint32(entries.length),
6432 ...[...entries]
6433 ]
6434 );
6435 }
6436
6437 _buildExports() {
6438 const entries = [];
6439 for (let i=0; i< this.exports.length; i++) {
6440 entries.push([
6441 ...utils.string(this.exports[i].exportName),
6442 0x00,
6443 ...utils.varuint32(this.exports[i].idx)
6444 ]);
6445 }
6446 return this._buildSection(
6447 0x07,
6448 utils.varuint32(entries.length).concat(...entries)
6449 );
6450 }
6451
6452 _buildCode() {
6453 const entries = [];
6454 for (let i=this.nImportFunctions; i< this.nInternalFunctions; i++) {
6455 entries.push(this.functions[i].getBody());
6456 }
6457 return this._buildSection(
6458 0x0a,
6459 utils.varuint32(entries.length).concat(...entries)
6460 );
6461 }
6462
6463 _buildData() {
6464 const entries = [];
6465 entries.push([
6466 0x00,
6467 0x41,
6468 0x00,
6469 0x0b,
6470 0x04,
6471 ...utils.u32(this.free)
6472 ]);
6473 for (let i=0; i< this.datas.length; i++) {
6474 entries.push([
6475 0x00,
6476 0x41,
6477 ...utils.varint32(this.datas[i].offset),
6478 0x0b,
6479 ...utils.varuint32(this.datas[i].bytes.length),
6480 ...this.datas[i].bytes,
6481 ]);
6482 }
6483 return this._buildSection(
6484 0x0b,
6485 utils.varuint32(entries.length).concat(...entries)
6486 );
6487 }
6488
6489}
6490
6491module.exports = ModuleBuilder;
6492
6493},{"./functionbuilder.js":19,"./utils.js":22}],22:[function(require,module,exports){
6494var bigInt = require("big-integer");
6495
6496function toNumber(n) {
6497 let v;
6498 if (typeof n=="string") {
6499 if (n.slice(0,2).toLowerCase() == "0x") {
6500 v = bigInt(n.slice(2),16);
6501 } else {
6502 v = bigInt(n);
6503 }
6504 } else {
6505 v = bigInt(n);
6506 }
6507 return v;
6508}
6509
6510function u32(n) {
6511 const b = [];
6512 const v = toNumber(n);
6513 b.push(v.and(0xFF).toJSNumber());
6514 b.push(v.shiftRight(8).and(0xFF).toJSNumber());
6515 b.push(v.shiftRight(16).and(0xFF).toJSNumber());
6516 b.push(v.shiftRight(24).and(0xFF).toJSNumber());
6517 return b;
6518}
6519
6520function u64(n) {
6521 const b = [];
6522 const v = toNumber(n);
6523 b.push(v.and(0xFF).toJSNumber());
6524 b.push(v.shiftRight(8).and(0xFF).toJSNumber());
6525 b.push(v.shiftRight(16).and(0xFF).toJSNumber());
6526 b.push(v.shiftRight(24).and(0xFF).toJSNumber());
6527 b.push(v.shiftRight(32).and(0xFF).toJSNumber());
6528 b.push(v.shiftRight(40).and(0xFF).toJSNumber());
6529 b.push(v.shiftRight(48).and(0xFF).toJSNumber());
6530 b.push(v.shiftRight(56).and(0xFF).toJSNumber());
6531 return b;
6532}
6533
6534function toUTF8Array(str) {
6535 var utf8 = [];
6536 for (var i=0; i < str.length; i++) {
6537 var charcode = str.charCodeAt(i);
6538 if (charcode < 0x80) utf8.push(charcode);
6539 else if (charcode < 0x800) {
6540 utf8.push(0xc0 | (charcode >> 6),
6541 0x80 | (charcode & 0x3f));
6542 }
6543 else if (charcode < 0xd800 || charcode >= 0xe000) {
6544 utf8.push(0xe0 | (charcode >> 12),
6545 0x80 | ((charcode>>6) & 0x3f),
6546 0x80 | (charcode & 0x3f));
6547 }
6548 // surrogate pair
6549 else {
6550 i++;
6551 // UTF-16 encodes 0x10000-0x10FFFF by
6552 // subtracting 0x10000 and splitting the
6553 // 20 bits of 0x0-0xFFFFF into two halves
6554 charcode = 0x10000 + (((charcode & 0x3ff)<<10)
6555 | (str.charCodeAt(i) & 0x3ff));
6556 utf8.push(0xf0 | (charcode >>18),
6557 0x80 | ((charcode>>12) & 0x3f),
6558 0x80 | ((charcode>>6) & 0x3f),
6559 0x80 | (charcode & 0x3f));
6560 }
6561 }
6562 return utf8;
6563}
6564
6565function string(str) {
6566 const bytes = toUTF8Array(str);
6567 return [ ...varuint32(bytes.length), ...bytes ];
6568}
6569
6570function varuint(n) {
6571 const code = [];
6572 let v = toNumber(n);
6573 if (v.isNegative()) throw new Error("Number cannot be negative");
6574 while (!v.isZero()) {
6575 code.push(v.and(0x7F).toJSNumber());
6576 v = v.shiftRight(7);
6577 }
6578 if (code.length==0) code.push(0);
6579 for (let i=0; i<code.length-1; i++) {
6580 code[i] = code[i] | 0x80;
6581 }
6582 return code;
6583}
6584
6585function varint(_n) {
6586 let n, sign;
6587 const bits = _n.bitLength().toJSNumber();
6588 if (_n<0) {
6589 sign = true;
6590 n = bigInt.one.shiftLeft(bits).add(_n);
6591 } else {
6592 sign = false;
6593 n = toNumber(_n);
6594 }
6595 const paddingBits = 7 - (bits % 7);
6596
6597 const padding = bigInt.one.shiftLeft(paddingBits).minus(1).shiftLeft(bits);
6598 const paddingMask = ((1 << (7 - paddingBits))-1) | 0x80;
6599
6600 const code = varuint(n.add(padding));
6601
6602 if (!sign) {
6603 code[code.length-1] = code[code.length-1] & paddingMask;
6604 }
6605
6606 return code;
6607}
6608
6609function varint32(n) {
6610 let v = toNumber(n);
6611 if (v.greater(bigInt("FFFFFFFF", 16))) throw new Error("Number too big");
6612 if (v.greater(bigInt("7FFFFFFF", 16))) v = v.minus(bigInt("100000000",16));
6613 if (v.lesser(bigInt("-80000000", 16))) throw new Error("Number too small");
6614 return varint(v);
6615}
6616
6617function varint64(n) {
6618 let v = toNumber(n);
6619 if (v.greater(bigInt("FFFFFFFFFFFFFFFF", 16))) throw new Error("Number too big");
6620 if (v.greater(bigInt("7FFFFFFFFFFFFFFF", 16))) v = v.minus(bigInt("10000000000000000",16));
6621 if (v.lesser(bigInt("-8000000000000000", 16))) throw new Error("Number too small");
6622 return varint(v);
6623}
6624
6625function varuint32(n) {
6626 let v = toNumber(n);
6627 if (v.greater(bigInt("FFFFFFFF", 16))) throw new Error("Number too big");
6628 return varuint(v);
6629}
6630
6631function varuint64(n) {
6632 let v = toNumber(n);
6633 if (v.greater(bigInt("FFFFFFFFFFFFFFFF", 16))) throw new Error("Number too big");
6634 return varuint(v);
6635}
6636
6637function toHexString(byteArray) {
6638 return Array.from(byteArray, function(byte) {
6639 return ("0" + (byte & 0xFF).toString(16)).slice(-2);
6640 }).join("");
6641}
6642
6643module.exports.toNumber = toNumber;
6644module.exports.u32 = u32;
6645module.exports.u64 = u64;
6646module.exports.varuint32 = varuint32;
6647module.exports.varuint64 = varuint64;
6648module.exports.varint32 = varint32;
6649module.exports.varint64 = varint64;
6650module.exports.string = string;
6651module.exports.toHexString = toHexString;
6652
6653},{"big-integer":2}],23:[function(require,module,exports){
6654/* globals window */
6655
6656console.log("Loading groth16/1...");
6657const buildF1 = require("./index.js").buildF1;
6658const buildBn128 = require("./index.js").buildBn128;
6659const buildGroth16 = require("./index.js").buildGroth16;
6660const bigInt = require("big-integer");
6661
6662
6663buildGroth16().then( (_groth16) => {
6664 window.groth16 = _groth16;
6665});
6666
6667
6668
6669
6670window.bigInt = bigInt;
6671window.q = bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208583");
6672
6673buildF1(window.q).then( (_f1) => { window.F1 = _f1; });
6674buildBn128().then( (_bn128) => {
6675 window.bn128 = _bn128;
6676 window.pg = window.bn128.g1_allocPoint(
6677 [ bigInt(1), bigInt(2), bigInt(1)]
6678 );
6679 window.pArr = window.bn128.alloc(32*4);
6680 for (let i=0; i<4; i++) {
6681 window.bn128.putInt(window.pArr+i*32, i);
6682 }
6683
6684 fetch("proving_key.bin").then( (response) => {
6685 return response.arrayBuffer();
6686 }).then( (b) => {
6687 window.provingKey = b;
6688 window.pProvingKey = window.bn128.putBin(b);
6689 window.pPointsA = window.pProvingKey + window.bn128.i32[(window.pProvingKey>>2) + 6];
6690 window.pPointsB2 = window.pProvingKey + window.bn128.i32[(window.pProvingKey>>2) + 7];
6691 window.nSignals = window.bn128.i32[(window.pProvingKey>>2)];
6692 });
6693
6694 fetch("witness.bin").then( (response) => {
6695 return response.arrayBuffer();
6696 }).then( (b) => {
6697 window.signals = b;
6698 window.pWitness = window.bn128.putBin(b)+4;
6699 });
6700
6701});
6702
6703window.calcProof = function() {
6704 const signals =window.signals.slice(4, 4+window.nSignals*32);
6705 const start = new Date().getTime();
6706
6707 window.groth16.proof(signals, window.provingKey).then((p)=> {
6708 const end = new Date().getTime();
6709 const time = end - start;
6710 console.log(JSON.stringify(p, null, 1));
6711 console.log(time);
6712 document.getElementById("result").innerHTML = time;
6713 });
6714};
6715
6716window.calcPolA = function() {
6717 const signals =window.signals.slice(4, 4+window.nSignals*32);
6718 const pkey32 = new Uint32Array(window.provingKey);
6719 const nSignals = pkey32[0];
6720 const domainSize = pkey32[2];
6721 const ppPolsA = pkey32[3];
6722 const ppPolsB = pkey32[4];
6723 const ppPolsC = pkey32[5];
6724 const polsA = window.provingKey.slice(ppPolsA, ppPolsA + ppPolsB);
6725 const polsB = window.provingKey.slice(ppPolsB, ppPolsB + ppPolsC);
6726
6727
6728 const pSignals = window.groth16.alloc(signals.byteLength);
6729 window.groth16.putBin(pSignals, signals);
6730 const pPolsA = window.groth16.alloc(polsA.byteLength);
6731 window.groth16.putBin(pPolsA, polsA);
6732 const pPolsB = window.groth16.alloc(polsB.byteLength);
6733 window.groth16.putBin(pPolsB, polsB);
6734
6735
6736 const pSignalsM = window.groth16.alloc(nSignals*32);
6737 const pPolA = window.groth16.alloc(domainSize*32);
6738 const pPolB = window.groth16.alloc(domainSize*32);
6739 const pPolA2 = window.groth16.alloc(domainSize*32*2);
6740 const pPolB2 = window.groth16.alloc(domainSize*32*2);
6741
6742 window.groth16.instance.exports.fft_toMontgomeryN(pSignals, pSignalsM, nSignals);
6743
6744 window.groth16.instance.exports.pol_zero(pPolA, domainSize);
6745 window.groth16.instance.exports.pol_zero(pPolB, domainSize);
6746
6747 window.groth16.instance.exports.pol_constructLC(pPolsA, pSignalsM, nSignals, pPolA);
6748 window.groth16.instance.exports.pol_constructLC(pPolsB, pSignalsM, nSignals, pPolB);
6749
6750 window.groth16.instance.exports.fft_fromMontgomeryN(pPolA, pPolA, domainSize);
6751
6752 for (let i=0; i<10; i++) {
6753 const a = window.groth16.bin2int(window.groth16.getBin(pPolA + i*32, 32));
6754 console.log(a.toString());
6755 }
6756};
6757
6758
6759window.calcPA_p = function() {
6760 const witness =window.witness.slice(4, 4+window.nSignals*32);
6761 const oPointsA = new Uint32Array(window.provingKey)[6];
6762 const pointsA =window.provingKey.slice(oPointsA, oPointsA + window.nSignals*64);
6763 window.groth16.g1_multiexp(witness, pointsA).then( function(r) {
6764 const p1 = window.groth16.g1_affine(r);
6765 const p2 = window.groth16.g1_fromMontgomery(p1);
6766 const p = window.groth16.bin2g1(p2);
6767 console.log(p);
6768 });
6769};
6770
6771window.calcPA = function(_n, _w) {
6772 const n = _n || window.nSignals;
6773 const w = _w || 5;
6774 const pA = window.bn128.alloc(32*3);
6775 window.bn128.g1_zero(pA);
6776 window.bn128.g1_multiexp(
6777 window.pWitness,
6778 window.pPointsA,
6779 n,
6780 w,
6781 pA
6782 );
6783 window.bn128.g1_affine(pA, pA);
6784 window.bn128.g1_fromMontgomery(pA, pA);
6785 const res = window.bn128.g1_getPoint(pA);
6786 console.log(res[0].toString());
6787 console.log(res[1].toString());
6788 console.log(res[2].toString());
6789};
6790
6791
6792window.calcPB2 = function(_n, _w) {
6793 const n = _n || window.nSignals;
6794 const w = _w || 5;
6795 const pB2 = window.bn128.alloc(32*6);
6796 window.bn128.g2_zero(pB2);
6797 window.bn128.g2_multiexp(
6798 window.pWitness,
6799 window.pPointsB2,
6800 n,
6801 w,
6802 pB2
6803 );
6804 window.bn128.g2_affine(pB2, pB2);
6805 window.bn128.g2_fromMontgomery(pB2, pB2);
6806 const res = window.bn128.g2_getPoint(pB2);
6807 console.log(res[0][0].toString());
6808 console.log(res[0][1].toString());
6809 console.log(res[1][0].toString());
6810 console.log(res[1][1].toString());
6811 console.log(res[2][0].toString());
6812 console.log(res[2][1].toString());
6813};
6814
6815
6816window.test = function() {
6817
6818 const t = window.F1.test_F1(100000000);
6819 document.getElementById("result").innerHTML = t;
6820};
6821
6822
6823},{"./index.js":1,"big-integer":2}],24:[function(require,module,exports){
6824(function (global){
6825'use strict';
6826
6827// compare and isBuffer taken from https://github.com/feross/buffer/blob/680e9e5e488f22aac27599a57dc844a6315928dd/index.js
6828// original notice:
6829
6830/*!
6831 * The buffer module from node.js, for the browser.
6832 *
6833 * @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
6834 * @license MIT
6835 */
6836function compare(a, b) {
6837 if (a === b) {
6838 return 0;
6839 }
6840
6841 var x = a.length;
6842 var y = b.length;
6843
6844 for (var i = 0, len = Math.min(x, y); i < len; ++i) {
6845 if (a[i] !== b[i]) {
6846 x = a[i];
6847 y = b[i];
6848 break;
6849 }
6850 }
6851
6852 if (x < y) {
6853 return -1;
6854 }
6855 if (y < x) {
6856 return 1;
6857 }
6858 return 0;
6859}
6860function isBuffer(b) {
6861 if (global.Buffer && typeof global.Buffer.isBuffer === 'function') {
6862 return global.Buffer.isBuffer(b);
6863 }
6864 return !!(b != null && b._isBuffer);
6865}
6866
6867// based on node assert, original notice:
6868
6869// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
6870//
6871// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
6872//
6873// Originally from narwhal.js (http://narwhaljs.org)
6874// Copyright (c) 2009 Thomas Robinson <280north.com>
6875//
6876// Permission is hereby granted, free of charge, to any person obtaining a copy
6877// of this software and associated documentation files (the 'Software'), to
6878// deal in the Software without restriction, including without limitation the
6879// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
6880// sell copies of the Software, and to permit persons to whom the Software is
6881// furnished to do so, subject to the following conditions:
6882//
6883// The above copyright notice and this permission notice shall be included in
6884// all copies or substantial portions of the Software.
6885//
6886// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
6887// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6888// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
6889// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
6890// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
6891// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
6892
6893var util = require('util/');
6894var hasOwn = Object.prototype.hasOwnProperty;
6895var pSlice = Array.prototype.slice;
6896var functionsHaveNames = (function () {
6897 return function foo() {}.name === 'foo';
6898}());
6899function pToString (obj) {
6900 return Object.prototype.toString.call(obj);
6901}
6902function isView(arrbuf) {
6903 if (isBuffer(arrbuf)) {
6904 return false;
6905 }
6906 if (typeof global.ArrayBuffer !== 'function') {
6907 return false;
6908 }
6909 if (typeof ArrayBuffer.isView === 'function') {
6910 return ArrayBuffer.isView(arrbuf);
6911 }
6912 if (!arrbuf) {
6913 return false;
6914 }
6915 if (arrbuf instanceof DataView) {
6916 return true;
6917 }
6918 if (arrbuf.buffer && arrbuf.buffer instanceof ArrayBuffer) {
6919 return true;
6920 }
6921 return false;
6922}
6923// 1. The assert module provides functions that throw
6924// AssertionError's when particular conditions are not met. The
6925// assert module must conform to the following interface.
6926
6927var assert = module.exports = ok;
6928
6929// 2. The AssertionError is defined in assert.
6930// new assert.AssertionError({ message: message,
6931// actual: actual,
6932// expected: expected })
6933
6934var regex = /\s*function\s+([^\(\s]*)\s*/;
6935// based on https://github.com/ljharb/function.prototype.name/blob/adeeeec8bfcc6068b187d7d9fb3d5bb1d3a30899/implementation.js
6936function getName(func) {
6937 if (!util.isFunction(func)) {
6938 return;
6939 }
6940 if (functionsHaveNames) {
6941 return func.name;
6942 }
6943 var str = func.toString();
6944 var match = str.match(regex);
6945 return match && match[1];
6946}
6947assert.AssertionError = function AssertionError(options) {
6948 this.name = 'AssertionError';
6949 this.actual = options.actual;
6950 this.expected = options.expected;
6951 this.operator = options.operator;
6952 if (options.message) {
6953 this.message = options.message;
6954 this.generatedMessage = false;
6955 } else {
6956 this.message = getMessage(this);
6957 this.generatedMessage = true;
6958 }
6959 var stackStartFunction = options.stackStartFunction || fail;
6960 if (Error.captureStackTrace) {
6961 Error.captureStackTrace(this, stackStartFunction);
6962 } else {
6963 // non v8 browsers so we can have a stacktrace
6964 var err = new Error();
6965 if (err.stack) {
6966 var out = err.stack;
6967
6968 // try to strip useless frames
6969 var fn_name = getName(stackStartFunction);
6970 var idx = out.indexOf('\n' + fn_name);
6971 if (idx >= 0) {
6972 // once we have located the function frame
6973 // we need to strip out everything before it (and its line)
6974 var next_line = out.indexOf('\n', idx + 1);
6975 out = out.substring(next_line + 1);
6976 }
6977
6978 this.stack = out;
6979 }
6980 }
6981};
6982
6983// assert.AssertionError instanceof Error
6984util.inherits(assert.AssertionError, Error);
6985
6986function truncate(s, n) {
6987 if (typeof s === 'string') {
6988 return s.length < n ? s : s.slice(0, n);
6989 } else {
6990 return s;
6991 }
6992}
6993function inspect(something) {
6994 if (functionsHaveNames || !util.isFunction(something)) {
6995 return util.inspect(something);
6996 }
6997 var rawname = getName(something);
6998 var name = rawname ? ': ' + rawname : '';
6999 return '[Function' + name + ']';
7000}
7001function getMessage(self) {
7002 return truncate(inspect(self.actual), 128) + ' ' +
7003 self.operator + ' ' +
7004 truncate(inspect(self.expected), 128);
7005}
7006
7007// At present only the three keys mentioned above are used and
7008// understood by the spec. Implementations or sub modules can pass
7009// other keys to the AssertionError's constructor - they will be
7010// ignored.
7011
7012// 3. All of the following functions must throw an AssertionError
7013// when a corresponding condition is not met, with a message that
7014// may be undefined if not provided. All assertion methods provide
7015// both the actual and expected values to the assertion error for
7016// display purposes.
7017
7018function fail(actual, expected, message, operator, stackStartFunction) {
7019 throw new assert.AssertionError({
7020 message: message,
7021 actual: actual,
7022 expected: expected,
7023 operator: operator,
7024 stackStartFunction: stackStartFunction
7025 });
7026}
7027
7028// EXTENSION! allows for well behaved errors defined elsewhere.
7029assert.fail = fail;
7030
7031// 4. Pure assertion tests whether a value is truthy, as determined
7032// by !!guard.
7033// assert.ok(guard, message_opt);
7034// This statement is equivalent to assert.equal(true, !!guard,
7035// message_opt);. To test strictly for the value true, use
7036// assert.strictEqual(true, guard, message_opt);.
7037
7038function ok(value, message) {
7039 if (!value) fail(value, true, message, '==', assert.ok);
7040}
7041assert.ok = ok;
7042
7043// 5. The equality assertion tests shallow, coercive equality with
7044// ==.
7045// assert.equal(actual, expected, message_opt);
7046
7047assert.equal = function equal(actual, expected, message) {
7048 if (actual != expected) fail(actual, expected, message, '==', assert.equal);
7049};
7050
7051// 6. The non-equality assertion tests for whether two objects are not equal
7052// with != assert.notEqual(actual, expected, message_opt);
7053
7054assert.notEqual = function notEqual(actual, expected, message) {
7055 if (actual == expected) {
7056 fail(actual, expected, message, '!=', assert.notEqual);
7057 }
7058};
7059
7060// 7. The equivalence assertion tests a deep equality relation.
7061// assert.deepEqual(actual, expected, message_opt);
7062
7063assert.deepEqual = function deepEqual(actual, expected, message) {
7064 if (!_deepEqual(actual, expected, false)) {
7065 fail(actual, expected, message, 'deepEqual', assert.deepEqual);
7066 }
7067};
7068
7069assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) {
7070 if (!_deepEqual(actual, expected, true)) {
7071 fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual);
7072 }
7073};
7074
7075function _deepEqual(actual, expected, strict, memos) {
7076 // 7.1. All identical values are equivalent, as determined by ===.
7077 if (actual === expected) {
7078 return true;
7079 } else if (isBuffer(actual) && isBuffer(expected)) {
7080 return compare(actual, expected) === 0;
7081
7082 // 7.2. If the expected value is a Date object, the actual value is
7083 // equivalent if it is also a Date object that refers to the same time.
7084 } else if (util.isDate(actual) && util.isDate(expected)) {
7085 return actual.getTime() === expected.getTime();
7086
7087 // 7.3 If the expected value is a RegExp object, the actual value is
7088 // equivalent if it is also a RegExp object with the same source and
7089 // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
7090 } else if (util.isRegExp(actual) && util.isRegExp(expected)) {
7091 return actual.source === expected.source &&
7092 actual.global === expected.global &&
7093 actual.multiline === expected.multiline &&
7094 actual.lastIndex === expected.lastIndex &&
7095 actual.ignoreCase === expected.ignoreCase;
7096
7097 // 7.4. Other pairs that do not both pass typeof value == 'object',
7098 // equivalence is determined by ==.
7099 } else if ((actual === null || typeof actual !== 'object') &&
7100 (expected === null || typeof expected !== 'object')) {
7101 return strict ? actual === expected : actual == expected;
7102
7103 // If both values are instances of typed arrays, wrap their underlying
7104 // ArrayBuffers in a Buffer each to increase performance
7105 // This optimization requires the arrays to have the same type as checked by
7106 // Object.prototype.toString (aka pToString). Never perform binary
7107 // comparisons for Float*Arrays, though, since e.g. +0 === -0 but their
7108 // bit patterns are not identical.
7109 } else if (isView(actual) && isView(expected) &&
7110 pToString(actual) === pToString(expected) &&
7111 !(actual instanceof Float32Array ||
7112 actual instanceof Float64Array)) {
7113 return compare(new Uint8Array(actual.buffer),
7114 new Uint8Array(expected.buffer)) === 0;
7115
7116 // 7.5 For all other Object pairs, including Array objects, equivalence is
7117 // determined by having the same number of owned properties (as verified
7118 // with Object.prototype.hasOwnProperty.call), the same set of keys
7119 // (although not necessarily the same order), equivalent values for every
7120 // corresponding key, and an identical 'prototype' property. Note: this
7121 // accounts for both named and indexed properties on Arrays.
7122 } else if (isBuffer(actual) !== isBuffer(expected)) {
7123 return false;
7124 } else {
7125 memos = memos || {actual: [], expected: []};
7126
7127 var actualIndex = memos.actual.indexOf(actual);
7128 if (actualIndex !== -1) {
7129 if (actualIndex === memos.expected.indexOf(expected)) {
7130 return true;
7131 }
7132 }
7133
7134 memos.actual.push(actual);
7135 memos.expected.push(expected);
7136
7137 return objEquiv(actual, expected, strict, memos);
7138 }
7139}
7140
7141function isArguments(object) {
7142 return Object.prototype.toString.call(object) == '[object Arguments]';
7143}
7144
7145function objEquiv(a, b, strict, actualVisitedObjects) {
7146 if (a === null || a === undefined || b === null || b === undefined)
7147 return false;
7148 // if one is a primitive, the other must be same
7149 if (util.isPrimitive(a) || util.isPrimitive(b))
7150 return a === b;
7151 if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b))
7152 return false;
7153 var aIsArgs = isArguments(a);
7154 var bIsArgs = isArguments(b);
7155 if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
7156 return false;
7157 if (aIsArgs) {
7158 a = pSlice.call(a);
7159 b = pSlice.call(b);
7160 return _deepEqual(a, b, strict);
7161 }
7162 var ka = objectKeys(a);
7163 var kb = objectKeys(b);
7164 var key, i;
7165 // having the same number of owned properties (keys incorporates
7166 // hasOwnProperty)
7167 if (ka.length !== kb.length)
7168 return false;
7169 //the same set of keys (although not necessarily the same order),
7170 ka.sort();
7171 kb.sort();
7172 //~~~cheap key test
7173 for (i = ka.length - 1; i >= 0; i--) {
7174 if (ka[i] !== kb[i])
7175 return false;
7176 }
7177 //equivalent values for every corresponding key, and
7178 //~~~possibly expensive deep test
7179 for (i = ka.length - 1; i >= 0; i--) {
7180 key = ka[i];
7181 if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects))
7182 return false;
7183 }
7184 return true;
7185}
7186
7187// 8. The non-equivalence assertion tests for any deep inequality.
7188// assert.notDeepEqual(actual, expected, message_opt);
7189
7190assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
7191 if (_deepEqual(actual, expected, false)) {
7192 fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
7193 }
7194};
7195
7196assert.notDeepStrictEqual = notDeepStrictEqual;
7197function notDeepStrictEqual(actual, expected, message) {
7198 if (_deepEqual(actual, expected, true)) {
7199 fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual);
7200 }
7201}
7202
7203
7204// 9. The strict equality assertion tests strict equality, as determined by ===.
7205// assert.strictEqual(actual, expected, message_opt);
7206
7207assert.strictEqual = function strictEqual(actual, expected, message) {
7208 if (actual !== expected) {
7209 fail(actual, expected, message, '===', assert.strictEqual);
7210 }
7211};
7212
7213// 10. The strict non-equality assertion tests for strict inequality, as
7214// determined by !==. assert.notStrictEqual(actual, expected, message_opt);
7215
7216assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
7217 if (actual === expected) {
7218 fail(actual, expected, message, '!==', assert.notStrictEqual);
7219 }
7220};
7221
7222function expectedException(actual, expected) {
7223 if (!actual || !expected) {
7224 return false;
7225 }
7226
7227 if (Object.prototype.toString.call(expected) == '[object RegExp]') {
7228 return expected.test(actual);
7229 }
7230
7231 try {
7232 if (actual instanceof expected) {
7233 return true;
7234 }
7235 } catch (e) {
7236 // Ignore. The instanceof check doesn't work for arrow functions.
7237 }
7238
7239 if (Error.isPrototypeOf(expected)) {
7240 return false;
7241 }
7242
7243 return expected.call({}, actual) === true;
7244}
7245
7246function _tryBlock(block) {
7247 var error;
7248 try {
7249 block();
7250 } catch (e) {
7251 error = e;
7252 }
7253 return error;
7254}
7255
7256function _throws(shouldThrow, block, expected, message) {
7257 var actual;
7258
7259 if (typeof block !== 'function') {
7260 throw new TypeError('"block" argument must be a function');
7261 }
7262
7263 if (typeof expected === 'string') {
7264 message = expected;
7265 expected = null;
7266 }
7267
7268 actual = _tryBlock(block);
7269
7270 message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
7271 (message ? ' ' + message : '.');
7272
7273 if (shouldThrow && !actual) {
7274 fail(actual, expected, 'Missing expected exception' + message);
7275 }
7276
7277 var userProvidedMessage = typeof message === 'string';
7278 var isUnwantedException = !shouldThrow && util.isError(actual);
7279 var isUnexpectedException = !shouldThrow && actual && !expected;
7280
7281 if ((isUnwantedException &&
7282 userProvidedMessage &&
7283 expectedException(actual, expected)) ||
7284 isUnexpectedException) {
7285 fail(actual, expected, 'Got unwanted exception' + message);
7286 }
7287
7288 if ((shouldThrow && actual && expected &&
7289 !expectedException(actual, expected)) || (!shouldThrow && actual)) {
7290 throw actual;
7291 }
7292}
7293
7294// 11. Expected to throw an error:
7295// assert.throws(block, Error_opt, message_opt);
7296
7297assert.throws = function(block, /*optional*/error, /*optional*/message) {
7298 _throws(true, block, error, message);
7299};
7300
7301// EXTENSION! This is annoying to write outside this module.
7302assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
7303 _throws(false, block, error, message);
7304};
7305
7306assert.ifError = function(err) { if (err) throw err; };
7307
7308var objectKeys = Object.keys || function (obj) {
7309 var keys = [];
7310 for (var key in obj) {
7311 if (hasOwn.call(obj, key)) keys.push(key);
7312 }
7313 return keys;
7314};
7315
7316}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
7317},{"util/":27}],25:[function(require,module,exports){
7318if (typeof Object.create === 'function') {
7319 // implementation from standard node.js 'util' module
7320 module.exports = function inherits(ctor, superCtor) {
7321 ctor.super_ = superCtor
7322 ctor.prototype = Object.create(superCtor.prototype, {
7323 constructor: {
7324 value: ctor,
7325 enumerable: false,
7326 writable: true,
7327 configurable: true
7328 }
7329 });
7330 };
7331} else {
7332 // old school shim for old browsers
7333 module.exports = function inherits(ctor, superCtor) {
7334 ctor.super_ = superCtor
7335 var TempCtor = function () {}
7336 TempCtor.prototype = superCtor.prototype
7337 ctor.prototype = new TempCtor()
7338 ctor.prototype.constructor = ctor
7339 }
7340}
7341
7342},{}],26:[function(require,module,exports){
7343module.exports = function isBuffer(arg) {
7344 return arg && typeof arg === 'object'
7345 && typeof arg.copy === 'function'
7346 && typeof arg.fill === 'function'
7347 && typeof arg.readUInt8 === 'function';
7348}
7349},{}],27:[function(require,module,exports){
7350(function (process,global){
7351// Copyright Joyent, Inc. and other Node contributors.
7352//
7353// Permission is hereby granted, free of charge, to any person obtaining a
7354// copy of this software and associated documentation files (the
7355// "Software"), to deal in the Software without restriction, including
7356// without limitation the rights to use, copy, modify, merge, publish,
7357// distribute, sublicense, and/or sell copies of the Software, and to permit
7358// persons to whom the Software is furnished to do so, subject to the
7359// following conditions:
7360//
7361// The above copyright notice and this permission notice shall be included
7362// in all copies or substantial portions of the Software.
7363//
7364// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
7365// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
7366// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
7367// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
7368// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
7369// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
7370// USE OR OTHER DEALINGS IN THE SOFTWARE.
7371
7372var formatRegExp = /%[sdj%]/g;
7373exports.format = function(f) {
7374 if (!isString(f)) {
7375 var objects = [];
7376 for (var i = 0; i < arguments.length; i++) {
7377 objects.push(inspect(arguments[i]));
7378 }
7379 return objects.join(' ');
7380 }
7381
7382 var i = 1;
7383 var args = arguments;
7384 var len = args.length;
7385 var str = String(f).replace(formatRegExp, function(x) {
7386 if (x === '%%') return '%';
7387 if (i >= len) return x;
7388 switch (x) {
7389 case '%s': return String(args[i++]);
7390 case '%d': return Number(args[i++]);
7391 case '%j':
7392 try {
7393 return JSON.stringify(args[i++]);
7394 } catch (_) {
7395 return '[Circular]';
7396 }
7397 default:
7398 return x;
7399 }
7400 });
7401 for (var x = args[i]; i < len; x = args[++i]) {
7402 if (isNull(x) || !isObject(x)) {
7403 str += ' ' + x;
7404 } else {
7405 str += ' ' + inspect(x);
7406 }
7407 }
7408 return str;
7409};
7410
7411
7412// Mark that a method should not be used.
7413// Returns a modified function which warns once by default.
7414// If --no-deprecation is set, then it is a no-op.
7415exports.deprecate = function(fn, msg) {
7416 // Allow for deprecating things in the process of starting up.
7417 if (isUndefined(global.process)) {
7418 return function() {
7419 return exports.deprecate(fn, msg).apply(this, arguments);
7420 };
7421 }
7422
7423 if (process.noDeprecation === true) {
7424 return fn;
7425 }
7426
7427 var warned = false;
7428 function deprecated() {
7429 if (!warned) {
7430 if (process.throwDeprecation) {
7431 throw new Error(msg);
7432 } else if (process.traceDeprecation) {
7433 console.trace(msg);
7434 } else {
7435 console.error(msg);
7436 }
7437 warned = true;
7438 }
7439 return fn.apply(this, arguments);
7440 }
7441
7442 return deprecated;
7443};
7444
7445
7446var debugs = {};
7447var debugEnviron;
7448exports.debuglog = function(set) {
7449 if (isUndefined(debugEnviron))
7450 debugEnviron = process.env.NODE_DEBUG || '';
7451 set = set.toUpperCase();
7452 if (!debugs[set]) {
7453 if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
7454 var pid = process.pid;
7455 debugs[set] = function() {
7456 var msg = exports.format.apply(exports, arguments);
7457 console.error('%s %d: %s', set, pid, msg);
7458 };
7459 } else {
7460 debugs[set] = function() {};
7461 }
7462 }
7463 return debugs[set];
7464};
7465
7466
7467/**
7468 * Echos the value of a value. Trys to print the value out
7469 * in the best way possible given the different types.
7470 *
7471 * @param {Object} obj The object to print out.
7472 * @param {Object} opts Optional options object that alters the output.
7473 */
7474/* legacy: obj, showHidden, depth, colors*/
7475function inspect(obj, opts) {
7476 // default options
7477 var ctx = {
7478 seen: [],
7479 stylize: stylizeNoColor
7480 };
7481 // legacy...
7482 if (arguments.length >= 3) ctx.depth = arguments[2];
7483 if (arguments.length >= 4) ctx.colors = arguments[3];
7484 if (isBoolean(opts)) {
7485 // legacy...
7486 ctx.showHidden = opts;
7487 } else if (opts) {
7488 // got an "options" object
7489 exports._extend(ctx, opts);
7490 }
7491 // set default options
7492 if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
7493 if (isUndefined(ctx.depth)) ctx.depth = 2;
7494 if (isUndefined(ctx.colors)) ctx.colors = false;
7495 if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
7496 if (ctx.colors) ctx.stylize = stylizeWithColor;
7497 return formatValue(ctx, obj, ctx.depth);
7498}
7499exports.inspect = inspect;
7500
7501
7502// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
7503inspect.colors = {
7504 'bold' : [1, 22],
7505 'italic' : [3, 23],
7506 'underline' : [4, 24],
7507 'inverse' : [7, 27],
7508 'white' : [37, 39],
7509 'grey' : [90, 39],
7510 'black' : [30, 39],
7511 'blue' : [34, 39],
7512 'cyan' : [36, 39],
7513 'green' : [32, 39],
7514 'magenta' : [35, 39],
7515 'red' : [31, 39],
7516 'yellow' : [33, 39]
7517};
7518
7519// Don't use 'blue' not visible on cmd.exe
7520inspect.styles = {
7521 'special': 'cyan',
7522 'number': 'yellow',
7523 'boolean': 'yellow',
7524 'undefined': 'grey',
7525 'null': 'bold',
7526 'string': 'green',
7527 'date': 'magenta',
7528 // "name": intentionally not styling
7529 'regexp': 'red'
7530};
7531
7532
7533function stylizeWithColor(str, styleType) {
7534 var style = inspect.styles[styleType];
7535
7536 if (style) {
7537 return '\u001b[' + inspect.colors[style][0] + 'm' + str +
7538 '\u001b[' + inspect.colors[style][1] + 'm';
7539 } else {
7540 return str;
7541 }
7542}
7543
7544
7545function stylizeNoColor(str, styleType) {
7546 return str;
7547}
7548
7549
7550function arrayToHash(array) {
7551 var hash = {};
7552
7553 array.forEach(function(val, idx) {
7554 hash[val] = true;
7555 });
7556
7557 return hash;
7558}
7559
7560
7561function formatValue(ctx, value, recurseTimes) {
7562 // Provide a hook for user-specified inspect functions.
7563 // Check that value is an object with an inspect function on it
7564 if (ctx.customInspect &&
7565 value &&
7566 isFunction(value.inspect) &&
7567 // Filter out the util module, it's inspect function is special
7568 value.inspect !== exports.inspect &&
7569 // Also filter out any prototype objects using the circular check.
7570 !(value.constructor && value.constructor.prototype === value)) {
7571 var ret = value.inspect(recurseTimes, ctx);
7572 if (!isString(ret)) {
7573 ret = formatValue(ctx, ret, recurseTimes);
7574 }
7575 return ret;
7576 }
7577
7578 // Primitive types cannot have properties
7579 var primitive = formatPrimitive(ctx, value);
7580 if (primitive) {
7581 return primitive;
7582 }
7583
7584 // Look up the keys of the object.
7585 var keys = Object.keys(value);
7586 var visibleKeys = arrayToHash(keys);
7587
7588 if (ctx.showHidden) {
7589 keys = Object.getOwnPropertyNames(value);
7590 }
7591
7592 // IE doesn't make error fields non-enumerable
7593 // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
7594 if (isError(value)
7595 && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
7596 return formatError(value);
7597 }
7598
7599 // Some type of object without properties can be shortcutted.
7600 if (keys.length === 0) {
7601 if (isFunction(value)) {
7602 var name = value.name ? ': ' + value.name : '';
7603 return ctx.stylize('[Function' + name + ']', 'special');
7604 }
7605 if (isRegExp(value)) {
7606 return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
7607 }
7608 if (isDate(value)) {
7609 return ctx.stylize(Date.prototype.toString.call(value), 'date');
7610 }
7611 if (isError(value)) {
7612 return formatError(value);
7613 }
7614 }
7615
7616 var base = '', array = false, braces = ['{', '}'];
7617
7618 // Make Array say that they are Array
7619 if (isArray(value)) {
7620 array = true;
7621 braces = ['[', ']'];
7622 }
7623
7624 // Make functions say that they are functions
7625 if (isFunction(value)) {
7626 var n = value.name ? ': ' + value.name : '';
7627 base = ' [Function' + n + ']';
7628 }
7629
7630 // Make RegExps say that they are RegExps
7631 if (isRegExp(value)) {
7632 base = ' ' + RegExp.prototype.toString.call(value);
7633 }
7634
7635 // Make dates with properties first say the date
7636 if (isDate(value)) {
7637 base = ' ' + Date.prototype.toUTCString.call(value);
7638 }
7639
7640 // Make error with message first say the error
7641 if (isError(value)) {
7642 base = ' ' + formatError(value);
7643 }
7644
7645 if (keys.length === 0 && (!array || value.length == 0)) {
7646 return braces[0] + base + braces[1];
7647 }
7648
7649 if (recurseTimes < 0) {
7650 if (isRegExp(value)) {
7651 return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
7652 } else {
7653 return ctx.stylize('[Object]', 'special');
7654 }
7655 }
7656
7657 ctx.seen.push(value);
7658
7659 var output;
7660 if (array) {
7661 output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
7662 } else {
7663 output = keys.map(function(key) {
7664 return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
7665 });
7666 }
7667
7668 ctx.seen.pop();
7669
7670 return reduceToSingleString(output, base, braces);
7671}
7672
7673
7674function formatPrimitive(ctx, value) {
7675 if (isUndefined(value))
7676 return ctx.stylize('undefined', 'undefined');
7677 if (isString(value)) {
7678 var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
7679 .replace(/'/g, "\\'")
7680 .replace(/\\"/g, '"') + '\'';
7681 return ctx.stylize(simple, 'string');
7682 }
7683 if (isNumber(value))
7684 return ctx.stylize('' + value, 'number');
7685 if (isBoolean(value))
7686 return ctx.stylize('' + value, 'boolean');
7687 // For some reason typeof null is "object", so special case here.
7688 if (isNull(value))
7689 return ctx.stylize('null', 'null');
7690}
7691
7692
7693function formatError(value) {
7694 return '[' + Error.prototype.toString.call(value) + ']';
7695}
7696
7697
7698function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
7699 var output = [];
7700 for (var i = 0, l = value.length; i < l; ++i) {
7701 if (hasOwnProperty(value, String(i))) {
7702 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
7703 String(i), true));
7704 } else {
7705 output.push('');
7706 }
7707 }
7708 keys.forEach(function(key) {
7709 if (!key.match(/^\d+$/)) {
7710 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
7711 key, true));
7712 }
7713 });
7714 return output;
7715}
7716
7717
7718function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
7719 var name, str, desc;
7720 desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
7721 if (desc.get) {
7722 if (desc.set) {
7723 str = ctx.stylize('[Getter/Setter]', 'special');
7724 } else {
7725 str = ctx.stylize('[Getter]', 'special');
7726 }
7727 } else {
7728 if (desc.set) {
7729 str = ctx.stylize('[Setter]', 'special');
7730 }
7731 }
7732 if (!hasOwnProperty(visibleKeys, key)) {
7733 name = '[' + key + ']';
7734 }
7735 if (!str) {
7736 if (ctx.seen.indexOf(desc.value) < 0) {
7737 if (isNull(recurseTimes)) {
7738 str = formatValue(ctx, desc.value, null);
7739 } else {
7740 str = formatValue(ctx, desc.value, recurseTimes - 1);
7741 }
7742 if (str.indexOf('\n') > -1) {
7743 if (array) {
7744 str = str.split('\n').map(function(line) {
7745 return ' ' + line;
7746 }).join('\n').substr(2);
7747 } else {
7748 str = '\n' + str.split('\n').map(function(line) {
7749 return ' ' + line;
7750 }).join('\n');
7751 }
7752 }
7753 } else {
7754 str = ctx.stylize('[Circular]', 'special');
7755 }
7756 }
7757 if (isUndefined(name)) {
7758 if (array && key.match(/^\d+$/)) {
7759 return str;
7760 }
7761 name = JSON.stringify('' + key);
7762 if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
7763 name = name.substr(1, name.length - 2);
7764 name = ctx.stylize(name, 'name');
7765 } else {
7766 name = name.replace(/'/g, "\\'")
7767 .replace(/\\"/g, '"')
7768 .replace(/(^"|"$)/g, "'");
7769 name = ctx.stylize(name, 'string');
7770 }
7771 }
7772
7773 return name + ': ' + str;
7774}
7775
7776
7777function reduceToSingleString(output, base, braces) {
7778 var numLinesEst = 0;
7779 var length = output.reduce(function(prev, cur) {
7780 numLinesEst++;
7781 if (cur.indexOf('\n') >= 0) numLinesEst++;
7782 return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
7783 }, 0);
7784
7785 if (length > 60) {
7786 return braces[0] +
7787 (base === '' ? '' : base + '\n ') +
7788 ' ' +
7789 output.join(',\n ') +
7790 ' ' +
7791 braces[1];
7792 }
7793
7794 return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
7795}
7796
7797
7798// NOTE: These type checking functions intentionally don't use `instanceof`
7799// because it is fragile and can be easily faked with `Object.create()`.
7800function isArray(ar) {
7801 return Array.isArray(ar);
7802}
7803exports.isArray = isArray;
7804
7805function isBoolean(arg) {
7806 return typeof arg === 'boolean';
7807}
7808exports.isBoolean = isBoolean;
7809
7810function isNull(arg) {
7811 return arg === null;
7812}
7813exports.isNull = isNull;
7814
7815function isNullOrUndefined(arg) {
7816 return arg == null;
7817}
7818exports.isNullOrUndefined = isNullOrUndefined;
7819
7820function isNumber(arg) {
7821 return typeof arg === 'number';
7822}
7823exports.isNumber = isNumber;
7824
7825function isString(arg) {
7826 return typeof arg === 'string';
7827}
7828exports.isString = isString;
7829
7830function isSymbol(arg) {
7831 return typeof arg === 'symbol';
7832}
7833exports.isSymbol = isSymbol;
7834
7835function isUndefined(arg) {
7836 return arg === void 0;
7837}
7838exports.isUndefined = isUndefined;
7839
7840function isRegExp(re) {
7841 return isObject(re) && objectToString(re) === '[object RegExp]';
7842}
7843exports.isRegExp = isRegExp;
7844
7845function isObject(arg) {
7846 return typeof arg === 'object' && arg !== null;
7847}
7848exports.isObject = isObject;
7849
7850function isDate(d) {
7851 return isObject(d) && objectToString(d) === '[object Date]';
7852}
7853exports.isDate = isDate;
7854
7855function isError(e) {
7856 return isObject(e) &&
7857 (objectToString(e) === '[object Error]' || e instanceof Error);
7858}
7859exports.isError = isError;
7860
7861function isFunction(arg) {
7862 return typeof arg === 'function';
7863}
7864exports.isFunction = isFunction;
7865
7866function isPrimitive(arg) {
7867 return arg === null ||
7868 typeof arg === 'boolean' ||
7869 typeof arg === 'number' ||
7870 typeof arg === 'string' ||
7871 typeof arg === 'symbol' || // ES6 symbol
7872 typeof arg === 'undefined';
7873}
7874exports.isPrimitive = isPrimitive;
7875
7876exports.isBuffer = require('./support/isBuffer');
7877
7878function objectToString(o) {
7879 return Object.prototype.toString.call(o);
7880}
7881
7882
7883function pad(n) {
7884 return n < 10 ? '0' + n.toString(10) : n.toString(10);
7885}
7886
7887
7888var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
7889 'Oct', 'Nov', 'Dec'];
7890
7891// 26 Feb 16:19:34
7892function timestamp() {
7893 var d = new Date();
7894 var time = [pad(d.getHours()),
7895 pad(d.getMinutes()),
7896 pad(d.getSeconds())].join(':');
7897 return [d.getDate(), months[d.getMonth()], time].join(' ');
7898}
7899
7900
7901// log is just a thin wrapper to console.log that prepends a timestamp
7902exports.log = function() {
7903 console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
7904};
7905
7906
7907/**
7908 * Inherit the prototype methods from one constructor into another.
7909 *
7910 * The Function.prototype.inherits from lang.js rewritten as a standalone
7911 * function (not on Function.prototype). NOTE: If this file is to be loaded
7912 * during bootstrapping this function needs to be rewritten using some native
7913 * functions as prototype setup using normal JavaScript does not work as
7914 * expected during bootstrapping (see mirror.js in r114903).
7915 *
7916 * @param {function} ctor Constructor function which needs to inherit the
7917 * prototype.
7918 * @param {function} superCtor Constructor function to inherit prototype from.
7919 */
7920exports.inherits = require('inherits');
7921
7922exports._extend = function(origin, add) {
7923 // Don't do anything if add isn't an object
7924 if (!add || !isObject(add)) return origin;
7925
7926 var keys = Object.keys(add);
7927 var i = keys.length;
7928 while (i--) {
7929 origin[keys[i]] = add[keys[i]];
7930 }
7931 return origin;
7932};
7933
7934function hasOwnProperty(obj, prop) {
7935 return Object.prototype.hasOwnProperty.call(obj, prop);
7936}
7937
7938}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
7939},{"./support/isBuffer":26,"_process":28,"inherits":25}],28:[function(require,module,exports){
7940// shim for using process in browser
7941var process = module.exports = {};
7942
7943// cached from whatever global is present so that test runners that stub it
7944// don't break things. But we need to wrap it in a try catch in case it is
7945// wrapped in strict mode code which doesn't define any globals. It's inside a
7946// function because try/catches deoptimize in certain engines.
7947
7948var cachedSetTimeout;
7949var cachedClearTimeout;
7950
7951function defaultSetTimout() {
7952 throw new Error('setTimeout has not been defined');
7953}
7954function defaultClearTimeout () {
7955 throw new Error('clearTimeout has not been defined');
7956}
7957(function () {
7958 try {
7959 if (typeof setTimeout === 'function') {
7960 cachedSetTimeout = setTimeout;
7961 } else {
7962 cachedSetTimeout = defaultSetTimout;
7963 }
7964 } catch (e) {
7965 cachedSetTimeout = defaultSetTimout;
7966 }
7967 try {
7968 if (typeof clearTimeout === 'function') {
7969 cachedClearTimeout = clearTimeout;
7970 } else {
7971 cachedClearTimeout = defaultClearTimeout;
7972 }
7973 } catch (e) {
7974 cachedClearTimeout = defaultClearTimeout;
7975 }
7976} ())
7977function runTimeout(fun) {
7978 if (cachedSetTimeout === setTimeout) {
7979 //normal enviroments in sane situations
7980 return setTimeout(fun, 0);
7981 }
7982 // if setTimeout wasn't available but was latter defined
7983 if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
7984 cachedSetTimeout = setTimeout;
7985 return setTimeout(fun, 0);
7986 }
7987 try {
7988 // when when somebody has screwed with setTimeout but no I.E. maddness
7989 return cachedSetTimeout(fun, 0);
7990 } catch(e){
7991 try {
7992 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
7993 return cachedSetTimeout.call(null, fun, 0);
7994 } catch(e){
7995 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
7996 return cachedSetTimeout.call(this, fun, 0);
7997 }
7998 }
7999
8000
8001}
8002function runClearTimeout(marker) {
8003 if (cachedClearTimeout === clearTimeout) {
8004 //normal enviroments in sane situations
8005 return clearTimeout(marker);
8006 }
8007 // if clearTimeout wasn't available but was latter defined
8008 if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
8009 cachedClearTimeout = clearTimeout;
8010 return clearTimeout(marker);
8011 }
8012 try {
8013 // when when somebody has screwed with setTimeout but no I.E. maddness
8014 return cachedClearTimeout(marker);
8015 } catch (e){
8016 try {
8017 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
8018 return cachedClearTimeout.call(null, marker);
8019 } catch (e){
8020 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
8021 // Some versions of I.E. have different rules for clearTimeout vs setTimeout
8022 return cachedClearTimeout.call(this, marker);
8023 }
8024 }
8025
8026
8027
8028}
8029var queue = [];
8030var draining = false;
8031var currentQueue;
8032var queueIndex = -1;
8033
8034function cleanUpNextTick() {
8035 if (!draining || !currentQueue) {
8036 return;
8037 }
8038 draining = false;
8039 if (currentQueue.length) {
8040 queue = currentQueue.concat(queue);
8041 } else {
8042 queueIndex = -1;
8043 }
8044 if (queue.length) {
8045 drainQueue();
8046 }
8047}
8048
8049function drainQueue() {
8050 if (draining) {
8051 return;
8052 }
8053 var timeout = runTimeout(cleanUpNextTick);
8054 draining = true;
8055
8056 var len = queue.length;
8057 while(len) {
8058 currentQueue = queue;
8059 queue = [];
8060 while (++queueIndex < len) {
8061 if (currentQueue) {
8062 currentQueue[queueIndex].run();
8063 }
8064 }
8065 queueIndex = -1;
8066 len = queue.length;
8067 }
8068 currentQueue = null;
8069 draining = false;
8070 runClearTimeout(timeout);
8071}
8072
8073process.nextTick = function (fun) {
8074 var args = new Array(arguments.length - 1);
8075 if (arguments.length > 1) {
8076 for (var i = 1; i < arguments.length; i++) {
8077 args[i - 1] = arguments[i];
8078 }
8079 }
8080 queue.push(new Item(fun, args));
8081 if (queue.length === 1 && !draining) {
8082 runTimeout(drainQueue);
8083 }
8084};
8085
8086// v8 likes predictible objects
8087function Item(fun, array) {
8088 this.fun = fun;
8089 this.array = array;
8090}
8091Item.prototype.run = function () {
8092 this.fun.apply(null, this.array);
8093};
8094process.title = 'browser';
8095process.browser = true;
8096process.env = {};
8097process.argv = [];
8098process.version = ''; // empty string to avoid regexp issues
8099process.versions = {};
8100
8101function noop() {}
8102
8103process.on = noop;
8104process.addListener = noop;
8105process.once = noop;
8106process.off = noop;
8107process.removeListener = noop;
8108process.removeAllListeners = noop;
8109process.emit = noop;
8110process.prependListener = noop;
8111process.prependOnceListener = noop;
8112
8113process.listeners = function (name) { return [] }
8114
8115process.binding = function (name) {
8116 throw new Error('process.binding is not supported');
8117};
8118
8119process.cwd = function () { return '/' };
8120process.chdir = function (dir) {
8121 throw new Error('process.chdir is not supported');
8122};
8123process.umask = function() { return 0; };
8124
8125},{}]},{},[23]);