Use BigInt if available
Jordi Baylina jordi@baylina.cat
Wed, 15 Aug 2018 09:59:18 +0200
5 files changed,
108 insertions(+),
5 deletions(-)
A
src/bigint.js
@@ -0,0 +1,78 @@
+/* global BigInt */ +const bigInt = require("big-integer"); + +if (typeof(BigInt) != "undefined") { + const wBigInt = BigInt; + wBigInt.prototype.modInv = function (q) { + let t = wBigInt.zero; + let r = q; + let newt = wBigInt.one; + let newr = this; + while (newr!=wBigInt.zero) { + let q = r/newr; + [t, newt] = [newt, t-q*newt]; + [r, newr] = [newr, r-q*newr]; + } + if (t<wBigInt.zero) t += q; + return t; + }; + + wBigInt.prototype.add = function(b) { + return this+b; + }; + + wBigInt.prototype.minus = function(b) { + return this-b; + }; + + wBigInt.prototype.times = function(b) { + return this*b; + }; + + wBigInt.prototype.mod = function(q) { + return this%q; + }; + + wBigInt.prototype.square = function() { + return this*this; + }; + + wBigInt.prototype.double = function() { + return this+this; + }; + + wBigInt.prototype.isOdd = function() { + return (this & wBigInt.one) == 1; + }; + + wBigInt.prototype.isZero = function() { + return (this == wBigInt.zero); + }; + + wBigInt.prototype.isNegative = function() { + return this < wBigInt.zero; + }; + + wBigInt.prototype.shiftRight = function(f) { + return this >> wBigInt(f); + }; + + wBigInt.prototype.greaterOrEquals = function(b) { + return this >= b; + }; + + wBigInt.prototype.lesserOrEquals = function(b) { + return this <= b; + }; + + wBigInt.prototype.equals = function(b) { + return this == b; + }; + + wBigInt.one = BigInt(1); + wBigInt.zero = BigInt(0); + + module.exports = wBigInt; +} else { + module.exports = bigInt; +}
M
src/bn128.js
→
src/bn128.js
@@ -1,7 +1,7 @@
-const bigInt = require("big-integer"); +const bigInt = require("./bigint.js"); const assert = require("assert"); -const F1Field = require("./f1field.js"); +const F1Field = require("./zqfield.js"); const F2Field = require("./f2field.js"); const F3Field = require("./f3field.js"); const GCurve = require("./gcurve.js");
M
src/f1field.js
→
src/zqfield.js
@@ -1,4 +1,4 @@
-const bigInt = require("big-integer"); +const bigInt = require("./bigint"); const fUtils = require("./futils.js"); class F1Field {
M
src/gcurve.js
→
src/gcurve.js
@@ -4,7 +4,7 @@ class GCurve {
constructor(F, g) { this.F = F; - this.g = F.copy(g); + this.g = [F.copy(g[0]), F.copy(g[1])]; if (this.g.length == 2) this.g[2] = this.F.one; this.zero = [this.F.zero, this.F.one, this.F.zero]; }
M
test/algebra.js
→
test/algebra.js
@@ -1,6 +1,6 @@
const chai = require("chai"); -const bigInt = require("big-integer"); +const bigInt = require("../src/bigint.js"); const BN128 = require("../src/BN128.js"); const assert = chai.assert;@@ -148,4 +148,29 @@
assert(bn128.F12.equals(res, bn128.F12.one)); }).timeout(10000); + it("Should match pairing 2", () => { + const bn128 = new BN128(); + + + const g1a = bn128.G1.mulEscalar(bn128.G1.g, 25); + const g2a = bn128.G2.mulEscalar(bn128.G2.g, 30); + + const g1b = bn128.G1.mulEscalar(bn128.G1.g, 30); + const g2b = bn128.G2.mulEscalar(bn128.G2.g, 25); + + + const pre1a = bn128.precomputeG1(g1a); + const pre2a = bn128.precomputeG2(g2a); + const pre1b = bn128.precomputeG1(g1b); + const pre2b = bn128.precomputeG2(g2b); + + const r1 = bn128.millerLoop(pre1a, pre2a); + const r2 = bn128.millerLoop(pre1b, pre2b); + + const rbe = bn128.F12.mul(r1, bn128.F12.inverse(r2)); + + const res = bn128.finalExponentiation(rbe); + + assert(bn128.F12.equals(res, bn128.F12.one)); + }).timeout(10000); });