emmansun / gmsm

ShangMi (SM) cipher suites for golang (Go语言商用密码软件)

Home Page:https://emmansun.github.io/gmsm

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

sm9/bn256: Implement complete addition formula

emmansun opened this issue · comments

References:

Code:

var threeCurveB = newGFp(3 * 5)

func (c *curvePoint) Add(p1, p2 *curvePoint) {
	// Complete addition formula for a = 0 from "Complete addition formulas for
	// prime order elliptic curves" (https://eprint.iacr.org/2015/1060), §3.2.

	t0, t1, t2, t3, t4 := new(gfP), new(gfP), new(gfP), new(gfP), new(gfP)
	x3, y3, z3 := new(gfP), new(gfP), new(gfP)
	gfpMul(t0, &p1.x, &p2.x)    // t0 := X1 * X2
	gfpMul(t1, &p1.y, &p2.y)    // t1 := Y1 * Y2
	gfpMul(t2, &p1.z, &p2.z)    // t2 := Z1 * Z2
	gfpAdd(t3, &p1.x, &p1.y)    // t3 := X1 + Y1
	gfpAdd(t4, &p2.x, &p2.y)    // t4 := X2 + Y2
	gfpMul(t3, t3, t4)          // t3 := t3 * t4 = (X1 + Y1) * (X2 + Y2)
	gfpAdd(t4, t0, t1)          // t4 := t0 + t1
	gfpSub(t3, t3, t4)          // t3 := t3 - t4 = X1 * Y2 + X2 * Y1
	gfpAdd(t4, &p1.y, &p1.z)    // t4 := Y1 + Z1
	gfpAdd(x3, &p2.y, &p2.z)    // X3 := Y2 + Z2
	gfpMul(t4, t4, x3)          // t4 := t4 * X3 = (Y1 + Z1)(Y2 + Z2)
	gfpAdd(x3, t1, t2)          // X3 := t1 + t2
	gfpSub(t4, t4, x3)          // t4 := t4 - X3 = Y1 * Z2 + Y2 * Z1
	gfpAdd(x3, &p1.x, &p1.z)    // X3 := X1 + Z1
	gfpAdd(y3, &p2.x, &p2.z)    // Y3 := X2 + Z2
	gfpMul(x3, x3, y3)          // X3 := X3 * Y3
	gfpAdd(y3, t0, t2)          // Y3 := t0 + t2
	gfpSub(y3, x3, y3)          // Y3 := X3 - Y3 = X1 * Z2 + X2 * Z1
	gfpDouble(x3, t0)           // X3 := t0 + t0
	gfpAdd(t0, x3, t0)          // t0 := X3 + t0 = 3 X1 * X2
	gfpMul(t2, threeCurveB, t2) // t2 := 3b * t2 = 3b * Z1 * Z2
	gfpAdd(z3, t1, t2)          // Z3 := t1 + t2 = Y1 * Y2 + 3b * Z1 * Z2
	gfpSub(t1, t1, t2)          // t1 := t1 - t2 = Y1 * Y2 - 3b * Z1 * Z2
	gfpMul(y3, threeCurveB, y3) // Y3 = 3b * Y3 = 3b(X1 * Z2 + X2 * Z1)
	gfpMul(x3, t4, y3)          // X3 := t4 * Y3 = 3b(X1 * Z2 + X2 * Z1)(Y1 * Z2 + Y2 * Z1)
	gfpMul(t2, t3, t1)          // t2 := t3 * t1 = (X1 * Y2 + X2 * Y1)(Y1 * Y2 - 3b * Z1 * Z2)
	gfpSub(x3, t2, x3)          // X3 := t2 - X3 = (X1 * Y2 + X2 * Y1)(Y1 * Y2 - 3b * Z1 * Z2) - 3b(X1 * Z2 + X2 * Z1)(Y1 * Z2 + Y2 * Z1)
	gfpMul(y3, y3, t0)          // Y3 := Y3 * t0 = 9b(X1 * Z2 + X2 * Z1)(X1 * X2)
	gfpMul(t1, t1, z3)          // t1 := t1 * Z3 = (Y1 * Y2 - 3b * Z1 * Z2)(Y1 * Y2 + 3b * Z1 * Z2)
	gfpAdd(y3, t1, y3)          // Y3 := t1 + Y3 = (Y1 * Y2 - 3b * Z1 * Z2)(Y1 * Y2 + 3b * Z1 * Z2) + 9b(X1 * Z2 + X2 * Z1)(X1 * X2)
	gfpMul(t0, t0, t3)          // t0 := t0 * t3 = 3 X1 * X2 (X1 * Y2 + X2 * Y1)
	gfpMul(z3, z3, t4)          // Z3 := Z3 * t4 = (Y1 * Y2 + 3b * Z1 * Z2)(Y1 * Z2 + Y2 * Z1)
	gfpAdd(z3, z3, t0)          // Z3 := Z3 + t0 = (Y1 * Y2 + 3b * Z1 * Z2)(Y1 * Z2 + Y2 * Z1) + 3 X1 * X2 (X1 * Y2 + X2 * Y1)

	c.x.Set(x3)
	c.y.Set(y3)
	c.z.Set(z3)
}

image

对照了好多遍,哪里有错?

啊,原来是投影不同!

goos: windows
goarch: amd64
pkg: github.com/emmansun/gmsm/sm9/bn256
cpu: Intel(R) Core(TM) i5-9500 CPU @ 3.00GHz
BenchmarkAddPoint
BenchmarkAddPoint/Add_complete
BenchmarkAddPoint/Add_complete-6
 4503493	       259.7 ns/op	       0 B/op	       0 allocs/op
BenchmarkAddPoint/Add_traditional
BenchmarkAddPoint/Add_traditional-6
 3892330	       302.5 ns/op	       0 B/op	       0 allocs/op

BenchmarkDoublePoint
BenchmarkDoublePoint/Double_complete
BenchmarkDoublePoint/Double_complete-6
 7551348	       162.7 ns/op	       0 B/op	       0 allocs/op
BenchmarkDoublePoint/Double_traditional
BenchmarkDoublePoint/Double_traditional-6
 7771260	       158.6 ns/op	       0 B/op	       0 allocs/op
PASS