mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-28 13:16:19 +08:00
sm9: reduce gfp2 mul
This commit is contained in:
parent
fab159f5f0
commit
a454c5f5ec
@ -251,6 +251,13 @@ func (e *gfP12) Invert(a *gfP12) *gfP12 {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *gfP12) Neg(a *gfP12) *gfP12 {
|
||||
e.x.Neg(&a.x)
|
||||
e.y.Neg(&a.y)
|
||||
e.z.Neg(&a.z)
|
||||
return e
|
||||
}
|
||||
|
||||
// (z + y*w + x*w^2)^p
|
||||
//= z^p + y^p*w*w^(p-1)+x^p*w^2*(w^2)^(p-1)
|
||||
// w2ToP2Minus1 = vToPMinus1 * wToPMinus1
|
||||
|
@ -5,28 +5,21 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
var testdataP4 = gfP4{
|
||||
gfP2{
|
||||
*fromBigInt(bigFromHex("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141")),
|
||||
*fromBigInt(bigFromHex("3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B")),
|
||||
},
|
||||
gfP2{
|
||||
*fromBigInt(bigFromHex("17509B092E845C1266BA0D262CBEE6ED0736A96FA347C8BD856DC76B84EBEB96")),
|
||||
*fromBigInt(bigFromHex("A7CF28D519BE3DA65F3170153D278FF247EFBA98A71A08116215BBA5C999A7C7")),
|
||||
},
|
||||
}
|
||||
|
||||
func Test_gfP12Square(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")),
|
||||
},
|
||||
},
|
||||
testdataP4,
|
||||
testdataP4,
|
||||
*(&gfP4{}).SetOne(),
|
||||
}
|
||||
xmulx := &gfP12{}
|
||||
@ -42,30 +35,7 @@ func Test_gfP12Square(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func Test_gfP12Invert(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{}).SetOne(),
|
||||
}
|
||||
func testGfP12Invert(t *testing.T, x *gfP12) {
|
||||
xInv := &gfP12{}
|
||||
xInv.Invert(x)
|
||||
|
||||
@ -74,35 +44,27 @@ func Test_gfP12Invert(t *testing.T) {
|
||||
if !y.IsOne() {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func Test_gfP12Invert(t *testing.T) {
|
||||
x := &gfP12{
|
||||
testdataP4,
|
||||
testdataP4,
|
||||
*(&gfP4{}).SetOne(),
|
||||
}
|
||||
testGfP12Invert(t, x)
|
||||
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")),
|
||||
},
|
||||
},
|
||||
testdataP4,
|
||||
testdataP4,
|
||||
*(&gfP4{}).SetZero(),
|
||||
}
|
||||
xInv.Invert(x)
|
||||
|
||||
y.Mul(x, xInv)
|
||||
if !y.IsOne() {
|
||||
t.Fail()
|
||||
testGfP12Invert(t, x)
|
||||
x = &gfP12{
|
||||
testdataP4,
|
||||
testdataP4,
|
||||
testdataP4,
|
||||
}
|
||||
testGfP12Invert(t, x)
|
||||
}
|
||||
|
||||
// Generate wToPMinus1
|
||||
@ -227,36 +189,9 @@ func Test_gfP12FrobeniusP3_Case2(t *testing.T) {
|
||||
|
||||
func Test_gfP12Frobenius(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")),
|
||||
},
|
||||
},
|
||||
testdataP4,
|
||||
testdataP4,
|
||||
testdataP4,
|
||||
}
|
||||
expected := &gfP12{}
|
||||
expected.Exp(x, p)
|
||||
@ -269,36 +204,9 @@ func Test_gfP12Frobenius(t *testing.T) {
|
||||
|
||||
func Test_gfP12FrobeniusP2(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")),
|
||||
},
|
||||
},
|
||||
testdataP4,
|
||||
testdataP4,
|
||||
testdataP4,
|
||||
}
|
||||
expected := &gfP12{}
|
||||
p2 := new(big.Int).Mul(p, p)
|
||||
@ -312,36 +220,9 @@ func Test_gfP12FrobeniusP2(t *testing.T) {
|
||||
|
||||
func Test_gfP12FrobeniusP3(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")),
|
||||
},
|
||||
},
|
||||
testdataP4,
|
||||
testdataP4,
|
||||
testdataP4,
|
||||
}
|
||||
expected := &gfP12{}
|
||||
p3 := new(big.Int).Mul(p, p)
|
||||
@ -356,36 +237,9 @@ func Test_gfP12FrobeniusP3(t *testing.T) {
|
||||
|
||||
func Test_gfP12FrobeniusP6(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")),
|
||||
},
|
||||
},
|
||||
testdataP4,
|
||||
testdataP4,
|
||||
testdataP4,
|
||||
}
|
||||
expected := &gfP12{}
|
||||
p6 := new(big.Int).Mul(p, p)
|
||||
@ -412,3 +266,22 @@ func Test_W3(t *testing.T) {
|
||||
t.Errorf("not expected")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGfP12Frobenius(b *testing.B) {
|
||||
x := &gfP12{
|
||||
testdataP4,
|
||||
testdataP4,
|
||||
testdataP4,
|
||||
}
|
||||
expected := &gfP12{}
|
||||
expected.Exp(x, p)
|
||||
got := &gfP12{}
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
got.Frobenius(x)
|
||||
if *expected != *got {
|
||||
b.Errorf("got %v, expected %v", got, expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,9 +9,9 @@ import (
|
||||
// http://eprint.iacr.org/2006/471.pdf.
|
||||
|
||||
// gfP2 implements a field of size p² as a quadratic extension of the base field
|
||||
// where i²=-2.
|
||||
// where u²=-2, beta=-2.
|
||||
type gfP2 struct {
|
||||
x, y gfP // value is xi+y.
|
||||
x, y gfP // value is xu+y.
|
||||
}
|
||||
|
||||
func gfP2Decode(in *gfP2) *gfP2 {
|
||||
@ -105,45 +105,50 @@ func (e *gfP2) Triple(a *gfP2) *gfP2 {
|
||||
// See "Multiplication and Squaring in Pairing-Friendly Fields",
|
||||
// http://eprint.iacr.org/2006/471.pdf
|
||||
// The Karatsuba method
|
||||
//(a0+a1*i)(b0+b1*i)=c0+c1*i, where
|
||||
//(a0+a1*u)(b0+b1*u)=c0+c1*u, where
|
||||
//c0 = a0*b0 - 2a1*b1
|
||||
//c1 = (a0 + a1)(b0 + b1) - a0*b0 - a1*b1 = a0*b1 + a1*b0
|
||||
func (e *gfP2) Mul(a, b *gfP2) *gfP2 {
|
||||
tx, t := &gfP{}, &gfP{}
|
||||
gfpMul(tx, &a.x, &b.y)
|
||||
gfpMul(t, &b.x, &a.y)
|
||||
gfpAdd(tx, tx, t)
|
||||
tx, ty, v0, v1 := &gfP{}, &gfP{}, &gfP{}, &gfP{}
|
||||
|
||||
ty := &gfP{}
|
||||
gfpMul(ty, &a.y, &b.y)
|
||||
gfpMul(t, &a.x, &b.x)
|
||||
gfpMul(t, t, two)
|
||||
gfpSub(ty, ty, t)
|
||||
gfpMul(v0, &a.y, &b.y)
|
||||
gfpMul(v1, &a.x, &b.x)
|
||||
|
||||
gfpAdd(tx, &a.x, &a.y)
|
||||
gfpAdd(ty, &b.x, &b.y)
|
||||
gfpMul(tx, tx, ty)
|
||||
gfpSub(tx, tx, v0)
|
||||
gfpSub(tx, tx, v1)
|
||||
|
||||
gfpSub(ty, v0, v1)
|
||||
gfpSub(ty, ty, v1)
|
||||
|
||||
e.x.Set(tx)
|
||||
e.y.Set(ty)
|
||||
return e
|
||||
}
|
||||
|
||||
// MulU: a * b * i
|
||||
//(a0+a1*i)(b0+b1*i)*i=c0+c1*i, where
|
||||
//c1 = (a0*b0 - 2a1*b1)i
|
||||
// MulU: a * b * u
|
||||
//(a0+a1*u)(b0+b1*u)*u=c0+c1*u, where
|
||||
//c1 = (a0*b0 - 2a1*b1)u
|
||||
//c0 = -2 * ((a0 + a1)(b0 + b1) - a0*b0 - a1*b1) = -2 * (a0*b1 + a1*b0)
|
||||
func (e *gfP2) MulU(a, b *gfP2) *gfP2 {
|
||||
// ty = -2 * (a0 * b1 + a1 * b0)
|
||||
ty, t := &gfP{}, &gfP{}
|
||||
gfpMul(ty, &a.x, &b.y)
|
||||
gfpMul(t, &b.x, &a.y)
|
||||
gfpAdd(ty, ty, t)
|
||||
tx, ty, v0, v1 := &gfP{}, &gfP{}, &gfP{}, &gfP{}
|
||||
|
||||
gfpMul(v0, &a.y, &b.y)
|
||||
gfpMul(v1, &a.x, &b.x)
|
||||
|
||||
gfpAdd(tx, &a.x, &a.y)
|
||||
gfpAdd(ty, &b.x, &b.y)
|
||||
|
||||
gfpMul(ty, tx, ty)
|
||||
gfpSub(ty, ty, v0)
|
||||
gfpSub(ty, ty, v1)
|
||||
gfpAdd(ty, ty, ty)
|
||||
gfpNeg(ty, ty)
|
||||
|
||||
// tx = a0 * b0 - 2 * a1 * b1
|
||||
tx := &gfP{}
|
||||
gfpMul(tx, &a.y, &b.y)
|
||||
gfpMul(t, &a.x, &b.x)
|
||||
gfpMul(t, t, two)
|
||||
gfpSub(tx, tx, t)
|
||||
|
||||
gfpSub(tx, v0, v1)
|
||||
gfpSub(tx, tx, v1)
|
||||
|
||||
e.x.Set(tx)
|
||||
e.y.Set(ty)
|
||||
@ -152,7 +157,7 @@ func (e *gfP2) MulU(a, b *gfP2) *gfP2 {
|
||||
|
||||
func (e *gfP2) Square(a *gfP2) *gfP2 {
|
||||
// Complex squaring algorithm:
|
||||
// (xi+y)² = y^2-2*x^2 + 2*i*x*y
|
||||
// (xu+y)² = y^2-2*x^2 + 2*u*x*y
|
||||
tx, ty := &gfP{}, &gfP{}
|
||||
gfpMul(tx, &a.x, &a.x)
|
||||
gfpMul(ty, &a.y, &a.y)
|
||||
@ -169,7 +174,7 @@ func (e *gfP2) Square(a *gfP2) *gfP2 {
|
||||
|
||||
func (e *gfP2) SquareU(a *gfP2) *gfP2 {
|
||||
// Complex squaring algorithm:
|
||||
// (xi+y)²*i = (y^2-2*x^2)i - 4*x*y
|
||||
// (xu+y)²*u = (y^2-2*x^2)u - 4*x*y
|
||||
|
||||
tx, ty := &gfP{}, &gfP{}
|
||||
// tx = a0^2 - 2 * a1^2
|
||||
@ -231,10 +236,10 @@ func (e *gfP2) Exp(f *gfP2, power *big.Int) *gfP2 {
|
||||
return e
|
||||
}
|
||||
|
||||
// (xi+y)^p = x * i^p + y
|
||||
// = x * i * i^(p-1) + y
|
||||
// = (-x)*i + y
|
||||
// here i^(p-1) = -1
|
||||
// (xu+y)^p = x * u^p + y
|
||||
// = x * u * u^(p-1) + y
|
||||
// = (-x)*u + y
|
||||
// here u^(p-1) = -1
|
||||
func (e *gfP2) Frobenius(a *gfP2) *gfP2 {
|
||||
e.Conjugate(a)
|
||||
return e
|
||||
|
@ -126,6 +126,52 @@ func Test_gfP2Sqrt(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGfP2Mul(b *testing.B) {
|
||||
x := &gfP2{
|
||||
*fromBigInt(bigFromHex("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141")),
|
||||
*fromBigInt(bigFromHex("3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B")),
|
||||
}
|
||||
y := &gfP2{
|
||||
*fromBigInt(bigFromHex("17509B092E845C1266BA0D262CBEE6ED0736A96FA347C8BD856DC76B84EBEB96")),
|
||||
*fromBigInt(bigFromHex("A7CF28D519BE3DA65F3170153D278FF247EFBA98A71A08116215BBA5C999A7C7")),
|
||||
}
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
t := &gfP2{}
|
||||
t.Mul(x, y)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGfP2MulU(b *testing.B) {
|
||||
x := &gfP2{
|
||||
*fromBigInt(bigFromHex("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141")),
|
||||
*fromBigInt(bigFromHex("3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B")),
|
||||
}
|
||||
y := &gfP2{
|
||||
*fromBigInt(bigFromHex("17509B092E845C1266BA0D262CBEE6ED0736A96FA347C8BD856DC76B84EBEB96")),
|
||||
*fromBigInt(bigFromHex("A7CF28D519BE3DA65F3170153D278FF247EFBA98A71A08116215BBA5C999A7C7")),
|
||||
}
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
t := &gfP2{}
|
||||
t.MulU(x, y)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGfP2Square(b *testing.B) {
|
||||
x := &gfP2{
|
||||
*fromBigInt(bigFromHex("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141")),
|
||||
*fromBigInt(bigFromHex("3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B")),
|
||||
}
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
x.Square(x)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
func Test_gfP2QuadraticResidue(t *testing.T) {
|
||||
x := &gfP2{
|
||||
|
@ -8,9 +8,9 @@ import "math/big"
|
||||
//
|
||||
|
||||
// gfP4 implements the field of size p^4 as a quadratic extension of gfP2
|
||||
// where u²=i.
|
||||
// where v²=ξ and ξ=u.
|
||||
type gfP4 struct {
|
||||
x, y gfP2 // value is xi+y.
|
||||
x, y gfP2 // value is xv+y.
|
||||
}
|
||||
|
||||
func gfP4Decode(in *gfP4) *gfP4 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user