diff --git a/sm9/bn256/bn_pair_test.go b/sm9/bn256/bn_pair_test.go index 0fce722..019f29d 100644 --- a/sm9/bn256/bn_pair_test.go +++ b/sm9/bn256/bn_pair_test.go @@ -98,39 +98,41 @@ func Test_Pairing_B2_2(t *testing.T) { } } +var testGfp12 = &gfP12{ + gfP4{ + gfP2{ + *fromBigInt(bigFromHex("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141")), + *fromBigInt(bigFromHex("3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B")), + }, + gfP2{ + *fromBigInt(bigFromHex("17509B092E845C1266BA0D262CBEE6ED0736A96FA347C8BD856DC76B84EBEB96")), + *fromBigInt(bigFromHex("A7CF28D519BE3DA65F3170153D278FF247EFBA98A71A08116215BBA5C999A7C7")), + }, + }, + gfP4{ + gfP2{ + *fromBigInt(bigFromHex("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141")), + *fromBigInt(bigFromHex("3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B")), + }, + gfP2{ + *fromBigInt(bigFromHex("17509B092E845C1266BA0D262CBEE6ED0736A96FA347C8BD856DC76B84EBEB96")), + *fromBigInt(bigFromHex("A7CF28D519BE3DA65F3170153D278FF247EFBA98A71A08116215BBA5C999A7C7")), + }, + }, + gfP4{ + gfP2{ + *fromBigInt(bigFromHex("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141")), + *fromBigInt(bigFromHex("3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B")), + }, + gfP2{ + *fromBigInt(bigFromHex("17509B092E845C1266BA0D262CBEE6ED0736A96FA347C8BD856DC76B84EBEB96")), + *fromBigInt(bigFromHex("A7CF28D519BE3DA65F3170153D278FF247EFBA98A71A08116215BBA5C999A7C7")), + }, + }, +} + func Test_finalExponentiation(t *testing.T) { - x := &gfP12{ - gfP4{ - gfP2{ - *fromBigInt(bigFromHex("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141")), - *fromBigInt(bigFromHex("3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B")), - }, - gfP2{ - *fromBigInt(bigFromHex("17509B092E845C1266BA0D262CBEE6ED0736A96FA347C8BD856DC76B84EBEB96")), - *fromBigInt(bigFromHex("A7CF28D519BE3DA65F3170153D278FF247EFBA98A71A08116215BBA5C999A7C7")), - }, - }, - gfP4{ - gfP2{ - *fromBigInt(bigFromHex("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141")), - *fromBigInt(bigFromHex("3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B")), - }, - gfP2{ - *fromBigInt(bigFromHex("17509B092E845C1266BA0D262CBEE6ED0736A96FA347C8BD856DC76B84EBEB96")), - *fromBigInt(bigFromHex("A7CF28D519BE3DA65F3170153D278FF247EFBA98A71A08116215BBA5C999A7C7")), - }, - }, - gfP4{ - gfP2{ - *fromBigInt(bigFromHex("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141")), - *fromBigInt(bigFromHex("3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B")), - }, - gfP2{ - *fromBigInt(bigFromHex("17509B092E845C1266BA0D262CBEE6ED0736A96FA347C8BD856DC76B84EBEB96")), - *fromBigInt(bigFromHex("A7CF28D519BE3DA65F3170153D278FF247EFBA98A71A08116215BBA5C999A7C7")), - }, - }, - } + x := testGfp12 got := finalExponentiation(x) exp := new(big.Int).Exp(p, big.NewInt(12), nil) @@ -142,3 +144,20 @@ func Test_finalExponentiation(t *testing.T) { t.Errorf("got %v, expected %v\n", got, expected) } } + +func BenchmarkFinalExponentiation(b *testing.B) { + x := testGfp12 + exp := new(big.Int).Exp(p, big.NewInt(12), nil) + exp.Sub(exp, big.NewInt(1)) + exp.Div(exp, Order) + expected := (&gfP12{}).Exp(x, exp) + + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + got := finalExponentiation(x) + if *got != *expected { + b.Errorf("got %v, expected %v\n", got, expected) + } + } +} diff --git a/sm9/bn256/gfp12.go b/sm9/bn256/gfp12.go index ddd9cba..ea5f1b4 100644 --- a/sm9/bn256/gfp12.go +++ b/sm9/bn256/gfp12.go @@ -141,24 +141,33 @@ func (e *gfP12) Mul(a, b *gfP12) *gfP12 { // +y0*z1*w + y0*y1*w^2 + y0*x1*v // +x0*z1*w^2 + x0*y1*v + x0*x1*v*w //=(z0*z1+y0*x1*v+x0*y1*v) + (z0*y1+y0*z1+x0*x1*v)w + (z0*x1 + y0*y1 + x0*z1)*w^2 - tx, ty, tz, t := &gfP4{}, &gfP4{}, &gfP4{}, &gfP4{} - tz.Mul(&a.z, &b.z) - t.MulV(&a.y, &b.x) - tz.Add(tz, t) - t.MulV(&a.x, &b.y) - tz.Add(tz, t) + tx, ty, tz, t, v0, v1, v2 := &gfP4{}, &gfP4{}, &gfP4{}, &gfP4{}, &gfP4{}, &gfP4{}, &gfP4{} + v0.Mul(&a.z, &b.z) + v1.Mul(&a.y, &b.y) + v2.Mul(&a.x, &b.x) - ty.Mul(&a.z, &b.y) - t.Mul(&a.y, &b.z) - ty.Add(ty, t) - t.MulV(&a.x, &b.x) + t.Add(&a.y, &a.x) + tz.Add(&b.y, &b.x) + t.Mul(t, tz) + t.Sub(t, v1) + t.Sub(t, v2) + t.MulV1(t) + tz.Add(t, v0) + + t.Add(&a.z, &a.y) + ty.Add(&b.z, &b.y) + ty.Mul(t, ty) + ty.Sub(ty, v0) + ty.Sub(ty, v1) + t.MulV1(v2) ty.Add(ty, t) - tx.Mul(&a.z, &b.x) - t.Mul(&a.y, &b.y) - tx.Add(tx, t) - t.Mul(&a.x, &b.z) - tx.Add(tx, t) + t.Add(&a.z, &a.x) + tx.Add(&b.z, &b.x) + tx.Mul(tx, t) + tx.Sub(tx, v0) + tx.Add(tx, v1) + tx.Sub(tx, v2) e.x.Set(tx) e.y.Set(ty) diff --git a/sm9/bn256/gfp4.go b/sm9/bn256/gfp4.go index 96c3c57..9a00444 100644 --- a/sm9/bn256/gfp4.go +++ b/sm9/bn256/gfp4.go @@ -143,6 +143,18 @@ func (e *gfP4) MulV(a, b *gfP4) *gfP4 { return e } +// MulV1: a * v +//(a0+a1*v)*v=c0+c1*v, where +// c0 = a1*u +// c1 = a0 +func (e *gfP4) MulV1(a *gfP4) *gfP4 { + tx := (&gfP2{}).Set(&a.y) + + e.y.MulU1(&a.x) + e.x.Set(tx) + return e +} + func (e *gfP4) Square(a *gfP4) *gfP4 { // Complex squaring algorithm: // (xv+y)² = (x^2*u + y^2) + 2*x*y*v