Skip to content

Commit

Permalink
Special squaring loop for use on elements in T_6(gfP2)
Browse files Browse the repository at this point in the history
  • Loading branch information
emmansun authored Jul 13, 2023
1 parent 63a5902 commit b532ebb
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 6 deletions.
113 changes: 113 additions & 0 deletions gfp12.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,45 @@ func (c *gfP12) Exp(a *gfP12, power *big.Int) *gfP12 {
return c
}

func (e *gfP12) SpecialPowV(a *gfP12) *gfP12 {
t0, t1, t2 := &gfP12{}, &gfP12{}, &gfP12{}

t0.SpecialSquare(a)
t0.SpecialSquare(t0)
t0.SpecialSquare(t0) // t0 = a ^ 8
t1.SpecialSquare(t0)
t1.SpecialSquare(t1)
t1.SpecialSquare(t1) // t1 = a ^ 64
t2.Conjugate(t0) // t2 = a ^ -8
t2.Mul(t2, a) // t2 = a ^ -7
t2.Mul(t2, t1) // t2 = a ^ 57
t2.SpecialSquare(t2)
t2.SpecialSquare(t2)
t2.SpecialSquare(t2)
t2.SpecialSquare(t2)
t2.SpecialSquare(t2)
t2.SpecialSquare(t2)
t2.SpecialSquare(t2) // t2 = a ^ (2^7 * 57) = a ^ 7296
t2.Mul(t2, a) // t2 = a ^ 7297
t2.SpecialSquare(t2)
t2.SpecialSquare(t2)
t2.SpecialSquare(t2)
t2.SpecialSquare(t2)
t2.SpecialSquare(t2)
t2.SpecialSquare(t2)
t2.SpecialSquare(t2)
t2.SpecialSquare(t2) // t2 = a ^ (7297 * 256) = a ^ 1868032
e.Mul(t2, a)
return e
}

func (e *gfP12) SpecialPowU(a *gfP12) *gfP12 {
e.SpecialPowV(a)
e.SpecialPowV(e)
e.SpecialPowV(e)
return e
}

