Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/rollup/circuit.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
tedwards "github.com/consensys/gnark-crypto/ecc/twistededwards"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/accumulator/merkle"
"github.com/consensys/gnark/std/algebra/twistededwards"
"github.com/consensys/gnark/std/algebra/native/twistededwards"
"github.com/consensys/gnark/std/hash/mimc"
"github.com/consensys/gnark/std/signature/eddsa"
)
Expand Down
4 changes: 2 additions & 2 deletions internal/stats/snippet.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"github.com/consensys/gnark"
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/algebra/sw_bls12377"
"github.com/consensys/gnark/std/algebra/sw_bls24315"
"github.com/consensys/gnark/std/algebra/native/sw_bls12377"
"github.com/consensys/gnark/std/algebra/native/sw_bls24315"
"github.com/consensys/gnark/std/hash/mimc"
"github.com/consensys/gnark/std/math/bits"
"github.com/consensys/gnark/std/math/emulated"
Expand Down
14 changes: 14 additions & 0 deletions std/algebra/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Package algebra implements:
// - base finite field 𝔽p arithmetic,
// - extension finite fields arithmetic (𝔽p², 𝔽p⁴, 𝔽p⁶, 𝔽p¹², 𝔽p²⁴),
// - short Weierstrass curve arithmetic over G1 (E/𝔽p) and G2 (Eₜ/𝔽p² or Eₜ/𝔽p⁴)
// - twisted Edwards curve arithmetic
//
// These arithmetic operations are implemented
// - using native field via the 2-chains BLS12-377/BW6-761 and BLS24-315/BW-633
// (`native/`) or associated twisted Edwards (e.g. Jubjub/BLS12-381) and
// - using nonnative field via field emulation (`emulated/`). This allows to
// use any curve over any (SNARK) field (e.g. secp256k1 curve arithmetic over
// BN254 SNARK field or BN254 pairing over BN254 SNARK field). The drawback
// of this approach is the extreme cost of the operations.
package algebra
7 changes: 7 additions & 0 deletions std/algebra/emulated/fields_bn254/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Package fields_bn254 implements the fields arithmetic of the Fp12 tower
// used to compute the pairing over the BN254 curve.
//
// 𝔽p²[u] = 𝔽p/u²+1
// 𝔽p⁶[v] = 𝔽p²/v³-9-u
// 𝔽p¹²[w] = 𝔽p⁶/w²-v
package fields_bn254
226 changes: 226 additions & 0 deletions std/algebra/emulated/fields_bn254/e12.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
package fields_bn254

type E12 struct {
C0, C1 E6
}

type Ext12 struct {
*Ext6
}

func NewExt12(baseField *curveF) *Ext12 {
return &Ext12{Ext6: NewExt6(baseField)}
}
func (e Ext12) Conjugate(x *E12) *E12 {
z1 := e.Ext6.Neg(&x.C1) // z.C1.Neg(&z.C1)
return &E12{ // return z
C0: x.C0,
C1: *z1,
}
}

func (e Ext12) Inverse(x *E12) *E12 {
// var t0, t1, tmp E6
t0 := e.Ext6.Square(&x.C0) // t0.Square(&x.C0)
t1 := e.Ext6.Square(&x.C1) // t1.Square(&x.C1)
tmp := e.Ext6.MulByNonResidue(t1) // tmp.MulByNonResidue(&t1)
t0 = e.Ext6.Sub(t0, tmp) // t0.Sub(&t0, &tmp)
t1 = e.Ext6.Inverse(t0) // t1.Inverse(&t0)
z0 := e.Ext6.Mul(&x.C0, t1) // z.C0.Mul(&x.C0, &t1)
z1 := e.Ext6.Mul(&x.C1, t1) // z.C1.Mul(&x.C1, &t1).
z1 = e.Ext6.Neg(z1) // Neg(&z.C1)
return &E12{ // return z
C0: *z0,
C1: *z1,
}
}

func (e Ext12) Mul(x, y *E12) *E12 {
// var a, b, c E6
a := e.Ext6.Add(&x.C0, &x.C1) // a.Add(&x.C0, &x.C1)
b := e.Ext6.Add(&y.C0, &y.C1) // b.Add(&y.C0, &y.C1)
a = e.Ext6.Mul(a, b) // a.Mul(&a, &b)
b = e.Ext6.Mul(&x.C0, &y.C0) // b.Mul(&x.C0, &y.C0)
c := e.Ext6.Mul(&x.C1, &y.C1) // c.Mul(&x.C1, &y.C1)
z1 := e.Ext6.Sub(a, b) // z.C1.Sub(&a, &b).
z1 = e.Ext6.Sub(z1, c) // Sub(&z.C1, &c)
z0 := e.Ext6.MulByNonResidue(c) // z.C0.MulByNonResidue(&c).
z0 = e.Ext6.Add(z0, b) // Add(&z.C0, &b)
return &E12{ // return z
C0: *z0,
C1: *z1,
}
}

