forked from enviPath/enviPy
Current Dev State
This commit is contained in:
375
static/js/ketcher2/node_modules/elliptic/lib/elliptic/curve/base.js
generated
vendored
Normal file
375
static/js/ketcher2/node_modules/elliptic/lib/elliptic/curve/base.js
generated
vendored
Normal file
@ -0,0 +1,375 @@
|
||||
'use strict';
|
||||
|
||||
var BN = require('bn.js');
|
||||
var elliptic = require('../../elliptic');
|
||||
var utils = elliptic.utils;
|
||||
var getNAF = utils.getNAF;
|
||||
var getJSF = utils.getJSF;
|
||||
var assert = utils.assert;
|
||||
|
||||
function BaseCurve(type, conf) {
|
||||
this.type = type;
|
||||
this.p = new BN(conf.p, 16);
|
||||
|
||||
// Use Montgomery, when there is no fast reduction for the prime
|
||||
this.red = conf.prime ? BN.red(conf.prime) : BN.mont(this.p);
|
||||
|
||||
// Useful for many curves
|
||||
this.zero = new BN(0).toRed(this.red);
|
||||
this.one = new BN(1).toRed(this.red);
|
||||
this.two = new BN(2).toRed(this.red);
|
||||
|
||||
// Curve configuration, optional
|
||||
this.n = conf.n && new BN(conf.n, 16);
|
||||
this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed);
|
||||
|
||||
// Temporary arrays
|
||||
this._wnafT1 = new Array(4);
|
||||
this._wnafT2 = new Array(4);
|
||||
this._wnafT3 = new Array(4);
|
||||
this._wnafT4 = new Array(4);
|
||||
|
||||
// Generalized Greg Maxwell's trick
|
||||
var adjustCount = this.n && this.p.div(this.n);
|
||||
if (!adjustCount || adjustCount.cmpn(100) > 0) {
|
||||
this.redN = null;
|
||||
} else {
|
||||
this._maxwellTrick = true;
|
||||
this.redN = this.n.toRed(this.red);
|
||||
}
|
||||
}
|
||||
module.exports = BaseCurve;
|
||||
|
||||
BaseCurve.prototype.point = function point() {
|
||||
throw new Error('Not implemented');
|
||||
};
|
||||
|
||||
BaseCurve.prototype.validate = function validate() {
|
||||
throw new Error('Not implemented');
|
||||
};
|
||||
|
||||
BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) {
|
||||
assert(p.precomputed);
|
||||
var doubles = p._getDoubles();
|
||||
|
||||
var naf = getNAF(k, 1);
|
||||
var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1);
|
||||
I /= 3;
|
||||
|
||||
// Translate into more windowed form
|
||||
var repr = [];
|
||||
for (var j = 0; j < naf.length; j += doubles.step) {
|
||||
var nafW = 0;
|
||||
for (var k = j + doubles.step - 1; k >= j; k--)
|
||||
nafW = (nafW << 1) + naf[k];
|
||||
repr.push(nafW);
|
||||
}
|
||||
|
||||
var a = this.jpoint(null, null, null);
|
||||
var b = this.jpoint(null, null, null);
|
||||
for (var i = I; i > 0; i--) {
|
||||
for (var j = 0; j < repr.length; j++) {
|
||||
var nafW = repr[j];
|
||||
if (nafW === i)
|
||||
b = b.mixedAdd(doubles.points[j]);
|
||||
else if (nafW === -i)
|
||||
b = b.mixedAdd(doubles.points[j].neg());
|
||||
}
|
||||
a = a.add(b);
|
||||
}
|
||||
return a.toP();
|
||||
};
|
||||
|
||||
BaseCurve.prototype._wnafMul = function _wnafMul(p, k) {
|
||||
var w = 4;
|
||||
|
||||
// Precompute window
|
||||
var nafPoints = p._getNAFPoints(w);
|
||||
w = nafPoints.wnd;
|
||||
var wnd = nafPoints.points;
|
||||
|
||||
// Get NAF form
|
||||
var naf = getNAF(k, w);
|
||||
|
||||
// Add `this`*(N+1) for every w-NAF index
|
||||
var acc = this.jpoint(null, null, null);
|
||||
for (var i = naf.length - 1; i >= 0; i--) {
|
||||
// Count zeroes
|
||||
for (var k = 0; i >= 0 && naf[i] === 0; i--)
|
||||
k++;
|
||||
if (i >= 0)
|
||||
k++;
|
||||
acc = acc.dblp(k);
|
||||
|
||||
if (i < 0)
|
||||
break;
|
||||
var z = naf[i];
|
||||
assert(z !== 0);
|
||||
if (p.type === 'affine') {
|
||||
// J +- P
|
||||
if (z > 0)
|
||||
acc = acc.mixedAdd(wnd[(z - 1) >> 1]);
|
||||
else
|
||||
acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg());
|
||||
} else {
|
||||
// J +- J
|
||||
if (z > 0)
|
||||
acc = acc.add(wnd[(z - 1) >> 1]);
|
||||
else
|
||||
acc = acc.add(wnd[(-z - 1) >> 1].neg());
|
||||
}
|
||||
}
|
||||
return p.type === 'affine' ? acc.toP() : acc;
|
||||
};
|
||||
|
||||
BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW,
|
||||
points,
|
||||
coeffs,
|
||||
len,
|
||||
jacobianResult) {
|
||||
var wndWidth = this._wnafT1;
|
||||
var wnd = this._wnafT2;
|
||||
var naf = this._wnafT3;
|
||||
|
||||
// Fill all arrays
|
||||
var max = 0;
|
||||
for (var i = 0; i < len; i++) {
|
||||
var p = points[i];
|
||||
var nafPoints = p._getNAFPoints(defW);
|
||||
wndWidth[i] = nafPoints.wnd;
|
||||
wnd[i] = nafPoints.points;
|
||||
}
|
||||
|
||||
// Comb small window NAFs
|
||||
for (var i = len - 1; i >= 1; i -= 2) {
|
||||
var a = i - 1;
|
||||
var b = i;
|
||||
if (wndWidth[a] !== 1 || wndWidth[b] !== 1) {
|
||||
naf[a] = getNAF(coeffs[a], wndWidth[a]);
|
||||
naf[b] = getNAF(coeffs[b], wndWidth[b]);
|
||||
max = Math.max(naf[a].length, max);
|
||||
max = Math.max(naf[b].length, max);
|
||||
continue;
|
||||
}
|
||||
|
||||
var comb = [
|
||||
points[a], /* 1 */
|
||||
null, /* 3 */
|
||||
null, /* 5 */
|
||||
points[b] /* 7 */
|
||||
];
|
||||
|
||||
// Try to avoid Projective points, if possible
|
||||
if (points[a].y.cmp(points[b].y) === 0) {
|
||||
comb[1] = points[a].add(points[b]);
|
||||
comb[2] = points[a].toJ().mixedAdd(points[b].neg());
|
||||
} else if (points[a].y.cmp(points[b].y.redNeg()) === 0) {
|
||||
comb[1] = points[a].toJ().mixedAdd(points[b]);
|
||||
comb[2] = points[a].add(points[b].neg());
|
||||
} else {
|
||||
comb[1] = points[a].toJ().mixedAdd(points[b]);
|
||||
comb[2] = points[a].toJ().mixedAdd(points[b].neg());
|
||||
}
|
||||
|
||||
var index = [
|
||||
-3, /* -1 -1 */
|
||||
-1, /* -1 0 */
|
||||
-5, /* -1 1 */
|
||||
-7, /* 0 -1 */
|
||||
0, /* 0 0 */
|
||||
7, /* 0 1 */
|
||||
5, /* 1 -1 */
|
||||
1, /* 1 0 */
|
||||
3 /* 1 1 */
|
||||
];
|
||||
|
||||
var jsf = getJSF(coeffs[a], coeffs[b]);
|
||||
max = Math.max(jsf[0].length, max);
|
||||
naf[a] = new Array(max);
|
||||
naf[b] = new Array(max);
|
||||
for (var j = 0; j < max; j++) {
|
||||
var ja = jsf[0][j] | 0;
|
||||
var jb = jsf[1][j] | 0;
|
||||
|
||||
naf[a][j] = index[(ja + 1) * 3 + (jb + 1)];
|
||||
naf[b][j] = 0;
|
||||
wnd[a] = comb;
|
||||
}
|
||||
}
|
||||
|
||||
var acc = this.jpoint(null, null, null);
|
||||
var tmp = this._wnafT4;
|
||||
for (var i = max; i >= 0; i--) {
|
||||
var k = 0;
|
||||
|
||||
while (i >= 0) {
|
||||
var zero = true;
|
||||
for (var j = 0; j < len; j++) {
|
||||
tmp[j] = naf[j][i] | 0;
|
||||
if (tmp[j] !== 0)
|
||||
zero = false;
|
||||
}
|
||||
if (!zero)
|
||||
break;
|
||||
k++;
|
||||
i--;
|
||||
}
|
||||
if (i >= 0)
|
||||
k++;
|
||||
acc = acc.dblp(k);
|
||||
if (i < 0)
|
||||
break;
|
||||
|
||||
for (var j = 0; j < len; j++) {
|
||||
var z = tmp[j];
|
||||
var p;
|
||||
if (z === 0)
|
||||
continue;
|
||||
else if (z > 0)
|
||||
p = wnd[j][(z - 1) >> 1];
|
||||
else if (z < 0)
|
||||
p = wnd[j][(-z - 1) >> 1].neg();
|
||||
|
||||
if (p.type === 'affine')
|
||||
acc = acc.mixedAdd(p);
|
||||
else
|
||||
acc = acc.add(p);
|
||||
}
|
||||
}
|
||||
// Zeroify references
|
||||
for (var i = 0; i < len; i++)
|
||||
wnd[i] = null;
|
||||
|
||||
if (jacobianResult)
|
||||
return acc;
|
||||
else
|
||||
return acc.toP();
|
||||
};
|
||||
|
||||
function BasePoint(curve, type) {
|
||||
this.curve = curve;
|
||||
this.type = type;
|
||||
this.precomputed = null;
|
||||
}
|
||||
BaseCurve.BasePoint = BasePoint;
|
||||
|
||||
BasePoint.prototype.eq = function eq(/*other*/) {
|
||||
throw new Error('Not implemented');
|
||||
};
|
||||
|
||||
BasePoint.prototype.validate = function validate() {
|
||||
return this.curve.validate(this);
|
||||
};
|
||||
|
||||
BaseCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
|
||||
bytes = utils.toArray(bytes, enc);
|
||||
|
||||
var len = this.p.byteLength();
|
||||
|
||||
// uncompressed, hybrid-odd, hybrid-even
|
||||
if ((bytes[0] === 0x04 || bytes[0] === 0x06 || bytes[0] === 0x07) &&
|
||||
bytes.length - 1 === 2 * len) {
|
||||
if (bytes[0] === 0x06)
|
||||
assert(bytes[bytes.length - 1] % 2 === 0);
|
||||
else if (bytes[0] === 0x07)
|
||||
assert(bytes[bytes.length - 1] % 2 === 1);
|
||||
|
||||
var res = this.point(bytes.slice(1, 1 + len),
|
||||
bytes.slice(1 + len, 1 + 2 * len));
|
||||
|
||||
return res;
|
||||
} else if ((bytes[0] === 0x02 || bytes[0] === 0x03) &&
|
||||
bytes.length - 1 === len) {
|
||||
return this.pointFromX(bytes.slice(1, 1 + len), bytes[0] === 0x03);
|
||||
}
|
||||
throw new Error('Unknown point format');
|
||||
};
|
||||
|
||||
BasePoint.prototype.encodeCompressed = function encodeCompressed(enc) {
|
||||
return this.encode(enc, true);
|
||||
};
|
||||
|
||||
BasePoint.prototype._encode = function _encode(compact) {
|
||||
var len = this.curve.p.byteLength();
|
||||
var x = this.getX().toArray('be', len);
|
||||
|
||||
if (compact)
|
||||
return [ this.getY().isEven() ? 0x02 : 0x03 ].concat(x);
|
||||
|
||||
return [ 0x04 ].concat(x, this.getY().toArray('be', len)) ;
|
||||
};
|
||||
|
||||
BasePoint.prototype.encode = function encode(enc, compact) {
|
||||
return utils.encode(this._encode(compact), enc);
|
||||
};
|
||||
|
||||
BasePoint.prototype.precompute = function precompute(power) {
|
||||
if (this.precomputed)
|
||||
return this;
|
||||
|
||||
var precomputed = {
|
||||
doubles: null,
|
||||
naf: null,
|
||||
beta: null
|
||||
};
|
||||
precomputed.naf = this._getNAFPoints(8);
|
||||
precomputed.doubles = this._getDoubles(4, power);
|
||||
precomputed.beta = this._getBeta();
|
||||
this.precomputed = precomputed;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
BasePoint.prototype._hasDoubles = function _hasDoubles(k) {
|
||||
if (!this.precomputed)
|
||||
return false;
|
||||
|
||||
var doubles = this.precomputed.doubles;
|
||||
if (!doubles)
|
||||
return false;
|
||||
|
||||
return doubles.points.length >= Math.ceil((k.bitLength() + 1) / doubles.step);
|
||||
};
|
||||
|
||||
BasePoint.prototype._getDoubles = function _getDoubles(step, power) {
|
||||
if (this.precomputed && this.precomputed.doubles)
|
||||
return this.precomputed.doubles;
|
||||
|
||||
var doubles = [ this ];
|
||||
var acc = this;
|
||||
for (var i = 0; i < power; i += step) {
|
||||
for (var j = 0; j < step; j++)
|
||||
acc = acc.dbl();
|
||||
doubles.push(acc);
|
||||
}
|
||||
return {
|
||||
step: step,
|
||||
points: doubles
|
||||
};
|
||||
};
|
||||
|
||||
BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) {
|
||||
if (this.precomputed && this.precomputed.naf)
|
||||
return this.precomputed.naf;
|
||||
|
||||
var res = [ this ];
|
||||
var max = (1 << wnd) - 1;
|
||||
var dbl = max === 1 ? null : this.dbl();
|
||||
for (var i = 1; i < max; i++)
|
||||
res[i] = res[i - 1].add(dbl);
|
||||
return {
|
||||
wnd: wnd,
|
||||
points: res
|
||||
};
|
||||
};
|
||||
|
||||
BasePoint.prototype._getBeta = function _getBeta() {
|
||||
return null;
|
||||
};
|
||||
|
||||
BasePoint.prototype.dblp = function dblp(k) {
|
||||
var r = this;
|
||||
for (var i = 0; i < k; i++)
|
||||
r = r.dbl();
|
||||
return r;
|
||||
};
|
||||
433
static/js/ketcher2/node_modules/elliptic/lib/elliptic/curve/edwards.js
generated
vendored
Normal file
433
static/js/ketcher2/node_modules/elliptic/lib/elliptic/curve/edwards.js
generated
vendored
Normal file
@ -0,0 +1,433 @@
|
||||
'use strict';
|
||||
|
||||
var curve = require('../curve');
|
||||
var elliptic = require('../../elliptic');
|
||||
var BN = require('bn.js');
|
||||
var inherits = require('inherits');
|
||||
var Base = curve.base;
|
||||
|
||||
var assert = elliptic.utils.assert;
|
||||
|
||||
function EdwardsCurve(conf) {
|
||||
// NOTE: Important as we are creating point in Base.call()
|
||||
this.twisted = (conf.a | 0) !== 1;
|
||||
this.mOneA = this.twisted && (conf.a | 0) === -1;
|
||||
this.extended = this.mOneA;
|
||||
|
||||
Base.call(this, 'edwards', conf);
|
||||
|
||||
this.a = new BN(conf.a, 16).umod(this.red.m);
|
||||
this.a = this.a.toRed(this.red);
|
||||
this.c = new BN(conf.c, 16).toRed(this.red);
|
||||
this.c2 = this.c.redSqr();
|
||||
this.d = new BN(conf.d, 16).toRed(this.red);
|
||||
this.dd = this.d.redAdd(this.d);
|
||||
|
||||
assert(!this.twisted || this.c.fromRed().cmpn(1) === 0);
|
||||
this.oneC = (conf.c | 0) === 1;
|
||||
}
|
||||
inherits(EdwardsCurve, Base);
|
||||
module.exports = EdwardsCurve;
|
||||
|
||||
EdwardsCurve.prototype._mulA = function _mulA(num) {
|
||||
if (this.mOneA)
|
||||
return num.redNeg();
|
||||
else
|
||||
return this.a.redMul(num);
|
||||
};
|
||||
|
||||
EdwardsCurve.prototype._mulC = function _mulC(num) {
|
||||
if (this.oneC)
|
||||
return num;
|
||||
else
|
||||
return this.c.redMul(num);
|
||||
};
|
||||
|
||||
// Just for compatibility with Short curve
|
||||
EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) {
|
||||
return this.point(x, y, z, t);
|
||||
};
|
||||
|
||||
EdwardsCurve.prototype.pointFromX = function pointFromX(x, odd) {
|
||||
x = new BN(x, 16);
|
||||
if (!x.red)
|
||||
x = x.toRed(this.red);
|
||||
|
||||
var x2 = x.redSqr();
|
||||
var rhs = this.c2.redSub(this.a.redMul(x2));
|
||||
var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2));
|
||||
|
||||
var y2 = rhs.redMul(lhs.redInvm());
|
||||
var y = y2.redSqrt();
|
||||
if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
|
||||
throw new Error('invalid point');
|
||||
|
||||
var isOdd = y.fromRed().isOdd();
|
||||
if (odd && !isOdd || !odd && isOdd)
|
||||
y = y.redNeg();
|
||||
|
||||
return this.point(x, y);
|
||||
};
|
||||
|
||||
EdwardsCurve.prototype.pointFromY = function pointFromY(y, odd) {
|
||||
y = new BN(y, 16);
|
||||
if (!y.red)
|
||||
y = y.toRed(this.red);
|
||||
|
||||
// x^2 = (y^2 - 1) / (d y^2 + 1)
|
||||
var y2 = y.redSqr();
|
||||
var lhs = y2.redSub(this.one);
|
||||
var rhs = y2.redMul(this.d).redAdd(this.one);
|
||||
var x2 = lhs.redMul(rhs.redInvm());
|
||||
|
||||
if (x2.cmp(this.zero) === 0) {
|
||||
if (odd)
|
||||
throw new Error('invalid point');
|
||||
else
|
||||
return this.point(this.zero, y);
|
||||
}
|
||||
|
||||
var x = x2.redSqrt();
|
||||
if (x.redSqr().redSub(x2).cmp(this.zero) !== 0)
|
||||
throw new Error('invalid point');
|
||||
|
||||
if (x.isOdd() !== odd)
|
||||
x = x.redNeg();
|
||||
|
||||
return this.point(x, y);
|
||||
};
|
||||
|
||||
EdwardsCurve.prototype.validate = function validate(point) {
|
||||
if (point.isInfinity())
|
||||
return true;
|
||||
|
||||
// Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2)
|
||||
point.normalize();
|
||||
|
||||
var x2 = point.x.redSqr();
|
||||
var y2 = point.y.redSqr();
|
||||
var lhs = x2.redMul(this.a).redAdd(y2);
|
||||
var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2)));
|
||||
|
||||
return lhs.cmp(rhs) === 0;
|
||||
};
|
||||
|
||||
function Point(curve, x, y, z, t) {
|
||||
Base.BasePoint.call(this, curve, 'projective');
|
||||
if (x === null && y === null && z === null) {
|
||||
this.x = this.curve.zero;
|
||||
this.y = this.curve.one;
|
||||
this.z = this.curve.one;
|
||||
this.t = this.curve.zero;
|
||||
this.zOne = true;
|
||||
} else {
|
||||
this.x = new BN(x, 16);
|
||||
this.y = new BN(y, 16);
|
||||
this.z = z ? new BN(z, 16) : this.curve.one;
|
||||
this.t = t && new BN(t, 16);
|
||||
if (!this.x.red)
|
||||
this.x = this.x.toRed(this.curve.red);
|
||||
if (!this.y.red)
|
||||
this.y = this.y.toRed(this.curve.red);
|
||||
if (!this.z.red)
|
||||
this.z = this.z.toRed(this.curve.red);
|
||||
if (this.t && !this.t.red)
|
||||
this.t = this.t.toRed(this.curve.red);
|
||||
this.zOne = this.z === this.curve.one;
|
||||
|
||||
// Use extended coordinates
|
||||
if (this.curve.extended && !this.t) {
|
||||
this.t = this.x.redMul(this.y);
|
||||
if (!this.zOne)
|
||||
this.t = this.t.redMul(this.z.redInvm());
|
||||
}
|
||||
}
|
||||
}
|
||||
inherits(Point, Base.BasePoint);
|
||||
|
||||
EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
|
||||
return Point.fromJSON(this, obj);
|
||||
};
|
||||
|
||||
EdwardsCurve.prototype.point = function point(x, y, z, t) {
|
||||
return new Point(this, x, y, z, t);
|
||||
};
|
||||
|
||||
Point.fromJSON = function fromJSON(curve, obj) {
|
||||
return new Point(curve, obj[0], obj[1], obj[2]);
|
||||
};
|
||||
|
||||
Point.prototype.inspect = function inspect() {
|
||||
if (this.isInfinity())
|
||||
return '<EC Point Infinity>';
|
||||
return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
|
||||
' y: ' + this.y.fromRed().toString(16, 2) +
|
||||
' z: ' + this.z.fromRed().toString(16, 2) + '>';
|
||||
};
|
||||
|
||||
Point.prototype.isInfinity = function isInfinity() {
|
||||
// XXX This code assumes that zero is always zero in red
|
||||
return this.x.cmpn(0) === 0 &&
|
||||
this.y.cmp(this.z) === 0;
|
||||
};
|
||||
|
||||
Point.prototype._extDbl = function _extDbl() {
|
||||
// hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
|
||||
// #doubling-dbl-2008-hwcd
|
||||
// 4M + 4S
|
||||
|
||||
// A = X1^2
|
||||
var a = this.x.redSqr();
|
||||
// B = Y1^2
|
||||
var b = this.y.redSqr();
|
||||
// C = 2 * Z1^2
|
||||
var c = this.z.redSqr();
|
||||
c = c.redIAdd(c);
|
||||
// D = a * A
|
||||
var d = this.curve._mulA(a);
|
||||
// E = (X1 + Y1)^2 - A - B
|
||||
var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b);
|
||||
// G = D + B
|
||||
var g = d.redAdd(b);
|
||||
// F = G - C
|
||||
var f = g.redSub(c);
|
||||
// H = D - B
|
||||
var h = d.redSub(b);
|
||||
// X3 = E * F
|
||||
var nx = e.redMul(f);
|
||||
// Y3 = G * H
|
||||
var ny = g.redMul(h);
|
||||
// T3 = E * H
|
||||
var nt = e.redMul(h);
|
||||
// Z3 = F * G
|
||||
var nz = f.redMul(g);
|
||||
return this.curve.point(nx, ny, nz, nt);
|
||||
};
|
||||
|
||||
Point.prototype._projDbl = function _projDbl() {
|
||||
// hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
|
||||
// #doubling-dbl-2008-bbjlp
|
||||
// #doubling-dbl-2007-bl
|
||||
// and others
|
||||
// Generally 3M + 4S or 2M + 4S
|
||||
|
||||
// B = (X1 + Y1)^2
|
||||
var b = this.x.redAdd(this.y).redSqr();
|
||||
// C = X1^2
|
||||
var c = this.x.redSqr();
|
||||
// D = Y1^2
|
||||
var d = this.y.redSqr();
|
||||
|
||||
var nx;
|
||||
var ny;
|
||||
var nz;
|
||||
if (this.curve.twisted) {
|
||||
// E = a * C
|
||||
var e = this.curve._mulA(c);
|
||||
// F = E + D
|
||||
var f = e.redAdd(d);
|
||||
if (this.zOne) {
|
||||
// X3 = (B - C - D) * (F - 2)
|
||||
nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two));
|
||||
// Y3 = F * (E - D)
|
||||
ny = f.redMul(e.redSub(d));
|
||||
// Z3 = F^2 - 2 * F
|
||||
nz = f.redSqr().redSub(f).redSub(f);
|
||||
} else {
|
||||
// H = Z1^2
|
||||
var h = this.z.redSqr();
|
||||
// J = F - 2 * H
|
||||
var j = f.redSub(h).redISub(h);
|
||||
// X3 = (B-C-D)*J
|
||||
nx = b.redSub(c).redISub(d).redMul(j);
|
||||
// Y3 = F * (E - D)
|
||||
ny = f.redMul(e.redSub(d));
|
||||
// Z3 = F * J
|
||||
nz = f.redMul(j);
|
||||
}
|
||||
} else {
|
||||
// E = C + D
|
||||
var e = c.redAdd(d);
|
||||
// H = (c * Z1)^2
|
||||
var h = this.curve._mulC(this.c.redMul(this.z)).redSqr();
|
||||
// J = E - 2 * H
|
||||
var j = e.redSub(h).redSub(h);
|
||||
// X3 = c * (B - E) * J
|
||||
nx = this.curve._mulC(b.redISub(e)).redMul(j);
|
||||
// Y3 = c * E * (C - D)
|
||||
ny = this.curve._mulC(e).redMul(c.redISub(d));
|
||||
// Z3 = E * J
|
||||
nz = e.redMul(j);
|
||||
}
|
||||
return this.curve.point(nx, ny, nz);
|
||||
};
|
||||
|
||||
Point.prototype.dbl = function dbl() {
|
||||
if (this.isInfinity())
|
||||
return this;
|
||||
|
||||
// Double in extended coordinates
|
||||
if (this.curve.extended)
|
||||
return this._extDbl();
|
||||
else
|
||||
return this._projDbl();
|
||||
};
|
||||
|
||||
Point.prototype._extAdd = function _extAdd(p) {
|
||||
// hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
|
||||
// #addition-add-2008-hwcd-3
|
||||
// 8M
|
||||
|
||||
// A = (Y1 - X1) * (Y2 - X2)
|
||||
var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x));
|
||||
// B = (Y1 + X1) * (Y2 + X2)
|
||||
var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x));
|
||||
// C = T1 * k * T2
|
||||
var c = this.t.redMul(this.curve.dd).redMul(p.t);
|
||||
// D = Z1 * 2 * Z2
|
||||
var d = this.z.redMul(p.z.redAdd(p.z));
|
||||
// E = B - A
|
||||
var e = b.redSub(a);
|
||||
// F = D - C
|
||||
var f = d.redSub(c);
|
||||
// G = D + C
|
||||
var g = d.redAdd(c);
|
||||
// H = B + A
|
||||
var h = b.redAdd(a);
|
||||
// X3 = E * F
|
||||
var nx = e.redMul(f);
|
||||
// Y3 = G * H
|
||||
var ny = g.redMul(h);
|
||||
// T3 = E * H
|
||||
var nt = e.redMul(h);
|
||||
// Z3 = F * G
|
||||
var nz = f.redMul(g);
|
||||
return this.curve.point(nx, ny, nz, nt);
|
||||
};
|
||||
|
||||
Point.prototype._projAdd = function _projAdd(p) {
|
||||
// hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
|
||||
// #addition-add-2008-bbjlp
|
||||
// #addition-add-2007-bl
|
||||
// 10M + 1S
|
||||
|
||||
// A = Z1 * Z2
|
||||
var a = this.z.redMul(p.z);
|
||||
// B = A^2
|
||||
var b = a.redSqr();
|
||||
// C = X1 * X2
|
||||
var c = this.x.redMul(p.x);
|
||||
// D = Y1 * Y2
|
||||
var d = this.y.redMul(p.y);
|
||||
// E = d * C * D
|
||||
var e = this.curve.d.redMul(c).redMul(d);
|
||||
// F = B - E
|
||||
var f = b.redSub(e);
|
||||
// G = B + E
|
||||
var g = b.redAdd(e);
|
||||
// X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D)
|
||||
var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d);
|
||||
var nx = a.redMul(f).redMul(tmp);
|
||||
var ny;
|
||||
var nz;
|
||||
if (this.curve.twisted) {
|
||||
// Y3 = A * G * (D - a * C)
|
||||
ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c)));
|
||||
// Z3 = F * G
|
||||
nz = f.redMul(g);
|
||||
} else {
|
||||
// Y3 = A * G * (D - C)
|
||||
ny = a.redMul(g).redMul(d.redSub(c));
|
||||
// Z3 = c * F * G
|
||||
nz = this.curve._mulC(f).redMul(g);
|
||||
}
|
||||
return this.curve.point(nx, ny, nz);
|
||||
};
|
||||
|
||||
Point.prototype.add = function add(p) {
|
||||
if (this.isInfinity())
|
||||
return p;
|
||||
if (p.isInfinity())
|
||||
return this;
|
||||
|
||||
if (this.curve.extended)
|
||||
return this._extAdd(p);
|
||||
else
|
||||
return this._projAdd(p);
|
||||
};
|
||||
|
||||
Point.prototype.mul = function mul(k) {
|
||||
if (this._hasDoubles(k))
|
||||
return this.curve._fixedNafMul(this, k);
|
||||
else
|
||||
return this.curve._wnafMul(this, k);
|
||||
};
|
||||
|
||||
Point.prototype.mulAdd = function mulAdd(k1, p, k2) {
|
||||
return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, false);
|
||||
};
|
||||
|
||||
Point.prototype.jmulAdd = function jmulAdd(k1, p, k2) {
|
||||
return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, true);
|
||||
};
|
||||
|
||||
Point.prototype.normalize = function normalize() {
|
||||
if (this.zOne)
|
||||
return this;
|
||||
|
||||
// Normalize coordinates
|
||||
var zi = this.z.redInvm();
|
||||
this.x = this.x.redMul(zi);
|
||||
this.y = this.y.redMul(zi);
|
||||
if (this.t)
|
||||
this.t = this.t.redMul(zi);
|
||||
this.z = this.curve.one;
|
||||
this.zOne = true;
|
||||
return this;
|
||||
};
|
||||
|
||||
Point.prototype.neg = function neg() {
|
||||
return this.curve.point(this.x.redNeg(),
|
||||
this.y,
|
||||
this.z,
|
||||
this.t && this.t.redNeg());
|
||||
};
|
||||
|
||||
Point.prototype.getX = function getX() {
|
||||
this.normalize();
|
||||
return this.x.fromRed();
|
||||
};
|
||||
|
||||
Point.prototype.getY = function getY() {
|
||||
this.normalize();
|
||||
return this.y.fromRed();
|
||||
};
|
||||
|
||||
Point.prototype.eq = function eq(other) {
|
||||
return this === other ||
|
||||
this.getX().cmp(other.getX()) === 0 &&
|
||||
this.getY().cmp(other.getY()) === 0;
|
||||
};
|
||||
|
||||
Point.prototype.eqXToP = function eqXToP(x) {
|
||||
var rx = x.toRed(this.curve.red).redMul(this.z);
|
||||
if (this.x.cmp(rx) === 0)
|
||||
return true;
|
||||
|
||||
var xc = x.clone();
|
||||
var t = this.curve.redN.redMul(this.z);
|
||||
for (;;) {
|
||||
xc.iadd(this.curve.n);
|
||||
if (xc.cmp(this.curve.p) >= 0)
|
||||
return false;
|
||||
|
||||
rx.redIAdd(t);
|
||||
if (this.x.cmp(rx) === 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// Compatibility with BaseCurve
|
||||
Point.prototype.toP = Point.prototype.normalize;
|
||||
Point.prototype.mixedAdd = Point.prototype.add;
|
||||
8
static/js/ketcher2/node_modules/elliptic/lib/elliptic/curve/index.js
generated
vendored
Normal file
8
static/js/ketcher2/node_modules/elliptic/lib/elliptic/curve/index.js
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
var curve = exports;
|
||||
|
||||
curve.base = require('./base');
|
||||
curve.short = require('./short');
|
||||
curve.mont = require('./mont');
|
||||
curve.edwards = require('./edwards');
|
||||
180
static/js/ketcher2/node_modules/elliptic/lib/elliptic/curve/mont.js
generated
vendored
Normal file
180
static/js/ketcher2/node_modules/elliptic/lib/elliptic/curve/mont.js
generated
vendored
Normal file
@ -0,0 +1,180 @@
|
||||
'use strict';
|
||||
|
||||
var curve = require('../curve');
|
||||
var BN = require('bn.js');
|
||||
var inherits = require('inherits');
|
||||
var Base = curve.base;
|
||||
|
||||
var elliptic = require('../../elliptic');
|
||||
var utils = elliptic.utils;
|
||||
|
||||
function MontCurve(conf) {
|
||||
Base.call(this, 'mont', conf);
|
||||
|
||||
this.a = new BN(conf.a, 16).toRed(this.red);
|
||||
this.b = new BN(conf.b, 16).toRed(this.red);
|
||||
this.i4 = new BN(4).toRed(this.red).redInvm();
|
||||
this.two = new BN(2).toRed(this.red);
|
||||
this.a24 = this.i4.redMul(this.a.redAdd(this.two));
|
||||
}
|
||||
inherits(MontCurve, Base);
|
||||
module.exports = MontCurve;
|
||||
|
||||
MontCurve.prototype.validate = function validate(point) {
|
||||
var x = point.normalize().x;
|
||||
var x2 = x.redSqr();
|
||||
var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x);
|
||||
var y = rhs.redSqrt();
|
||||
|
||||
return y.redSqr().cmp(rhs) === 0;
|
||||
};
|
||||
|
||||
function Point(curve, x, z) {
|
||||
Base.BasePoint.call(this, curve, 'projective');
|
||||
if (x === null && z === null) {
|
||||
this.x = this.curve.one;
|
||||
this.z = this.curve.zero;
|
||||
} else {
|
||||
this.x = new BN(x, 16);
|
||||
this.z = new BN(z, 16);
|
||||
if (!this.x.red)
|
||||
this.x = this.x.toRed(this.curve.red);
|
||||
if (!this.z.red)
|
||||
this.z = this.z.toRed(this.curve.red);
|
||||
}
|
||||
}
|
||||
inherits(Point, Base.BasePoint);
|
||||
|
||||
MontCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
|
||||
return this.point(utils.toArray(bytes, enc), 1);
|
||||
};
|
||||
|
||||
MontCurve.prototype.point = function point(x, z) {
|
||||
return new Point(this, x, z);
|
||||
};
|
||||
|
||||
MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
|
||||
return Point.fromJSON(this, obj);
|
||||
};
|
||||
|
||||
Point.prototype.precompute = function precompute() {
|
||||
// No-op
|
||||
};
|
||||
|
||||
Point.prototype._encode = function _encode() {
|
||||
return this.getX().toArray('be', this.curve.p.byteLength());
|
||||
};
|
||||
|
||||
Point.fromJSON = function fromJSON(curve, obj) {
|
||||
return new Point(curve, obj[0], obj[1] || curve.one);
|
||||
};
|
||||
|
||||
Point.prototype.inspect = function inspect() {
|
||||
if (this.isInfinity())
|
||||
return '<EC Point Infinity>';
|
||||
return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
|
||||
' z: ' + this.z.fromRed().toString(16, 2) + '>';
|
||||
};
|
||||
|
||||
Point.prototype.isInfinity = function isInfinity() {
|
||||
// XXX This code assumes that zero is always zero in red
|
||||
return this.z.cmpn(0) === 0;
|
||||
};
|
||||
|
||||
Point.prototype.dbl = function dbl() {
|
||||
// http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3
|
||||
// 2M + 2S + 4A
|
||||
|
||||
// A = X1 + Z1
|
||||
var a = this.x.redAdd(this.z);
|
||||
// AA = A^2
|
||||
var aa = a.redSqr();
|
||||
// B = X1 - Z1
|
||||
var b = this.x.redSub(this.z);
|
||||
// BB = B^2
|
||||
var bb = b.redSqr();
|
||||
// C = AA - BB
|
||||
var c = aa.redSub(bb);
|
||||
// X3 = AA * BB
|
||||
var nx = aa.redMul(bb);
|
||||
// Z3 = C * (BB + A24 * C)
|
||||
var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c)));
|
||||
return this.curve.point(nx, nz);
|
||||
};
|
||||
|
||||
Point.prototype.add = function add() {
|
||||
throw new Error('Not supported on Montgomery curve');
|
||||
};
|
||||
|
||||
Point.prototype.diffAdd = function diffAdd(p, diff) {
|
||||
// http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3
|
||||
// 4M + 2S + 6A
|
||||
|
||||
// A = X2 + Z2
|
||||
var a = this.x.redAdd(this.z);
|
||||
// B = X2 - Z2
|
||||
var b = this.x.redSub(this.z);
|
||||
// C = X3 + Z3
|
||||
var c = p.x.redAdd(p.z);
|
||||
// D = X3 - Z3
|
||||
var d = p.x.redSub(p.z);
|
||||
// DA = D * A
|
||||
var da = d.redMul(a);
|
||||
// CB = C * B
|
||||
var cb = c.redMul(b);
|
||||
// X5 = Z1 * (DA + CB)^2
|
||||
var nx = diff.z.redMul(da.redAdd(cb).redSqr());
|
||||
// Z5 = X1 * (DA - CB)^2
|
||||
var nz = diff.x.redMul(da.redISub(cb).redSqr());
|
||||
return this.curve.point(nx, nz);
|
||||
};
|
||||
|
||||
Point.prototype.mul = function mul(k) {
|
||||
var t = k.clone();
|
||||
var a = this; // (N / 2) * Q + Q
|
||||
var b = this.curve.point(null, null); // (N / 2) * Q
|
||||
var c = this; // Q
|
||||
|
||||
for (var bits = []; t.cmpn(0) !== 0; t.iushrn(1))
|
||||
bits.push(t.andln(1));
|
||||
|
||||
for (var i = bits.length - 1; i >= 0; i--) {
|
||||
if (bits[i] === 0) {
|
||||
// N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q
|
||||
a = a.diffAdd(b, c);
|
||||
// N * Q = 2 * ((N / 2) * Q + Q))
|
||||
b = b.dbl();
|
||||
} else {
|
||||
// N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q)
|
||||
b = a.diffAdd(b, c);
|
||||
// N * Q + Q = 2 * ((N / 2) * Q + Q)
|
||||
a = a.dbl();
|
||||
}
|
||||
}
|
||||
return b;
|
||||
};
|
||||
|
||||
Point.prototype.mulAdd = function mulAdd() {
|
||||
throw new Error('Not supported on Montgomery curve');
|
||||
};
|
||||
|
||||
Point.prototype.jumlAdd = function jumlAdd() {
|
||||
throw new Error('Not supported on Montgomery curve');
|
||||
};
|
||||
|
||||
Point.prototype.eq = function eq(other) {
|
||||
return this.getX().cmp(other.getX()) === 0;
|
||||
};
|
||||
|
||||
Point.prototype.normalize = function normalize() {
|
||||
this.x = this.x.redMul(this.z.redInvm());
|
||||
this.z = this.curve.one;
|
||||
return this;
|
||||
};
|
||||
|
||||
Point.prototype.getX = function getX() {
|
||||
// Normalize coordinates
|
||||
this.normalize();
|
||||
|
||||
return this.x.fromRed();
|
||||
};
|
||||
938
static/js/ketcher2/node_modules/elliptic/lib/elliptic/curve/short.js
generated
vendored
Normal file
938
static/js/ketcher2/node_modules/elliptic/lib/elliptic/curve/short.js
generated
vendored
Normal file
@ -0,0 +1,938 @@
|
||||
'use strict';
|
||||
|
||||
var curve = require('../curve');
|
||||
var elliptic = require('../../elliptic');
|
||||
var BN = require('bn.js');
|
||||
var inherits = require('inherits');
|
||||
var Base = curve.base;
|
||||
|
||||
var assert = elliptic.utils.assert;
|
||||
|
||||
function ShortCurve(conf) {
|
||||
Base.call(this, 'short', conf);
|
||||
|
||||
this.a = new BN(conf.a, 16).toRed(this.red);
|
||||
this.b = new BN(conf.b, 16).toRed(this.red);
|
||||
this.tinv = this.two.redInvm();
|
||||
|
||||
this.zeroA = this.a.fromRed().cmpn(0) === 0;
|
||||
this.threeA = this.a.fromRed().sub(this.p).cmpn(-3) === 0;
|
||||
|
||||
// If the curve is endomorphic, precalculate beta and lambda
|
||||
this.endo = this._getEndomorphism(conf);
|
||||
this._endoWnafT1 = new Array(4);
|
||||
this._endoWnafT2 = new Array(4);
|
||||
}
|
||||
inherits(ShortCurve, Base);
|
||||
module.exports = ShortCurve;
|
||||
|
||||
ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) {
|
||||
// No efficient endomorphism
|
||||
if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1)
|
||||
return;
|
||||
|
||||
// Compute beta and lambda, that lambda * P = (beta * Px; Py)
|
||||
var beta;
|
||||
var lambda;
|
||||
if (conf.beta) {
|
||||
beta = new BN(conf.beta, 16).toRed(this.red);
|
||||
} else {
|
||||
var betas = this._getEndoRoots(this.p);
|
||||
// Choose the smallest beta
|
||||
beta = betas[0].cmp(betas[1]) < 0 ? betas[0] : betas[1];
|
||||
beta = beta.toRed(this.red);
|
||||
}
|
||||
if (conf.lambda) {
|
||||
lambda = new BN(conf.lambda, 16);
|
||||
} else {
|
||||
// Choose the lambda that is matching selected beta
|
||||
var lambdas = this._getEndoRoots(this.n);
|
||||
if (this.g.mul(lambdas[0]).x.cmp(this.g.x.redMul(beta)) === 0) {
|
||||
lambda = lambdas[0];
|
||||
} else {
|
||||
lambda = lambdas[1];
|
||||
assert(this.g.mul(lambda).x.cmp(this.g.x.redMul(beta)) === 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Get basis vectors, used for balanced length-two representation
|
||||
var basis;
|
||||
if (conf.basis) {
|
||||
basis = conf.basis.map(function(vec) {
|
||||
return {
|
||||
a: new BN(vec.a, 16),
|
||||
b: new BN(vec.b, 16)
|
||||
};
|
||||
});
|
||||
} else {
|
||||
basis = this._getEndoBasis(lambda);
|
||||
}
|
||||
|
||||
return {
|
||||
beta: beta,
|
||||
lambda: lambda,
|
||||
basis: basis
|
||||
};
|
||||
};
|
||||
|
||||
ShortCurve.prototype._getEndoRoots = function _getEndoRoots(num) {
|
||||
// Find roots of for x^2 + x + 1 in F
|
||||
// Root = (-1 +- Sqrt(-3)) / 2
|
||||
//
|
||||
var red = num === this.p ? this.red : BN.mont(num);
|
||||
var tinv = new BN(2).toRed(red).redInvm();
|
||||
var ntinv = tinv.redNeg();
|
||||
|
||||
var s = new BN(3).toRed(red).redNeg().redSqrt().redMul(tinv);
|
||||
|
||||
var l1 = ntinv.redAdd(s).fromRed();
|
||||
var l2 = ntinv.redSub(s).fromRed();
|
||||
return [ l1, l2 ];
|
||||
};
|
||||
|
||||
ShortCurve.prototype._getEndoBasis = function _getEndoBasis(lambda) {
|
||||
// aprxSqrt >= sqrt(this.n)
|
||||
var aprxSqrt = this.n.ushrn(Math.floor(this.n.bitLength() / 2));
|
||||
|
||||
// 3.74
|
||||
// Run EGCD, until r(L + 1) < aprxSqrt
|
||||
var u = lambda;
|
||||
var v = this.n.clone();
|
||||
var x1 = new BN(1);
|
||||
var y1 = new BN(0);
|
||||
var x2 = new BN(0);
|
||||
var y2 = new BN(1);
|
||||
|
||||
// NOTE: all vectors are roots of: a + b * lambda = 0 (mod n)
|
||||
var a0;
|
||||
var b0;
|
||||
// First vector
|
||||
var a1;
|
||||
var b1;
|
||||
// Second vector
|
||||
var a2;
|
||||
var b2;
|
||||
|
||||
var prevR;
|
||||
var i = 0;
|
||||
var r;
|
||||
var x;
|
||||
while (u.cmpn(0) !== 0) {
|
||||
var q = v.div(u);
|
||||
r = v.sub(q.mul(u));
|
||||
x = x2.sub(q.mul(x1));
|
||||
var y = y2.sub(q.mul(y1));
|
||||
|
||||
if (!a1 && r.cmp(aprxSqrt) < 0) {
|
||||
a0 = prevR.neg();
|
||||
b0 = x1;
|
||||
a1 = r.neg();
|
||||
b1 = x;
|
||||
} else if (a1 && ++i === 2) {
|
||||
break;
|
||||
}
|
||||
prevR = r;
|
||||
|
||||
v = u;
|
||||
u = r;
|
||||
x2 = x1;
|
||||
x1 = x;
|
||||
y2 = y1;
|
||||
y1 = y;
|
||||
}
|
||||
a2 = r.neg();
|
||||
b2 = x;
|
||||
|
||||
var len1 = a1.sqr().add(b1.sqr());
|
||||
var len2 = a2.sqr().add(b2.sqr());
|
||||
if (len2.cmp(len1) >= 0) {
|
||||
a2 = a0;
|
||||
b2 = b0;
|
||||
}
|
||||
|
||||
// Normalize signs
|
||||
if (a1.negative) {
|
||||
a1 = a1.neg();
|
||||
b1 = b1.neg();
|
||||
}
|
||||
if (a2.negative) {
|
||||
a2 = a2.neg();
|
||||
b2 = b2.neg();
|
||||
}
|
||||
|
||||
return [
|
||||
{ a: a1, b: b1 },
|
||||
{ a: a2, b: b2 }
|
||||
];
|
||||
};
|
||||
|
||||
ShortCurve.prototype._endoSplit = function _endoSplit(k) {
|
||||
var basis = this.endo.basis;
|
||||
var v1 = basis[0];
|
||||
var v2 = basis[1];
|
||||
|
||||
var c1 = v2.b.mul(k).divRound(this.n);
|
||||
var c2 = v1.b.neg().mul(k).divRound(this.n);
|
||||
|
||||
var p1 = c1.mul(v1.a);
|
||||
var p2 = c2.mul(v2.a);
|
||||
var q1 = c1.mul(v1.b);
|
||||
var q2 = c2.mul(v2.b);
|
||||
|
||||
// Calculate answer
|
||||
var k1 = k.sub(p1).sub(p2);
|
||||
var k2 = q1.add(q2).neg();
|
||||
return { k1: k1, k2: k2 };
|
||||
};
|
||||
|
||||
ShortCurve.prototype.pointFromX = function pointFromX(x, odd) {
|
||||
x = new BN(x, 16);
|
||||
if (!x.red)
|
||||
x = x.toRed(this.red);
|
||||
|
||||
var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b);
|
||||
var y = y2.redSqrt();
|
||||
if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
|
||||
throw new Error('invalid point');
|
||||
|
||||
// XXX Is there any way to tell if the number is odd without converting it
|
||||
// to non-red form?
|
||||
var isOdd = y.fromRed().isOdd();
|
||||
if (odd && !isOdd || !odd && isOdd)
|
||||
y = y.redNeg();
|
||||
|
||||
return this.point(x, y);
|
||||
};
|
||||
|
||||
ShortCurve.prototype.validate = function validate(point) {
|
||||
if (point.inf)
|
||||
return true;
|
||||
|
||||
var x = point.x;
|
||||
var y = point.y;
|
||||
|
||||
var ax = this.a.redMul(x);
|
||||
var rhs = x.redSqr().redMul(x).redIAdd(ax).redIAdd(this.b);
|
||||
return y.redSqr().redISub(rhs).cmpn(0) === 0;
|
||||
};
|
||||
|
||||
ShortCurve.prototype._endoWnafMulAdd =
|
||||
function _endoWnafMulAdd(points, coeffs, jacobianResult) {
|
||||
var npoints = this._endoWnafT1;
|
||||
var ncoeffs = this._endoWnafT2;
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
var split = this._endoSplit(coeffs[i]);
|
||||
var p = points[i];
|
||||
var beta = p._getBeta();
|
||||
|
||||
if (split.k1.negative) {
|
||||
split.k1.ineg();
|
||||
p = p.neg(true);
|
||||
}
|
||||
if (split.k2.negative) {
|
||||
split.k2.ineg();
|
||||
beta = beta.neg(true);
|
||||
}
|
||||
|
||||
npoints[i * 2] = p;
|
||||
npoints[i * 2 + 1] = beta;
|
||||
ncoeffs[i * 2] = split.k1;
|
||||
ncoeffs[i * 2 + 1] = split.k2;
|
||||
}
|
||||
var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2, jacobianResult);
|
||||
|
||||
// Clean-up references to points and coefficients
|
||||
for (var j = 0; j < i * 2; j++) {
|
||||
npoints[j] = null;
|
||||
ncoeffs[j] = null;
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
function Point(curve, x, y, isRed) {
|
||||
Base.BasePoint.call(this, curve, 'affine');
|
||||
if (x === null && y === null) {
|
||||
this.x = null;
|
||||
this.y = null;
|
||||
this.inf = true;
|
||||
} else {
|
||||
this.x = new BN(x, 16);
|
||||
this.y = new BN(y, 16);
|
||||
// Force redgomery representation when loading from JSON
|
||||
if (isRed) {
|
||||
this.x.forceRed(this.curve.red);
|
||||
this.y.forceRed(this.curve.red);
|
||||
}
|
||||
if (!this.x.red)
|
||||
this.x = this.x.toRed(this.curve.red);
|
||||
if (!this.y.red)
|
||||
this.y = this.y.toRed(this.curve.red);
|
||||
this.inf = false;
|
||||
}
|
||||
}
|
||||
inherits(Point, Base.BasePoint);
|
||||
|
||||
ShortCurve.prototype.point = function point(x, y, isRed) {
|
||||
return new Point(this, x, y, isRed);
|
||||
};
|
||||
|
||||
ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) {
|
||||
return Point.fromJSON(this, obj, red);
|
||||
};
|
||||
|
||||
Point.prototype._getBeta = function _getBeta() {
|
||||
if (!this.curve.endo)
|
||||
return;
|
||||
|
||||
var pre = this.precomputed;
|
||||
if (pre && pre.beta)
|
||||
return pre.beta;
|
||||
|
||||
var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y);
|
||||
if (pre) {
|
||||
var curve = this.curve;
|
||||
var endoMul = function(p) {
|
||||
return curve.point(p.x.redMul(curve.endo.beta), p.y);
|
||||
};
|
||||
pre.beta = beta;
|
||||
beta.precomputed = {
|
||||
beta: null,
|
||||
naf: pre.naf && {
|
||||
wnd: pre.naf.wnd,
|
||||
points: pre.naf.points.map(endoMul)
|
||||
},
|
||||
doubles: pre.doubles && {
|
||||
step: pre.doubles.step,
|
||||
points: pre.doubles.points.map(endoMul)
|
||||
}
|
||||
};
|
||||
}
|
||||
return beta;
|
||||
};
|
||||
|
||||
Point.prototype.toJSON = function toJSON() {
|
||||
if (!this.precomputed)
|
||||
return [ this.x, this.y ];
|
||||
|
||||
return [ this.x, this.y, this.precomputed && {
|
||||
doubles: this.precomputed.doubles && {
|
||||
step: this.precomputed.doubles.step,
|
||||
points: this.precomputed.doubles.points.slice(1)
|
||||
},
|
||||
naf: this.precomputed.naf && {
|
||||
wnd: this.precomputed.naf.wnd,
|
||||
points: this.precomputed.naf.points.slice(1)
|
||||
}
|
||||
} ];
|
||||
};
|
||||
|
||||
Point.fromJSON = function fromJSON(curve, obj, red) {
|
||||
if (typeof obj === 'string')
|
||||
obj = JSON.parse(obj);
|
||||
var res = curve.point(obj[0], obj[1], red);
|
||||
if (!obj[2])
|
||||
return res;
|
||||
|
||||
function obj2point(obj) {
|
||||
return curve.point(obj[0], obj[1], red);
|
||||
}
|
||||
|
||||
var pre = obj[2];
|
||||
res.precomputed = {
|
||||
beta: null,
|
||||
doubles: pre.doubles && {
|
||||
step: pre.doubles.step,
|
||||
points: [ res ].concat(pre.doubles.points.map(obj2point))
|
||||
},
|
||||
naf: pre.naf && {
|
||||
wnd: pre.naf.wnd,
|
||||
points: [ res ].concat(pre.naf.points.map(obj2point))
|
||||
}
|
||||
};
|
||||
return res;
|
||||
};
|
||||
|
||||
Point.prototype.inspect = function inspect() {
|
||||
if (this.isInfinity())
|
||||
return '<EC Point Infinity>';
|
||||
return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
|
||||
' y: ' + this.y.fromRed().toString(16, 2) + '>';
|
||||
};
|
||||
|
||||
Point.prototype.isInfinity = function isInfinity() {
|
||||
return this.inf;
|
||||
};
|
||||
|
||||
Point.prototype.add = function add(p) {
|
||||
// O + P = P
|
||||
if (this.inf)
|
||||
return p;
|
||||
|
||||
// P + O = P
|
||||
if (p.inf)
|
||||
return this;
|
||||
|
||||
// P + P = 2P
|
||||
if (this.eq(p))
|
||||
return this.dbl();
|
||||
|
||||
// P + (-P) = O
|
||||
if (this.neg().eq(p))
|
||||
return this.curve.point(null, null);
|
||||
|
||||
// P + Q = O
|
||||
if (this.x.cmp(p.x) === 0)
|
||||
return this.curve.point(null, null);
|
||||
|
||||
var c = this.y.redSub(p.y);
|
||||
if (c.cmpn(0) !== 0)
|
||||
c = c.redMul(this.x.redSub(p.x).redInvm());
|
||||
var nx = c.redSqr().redISub(this.x).redISub(p.x);
|
||||
var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
|
||||
return this.curve.point(nx, ny);
|
||||
};
|
||||
|
||||
Point.prototype.dbl = function dbl() {
|
||||
if (this.inf)
|
||||
return this;
|
||||
|
||||
// 2P = O
|
||||
var ys1 = this.y.redAdd(this.y);
|
||||
if (ys1.cmpn(0) === 0)
|
||||
return this.curve.point(null, null);
|
||||
|
||||
var a = this.curve.a;
|
||||
|
||||
var x2 = this.x.redSqr();
|
||||
var dyinv = ys1.redInvm();
|
||||
var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv);
|
||||
|
||||
var nx = c.redSqr().redISub(this.x.redAdd(this.x));
|
||||
var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
|
||||
return this.curve.point(nx, ny);
|
||||
};
|
||||
|
||||
Point.prototype.getX = function getX() {
|
||||
return this.x.fromRed();
|
||||
};
|
||||
|
||||
Point.prototype.getY = function getY() {
|
||||
return this.y.fromRed();
|
||||
};
|
||||
|
||||
Point.prototype.mul = function mul(k) {
|
||||
k = new BN(k, 16);
|
||||
|
||||
if (this._hasDoubles(k))
|
||||
return this.curve._fixedNafMul(this, k);
|
||||
else if (this.curve.endo)
|
||||
return this.curve._endoWnafMulAdd([ this ], [ k ]);
|
||||
else
|
||||
return this.curve._wnafMul(this, k);
|
||||
};
|
||||
|
||||
Point.prototype.mulAdd = function mulAdd(k1, p2, k2) {
|
||||
var points = [ this, p2 ];
|
||||
var coeffs = [ k1, k2 ];
|
||||
if (this.curve.endo)
|
||||
return this.curve._endoWnafMulAdd(points, coeffs);
|
||||
else
|
||||
return this.curve._wnafMulAdd(1, points, coeffs, 2);
|
||||
};
|
||||
|
||||
Point.prototype.jmulAdd = function jmulAdd(k1, p2, k2) {
|
||||
var points = [ this, p2 ];
|
||||
var coeffs = [ k1, k2 ];
|
||||
if (this.curve.endo)
|
||||
return this.curve._endoWnafMulAdd(points, coeffs, true);
|
||||
else
|
||||
return this.curve._wnafMulAdd(1, points, coeffs, 2, true);
|
||||
};
|
||||
|
||||
Point.prototype.eq = function eq(p) {
|
||||
return this === p ||
|
||||
this.inf === p.inf &&
|
||||
(this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0);
|
||||
};
|
||||
|
||||
Point.prototype.neg = function neg(_precompute) {
|
||||
if (this.inf)
|
||||
return this;
|
||||
|
||||
var res = this.curve.point(this.x, this.y.redNeg());
|
||||
if (_precompute && this.precomputed) {
|
||||
var pre = this.precomputed;
|
||||
var negate = function(p) {
|
||||
return p.neg();
|
||||
};
|
||||
res.precomputed = {
|
||||
naf: pre.naf && {
|
||||
wnd: pre.naf.wnd,
|
||||
points: pre.naf.points.map(negate)
|
||||
},
|
||||
doubles: pre.doubles && {
|
||||
step: pre.doubles.step,
|
||||
points: pre.doubles.points.map(negate)
|
||||
}
|
||||
};
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
Point.prototype.toJ = function toJ() {
|
||||
if (this.inf)
|
||||
return this.curve.jpoint(null, null, null);
|
||||
|
||||
var res = this.curve.jpoint(this.x, this.y, this.curve.one);
|
||||
return res;
|
||||
};
|
||||
|
||||
function JPoint(curve, x, y, z) {
|
||||
Base.BasePoint.call(this, curve, 'jacobian');
|
||||
if (x === null && y === null && z === null) {
|
||||
this.x = this.curve.one;
|
||||
this.y = this.curve.one;
|
||||
this.z = new BN(0);
|
||||
} else {
|
||||
this.x = new BN(x, 16);
|
||||
this.y = new BN(y, 16);
|
||||
this.z = new BN(z, 16);
|
||||
}
|
||||
if (!this.x.red)
|
||||
this.x = this.x.toRed(this.curve.red);
|
||||
if (!this.y.red)
|
||||
this.y = this.y.toRed(this.curve.red);
|
||||
if (!this.z.red)
|
||||
this.z = this.z.toRed(this.curve.red);
|
||||
|
||||
this.zOne = this.z === this.curve.one;
|
||||
}
|
||||
inherits(JPoint, Base.BasePoint);
|
||||
|
||||
ShortCurve.prototype.jpoint = function jpoint(x, y, z) {
|
||||
return new JPoint(this, x, y, z);
|
||||
};
|
||||
|
||||
JPoint.prototype.toP = function toP() {
|
||||
if (this.isInfinity())
|
||||
return this.curve.point(null, null);
|
||||
|
||||
var zinv = this.z.redInvm();
|
||||
var zinv2 = zinv.redSqr();
|
||||
var ax = this.x.redMul(zinv2);
|
||||
var ay = this.y.redMul(zinv2).redMul(zinv);
|
||||
|
||||
return this.curve.point(ax, ay);
|
||||
};
|
||||
|
||||
JPoint.prototype.neg = function neg() {
|
||||
return this.curve.jpoint(this.x, this.y.redNeg(), this.z);
|
||||
};
|
||||
|
||||
JPoint.prototype.add = function add(p) {
|
||||
// O + P = P
|
||||
if (this.isInfinity())
|
||||
return p;
|
||||
|
||||
// P + O = P
|
||||
if (p.isInfinity())
|
||||
return this;
|
||||
|
||||
// 12M + 4S + 7A
|
||||
var pz2 = p.z.redSqr();
|
||||
var z2 = this.z.redSqr();
|
||||
var u1 = this.x.redMul(pz2);
|
||||
var u2 = p.x.redMul(z2);
|
||||
var s1 = this.y.redMul(pz2.redMul(p.z));
|
||||
var s2 = p.y.redMul(z2.redMul(this.z));
|
||||
|
||||
var h = u1.redSub(u2);
|
||||
var r = s1.redSub(s2);
|
||||
if (h.cmpn(0) === 0) {
|
||||
if (r.cmpn(0) !== 0)
|
||||
return this.curve.jpoint(null, null, null);
|
||||
else
|
||||
return this.dbl();
|
||||
}
|
||||
|
||||
var h2 = h.redSqr();
|
||||
var h3 = h2.redMul(h);
|
||||
var v = u1.redMul(h2);
|
||||
|
||||
var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
|
||||
var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
|
||||
var nz = this.z.redMul(p.z).redMul(h);
|
||||
|
||||
return this.curve.jpoint(nx, ny, nz);
|
||||
};
|
||||
|
||||
JPoint.prototype.mixedAdd = function mixedAdd(p) {
|
||||
// O + P = P
|
||||
if (this.isInfinity())
|
||||
return p.toJ();
|
||||
|
||||
// P + O = P
|
||||
if (p.isInfinity())
|
||||
return this;
|
||||
|
||||
// 8M + 3S + 7A
|
||||
var z2 = this.z.redSqr();
|
||||
var u1 = this.x;
|
||||
var u2 = p.x.redMul(z2);
|
||||
var s1 = this.y;
|
||||
var s2 = p.y.redMul(z2).redMul(this.z);
|
||||
|
||||
var h = u1.redSub(u2);
|
||||
var r = s1.redSub(s2);
|
||||
if (h.cmpn(0) === 0) {
|
||||
if (r.cmpn(0) !== 0)
|
||||
return this.curve.jpoint(null, null, null);
|
||||
else
|
||||
return this.dbl();
|
||||
}
|
||||
|
||||
var h2 = h.redSqr();
|
||||
var h3 = h2.redMul(h);
|
||||
var v = u1.redMul(h2);
|
||||
|
||||
var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
|
||||
var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
|
||||
var nz = this.z.redMul(h);
|
||||
|
||||
return this.curve.jpoint(nx, ny, nz);
|
||||
};
|
||||
|
||||
JPoint.prototype.dblp = function dblp(pow) {
|
||||
if (pow === 0)
|
||||
return this;
|
||||
if (this.isInfinity())
|
||||
return this;
|
||||
if (!pow)
|
||||
return this.dbl();
|
||||
|
||||
if (this.curve.zeroA || this.curve.threeA) {
|
||||
var r = this;
|
||||
for (var i = 0; i < pow; i++)
|
||||
r = r.dbl();
|
||||
return r;
|
||||
}
|
||||
|
||||
// 1M + 2S + 1A + N * (4S + 5M + 8A)
|
||||
// N = 1 => 6M + 6S + 9A
|
||||
var a = this.curve.a;
|
||||
var tinv = this.curve.tinv;
|
||||
|
||||
var jx = this.x;
|
||||
var jy = this.y;
|
||||
var jz = this.z;
|
||||
var jz4 = jz.redSqr().redSqr();
|
||||
|
||||
// Reuse results
|
||||
var jyd = jy.redAdd(jy);
|
||||
for (var i = 0; i < pow; i++) {
|
||||
var jx2 = jx.redSqr();
|
||||
var jyd2 = jyd.redSqr();
|
||||
var jyd4 = jyd2.redSqr();
|
||||
var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
|
||||
|
||||
var t1 = jx.redMul(jyd2);
|
||||
var nx = c.redSqr().redISub(t1.redAdd(t1));
|
||||
var t2 = t1.redISub(nx);
|
||||
var dny = c.redMul(t2);
|
||||
dny = dny.redIAdd(dny).redISub(jyd4);
|
||||
var nz = jyd.redMul(jz);
|
||||
if (i + 1 < pow)
|
||||
jz4 = jz4.redMul(jyd4);
|
||||
|
||||
jx = nx;
|
||||
jz = nz;
|
||||
jyd = dny;
|
||||
}
|
||||
|
||||
return this.curve.jpoint(jx, jyd.redMul(tinv), jz);
|
||||
};
|
||||
|
||||
JPoint.prototype.dbl = function dbl() {
|
||||
if (this.isInfinity())
|
||||
return this;
|
||||
|
||||
if (this.curve.zeroA)
|
||||
return this._zeroDbl();
|
||||
else if (this.curve.threeA)
|
||||
return this._threeDbl();
|
||||
else
|
||||
return this._dbl();
|
||||
};
|
||||
|
||||
JPoint.prototype._zeroDbl = function _zeroDbl() {
|
||||
var nx;
|
||||
var ny;
|
||||
var nz;
|
||||
// Z = 1
|
||||
if (this.zOne) {
|
||||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
|
||||
// #doubling-mdbl-2007-bl
|
||||
// 1M + 5S + 14A
|
||||
|
||||
// XX = X1^2
|
||||
var xx = this.x.redSqr();
|
||||
// YY = Y1^2
|
||||
var yy = this.y.redSqr();
|
||||
// YYYY = YY^2
|
||||
var yyyy = yy.redSqr();
|
||||
// S = 2 * ((X1 + YY)^2 - XX - YYYY)
|
||||
var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
|
||||
s = s.redIAdd(s);
|
||||
// M = 3 * XX + a; a = 0
|
||||
var m = xx.redAdd(xx).redIAdd(xx);
|
||||
// T = M ^ 2 - 2*S
|
||||
var t = m.redSqr().redISub(s).redISub(s);
|
||||
|
||||
// 8 * YYYY
|
||||
var yyyy8 = yyyy.redIAdd(yyyy);
|
||||
yyyy8 = yyyy8.redIAdd(yyyy8);
|
||||
yyyy8 = yyyy8.redIAdd(yyyy8);
|
||||
|
||||
// X3 = T
|
||||
nx = t;
|
||||
// Y3 = M * (S - T) - 8 * YYYY
|
||||
ny = m.redMul(s.redISub(t)).redISub(yyyy8);
|
||||
// Z3 = 2*Y1
|
||||
nz = this.y.redAdd(this.y);
|
||||
} else {
|
||||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
|
||||
// #doubling-dbl-2009-l
|
||||
// 2M + 5S + 13A
|
||||
|
||||
// A = X1^2
|
||||
var a = this.x.redSqr();
|
||||
// B = Y1^2
|
||||
var b = this.y.redSqr();
|
||||
// C = B^2
|
||||
var c = b.redSqr();
|
||||
// D = 2 * ((X1 + B)^2 - A - C)
|
||||
var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c);
|
||||
d = d.redIAdd(d);
|
||||
// E = 3 * A
|
||||
var e = a.redAdd(a).redIAdd(a);
|
||||
// F = E^2
|
||||
var f = e.redSqr();
|
||||
|
||||
// 8 * C
|
||||
var c8 = c.redIAdd(c);
|
||||
c8 = c8.redIAdd(c8);
|
||||
c8 = c8.redIAdd(c8);
|
||||
|
||||
// X3 = F - 2 * D
|
||||
nx = f.redISub(d).redISub(d);
|
||||
// Y3 = E * (D - X3) - 8 * C
|
||||
ny = e.redMul(d.redISub(nx)).redISub(c8);
|
||||
// Z3 = 2 * Y1 * Z1
|
||||
nz = this.y.redMul(this.z);
|
||||
nz = nz.redIAdd(nz);
|
||||
}
|
||||
|
||||
return this.curve.jpoint(nx, ny, nz);
|
||||
};
|
||||
|
||||
JPoint.prototype._threeDbl = function _threeDbl() {
|
||||
var nx;
|
||||
var ny;
|
||||
var nz;
|
||||
// Z = 1
|
||||
if (this.zOne) {
|
||||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html
|
||||
// #doubling-mdbl-2007-bl
|
||||
// 1M + 5S + 15A
|
||||
|
||||
// XX = X1^2
|
||||
var xx = this.x.redSqr();
|
||||
// YY = Y1^2
|
||||
var yy = this.y.redSqr();
|
||||
// YYYY = YY^2
|
||||
var yyyy = yy.redSqr();
|
||||
// S = 2 * ((X1 + YY)^2 - XX - YYYY)
|
||||
var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
|
||||
s = s.redIAdd(s);
|
||||
// M = 3 * XX + a
|
||||
var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a);
|
||||
// T = M^2 - 2 * S
|
||||
var t = m.redSqr().redISub(s).redISub(s);
|
||||
// X3 = T
|
||||
nx = t;
|
||||
// Y3 = M * (S - T) - 8 * YYYY
|
||||
var yyyy8 = yyyy.redIAdd(yyyy);
|
||||
yyyy8 = yyyy8.redIAdd(yyyy8);
|
||||
yyyy8 = yyyy8.redIAdd(yyyy8);
|
||||
ny = m.redMul(s.redISub(t)).redISub(yyyy8);
|
||||
// Z3 = 2 * Y1
|
||||
nz = this.y.redAdd(this.y);
|
||||
} else {
|
||||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
|
||||
// 3M + 5S
|
||||
|
||||
// delta = Z1^2
|
||||
var delta = this.z.redSqr();
|
||||
// gamma = Y1^2
|
||||
var gamma = this.y.redSqr();
|
||||
// beta = X1 * gamma
|
||||
var beta = this.x.redMul(gamma);
|
||||
// alpha = 3 * (X1 - delta) * (X1 + delta)
|
||||
var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta));
|
||||
alpha = alpha.redAdd(alpha).redIAdd(alpha);
|
||||
// X3 = alpha^2 - 8 * beta
|
||||
var beta4 = beta.redIAdd(beta);
|
||||
beta4 = beta4.redIAdd(beta4);
|
||||
var beta8 = beta4.redAdd(beta4);
|
||||
nx = alpha.redSqr().redISub(beta8);
|
||||
// Z3 = (Y1 + Z1)^2 - gamma - delta
|
||||
nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta);
|
||||
// Y3 = alpha * (4 * beta - X3) - 8 * gamma^2
|
||||
var ggamma8 = gamma.redSqr();
|
||||
ggamma8 = ggamma8.redIAdd(ggamma8);
|
||||
ggamma8 = ggamma8.redIAdd(ggamma8);
|
||||
ggamma8 = ggamma8.redIAdd(ggamma8);
|
||||
ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8);
|
||||
}
|
||||
|
||||
return this.curve.jpoint(nx, ny, nz);
|
||||
};
|
||||
|
||||
JPoint.prototype._dbl = function _dbl() {
|
||||
var a = this.curve.a;
|
||||
|
||||
// 4M + 6S + 10A
|
||||
var jx = this.x;
|
||||
var jy = this.y;
|
||||
var jz = this.z;
|
||||
var jz4 = jz.redSqr().redSqr();
|
||||
|
||||
var jx2 = jx.redSqr();
|
||||
var jy2 = jy.redSqr();
|
||||
|
||||
var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
|
||||
|
||||
var jxd4 = jx.redAdd(jx);
|
||||
jxd4 = jxd4.redIAdd(jxd4);
|
||||
var t1 = jxd4.redMul(jy2);
|
||||
var nx = c.redSqr().redISub(t1.redAdd(t1));
|
||||
var t2 = t1.redISub(nx);
|
||||
|
||||
var jyd8 = jy2.redSqr();
|
||||
jyd8 = jyd8.redIAdd(jyd8);
|
||||
jyd8 = jyd8.redIAdd(jyd8);
|
||||
jyd8 = jyd8.redIAdd(jyd8);
|
||||
var ny = c.redMul(t2).redISub(jyd8);
|
||||
var nz = jy.redAdd(jy).redMul(jz);
|
||||
|
||||
return this.curve.jpoint(nx, ny, nz);
|
||||
};
|
||||
|
||||
JPoint.prototype.trpl = function trpl() {
|
||||
if (!this.curve.zeroA)
|
||||
return this.dbl().add(this);
|
||||
|
||||
// hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl
|
||||
// 5M + 10S + ...
|
||||
|
||||
// XX = X1^2
|
||||
var xx = this.x.redSqr();
|
||||
// YY = Y1^2
|
||||
var yy = this.y.redSqr();
|
||||
// ZZ = Z1^2
|
||||
var zz = this.z.redSqr();
|
||||
// YYYY = YY^2
|
||||
var yyyy = yy.redSqr();
|
||||
// M = 3 * XX + a * ZZ2; a = 0
|
||||
var m = xx.redAdd(xx).redIAdd(xx);
|
||||
// MM = M^2
|
||||
var mm = m.redSqr();
|
||||
// E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM
|
||||
var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
|
||||
e = e.redIAdd(e);
|
||||
e = e.redAdd(e).redIAdd(e);
|
||||
e = e.redISub(mm);
|
||||
// EE = E^2
|
||||
var ee = e.redSqr();
|
||||
// T = 16*YYYY
|
||||
var t = yyyy.redIAdd(yyyy);
|
||||
t = t.redIAdd(t);
|
||||
t = t.redIAdd(t);
|
||||
t = t.redIAdd(t);
|
||||
// U = (M + E)^2 - MM - EE - T
|
||||
var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t);
|
||||
// X3 = 4 * (X1 * EE - 4 * YY * U)
|
||||
var yyu4 = yy.redMul(u);
|
||||
yyu4 = yyu4.redIAdd(yyu4);
|
||||
yyu4 = yyu4.redIAdd(yyu4);
|
||||
var nx = this.x.redMul(ee).redISub(yyu4);
|
||||
nx = nx.redIAdd(nx);
|
||||
nx = nx.redIAdd(nx);
|
||||
// Y3 = 8 * Y1 * (U * (T - U) - E * EE)
|
||||
var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee)));
|
||||
ny = ny.redIAdd(ny);
|
||||
ny = ny.redIAdd(ny);
|
||||
ny = ny.redIAdd(ny);
|
||||
// Z3 = (Z1 + E)^2 - ZZ - EE
|
||||
var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee);
|
||||
|
||||
return this.curve.jpoint(nx, ny, nz);
|
||||
};
|
||||
|
||||
JPoint.prototype.mul = function mul(k, kbase) {
|
||||
k = new BN(k, kbase);
|
||||
|
||||
return this.curve._wnafMul(this, k);
|
||||
};
|
||||
|
||||
JPoint.prototype.eq = function eq(p) {
|
||||
if (p.type === 'affine')
|
||||
return this.eq(p.toJ());
|
||||
|
||||
if (this === p)
|
||||
return true;
|
||||
|
||||
// x1 * z2^2 == x2 * z1^2
|
||||
var z2 = this.z.redSqr();
|
||||
var pz2 = p.z.redSqr();
|
||||
if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0)
|
||||
return false;
|
||||
|
||||
// y1 * z2^3 == y2 * z1^3
|
||||
var z3 = z2.redMul(this.z);
|
||||
var pz3 = pz2.redMul(p.z);
|
||||
return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0;
|
||||
};
|
||||
|
||||
JPoint.prototype.eqXToP = function eqXToP(x) {
|
||||
var zs = this.z.redSqr();
|
||||
var rx = x.toRed(this.curve.red).redMul(zs);
|
||||
if (this.x.cmp(rx) === 0)
|
||||
return true;
|
||||
|
||||
var xc = x.clone();
|
||||
var t = this.curve.redN.redMul(zs);
|
||||
for (;;) {
|
||||
xc.iadd(this.curve.n);
|
||||
if (xc.cmp(this.curve.p) >= 0)
|
||||
return false;
|
||||
|
||||
rx.redIAdd(t);
|
||||
if (this.x.cmp(rx) === 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
JPoint.prototype.inspect = function inspect() {
|
||||
if (this.isInfinity())
|
||||
return '<EC JPoint Infinity>';
|
||||
return '<EC JPoint x: ' + this.x.toString(16, 2) +
|
||||
' y: ' + this.y.toString(16, 2) +
|
||||
' z: ' + this.z.toString(16, 2) + '>';
|
||||
};
|
||||
|
||||
JPoint.prototype.isInfinity = function isInfinity() {
|
||||
// XXX This code assumes that zero is always zero in red
|
||||
return this.z.cmpn(0) === 0;
|
||||
};
|
||||
Reference in New Issue
Block a user