Skip to content

Commit

Permalink
perf(bls12-377): implement a variant of Karabina cyclo square
Browse files Browse the repository at this point in the history
  • Loading branch information
yelhousni committed Nov 23, 2023
1 parent d7e8d78 commit f52c4cb
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 41 deletions.
94 changes: 84 additions & 10 deletions std/algebra/native/fields_bls12377/e12.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,65 @@ func (e *E12) Square(api frontend.API, x E12) *E12 {
return e
}

func (e *E12) CyclotomicSquareKarabina12345(api frontend.API, x E12) *E12 {

var h1, h2, h3, h4, h5, g1g5, g3g2, t E2

// h4 = -g4 + 3((g3+g5)(g1+c*g2)-g1g5-c*g3g2)
g1g5.Mul(api, x.C0.B1, x.C1.B2)
g3g2.Mul(api, x.C1.B0, x.C0.B2)
h4.MulByNonResidue(api, x.C0.B2)
h4.Add(api, h4, x.C0.B1)
t.Add(api, x.C1.B0, x.C1.B2)
h4.Mul(api, h4, t)
h4.Sub(api, h4, g1g5)
t.MulByNonResidue(api, g3g2)
h4.Sub(api, h4, t)
h4.MulByFp(api, h4, newInt("3"))
e.C1.B1.Sub(api, h4, x.C1.B1)

// h3 = 2(g3+3c*g1g5)
h3.MulByNonResidue(api, g1g5)
h3.MulByFp(api, h3, newInt("3"))
h3.Add(api, h3, x.C1.B0)
e.C1.B0.MulByFp(api, h3, newInt("2"))

// h2 = 3((g1+g5)(g1+c*g5)-c*g1g5-g1g5)-2g2
t.MulByNonResidue(api, x.C1.B2)
t.Add(api, t, x.C0.B1)
h2.Add(api, x.C1.B2, x.C0.B1)
h2.Mul(api, h2, t)
h2.Sub(api, h2, g1g5)
t.MulByNonResidue(api, g1g5)
h2.Sub(api, h2, t)
h2.MulByFp(api, h2, newInt("3"))
t.MulByFp(api, x.C0.B2, newInt("2"))
e.C0.B2.Sub(api, h2, t)

// h1 = 3((g3+g2)(g3+c*g2)-c*g3g2-g3g2)-2g1
t.MulByNonResidue(api, x.C0.B2)
t.Add(api, t, x.C1.B0)
h1.Add(api, x.C0.B2, x.C1.B0)
h1.Mul(api, h1, t)
h1.Sub(api, h1, g3g2)
t.MulByNonResidue(api, g3g2)
h1.Sub(api, h1, t)
h1.MulByFp(api, h1, newInt("3"))
t.MulByFp(api, x.C0.B1, newInt("2"))
e.C0.B1.Sub(api, h1, t)

// h5 = 2(g5+3g3g2)
h5.MulByFp(api, g3g2, newInt("3"))
h5.Add(api, h5, x.C1.B2)
e.C1.B2.MulByFp(api, h5, newInt("2"))

return e
}