func (e Ext12) CyclotomicSquare(x *E12) *E12 {
// var t [9]E2
t0 := e.Ext2.Square(&x.C1.B1) // t[0].Square(&x.C1.B1)
t1 := e.Ext2.Square(&x.C0.B0) // t[1].Square(&x.C0.B0)
t6 := e.Ext2.Add(&x.C1.B1, &x.C0.B0) // t[6].Add(&x.C1.B1, &x.C0.B0).
t6 = e.Ext2.Square(t6) // Square(&t[6]).
t6 = e.Ext2.Sub(t6, t0) // Sub(&t[6], &t[0]).
t6 = e.Ext2.Sub(t6, t1) // Sub(&t[6], &t[1])
t2 := e.Ext2.Square(&x.C0.B2) // t[2].Square(&x.C0.B2)
t3 := e.Ext2.Square(&x.C1.B0) // t[3].Square(&x.C1.B0)
t7 := e.Ext2.Add(&x.C0.B2, &x.C1.B0) // t[7].Add(&x.C0.B2, &x.C1.B0).
t7 = e.Ext2.Square(t7) // Square(&t[7]).
t7 = e.Ext2.Sub(t7, t2) // Sub(&t[7], &t[2]).
t7 = e.Ext2.Sub(t7, t3) // Sub(&t[7], &t[3])
t4 := e.Ext2.Square(&x.C1.B2) // t[4].Square(&x.C1.B2)
t5 := e.Ext2.Square(&x.C0.B1) // t[5].Square(&x.C0.B1)
t8 := e.Ext2.Add(&x.C1.B2, &x.C0.B1) // t[8].Add(&x.C1.B2, &x.C0.B1).
t8 = e.Ext2.Square(t8) // Square(&t[8]).
t8 = e.Ext2.Sub(t8, t4) // Sub(&t[8], &t[4]).
t8 = e.Ext2.Sub(t8, t5) // Sub(&t[8], &t[5]).
t8 = e.Ext2.MulByNonResidue(t8) // MulByNonResidue(&t[8])
t0 = e.Ext2.MulByNonResidue(t0) // t[0].MulByNonResidue(&t[0]).
t0 = e.Ext2.Add(t0, t1) // Add(&t[0], &t[1])
t2 = e.Ext2.MulByNonResidue(t2) // t[2].MulByNonResidue(&t[2]).
t2 = e.Ext2.Add(t2, t3) // Add(&t[2], &t[3])
t4 = e.Ext2.MulByNonResidue(t4) // t[4].MulByNonResidue(&t[4]).
t4 = e.Ext2.Add(t4, t5) // Add(&t[4], &t[5])
z00 := e.Ext2.Sub(t0, &x.C0.B0) // z.C0.B0.Sub(&t[0], &x.C0.B0).
z00 = e.Ext2.Double(z00) // Double(&z.C0.B0).
z00 = e.Ext2.Add(z00, t0) // Add(&z.C0.B0, &t[0])
z01 := e.Ext2.Sub(t2, &x.C0.B1) // z.C0.B1.Sub(&t[2], &x.C0.B1).
z01 = e.Ext2.Double(z01) // Double(&z.C0.B1).
z01 = e.Ext2.Add(z01, t2) // Add(&z.C0.B1, &t[2])
z02 := e.Ext2.Sub(t4, &x.C0.B2) // z.C0.B2.Sub(&t[4], &x.C0.B2).
z02 = e.Ext2.Double(z02) // Double(&z.C0.B2).
z02 = e.Ext2.Add(z02, t4) // Add(&z.C0.B2, &t[4])
z10 := e.Ext2.Add(t8, &x.C1.B0) // z.C1.B0.Add(&t[8], &x.C1.B0).
z10 = e.Ext2.Double(z10) // Double(&z.C1.B0).
z10 = e.Ext2.Add(z10, t8) // Add(&z.C1.B0, &t[8])
z11 := e.Ext2.Add(t6, &x.C1.B1) // z.C1.B1.Add(&t[6], &x.C1.B1).
z11 = e.Ext2.Double(z11) // Double(&z.C1.B1).
z11 = e.Ext2.Add(z11, t6) // Add(&z.C1.B1, &t[6])
z12 := e.Ext2.Add(t7, &x.C1.B2) // z.C1.B2.Add(&t[7], &x.C1.B2).
z12 = e.Ext2.Double(z12) // Double(&z.C1.B2).
z12 = e.Ext2.Add(z12, t7) // Add(&z.C1.B2, &t[7])
return &E12{ // return z
C0: E6{
B0: *z00,
B1: *z01,
B2: *z02,
},
C1: E6{
B0: *z10,
B1: *z11,
B2: *z12,
},
}
}

