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