mirror of
https://github.com/Instadapp/Swap-Aggregator-Subgraph.git
synced 2024-07-29 21:57:12 +00:00
180 lines
4.0 KiB
JavaScript
180 lines
4.0 KiB
JavaScript
'use strict'
|
|
var BN = require('./bn')
|
|
|
|
function ECJPoint (x, y, z) {
|
|
if (x === null && y === null && z === null) {
|
|
this.x = ECJPoint.one
|
|
this.y = ECJPoint.one
|
|
this.z = ECJPoint.zero
|
|
} else {
|
|
this.x = x
|
|
this.y = y
|
|
this.z = z
|
|
}
|
|
|
|
this.zOne = this.z === ECJPoint.one
|
|
}
|
|
|
|
ECJPoint.zero = BN.fromNumber(0)
|
|
ECJPoint.one = BN.fromNumber(1)
|
|
|
|
ECJPoint.prototype.neg = function () {
|
|
if (this.inf) return this
|
|
|
|
return new ECJPoint(this.x, this.y.redNeg(), this.z)
|
|
}
|
|
|
|
ECJPoint.prototype.add = function (p) {
|
|
// O + P = P
|
|
if (this.inf) return p
|
|
|
|
// P + O = P
|
|
if (p.inf) return this
|
|
|
|
// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-1998-cmo-2
|
|
// 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.isZero()) {
|
|
if (r.isZero()) return this.dbl()
|
|
return new ECJPoint(null, null, null)
|
|
}
|
|
|
|
var h2 = h.redSqr()
|
|
var v = u1.redMul(h2)
|
|
var h3 = h2.redMul(h)
|
|
|
|
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 new ECJPoint(nx, ny, nz)
|
|
}
|
|
|
|
ECJPoint.prototype.mixedAdd = function (p) {
|
|
// O + P = P
|
|
if (this.inf) return p.toECJPoint()
|
|
|
|
// P + O = P
|
|
if (p.inf) return this
|
|
|
|
// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-1998-cmo-2
|
|
// with p.z = 1
|
|
// 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.isZero()) {
|
|
if (r.isZero()) return this.dbl()
|
|
return new ECJPoint(null, null, null)
|
|
}
|
|
|
|
var h2 = h.redSqr()
|
|
var v = u1.redMul(h2)
|
|
var h3 = h2.redMul(h)
|
|
|
|
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 new ECJPoint(nx, ny, nz)
|
|
}
|
|
|
|
ECJPoint.prototype.dbl = function () {
|
|
if (this.inf) return this
|
|
|
|
var nx
|
|
var ny
|
|
var nz
|
|
|
|
// Z = 1
|
|
if (this.zOne) {
|
|
// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl
|
|
// 1M + 5S + 6A + 3*2 + 1*3 + 1*8
|
|
|
|
// 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
|
|
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).redIAdd(yyyy).redIAdd(yyyy)
|
|
|
|
// 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 {
|
|
// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
|
|
// 2M + 5S + 6A + 3*2 + 1*3 + 1*8
|
|
|
|
// 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).redIAdd(c).redIAdd(c)
|
|
|
|
// 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 new ECJPoint(nx, ny, nz)
|
|
}
|
|
|
|
ECJPoint.prototype.dblp = function (pow) {
|
|
if (pow === 0 || this.inf) return this
|
|
|
|
var point = this
|
|
for (var i = 0; i < pow; i++) point = point.dbl()
|
|
|
|
return point
|
|
}
|
|
|
|
Object.defineProperty(ECJPoint.prototype, 'inf', {
|
|
enumerable: true,
|
|
get: function () {
|
|
return this.z.isZero()
|
|
}
|
|
})
|
|
|
|
module.exports = ECJPoint
|