func (e Ext12) NCycloSquare(z *E12, n int) *E12 {
for i := 0; i < n; i++ {
z = e.CyclotomicSquare(z)
}
return z
}

func (e Ext12) Frobenius(x *E12) *E12 {
// var t [6]E2
t0 := e.Ext2.Conjugate(&x.C0.B0) // t[0].Conjugate(&x.C0.B0)
t1 := e.Ext2.Conjugate(&x.C0.B1) // t[1].Conjugate(&x.C0.B1)
t2 := e.Ext2.Conjugate(&x.C0.B2) // t[2].Conjugate(&x.C0.B2)
t3 := e.Ext2.Conjugate(&x.C1.B0) // t[3].Conjugate(&x.C1.B0)
t4 := e.Ext2.Conjugate(&x.C1.B1) // t[4].Conjugate(&x.C1.B1)
t5 := e.Ext2.Conjugate(&x.C1.B2) // t[5].Conjugate(&x.C1.B2)
t1 = e.Ext2.MulByNonResidue1Power2(t1) // t[1].MulByNonResidue1Power2(&t[1])
t2 = e.Ext2.MulByNonResidue1Power4(t2) // t[2].MulByNonResidue1Power4(&t[2])
t3 = e.Ext2.MulByNonResidue1Power1(t3) // t[3].MulByNonResidue1Power1(&t[3])
t4 = e.Ext2.MulByNonResidue1Power3(t4) // t[4].MulByNonResidue1Power3(&t[4])
t5 = e.Ext2.MulByNonResidue1Power5(t5) // t[5].MulByNonResidue1Power5(&t[5])
return &E12{ // return z
C0: E6{
B0: *t0, // z.C0.B0 = t[0]
B1: *t1, // z.C0.B1 = t[1]
B2: *t2, // z.C0.B2 = t[2]
},
C1: E6{
B0: *t3, // z.C1.B0 = t[3]
B1: *t4, // z.C1.B1 = t[4]
B2: *t5, // z.C1.B2 = t[5]
},
}
}

func (e Ext12) FrobeniusSquare(x *E12) *E12 {
z00 := &x.C0.B0 // z.C0.B0 = x.C0.B0
z01 := e.Ext2.MulByNonResidue2Power2(&x.C0.B1) // z.C0.B1.MulByNonResidue2Power2(&x.C0.B1)
z02 := e.Ext2.MulByNonResidue2Power4(&x.C0.B2) // z.C0.B2.MulByNonResidue2Power4(&x.C0.B2)
z10 := e.Ext2.MulByNonResidue2Power1(&x.C1.B0) // z.C1.B0.MulByNonResidue2Power1(&x.C1.B0)
z11 := e.Ext2.MulByNonResidue2Power3(&x.C1.B1) // z.C1.B1.MulByNonResidue2Power3(&x.C1.B1)
z12 := e.Ext2.MulByNonResidue2Power5(&x.C1.B2) // z.C1.B2.MulByNonResidue2Power5(&x.C1.B2)
return &E12{ // return z
C0: E6{B0: *z00, B1: *z01, B2: *z02},
C1: E6{B0: *z10, B1: *z11, B2: *z12},
}
}

func (e Ext12) FrobeniusCube(x *E12) *E12 {
// var t [6]E2
t0 := e.Ext2.Conjugate(&x.C0.B0) // t[0].Conjugate(&x.C0.B0)
t1 := e.Ext2.Conjugate(&x.C0.B1) // t[1].Conjugate(&x.C0.B1)
t2 := e.Ext2.Conjugate(&x.C0.B2) // t[2].Conjugate(&x.C0.B2)
t3 := e.Ext2.Conjugate(&x.C1.B0) // t[3].Conjugate(&x.C1.B0)
t4 := e.Ext2.Conjugate(&x.C1.B1) // t[4].Conjugate(&x.C1.B1)
t5 := e.Ext2.Conjugate(&x.C1.B2) // t[5].Conjugate(&x.C1.B2)
t1 = e.Ext2.MulByNonResidue3Power2(t1) // t[1].MulByNonResidue3Power2(&t[1])
t2 = e.Ext2.MulByNonResidue3Power4(t2) // t[2].MulByNonResidue3Power4(&t[2])
t3 = e.Ext2.MulByNonResidue3Power1(t3) // t[3].MulByNonResidue3Power1(&t[3])
t4 = e.Ext2.MulByNonResidue3Power3(t4) // t[4].MulByNonResidue3Power3(&t[4])
t5 = e.Ext2.MulByNonResidue3Power5(t5) // t[5].MulByNonResidue3Power5(&t[5])
return &E12{ // return z
C0: E6{
B0: *t0, // z.C0.B0 = t[0]
B1: *t1, // z.C0.B1 = t[1]
B2: *t2, // z.C0.B2 = t[2]
},
C1: E6{
B0: *t3, // z.C1.B0 = t[3]
B1: *t4, // z.C1.B1 = t[4]
B2: *t5, // z.C1.B2 = t[5]
},
}
}

