Skip to content

Commit

Permalink
Implement Granger-Scott faster squaring in the cyclotomic subgroup.
Browse files Browse the repository at this point in the history
  • Loading branch information
armfazh authored and bwesterb committed Jan 3, 2024
1 parent c48866b commit ede59c5
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 6 deletions.
37 changes: 36 additions & 1 deletion ecc/bls12381/ff/cyclo6.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,44 @@ func (z Cyclo6) IsEqual(x *Cyclo6) int { return (Fp12)(z).IsEqual((*Fp12)(x))
func (z Cyclo6) IsIdentity() int { i := &Fp12{}; i.SetOne(); return z.IsEqual((*Cyclo6)(i)) }
func (z *Cyclo6) Frob(x *Cyclo6) { (*Fp12)(z).Frob((*Fp12)(x)) }
func (z *Cyclo6) Mul(x, y *Cyclo6) { (*Fp12)(z).Mul((*Fp12)(x), (*Fp12)(y)) }
func (z *Cyclo6) Sqr(x *Cyclo6) { (*Fp12)(z).Sqr((*Fp12)(x)) }
func (z *Cyclo6) Inv(x *Cyclo6) { *z = *x; z[1].Neg() }
func (z *Cyclo6) exp(x *Cyclo6, n []byte) { (*Fp12)(z).Exp((*Fp12)(x), n) }
func (z *Cyclo6) Sqr(x *Cyclo6) {
// Method of Granger-Scott.
// Page 7 of "Faster Squaring in the Cyclotomic Subgroup of Sixth Degree Extensions"
// https://www.iacr.org/archive/pkc2010/60560212/60560212.pdf
var xx, zz Fp12Cubic
xx.FromFp12((*Fp12)(x))

a, b, c := &xx[0], &xx[1], &xx[2]
z0, z1, z2 := &zz[0], &zz[1], &zz[2]

var aa, bb, cc, tt Fp4
aa.Sqr(a)
bb.Sqr(b)
cc.Sqr(c)
cc.mulT(&cc)

z0.Add(&aa, &aa)
z0.Add(z0, &aa)
tt.Add(a, a)
tt.Cjg()
z0.Sub(z0, &tt)

z1.Add(&cc, &cc)
z1.Add(z1, &cc)
tt.Add(b, b)
tt.Cjg()
z1.Add(z1, &tt)

z2.Add(&bb, &bb)
z2.Add(z2, &bb)
tt.Add(c, c)
tt.Cjg()
z2.Sub(z2, &tt)

(*Fp12)(z).FromFp12Cubic(&zz)
}

// PowToX computes z = x^paramX, where paramX is the parameter of the BLS curve.
func (z *Cyclo6) PowToX(x *Cyclo6) {
Expand Down
13 changes: 13 additions & 0 deletions ecc/bls12381/ff/cyclo6_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,19 @@ func TestCyclo6(t *testing.T) {
}
}
})
t.Run("sqr_sqrfasr", func(t *testing.T) {
var want, got Cyclo6
for i := 0; i < testTimes; i++ {
x := randomCyclo6(t)

// Specialized square in cyclotomic vs Generic Square in Fp12
got.Sqr(x)
(*Fp12)(&want).Sqr((*Fp12)(x))
if got.IsEqual(&want) == 0 {
test.ReportError(t, got, want, x)
}
}
})

t.Run("invFp12_vs_invCyclo6", func(t *testing.T) {
var want, got Fp12
Expand Down
2 changes: 1 addition & 1 deletion ecc/bls12381/ff/fp12cubic.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (z *Fp12Cubic) FromFp12(x *Fp12) {
z[2][1] = x[1][2] // w^5
}

func (z *Fp12) FromFp12Alt(x *Fp12Cubic) {
func (z *Fp12) FromFp12Cubic(x *Fp12Cubic) {
z[0][0] = x[0][0] // w^0
z[1][0] = x[1][0] // w^1
z[0][1] = x[2][0] // w^2
Expand Down
6 changes: 3 additions & 3 deletions ecc/bls12381/ff/fp12cubic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func TestFP12CubicAdd(t *testing.T) {
yalt.FromFp12(y)
zalt.Add(&xalt, &yalt)
z.Add(x, y)
zcmp.FromFp12Alt(&zalt)
zcmp.FromFp12Cubic(&zalt)
if z.IsEqual(&zcmp) == 0 {
test.ReportError(t, z, zcmp, x, y)
}
Expand All @@ -35,7 +35,7 @@ func TestFP12CubicMul(t *testing.T) {
yalt.FromFp12(y)
zalt.Mul(&xalt, &yalt)
z.Mul(x, y)
zcmp.FromFp12Alt(&zalt)
zcmp.FromFp12Cubic(&zalt)
if z.IsEqual(&zcmp) == 0 {
test.ReportError(t, z, zcmp, x, y)
}
Expand All @@ -51,7 +51,7 @@ func TestFP12AltSqr(t *testing.T) {
xalt.FromFp12(x)
zalt.Sqr(&xalt)
z.Sqr(x)
zcmp.FromFp12Alt(&zalt)
zcmp.FromFp12Cubic(&zalt)
if z.IsEqual(&zcmp) == 0 {
test.ReportError(t, z, zcmp, x)
}
Expand Down
2 changes: 2 additions & 0 deletions ecc/bls12381/ff/fp4.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ func (z *Fp4) IsEqual(x *Fp4) int {
return z[0].IsEqual(&x[0]) & z[1].IsEqual(&x[1])
}

func (z *Fp4) Cjg() { z[1].Neg() }

func (z *Fp4) Neg() {
z[0].Neg()
z[1].Neg()
Expand Down
2 changes: 1 addition & 1 deletion ecc/bls12381/pair.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func miller(f *ff.Fp12, P *G1, Q *G2) {
acc.MulLine(acc, g)
}
}
f.FromFp12Alt(acc)
f.FromFp12Cubic(acc)
f.Cjg() // inverts f as paramX is negative.
}

Expand Down

0 comments on commit ede59c5

Please sign in to comment.