sm9/bn256: add double & triple, fix gfpNeg issue, use Square as possible

This commit is contained in:
Sun Yimin 2023-07-11 17:30:48 +08:00 committed by GitHub
parent ba3cbd23c8
commit 9ec8d3bc04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 313 additions and 81 deletions

View File

@ -12,8 +12,8 @@ func lineFunctionAdd(r, p, rOut *twistPoint, q *curvePoint, r2, a, b, c *gfP2) {
H := (&gfP2{}).Sub(B, &r.x) // H = Xp * Zr^2 - Xr H := (&gfP2{}).Sub(B, &r.x) // H = Xp * Zr^2 - Xr
I := (&gfP2{}).SquareNC(H) // I = (Xp * Zr^2 - Xr)^2 = Xp^2*Zr^4 + Xr^2 - 2Xr*Xp*Zr^2 I := (&gfP2{}).SquareNC(H) // I = (Xp * Zr^2 - Xr)^2 = Xp^2*Zr^4 + Xr^2 - 2Xr*Xp*Zr^2
E := (&gfP2{}).Add(I, I) // E = 2*(Xp * Zr^2 - Xr)^2 E := (&gfP2{}).Double(I) // E = 2*(Xp * Zr^2 - Xr)^2
E.Add(E, E) // E = 4*(Xp * Zr^2 - Xr)^2 E.Double(E) // E = 4*(Xp * Zr^2 - Xr)^2
J := (&gfP2{}).MulNC(H, E) // J = 4*(Xp * Zr^2 - Xr)^3 J := (&gfP2{}).MulNC(H, E) // J = 4*(Xp * Zr^2 - Xr)^3
@ -29,7 +29,7 @@ func lineFunctionAdd(r, p, rOut *twistPoint, q *curvePoint, r2, a, b, c *gfP2) {
t := (&gfP2{}).Sub(V, &rOut.x) // t = V - rOut.x t := (&gfP2{}).Sub(V, &rOut.x) // t = V - rOut.x
t.Mul(t, L1) // t = L1*(V-rOut.x) t.Mul(t, L1) // t = L1*(V-rOut.x)
t2 := (&gfP2{}).MulNC(&r.y, J) t2 := (&gfP2{}).MulNC(&r.y, J)
t2.Add(t2, t2) // t2 = 2Yr * J t2.Double(t2) // t2 = 2Yr * J
rOut.y.Sub(t, t2) // rOut.y = L1*(V-rOut.x) - 2Yr*J rOut.y.Sub(t, t2) // rOut.y = L1*(V-rOut.x) - 2Yr*J
rOut.t.SquareNC(&rOut.z) rOut.t.SquareNC(&rOut.z)
@ -38,14 +38,14 @@ func lineFunctionAdd(r, p, rOut *twistPoint, q *curvePoint, r2, a, b, c *gfP2) {
t.Add(&p.y, &rOut.z).Square(t).Sub(t, r2).Sub(t, &rOut.t) t.Add(&p.y, &rOut.z).Square(t).Sub(t, r2).Sub(t, &rOut.t)
t2.Mul(L1, &p.x) t2.Mul(L1, &p.x)
t2.Add(t2, t2) // t2 = 2 L1 * Xp t2.Double(t2) // t2 = 2 L1 * Xp
a.Sub(t2, t) // a = 2 L1 * Xp - 2 Yp * rOut.z = 2 L1 * Xp - (Yp + rOut.Z)^2 + Yp^2 + rOut.Z^2 a.Sub(t2, t) // a = 2 L1 * Xp - 2 Yp * rOut.z = 2 L1 * Xp - (Yp + rOut.Z)^2 + Yp^2 + rOut.Z^2
c.MulScalar(&rOut.z, &q.y) // c = rOut.z * Yq c.MulScalar(&rOut.z, &q.y) // c = rOut.z * Yq
c.Add(c, c) // c = 2 * rOut.z * Yq c.Double(c) // c = 2 * rOut.z * Yq
b.Neg(L1) // b= -L1 b.Neg(L1) // b= -L1
b.MulScalar(b, &q.x).Add(b, b) // b = -2 * L1 * Xq b.MulScalar(b, &q.x).Double(b) // b = -2 * L1 * Xq
} }
func lineFunctionDouble(r, rOut *twistPoint, q *curvePoint, a, b, c *gfP2) { func lineFunctionDouble(r, rOut *twistPoint, q *curvePoint, a, b, c *gfP2) {
@ -56,9 +56,9 @@ func lineFunctionDouble(r, rOut *twistPoint, q *curvePoint, a, b, c *gfP2) {
C := (&gfP2{}).SquareNC(B) // C = Yr ^ 4 C := (&gfP2{}).SquareNC(B) // C = Yr ^ 4
D := (&gfP2{}).Add(&r.x, B) D := (&gfP2{}).Add(&r.x, B)
D.Square(D).Sub(D, A).Sub(D, C).Add(D, D) D.Square(D).Sub(D, A).Sub(D, C).Double(D)
E := (&gfP2{}).Add(A, A) // E := (&gfP2{}).Double(A) //
E.Add(E, A) // E = 3 * Xr ^ 2 E.Add(E, A) // E = 3 * Xr ^ 2
G := (&gfP2{}).SquareNC(E) // G = 9 * Xr^4 G := (&gfP2{}).SquareNC(E) // G = 9 * Xr^4
@ -68,23 +68,23 @@ func lineFunctionDouble(r, rOut *twistPoint, q *curvePoint, a, b, c *gfP2) {
rOut.z.Add(&r.y, &r.z).Square(&rOut.z).Sub(&rOut.z, B).Sub(&rOut.z, &r.t) // Z3 = (Yr + Zr)^2 - Yr^2 - Zr^2 = 2Yr*Zr rOut.z.Add(&r.y, &r.z).Square(&rOut.z).Sub(&rOut.z, B).Sub(&rOut.z, &r.t) // Z3 = (Yr + Zr)^2 - Yr^2 - Zr^2 = 2Yr*Zr
rOut.y.Sub(D, &rOut.x).Mul(&rOut.y, E) rOut.y.Sub(D, &rOut.x).Mul(&rOut.y, E)
t := (&gfP2{}).Add(C, C) // t = 2 * r.y ^ 4 t := (&gfP2{}).Double(C) // t = 2 * r.y ^ 4
t.Add(t, t).Add(t, t) // t = 8 * Yr ^ 4 t.Double(t).Double(t) // t = 8 * Yr ^ 4
rOut.y.Sub(&rOut.y, t) rOut.y.Sub(&rOut.y, t)
rOut.t.SquareNC(&rOut.z) rOut.t.SquareNC(&rOut.z)
t.Mul(E, &r.t).Add(t, t) // t = 2(E * Tr) t.Mul(E, &r.t).Double(t) // t = 2(E * Tr)
b.Neg(t) // b = -2(E * Tr) b.Neg(t) // b = -2(E * Tr)
b.MulScalar(b, &q.x) // b = -2(E * Tr * Xq) b.MulScalar(b, &q.x) // b = -2(E * Tr * Xq)
a.Add(&r.x, E) // a = Xr + E a.Add(&r.x, E) // a = Xr + E
a.Square(a).Sub(a, A).Sub(a, G) // a = (Xr + E) ^ 2 - A - G a.Square(a).Sub(a, A).Sub(a, G) // a = (Xr + E) ^ 2 - A - G
t.Add(B, B).Add(t, t) // t = 4B t.Double(B).Double(t) // t = 4B
a.Sub(a, t) // a = (Xr + E) ^ 2 - A - G - 4B a.Sub(a, t) // a = (Xr + E) ^ 2 - A - G - 4B
c.Mul(&rOut.z, &r.t) // c = rOut.z * Tr c.Mul(&rOut.z, &r.t) // c = rOut.z * Tr
c.Add(c, c).MulScalar(c, &q.y) // c = 2 rOut.z * Tr * Yq c.Double(c).MulScalar(c, &q.y) // c = 2 rOut.z * Tr * Yq
} }
// (ret.z + ret.y*w + ret.x*w^2)* ((cv+a) + b*w^2) // (ret.z + ret.y*w + ret.x*w^2)* ((cv+a) + b*w^2)

View File

@ -38,7 +38,7 @@ func (c *curvePoint) Set(a *curvePoint) {
func (c *curvePoint) polynomial(x *gfP) *gfP { func (c *curvePoint) polynomial(x *gfP) *gfP {
x3 := &gfP{} x3 := &gfP{}
gfpMul(x3, x, x) gfpSqr(x3, x, 1)
gfpMul(x3, x3, x) gfpMul(x3, x3, x)
gfpAdd(x3, x3, curveB) gfpAdd(x3, x3, curveB)
return x3 return x3
@ -52,7 +52,7 @@ func (c *curvePoint) IsOnCurve() bool {
} }
y2 := &gfP{} y2 := &gfP{}
gfpMul(y2, &c.y, &c.y) gfpSqr(y2, &c.y, 1)
x3 := c.polynomial(&c.x) x3 := c.polynomial(&c.x)
@ -98,8 +98,8 @@ func (c *curvePoint) Add(a, b *curvePoint) {
// by [u1:s1:z1·z2] and [u2:s2:z1·z2] // by [u1:s1:z1·z2] and [u2:s2:z1·z2]
// where u1 = x1·z2², s1 = y1·z2³ and u1 = x2·z1², s2 = y2·z1³ // where u1 = x1·z2², s1 = y1·z2³ and u1 = x2·z1², s2 = y2·z1³
z12, z22 := &gfP{}, &gfP{} z12, z22 := &gfP{}, &gfP{}
gfpMul(z12, &a.z, &a.z) gfpSqr(z12, &a.z, 1)
gfpMul(z22, &b.z, &b.z) gfpSqr(z22, &b.z, 1)
u1, u2 := &gfP{}, &gfP{} u1, u2 := &gfP{}, &gfP{}
gfpMul(u1, &a.x, z22) gfpMul(u1, &a.x, z22)
@ -123,10 +123,10 @@ func (c *curvePoint) Add(a, b *curvePoint) {
h := &gfP{} h := &gfP{}
gfpSub(h, u2, u1) gfpSub(h, u2, u1)
gfpAdd(t, h, h) gfpDouble(t, h)
// i = 4h² // i = 4h²
i := &gfP{} i := &gfP{}
gfpMul(i, t, t) gfpSqr(i, t, 1)
// j = 4h³ // j = 4h³
j := &gfP{} j := &gfP{}
gfpMul(j, h, i) gfpMul(j, h, i)
@ -138,15 +138,15 @@ func (c *curvePoint) Add(a, b *curvePoint) {
return return
} }
r := &gfP{} r := &gfP{}
gfpAdd(r, t, t) gfpDouble(r, t)
v := &gfP{} v := &gfP{}
gfpMul(v, u1, i) gfpMul(v, u1, i)
// t4 = 4(s2-s1)² // t4 = 4(s2-s1)²
t4, t6 := &gfP{}, &gfP{} t4, t6 := &gfP{}, &gfP{}
gfpMul(t4, r, r) gfpSqr(t4, r, 1)
gfpAdd(t, v, v) gfpDouble(t, v)
gfpSub(t6, t4, j) gfpSub(t6, t4, j)
gfpSub(&c.x, t6, t) gfpSub(&c.x, t6, t)
@ -156,13 +156,13 @@ func (c *curvePoint) Add(a, b *curvePoint) {
// y = - 2·s1·j - (s2-s1)(2x - 2i·u1) = r(v-x) - 2·s1·j // y = - 2·s1·j - (s2-s1)(2x - 2i·u1) = r(v-x) - 2·s1·j
gfpSub(t, v, &c.x) // t7 gfpSub(t, v, &c.x) // t7
gfpMul(t4, s1, j) // t8 gfpMul(t4, s1, j) // t8
gfpAdd(t6, t4, t4) // t9 gfpDouble(t6, t4) // t9
gfpMul(t4, r, t) // t10 gfpMul(t4, r, t) // t10
gfpSub(&c.y, t4, t6) gfpSub(&c.y, t4, t6)
// Set z = 2(u2-u1)·z1·z2 = 2h·z1·z2 // Set z = 2(u2-u1)·z1·z2 = 2h·z1·z2
gfpAdd(t, &a.z, &b.z) // t11 gfpAdd(t, &a.z, &b.z) // t11
gfpMul(t4, t, t) // t12 gfpSqr(t4, t, 1) // t12
gfpSub(t, t4, z12) // t13 gfpSub(t, t4, z12) // t13
gfpSub(t4, t, z22) // t14 gfpSub(t4, t, z22) // t14
gfpMul(&c.z, t4, h) gfpMul(&c.z, t4, h)
@ -171,31 +171,31 @@ func (c *curvePoint) Add(a, b *curvePoint) {
func (c *curvePoint) Double(a *curvePoint) { func (c *curvePoint) Double(a *curvePoint) {
// See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/doubling/dbl-2009-l.op3 // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/doubling/dbl-2009-l.op3
A, B, C := &gfP{}, &gfP{}, &gfP{} A, B, C := &gfP{}, &gfP{}, &gfP{}
gfpMul(A, &a.x, &a.x) gfpSqr(A, &a.x, 1)
gfpMul(B, &a.y, &a.y) gfpSqr(B, &a.y, 1)
gfpMul(C, B, B) gfpSqr(C, B, 1)
t, t2 := &gfP{}, &gfP{} t, t2 := &gfP{}, &gfP{}
gfpAdd(t, &a.x, B) gfpAdd(t, &a.x, B)
gfpMul(t2, t, t) gfpSqr(t2, t, 1)
gfpSub(t, t2, A) gfpSub(t, t2, A)
gfpSub(t2, t, C) gfpSub(t2, t, C)
d, e, f := &gfP{}, &gfP{}, &gfP{} d, e, f := &gfP{}, &gfP{}, &gfP{}
gfpAdd(d, t2, t2) gfpAdd(d, t2, t2)
gfpAdd(t, A, A) gfpDouble(t, A)
gfpAdd(e, t, A) gfpAdd(e, t, A)
gfpMul(f, e, e) gfpSqr(f, e, 1)
gfpAdd(t, d, d) gfpDouble(t, d)
gfpSub(&c.x, f, t) gfpSub(&c.x, f, t)
gfpMul(&c.z, &a.y, &a.z) gfpMul(&c.z, &a.y, &a.z)
gfpAdd(&c.z, &c.z, &c.z) gfpDouble(&c.z, &c.z)
gfpAdd(t, C, C) gfpDouble(t, C)
gfpAdd(t2, t, t) gfpDouble(t2, t)
gfpAdd(t, t2, t2) gfpDouble(t, t2)
gfpSub(&c.y, d, &c.x) gfpSub(&c.y, d, &c.x)
gfpMul(t2, e, &c.y) gfpMul(t2, e, &c.y)
gfpSub(&c.y, t2, t) gfpSub(&c.y, t2, t)
@ -232,7 +232,7 @@ func (c *curvePoint) MakeAffine() {
t, zInv2 := &gfP{}, &gfP{} t, zInv2 := &gfP{}, &gfP{}
gfpMul(t, &c.y, zInv) gfpMul(t, &c.y, zInv)
gfpMul(zInv2, zInv, zInv) gfpSqr(zInv2, zInv, 1)
gfpMul(&c.x, &c.x, zInv2) gfpMul(&c.x, &c.x, zInv2)
gfpMul(&c.y, t, zInv2) gfpMul(&c.y, t, zInv2)

View File

@ -258,11 +258,11 @@ func (e *gfP12) SpecialSquares(a *gfP12, n int) *gfP12 {
ty.Triple(v1) ty.Triple(v1)
tz.Triple(v2) tz.Triple(v2)
v0.Add(&a.x, &a.x) // (f12, f01) v0.Double(&a.x) // (f12, f01)
v0.y.Neg(&v0.y) v0.y.Neg(&v0.y)
v1.Add(&a.y, &a.y) // (f02, f10) v1.Double(&a.y) // (f02, f10)
v1.x.Neg(&v1.x) v1.x.Neg(&v1.x)
v2.Add(&a.z, &a.z) // (f11, f00) v2.Double(&a.z) // (f11, f00)
v2.y.Neg(&v2.y) v2.y.Neg(&v2.y)
v0.Add(ty, v0) v0.Add(ty, v0)
@ -285,11 +285,11 @@ func (e *gfP12) SpecialSquares(a *gfP12, n int) *gfP12 {
ty.Triple(v1) ty.Triple(v1)
tz.Triple(v2) tz.Triple(v2)
v0.Add(&in.x, &in.x) // (f12, f01) v0.Double(&in.x) // (f12, f01)
v0.y.Neg(&v0.y) v0.y.Neg(&v0.y)
v1.Add(&in.y, &in.y) // (f02, f10) v1.Double(&in.y) // (f02, f10)
v1.x.Neg(&v1.x) v1.x.Neg(&v1.x)
v2.Add(&in.z, &in.z) // (f11, f00) v2.Double(&in.z) // (f11, f00)
v2.y.Neg(&v2.y) v2.y.Neg(&v2.y)
v0.Add(ty, v0) v0.Add(ty, v0)
@ -321,11 +321,11 @@ func (e *gfP12) SpecialSquareNC(a *gfP12) *gfP12 {
ty.Triple(v1) ty.Triple(v1)
tz.Triple(v2) tz.Triple(v2)
v0.Add(&a.x, &a.x) // (f12, f01) v0.Double(&a.x) // (f12, f01)
v0.y.Neg(&v0.y) v0.y.Neg(&v0.y)
v1.Add(&a.y, &a.y) // (f02, f10) v1.Double(&a.y) // (f02, f10)
v1.x.Neg(&v1.x) v1.x.Neg(&v1.x)
v2.Add(&a.z, &a.z) // (f11, f00) v2.Double(&a.z) // (f11, f00)
v2.y.Neg(&v2.y) v2.y.Neg(&v2.y)
v0.Add(ty, v0) v0.Add(ty, v0)

View File

@ -75,13 +75,13 @@ func (e *gfP2) IsOne() bool {
func (e *gfP2) Conjugate(a *gfP2) *gfP2 { func (e *gfP2) Conjugate(a *gfP2) *gfP2 {
e.y.Set(&a.y) e.y.Set(&a.y)
gfpSub(&e.x, zero, &a.x) gfpNeg(&e.x, &a.x)
return e return e
} }
func (e *gfP2) Neg(a *gfP2) *gfP2 { func (e *gfP2) Neg(a *gfP2) *gfP2 {
gfpSub(&e.x, zero, &a.x) gfpNeg(&e.x, &a.x)
gfpSub(&e.y, zero, &a.y) gfpNeg(&e.y, &a.y)
return e return e
} }
@ -98,17 +98,14 @@ func (e *gfP2) Sub(a, b *gfP2) *gfP2 {
} }
func (e *gfP2) Double(a *gfP2) *gfP2 { func (e *gfP2) Double(a *gfP2) *gfP2 {
gfpAdd(&e.x, &a.x, &a.x) gfpDouble(&e.x, &a.x)
gfpAdd(&e.y, &a.y, &a.y) gfpDouble(&e.y, &a.y)
return e return e
} }
func (e *gfP2) Triple(a *gfP2) *gfP2 { func (e *gfP2) Triple(a *gfP2) *gfP2 {
gfpAdd(&e.x, &a.x, &a.x) gfpTriple(&e.x, &a.x)
gfpAdd(&e.y, &a.y, &a.y) gfpTriple(&e.y, &a.y)
gfpAdd(&e.x, &e.x, &a.x)
gfpAdd(&e.y, &e.y, &a.y)
return e return e
} }
@ -172,8 +169,8 @@ func (e *gfP2) MulUNC(a, b *gfP2) *gfP2 {
gfpMul(ty, tx, ty) gfpMul(ty, tx, ty)
gfpSub(ty, ty, v0) gfpSub(ty, ty, v0)
gfpSub(ty, ty, v1) gfpSub(ty, ty, v1)
gfpAdd(ty, ty, ty) gfpDouble(ty, ty)
gfpSub(ty, zero, ty) gfpNeg(ty, ty)
gfpSub(tx, v0, v1) gfpSub(tx, v0, v1)
gfpSub(tx, tx, v1) gfpSub(tx, tx, v1)
@ -187,8 +184,8 @@ func (e *gfP2) MulUNC(a, b *gfP2) *gfP2 {
// c0 = -2a1 // c0 = -2a1
func (e *gfP2) MulU1(a *gfP2) *gfP2 { func (e *gfP2) MulU1(a *gfP2) *gfP2 {
t := &gfP{} t := &gfP{}
gfpAdd(t, &a.x, &a.x) gfpDouble(t, &a.x)
gfpSub(t, zero, t) gfpNeg(t, t)
gfpCopy(&e.x, &a.y) gfpCopy(&e.x, &a.y)
gfpCopy(&e.y, t) gfpCopy(&e.y, t)
@ -212,12 +209,12 @@ func (e *gfP2) SquareNC(a *gfP2) *gfP2 {
ty := &e.y ty := &e.y
gfpAdd(ty, &a.x, &a.y) gfpAdd(ty, &a.x, &a.y)
gfpAdd(tx, &a.x, &a.x) gfpDouble(tx, &a.x)
gfpSub(tx, &a.y, tx) gfpSub(tx, &a.y, tx)
gfpMul(ty, tx, ty) gfpMul(ty, tx, ty)
gfpMul(tx, &a.x, &a.y) gfpMul(tx, &a.x, &a.y)
gfpAdd(ty, tx, ty) gfpAdd(ty, tx, ty)
gfpAdd(tx, tx, tx) gfpDouble(tx, tx)
return e return e
} }
@ -240,14 +237,14 @@ func (e *gfP2) SquareUNC(a *gfP2) *gfP2 {
ty := &e.y ty := &e.y
gfpAdd(tx, &a.x, &a.y) gfpAdd(tx, &a.x, &a.y)
gfpAdd(ty, &a.x, &a.x) gfpDouble(ty, &a.x)
gfpSub(ty, &a.y, ty) gfpSub(ty, &a.y, ty)
gfpMul(tx, tx, ty) gfpMul(tx, tx, ty)
gfpMul(ty, &a.x, &a.y) gfpMul(ty, &a.x, &a.y)
gfpAdd(tx, tx, ty) gfpAdd(tx, tx, ty)
gfpAdd(ty, ty, ty) gfpDouble(ty, ty)
gfpAdd(ty, ty, ty) gfpDouble(ty, ty)
gfpSub(ty, zero, ty) gfpNeg(ty, ty)
return e return e
} }
@ -263,14 +260,14 @@ func (e *gfP2) Invert(a *gfP2) *gfP2 {
// ftp://136.206.11.249/pub/crypto/pairings.pdf // ftp://136.206.11.249/pub/crypto/pairings.pdf
t1, t2, t3 := &gfP{}, &gfP{}, &gfP{} t1, t2, t3 := &gfP{}, &gfP{}, &gfP{}
gfpSqr(t1, &a.x, 1) gfpSqr(t1, &a.x, 1)
gfpAdd(t3, t1, t1) gfpDouble(t3, t1)
gfpSqr(t2, &a.y, 1) gfpSqr(t2, &a.y, 1)
gfpAdd(t3, t3, t2) gfpAdd(t3, t3, t2)
inv := &gfP{} inv := &gfP{}
inv.Invert(t3) // inv = (2 * a.x ^ 2 + a.y ^ 2) ^ (-1) inv.Invert(t3) // inv = (2 * a.x ^ 2 + a.y ^ 2) ^ (-1)
gfpSub(t1, zero, &a.x) gfpNeg(t1, &a.x)
gfpMul(&e.x, t1, inv) // x = - a.x * inv gfpMul(&e.x, t1, inv) // x = - a.x * inv
gfpMul(&e.y, &a.y, inv) // y = a.y * inv gfpMul(&e.y, &a.y, inv) // y = a.y * inv

View File

@ -152,10 +152,11 @@ func BenchmarkGfP2MulU(b *testing.B) {
*fromBigInt(bigFromHex("17509B092E845C1266BA0D262CBEE6ED0736A96FA347C8BD856DC76B84EBEB96")), *fromBigInt(bigFromHex("17509B092E845C1266BA0D262CBEE6ED0736A96FA347C8BD856DC76B84EBEB96")),
*fromBigInt(bigFromHex("A7CF28D519BE3DA65F3170153D278FF247EFBA98A71A08116215BBA5C999A7C7")), *fromBigInt(bigFromHex("A7CF28D519BE3DA65F3170153D278FF247EFBA98A71A08116215BBA5C999A7C7")),
} }
t := &gfP2{}
b.ReportAllocs() b.ReportAllocs()
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
t := &gfP2{}
t.MulU(x, y) t.MulU(x, y)
} }
} }
@ -184,6 +185,32 @@ func BenchmarkGfP2SquareU(b *testing.B) {
} }
} }
func BenchmarkGfP2Neg(b *testing.B) {
x := &gfP2{
*fromBigInt(bigFromHex("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141")),
*fromBigInt(bigFromHex("3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B")),
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
gfpNeg(&x.x, &x.x)
gfpNeg(&x.y, &x.y)
}
}
func BenchmarkGfP2Neg2(b *testing.B) {
x := &gfP2{
*fromBigInt(bigFromHex("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141")),
*fromBigInt(bigFromHex("3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B")),
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
gfpSub(&x.x, zero, &x.x)
gfpSub(&x.y, zero, &x.y)
}
}
/* /*
func Test_gfP2QuadraticResidue(t *testing.T) { func Test_gfP2QuadraticResidue(t *testing.T) {
x := &gfP2{ x := &gfP2{

View File

@ -73,6 +73,12 @@ func (e *gfP4) Add(a, b *gfP4) *gfP4 {
return e return e
} }
func (e *gfP4) Double(a *gfP4) *gfP4 {
e.x.Double(&a.x)
e.y.Double(&a.y)
return e
}
func (e *gfP4) Triple(a *gfP4) *gfP4 { func (e *gfP4) Triple(a *gfP4) *gfP4 {
e.x.Triple(&a.x) e.x.Triple(&a.x)
e.y.Triple(&a.y) e.y.Triple(&a.y)

View File

@ -104,6 +104,51 @@ TEXT ·gfpAdd(SB),0,$0-24
storeBlock(R8,R9,R10,R11, 0(DI)) storeBlock(R8,R9,R10,R11, 0(DI))
RET RET
TEXT ·gfpDouble(SB),0,$0-16
MOVQ a+0(FP), DI
MOVQ b+8(FP), SI
loadBlock(0(SI), R8,R9,R10,R11)
XORQ R12, R12
ADDQ R8, R8
ADCQ R9, R9
ADCQ R10, R10
ADCQ R11, R11
ADCQ $0, R12
gfpCarry(R8,R9,R10,R11, R13,R14,CX,AX,R12)
storeBlock(R8,R9,R10,R11, 0(DI))
RET
TEXT ·gfpTriple(SB),0,$0-16
MOVQ a+0(FP), DI
MOVQ b+8(FP), SI
loadBlock(0(SI), R8,R9,R10,R11)
XORQ R12, R12
ADDQ R8, R8
ADCQ R9, R9
ADCQ R10, R10
ADCQ R11, R11
ADCQ $0, R12
gfpCarry(R8,R9,R10,R11, R13,R14,CX,AX,R12)
XORQ R12, R12
ADDQ 0(SI), R8
ADCQ 8(SI), R9
ADCQ 16(SI), R10
ADCQ 24(SI), R11
ADCQ $0, R12
gfpCarry(R8,R9,R10,R11, R13,R14,CX,AX,R12)
storeBlock(R8,R9,R10,R11, 0(DI))
RET
TEXT ·gfpSub(SB),0,$0-24 TEXT ·gfpSub(SB),0,$0-24
MOVQ a+8(FP), DI MOVQ a+8(FP), DI
MOVQ b+16(FP), SI MOVQ b+16(FP), SI

View File

@ -109,6 +109,83 @@ TEXT ·gfpAdd(SB),0,$0-24
storeBlock(R1,R2,R3,R4, 0(R0)) storeBlock(R1,R2,R3,R4, 0(R0))
RET RET
TEXT ·gfpDouble(SB),0,$0-16
MOVD a+8(FP), R0
loadBlock(0(R0), R1,R2,R3,R4)
loadModulus(R9,R10,R11,R12)
MOVD ZR, R0
ADDS R1, R1
ADCS R2, R2
ADCS R3, R3
ADCS R4, R4
ADCS ZR, R0
SUBS R9, R1, R5
SBCS R10, R2, R6
SBCS R11, R3, R7
SBCS R12, R4, R8
SBCS ZR, R0, R0
CSEL CS, R5, R1, R1
CSEL CS, R6, R2, R2
CSEL CS, R7, R3, R3
CSEL CS, R8, R4, R4
MOVD c+0(FP), R0
storeBlock(R1,R2,R3,R4, 0(R0))
RET
TEXT ·gfpTriple(SB),0,$0-16
MOVD a+8(FP), R0
loadBlock(0(R0), R1,R2,R3,R4)
MOVD R1, R19
MOVD R2, R20
MOVD R3, R21
MOVD R4, R22
loadModulus(R9,R10,R11,R12)
MOVD ZR, R0
ADDS R1, R1
ADCS R2, R2
ADCS R3, R3
ADCS R4, R4
ADCS ZR, R0
SUBS R9, R1, R5
SBCS R10, R2, R6
SBCS R11, R3, R7
SBCS R12, R4, R8
SBCS ZR, R0, R0
CSEL CS, R5, R1, R1
CSEL CS, R6, R2, R2
CSEL CS, R7, R3, R3
CSEL CS, R8, R4, R4
MOVD ZR, R0
ADDS R19, R1
ADCS R20, R2
ADCS R21, R3
ADCS R22, R4
ADCS ZR, R0
SUBS R9, R1, R5
SBCS R10, R2, R6
SBCS R11, R3, R7
SBCS R12, R4, R8
SBCS ZR, R0, R0
CSEL CS, R5, R1, R1
CSEL CS, R6, R2, R2
CSEL CS, R7, R3, R3
CSEL CS, R8, R4, R4
MOVD c+0(FP), R0
storeBlock(R1,R2,R3,R4, 0(R0))
RET
TEXT ·gfpSub(SB),0,$0-24 TEXT ·gfpSub(SB),0,$0-24
MOVD a+8(FP), R0 MOVD a+8(FP), R0
loadBlock(0(R0), R1,R2,R3,R4) loadBlock(0(R0), R1,R2,R3,R4)

View File

@ -26,6 +26,16 @@ func gfpNeg(c, a *gfP)
//go:noescape //go:noescape
func gfpAdd(c, a, b *gfP) func gfpAdd(c, a, b *gfP)
// Set c = a + a
//
//go:noescape
func gfpDouble(c, a *gfP)
// Set c = a + a + a
//
//go:noescape
func gfpTriple(c, a *gfP)
// Set c = a - b, if c is negative, then c = c + p // Set c = a - b, if c is negative, then c = c + p
// //
//go:noescape //go:noescape

View File

@ -42,6 +42,15 @@ func gfpAdd(c, a, b *gfP) {
gfpCarry(c, carry) gfpCarry(c, carry)
} }
func gfpDouble(c, a *gfP) {
gfpAdd(c, a, a)
}
func gfpTriple(c, a *gfP) {
gfpAdd(c, a, a)
gfpAdd(c, c, a)
}
func gfpSub(c, a, b *gfP) { func gfpSub(c, a, b *gfP) {
t := &gfP{} t := &gfP{}

View File

@ -225,3 +225,64 @@ func BenchmarkGfPSqr(b *testing.B) {
gfpSqr(ret, x, 1) gfpSqr(ret, x, 1)
} }
} }
func BenchmarkGfPTriple(b *testing.B) {
x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596"))
b.ReportAllocs()
b.ResetTimer()
ret := &gfP{}
for i := 0; i < b.N; i++ {
gfpTriple(ret, x)
}
}
func BenchmarkGfPTriple2(b *testing.B) {
x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596"))
b.ReportAllocs()
b.ResetTimer()
ret := &gfP{}
for i := 0; i < b.N; i++ {
gfpAdd(ret, x, x)
gfpAdd(ret, ret, x)
}
}
func BenchmarkGfPDouble(b *testing.B) {
x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596"))
b.ReportAllocs()
b.ResetTimer()
ret := &gfP{}
for i := 0; i < b.N; i++ {
gfpDouble(ret, x)
}
}
func BenchmarkGfPDouble2(b *testing.B) {
x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596"))
b.ReportAllocs()
b.ResetTimer()
ret := &gfP{}
for i := 0; i < b.N; i++ {
gfpAdd(ret, x, x)
}
}
func BenchmarkGfPNeg(b *testing.B) {
x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596"))
b.ReportAllocs()
b.ResetTimer()
ret := &gfP{}
for i := 0; i < b.N; i++ {
gfpNeg(ret, x)
}
}
func BenchmarkGfPNeg2(b *testing.B) {
x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596"))
b.ReportAllocs()
b.ResetTimer()
ret := &gfP{}
for i := 0; i < b.N; i++ {
gfpSub(ret, zero, x)
}
}

View File

@ -114,7 +114,7 @@ func (c *twistPoint) Add(a, b *twistPoint) {
h := (&gfP2{}).Sub(u2, u1) h := (&gfP2{}).Sub(u2, u1)
xEqual := h.IsZero() xEqual := h.IsZero()
t.Add(h, h) t.Double(h)
i := (&gfP2{}).SquareNC(t) i := (&gfP2{}).SquareNC(t)
j := (&gfP2{}).MulNC(h, i) j := (&gfP2{}).MulNC(h, i)
@ -124,18 +124,18 @@ func (c *twistPoint) Add(a, b *twistPoint) {
c.Double(a) c.Double(a)
return return
} }
r := (&gfP2{}).Add(t, t) r := (&gfP2{}).Double(t)
v := (&gfP2{}).MulNC(u1, i) v := (&gfP2{}).MulNC(u1, i)
t4 := (&gfP2{}).SquareNC(r) t4 := (&gfP2{}).SquareNC(r)
t.Add(v, v) t.Double(v)
t6 := (&gfP2{}).Sub(t4, j) t6 := (&gfP2{}).Sub(t4, j)
c.x.Sub(t6, t) c.x.Sub(t6, t)
t.Sub(v, &c.x) // t7 t.Sub(v, &c.x) // t7
t4.Mul(s1, j) // t8 t4.Mul(s1, j) // t8
t6.Add(t4, t4) // t9 t6.Double(t4) // t9
t4.Mul(r, t) // t10 t4.Mul(r, t) // t10
c.y.Sub(t4, t6) c.y.Sub(t4, t6)
@ -156,20 +156,20 @@ func (c *twistPoint) Double(a *twistPoint) {
t2 := (&gfP2{}).SquareNC(t) t2 := (&gfP2{}).SquareNC(t)
t.Sub(t2, A) t.Sub(t2, A)
t2.Sub(t, C) t2.Sub(t, C)
d := (&gfP2{}).Add(t2, t2) d := (&gfP2{}).Double(t2)
t.Add(A, A) t.Double(A)
e := (&gfP2{}).Add(t, A) e := (&gfP2{}).Add(t, A)
f := (&gfP2{}).SquareNC(e) f := (&gfP2{}).SquareNC(e)
t.Add(d, d) t.Double(d)
c.x.Sub(f, t) c.x.Sub(f, t)
c.z.Mul(&a.y, &a.z) c.z.Mul(&a.y, &a.z)
c.z.Add(&c.z, &c.z) c.z.Double(&c.z)
t.Add(C, C) t.Double(C)
t2.Add(t, t) t2.Double(t)
t.Add(t2, t2) t.Double(t2)
c.y.Sub(d, &c.x) c.y.Sub(d, &c.x)
t2.Mul(e, &c.y) t2.Mul(e, &c.y)
c.y.Sub(t2, t) c.y.Sub(t2, t)