func (e Ext12) One() *E12 {
z000 := e.fp.One()
zero := e.fp.Zero()
return &E12{
C0: E6{
B0: E2{A0: *z000, A1: *zero},
B1: E2{A0: *zero, A1: *zero},
B2: E2{A0: *zero, A1: *zero},
},
C1: E6{
B0: E2{A0: *zero, A1: *zero},
B1: E2{A0: *zero, A1: *zero},
B2: E2{A0: *zero, A1: *zero},
},
}
}

func (e Ext12) Square(x *E12) *E12 {
// var c0, c2, c3 E6
c0 := e.Ext6.Sub(&x.C0, &x.C1) // c0.Sub(&x.C0, &x.C1)
c3 := e.Ext6.MulByNonResidue(&x.C1) // c3.MulByNonResidue(&x.C1).
c3 = e.Ext6.Neg(c3) // Neg(&c3).
c3 = e.Ext6.Add(&x.C0, c3) // Add(&x.C0, &c3)
c2 := e.Ext6.Mul(&x.C0, &x.C1) // c2.Mul(&x.C0, &x.C1)
c0 = e.Ext6.Mul(c0, c3) // c0.Mul(&c0, &c3).
c0 = e.Ext6.Add(c0, c2) // Add(&c0, &c2)
z1 := e.Ext6.double(c2) // z.C1.Double(&c2)
c2 = e.Ext6.MulByNonResidue(c2) // c2.MulByNonResidue(&c2)
z0 := e.Ext6.Add(c0, c2) // z.C0.Add(&c0, &c2)
return &E12{ // return z
C0: *z0,
C1: *z1,
}
}

func (e Ext12) AssertIsEqual(x, y *E12) {
e.Ext6.AssertIsEqual(&x.C0, &y.C0)
e.Ext6.AssertIsEqual(&x.C1, &y.C1)
}
96 changes: 96 additions & 0 deletions std/algebra/emulated/fields_bn254/e12_pairing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package fields_bn254

func (e Ext12) Expt(x *E12) *E12 {
// var result, t0, t1, t2, t3, t4, t5, t6 E12
t3 := e.CyclotomicSquare(x) // t3.CyclotomicSquare(x)
t5 := e.CyclotomicSquare(t3) // t5.CyclotomicSquare(&t3)
result := e.CyclotomicSquare(t5) // result.CyclotomicSquare(&t5)
t0 := e.CyclotomicSquare(result) // t0.CyclotomicSquare(&result)
t2 := e.Mul(x, t0) // t2.Mul(x, &t0)
t0 = e.Mul(t3, t2) // t0.Mul(&t3, &t2)
t1 := e.Mul(x, t0) // t1.Mul(x, &t0)
t4 := e.Mul(result, t2) // t4.Mul(&result, &t2)
t6 := e.CyclotomicSquare(t2) // t6.CyclotomicSquare(&t2)
t1 = e.Mul(t0, t1) // t1.Mul(&t0, &t1)
t0 = e.Mul(t3, t1) // t0.Mul(&t3, &t1)
t6 = e.NCycloSquare(t6, 6) // t6.NCycloSquare(6)
t5 = e.Mul(t5, t6) // t5.Mul(&t5, &t6)
t5 = e.Mul(t4, t5) // t5.Mul(&t4, &t5)
t5 = e.NCycloSquare(t5, 7) // t5.NCycloSquare(7)
t4 = e.Mul(t4, t5) // t4.Mul(&t4, &t5)
t4 = e.NCycloSquare(t4, 8) // t4.NCycloSquare(8)
t4 = e.Mul(t0, t4) // t4.Mul(&t0, &t4)
t3 = e.Mul(t3, t4) // t3.Mul(&t3, &t4)
t3 = e.NCycloSquare(t3, 6) // t3.NCycloSquare(6)
t2 = e.Mul(t2, t3) // t2.Mul(&t2, &t3)
t2 = e.NCycloSquare(t2, 8) // t2.NCycloSquare(8)
t2 = e.Mul(t0, t2) // t2.Mul(&t0, &t2)
t2 = e.NCycloSquare(t2, 6) // t2.NCycloSquare(6)
t2 = e.Mul(t0, t2) // t2.Mul(&t0, &t2)
t2 = e.NCycloSquare(t2, 10) // t2.NCycloSquare(10)
t1 = e.Mul(t1, t2) // t1.Mul(&t1, &t2)
t1 = e.NCycloSquare(t1, 6) // t1.NCycloSquare(6)
t0 = e.Mul(t0, t1) // t0.Mul(&t0, &t1)
z := e.Mul(result, t0) // z.Mul(&result, &t0)
return z // return z
}