func (e *gfP12) Square(a *gfP12) *gfP12 {
// Complex squaring algorithm
v0 := (&gfP6{}).Mul(&a.x, &a.y)
Expand All @@ -174,6 +213,80 @@ func (e *gfP12) Square(a *gfP12) *gfP12 {
return e
}

// Special squaring loop for use on elements in T_6(gfP2) (after the
// easy part of the final exponentiation. Used in the hard part
// of the final exponentiation. Function uses formulas in
// Granger/Scott (PKC2010).
func (e *gfP12) SpecialSquare(a *gfP12) *gfP12 {
tmp := &gfP12{}

f02 := &tmp.y.x
f01 := &tmp.y.y
f00 := &tmp.y.z
f12 := &tmp.x.x
f11 := &tmp.x.y
f10 := &tmp.x.z

t00, t01, t02, t10, t11, t12 := &gfP2{}, &gfP2{}, &gfP2{}, &gfP2{}, &gfP2{}, &gfP2{}

gfP4Square(t11, t00, &a.x.y, &a.y.z)
gfP4Square(t12, t01, &a.y.x, &a.x.z)
gfP4Square(t02, t10, &a.x.x, &a.y.y)

f00.MulXi(t02)
t02.Set(t10)
t10.Set(f00)

f00.Add(t00, t00)
t00.Add(f00, t00)
f00.Add(t01, t01)
t01.Add(f00, t01)
f00.Add(t02, t02)
t02.Add(f00, t02)
f00.Add(t10, t10)
t10.Add(f00, t10)
f00.Add(t11, t11)
t11.Add(f00, t11)
f00.Add(t12, t12)
t12.Add(f00, t12)

f00.Add(&a.y.z, &a.y.z)
f00.Neg(f00)
f01.Add(&a.y.y, &a.y.y)
f01.Neg(f01)
f02.Add(&a.y.x, &a.y.x)
f02.Neg(f02)
f10.Add(&a.x.z, &a.x.z)
f11.Add(&a.x.y, &a.x.y)
f12.Add(&a.x.x, &a.x.x)

f00.Add(f00, t00)
f01.Add(f01, t01)
f02.Add(f02, t02)
f10.Add(f10, t10)
f11.Add(f11, t11)
f12.Add(f12, t12)

return e.Set(tmp)
}

// Implicit gfP4 squaring for Granger/Scott special squaring in final expo
// gfP4Square takes two gfP2 x, y representing the gfP4 element.
func gfP4Square(retX, retY, x, y *gfP2) {
t1, t2 := &gfP2{}, &gfP2{}

t1.Square(x)
t2.Square(y)

retX.Add(x, y)
retX.Square(retX)
retX.Sub(retX, t1)
retX.Sub(retX, t2) // retX = 2xy

retY.MulXi(t1)
retY.Add(retY, t2) // retY = x^2*xi + y^2
}

func (e *gfP12) Invert(a *gfP12) *gfP12 {
// See "Implementing cryptographic pairings", M. Scott, section 3.2.
// ftp://136.206.11.249/pub/crypto/pairings.pdf
Expand Down
84 changes: 84 additions & 0 deletions gfp12_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package bn256

import (
"math/big"
"testing"
)

func TestGfP12SpecialSquare(t *testing.T) {
in := gfP12Gen

got := &gfP12{}
expected := &gfP12{}

got.SpecialSquare(in)
expected.Square(in)

if *got != *expected {
t.Errorf("not same got=%v, expected=%v", got, expected)
}
}

func TestGfp12SpecialPowV(t *testing.T) {
in := gfP12Gen

got := &gfP12{}
expected := &gfP12{}

got.SpecialPowV(in)
expected.Exp(in, big.NewInt(1868033))

if *got != *expected {
t.Errorf("not same got=%v, expected=%v", got, expected)
}
}

func TestGfp12SpecialPowU(t *testing.T) {
in := gfP12Gen

got := &gfP12{}
expected := &gfP12{}

got.SpecialPowU(in)
expected.Exp(in, u)

if *got != *expected {
t.Errorf("not same got=%v, expected=%v", got, expected)
}
}

func BenchmarkGfp12Square(b *testing.B) {
got := &gfP12{}
b.ResetTimer()

for i := 0; i < b.N; i++ {
got.Square(gfP12Gen)
}
}

func BenchmarkGfp12SpecialSquare(b *testing.B) {
got := &gfP12{}
b.ResetTimer()

for i := 0; i < b.N; i++ {
got.SpecialSquare(gfP12Gen)
}
}

func BenchmarkGfp12ExpU(b *testing.B) {
got := &gfP12{}
b.ResetTimer()

for i := 0; i < b.N; i++ {
got.Exp(gfP12Gen, u)
}
}

func BenchmarkGfp12SpecialPowU(b *testing.B) {
got := &gfP12{}
b.ResetTimer()

for i := 0; i < b.N; i++ {
got.SpecialPowU(gfP12Gen)
}
}
12 changes: 6 additions & 6 deletions optate.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,9 @@ func finalExponentiation(in *gfP12) *gfP12 {
fp2 := (&gfP12{}).FrobeniusP2(t1)
fp3 := (&gfP12{}).Frobenius(fp2)

fu := (&gfP12{}).Exp(t1, u)
fu2 := (&gfP12{}).Exp(fu, u)
fu3 := (&gfP12{}).Exp(fu2, u)
fu := (&gfP12{}).SpecialPowU(t1)
fu2 := (&gfP12{}).SpecialPowU(fu)
fu3 := (&gfP12{}).SpecialPowU(fu2)

y3 := (&gfP12{}).Frobenius(fu)
fu2p := (&gfP12{}).Frobenius(fu2)
Expand All @@ -245,14 +245,14 @@ func finalExponentiation(in *gfP12) *gfP12 {
y6 := (&gfP12{}).Mul(fu3, fu3p)
y6.Conjugate(y6)

t0 := (&gfP12{}).Square(y6)
t0 := (&gfP12{}).SpecialSquare(y6)
t0.Mul(t0, y4).Mul(t0, y5)
t1.Mul(y3, y5).Mul(t1, t0)
t0.Mul(t0, y2)
t1.Square(t1).Mul(t1, t0).Square(t1)
t1.SpecialSquare(t1).Mul(t1, t0).SpecialSquare(t1)
t0.Mul(t1, y1)
t1.Mul(t1, y0)
t0.Square(t0).Mul(t0, t1)
t0.SpecialSquare(t0).Mul(t0, t1)

return t0
}
Expand Down

0 comments on commit b532ebb

Please sign in to comment.