// Karabina's compressed cyclotomic square
// https://eprint.iacr.org/2010/542.pdf
// Th. 3.2 with minor modifications to fit our tower
func (e *E12) CyclotomicSquareCompressed(api frontend.API, x E12) *E12 {
func (e *E12) CyclotomicSquareKarabina2345(api frontend.API, x E12) *E12 {

var t [7]E2

Expand Down Expand Up @@ -260,8 +315,34 @@ func (e *E12) CyclotomicSquareCompressed(api frontend.API, x E12) *E12 {
return e
}

// Decompress Karabina's cyclotomic square result
func (e *E12) Decompress(api frontend.API, x E12) *E12 {
// DecompressKarabina12345 Karabina's cyclotomic square result SQR12345
func (e *E12) DecompressKarabina12345(api frontend.API, x E12) *E12 {

var h0, t0, t1 E2

// h0 = (2g4^2 + g3g5 - 3g2g1)*c + 1
t0.Mul(api, x.C0.B1, x.C0.B2)
t0.MulByFp(api, t0, newInt("3"))
t1.Mul(api, x.C1.B0, x.C1.B2)
h0.Square(api, x.C1.B1)
h0.MulByFp(api, h0, newInt("2"))
h0.Add(api, h0, t1)
h0.Sub(api, h0, t0)
h0.MulByNonResidue(api, h0)
var one E2
one.SetOne()
e.C0.B0.Add(api, h0, one)
e.C0.B1 = x.C0.B1
e.C0.B2 = x.C0.B2
e.C1.B0 = x.C1.B0
e.C1.B1 = x.C1.B1
e.C1.B2 = x.C1.B2

return e
}

// DecompressKarabina2345 Karabina's cyclotomic square result SQR2345
func (e *E12) DecompressKarabina2345(api frontend.API, x E12) *E12 {

var t [3]E2
var _t [2]E2
Expand Down Expand Up @@ -542,13 +623,6 @@ func (e *E12) Select(api frontend.API, b frontend.Variable, r1, r2 E12) *E12 {
return e
}

// nSquareCompressed repeated compressed cyclotmic square
func (e *E12) nSquareCompressed(api frontend.API, n int) {
for i := 0; i < n; i++ {
e.CyclotomicSquareCompressed(api, *e)
}
}

// Assign a value to self (witness assignment)
func (e *E12) Assign(a *bls12377.E12) {
e.C0.Assign(&a.C0)
Expand Down
30 changes: 22 additions & 8 deletions std/algebra/native/fields_bls12377/e12_pairing.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@ package fields_bls12377

import "github.com/consensys/gnark/frontend"

// nSquareKarabina2345 repeated compressed cyclotmic square
func (e *E12) nSquareKarabina2345(api frontend.API, n int) {
for i := 0; i < n; i++ {
e.CyclotomicSquareKarabina2345(api, *e)
}
}

// nSquareKarabina12345 repeated compressed cyclotmic square
func (e *E12) nSquareKarabina12345(api frontend.API, n int) {
for i := 0; i < n; i++ {
e.CyclotomicSquareKarabina12345(api, *e)
}
}

// Square034 squares a sparse element in Fp12
func (e *E12) Square034(api frontend.API, x E12) *E12 {
var c0, c2, c3 E6
Expand Down Expand Up @@ -116,20 +130,20 @@ func (e *E12) Expt(api frontend.API, e1 E12, exponent uint64) *E12 {

res := e1

res.nSquareCompressed(api, 5)
res.Decompress(api, res)
res.nSquareKarabina2345(api, 5)
res.DecompressKarabina2345(api, res)
res.Mul(api, res, e1)
x33 := res
res.nSquareCompressed(api, 7)
res.Decompress(api, res)
res.nSquareKarabina2345(api, 7)
res.DecompressKarabina2345(api, res)
res.Mul(api, res, x33)
res.nSquareCompressed(api, 4)
res.Decompress(api, res)
res.nSquareKarabina2345(api, 4)
res.DecompressKarabina2345(api, res)
res.Mul(api, res, e1)
res.CyclotomicSquare(api, res)
res.Mul(api, res, e1)
res.nSquareCompressed(api, 46)
res.Decompress(api, res)
res.nSquareKarabina2345(api, 46)
res.DecompressKarabina2345(api, res)
res.Mul(api, res, e1)

*e = res
Expand Down
12 changes: 6 additions & 6 deletions std/algebra/native/fields_bls12377/e12_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,25 +198,25 @@ func TestFp12CyclotomicSquare(t *testing.T) {

}

type fp12CycloSquareCompressed struct {
type fp12CycloSquareKarabina2345 struct {
A E12
B E12 `gnark:",public"`
}

func (circuit *fp12CycloSquareCompressed) Define(api frontend.API) error {
func (circuit *fp12CycloSquareKarabina2345) Define(api frontend.API) error {

var u, v E12
u.Square(api, circuit.A)
v.CyclotomicSquareCompressed(api, circuit.A)
v.Decompress(api, v)
v.CyclotomicSquareKarabina2345(api, circuit.A)
v.DecompressKarabina2345(api, v)
u.AssertIsEqual(api, v)
u.AssertIsEqual(api, circuit.B)
return nil
}

func TestFp12CyclotomicSquareCompressed(t *testing.T) {
func TestFp12CyclotomicSquareKarabina2345(t *testing.T) {

var circuit, witness fp12CycloSquareCompressed
var circuit, witness fp12CycloSquareKarabina2345

// witness values
var a, b bls12377.E12
Expand Down
12 changes: 6 additions & 6 deletions std/algebra/native/fields_bls24315/e24.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ func (e *E24) Square(api frontend.API, x E24) *E24 {

// Karabina's compressed cyclotomic square
// https://eprint.iacr.org/2010/542.pdf
func (e *E24) CyclotomicSquareCompressed(api frontend.API, x E24) *E24 {
func (e *E24) CyclotomicSquareKarabina2345(api frontend.API, x E24) *E24 {
var t [7]E4

// t0 = g1²
Expand Down Expand Up @@ -257,8 +257,8 @@ func (e *E24) CyclotomicSquareCompressed(api frontend.API, x E24) *E24 {
return e
}

// Decompress Karabina's cyclotomic square result
func (e *E24) Decompress(api frontend.API, x E24) *E24 {
// DecompressKarabina2345 Karabina's cyclotomic square result
func (e *E24) DecompressKarabina2345(api frontend.API, x E24) *E24 {

var t [3]E4
var _t [2]E4
Expand Down Expand Up @@ -549,10 +549,10 @@ func (e *E24) DivUnchecked(api frontend.API, e1, e2 E24) *E24 {
return e
}

// nSquareCompressed repeated compressed cyclotmic square
func (e *E24) nSquareCompressed(api frontend.API, n int) {
// nSquareKarabina2345 repeated compressed cyclotmic square
func (e *E24) nSquareKarabina2345(api frontend.API, n int) {
for i := 0; i < n; i++ {
e.CyclotomicSquareCompressed(api, *e)
e.CyclotomicSquareKarabina2345(api, *e)
}
}

Expand Down
8 changes: 4 additions & 4 deletions std/algebra/native/fields_bls24315/e24_pairing.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ func (e *E24) Expt(api frontend.API, x E24, exponent uint64) *E24 {

res.nSquare(api, 2)
res.Mul(api, res, xInv)
res.nSquareCompressed(api, 8)
res.Decompress(api, res)
res.nSquareKarabina2345(api, 8)
res.DecompressKarabina2345(api, res)
res.Mul(api, res, xInv)
res.nSquare(api, 2)
res.Mul(api, res, x)
res.nSquareCompressed(api, 20)
res.Decompress(api, res)
res.nSquareKarabina2345(api, 20)
res.DecompressKarabina2345(api, res)
res.Mul(api, res, xInv)
res.Conjugate(api, res)

Expand Down
14 changes: 7 additions & 7 deletions std/algebra/native/fields_bls24315/e24_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,25 +194,25 @@ func TestFp24CyclotomicSquare(t *testing.T) {

}

type fp24CycloSquareCompressed struct {
type fp24CycloSquareKarabina2345 struct {
A E24
B E24 `gnark:",public"`
}

func (circuit *fp24CycloSquareCompressed) Define(api frontend.API) error {
func (circuit *fp24CycloSquareKarabina2345) Define(api frontend.API) error {

var u, v E24
u.Square(api, circuit.A)
v.CyclotomicSquareCompressed(api, circuit.A)
v.Decompress(api, v)
v.CyclotomicSquareKarabina2345(api, circuit.A)
v.DecompressKarabina2345(api, v)
u.AssertIsEqual(api, v)
u.AssertIsEqual(api, circuit.B)
return nil
}

func TestFp24CyclotomicSquareCompressed(t *testing.T) {
func TestFp24CyclotomicSquareKarabina2345(t *testing.T) {

var circuit, witness fp24CycloSquareCompressed
var circuit, witness fp24CycloSquareKarabina2345

// witness values
var a, b bls24315.E24
Expand All @@ -225,7 +225,7 @@ func TestFp24CyclotomicSquareCompressed(t *testing.T) {
tmp.Mul(&tmp, &a)
a.FrobeniusQuad(&tmp).Mul(&a, &tmp)

b.CyclotomicSquare(&a)
b.CyclotomicSquareCompressed(&a)
b.DecompressKarabina(&b)
witness.A.Assign(&a)
witness.B.Assign(&b)
Expand Down

0 comments on commit f52c4cb

Please sign in to comment.