func (e Ext12) MulBy034(z *E12, c0, c3, c4 *E2) *E12 {
// var a, b, d E6
a := e.Ext6.MulByE2(&z.C0, c0) // a.MulByE2(&z.C0, c0)
// b.Set(&z.C1)
b := e.Ext6.MulBy01(&z.C1, c3, c4) // b.MulBy01(c3, c4)
c0 = e.Ext2.Add(c0, c3) // c0.Add(c0, c3)
d := e.Ext6.Add(&z.C0, &z.C1) // d.Add(&z.C0, &z.C1)
d = e.Ext6.MulBy01(d, c0, c4) // d.MulBy01(c0, c4)
z1 := e.Add(a, b) // z.C1.Add(&a, &b).
z1 = e.Neg(z1) // Neg(&z.C1).
z1 = e.Add(z1, d) // Add(&z.C1, &d)
z0 := e.MulByNonResidue(b) // z.C0.MulByNonResidue(&b).
z0 = e.Add(z0, a) // Add(&z.C0, &a)
return &E12{ // return z
C0: *z0,
C1: *z1,
}
}

func (e Ext12) MulBy034by034(d0, d3, d4, c0, c3, c4 *E2) *E12 {
// var tmp, x0, x3, x4, x04, x03, x34 E2
x0 := e.Ext2.Mul(c0, d0) // x0.Mul(c0, d0)
x3 := e.Ext2.Mul(c3, d3) // x3.Mul(c3, d3)
x4 := e.Ext2.Mul(c4, d4) // x4.Mul(c4, d4)
tmp := e.Ext2.Add(c0, c4) // tmp.Add(c0, c4)
x04 := e.Ext2.Add(d0, d4) // x04.Add(d0, d4).
x04 = e.Ext2.Mul(x04, tmp) // Mul(&x04, &tmp).
x04 = e.Ext2.Sub(x04, x0) // Sub(&x04, &x0).
x04 = e.Ext2.Sub(x04, x4) // Sub(&x04, &x4)
tmp = e.Ext2.Add(c0, c3) // tmp.Add(c0, c3)
x03 := e.Ext2.Add(d0, d3) // x03.Add(d0, d3).
x03 = e.Ext2.Mul(x03, tmp) // Mul(&x03, &tmp).
x03 = e.Ext2.Sub(x03, x0) // Sub(&x03, &x0).
x03 = e.Ext2.Sub(x03, x3) // Sub(&x03, &x3)
tmp = e.Ext2.Add(c3, c4) // tmp.Add(c3, c4)
x34 := e.Ext2.Add(d3, d4) // x34.Add(d3, d4).
x34 = e.Ext2.Mul(x34, tmp) // Mul(&x34, &tmp).
x34 = e.Ext2.Sub(x34, x3) // Sub(&x34, &x3).
x34 = e.Ext2.Sub(x34, x4) // Sub(&x34, &x4)
z00 := e.Ext2.MulByNonResidue(x4) // z.C0.B0.MulByNonResidue(&x4).
z00 = e.Ext2.Add(z00, x0) // Add(&z.C0.B0, &x0)
z01 := x3 // z.C0.B1.Set(&x3)
z02 := x34 // z.C0.B2.Set(&x34)
z10 := x03 // z.C1.B0.Set(&x03)
z11 := x04 // z.C1.B1.Set(&x04)
z12 := e.Ext2.Zero() // z.C1.B2.SetZero()
return &E12{ // return z
C0: E6{
B0: *z00,
B1: *z01,
B2: *z02,
},
C1: E6{
B0: *z10,
B1: *z11,
B2: *z12,
},
}
}
Loading