Skip to content

Commit

Permalink
Merge branch 'master' into perf/kzg
Browse files Browse the repository at this point in the history
  • Loading branch information
yelhousni committed Oct 19, 2023
2 parents 768d2ad + 3f137c7 commit dea5a07
Show file tree
Hide file tree
Showing 4 changed files with 296 additions and 181 deletions.
19 changes: 9 additions & 10 deletions std/algebra/emulated/fields_bls12381/e12_pairing.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,7 @@ func (e Ext12) ExptTorus(x *E6) *E6 {
// }
func (e *Ext12) MulBy014(z *E12, c0, c1 *E2) *E12 {

a := z.C0
a = *e.MulBy01(&a, c0, c1)
a := e.MulBy01(&z.C0, c0, c1)

var b E6
// Mul by E6{0, 1, 0}
Expand All @@ -94,10 +93,10 @@ func (e *Ext12) MulBy014(z *E12, c0, c1 *E2) *E12 {

zC1 := e.Ext6.Add(&z.C1, &z.C0)
zC1 = e.Ext6.MulBy01(zC1, c0, d)
zC1 = e.Ext6.Sub(zC1, &a)
zC1 = e.Ext6.Sub(zC1, a)
zC1 = e.Ext6.Sub(zC1, &b)
zC0 := e.Ext6.MulByNonResidue(&b)
zC0 = e.Ext6.Add(zC0, &a)
zC0 = e.Ext6.Add(zC0, a)

return &E12{
C0: *zC0,
Expand All @@ -118,7 +117,7 @@ func (e *Ext12) MulBy014(z *E12, c0, c1 *E2) *E12 {
// C0: E6{B0: d0, B1: d1, B2: 0},
// C1: E6{B0: 0, B1: 1, B2: 0},
// }
func (e Ext12) Mul014By014(d0, d1, c0, c1 *E2) *[5]E2 {
func (e Ext12) Mul014By014(d0, d1, c0, c1 *E2) [5]*E2 {
one := e.Ext2.One()
x0 := e.Ext2.Mul(c0, d0)
x1 := e.Ext2.Mul(c1, d1)
Expand All @@ -141,7 +140,7 @@ func (e Ext12) Mul014By014(d0, d1, c0, c1 *E2) *[5]E2 {
zC0B0 := e.Ext2.NonResidue()
zC0B0 = e.Ext2.Add(zC0B0, x0)

return &[5]E2{*zC0B0, *x01, *x1, *x04, *x14}
return [5]*E2{zC0B0, x01, x1, x04, x14}
}

// MulBy01245 multiplies z by an E12 sparse element of the form
Expand All @@ -150,14 +149,14 @@ func (e Ext12) Mul014By014(d0, d1, c0, c1 *E2) *[5]E2 {
// C0: E6{B0: c0, B1: c1, B2: c2},
// C1: E6{B0: 0, B1: c4, B2: c5},
// }
func (e *Ext12) MulBy01245(z *E12, x *[5]E2) *E12 {
c0 := &E6{B0: x[0], B1: x[1], B2: x[2]}
c1 := &E6{B0: *e.Ext2.Zero(), B1: x[3], B2: x[4]}
func (e *Ext12) MulBy01245(z *E12, x [5]*E2) *E12 {
c0 := &E6{B0: *x[0], B1: *x[1], B2: *x[2]}
c1 := &E6{B0: *e.Ext2.Zero(), B1: *x[3], B2: *x[4]}
a := e.Ext6.Add(&z.C0, &z.C1)
b := e.Ext6.Add(c0, c1)
a = e.Ext6.Mul(a, b)
b = e.Ext6.Mul(&z.C0, c0)
c := e.Ext6.MulBy12(&z.C1, &x[3], &x[4])
c := e.Ext6.MulBy12(&z.C1, x[3], x[4])
z1 := e.Ext6.Sub(a, b)
z1 = e.Ext6.Sub(z1, c)
z0 := e.Ext6.MulByNonResidue(c)
Expand Down
39 changes: 21 additions & 18 deletions std/algebra/emulated/fields_bn254/e12_pairing.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (e *Ext12) Square034(x *E12) *E12 {
B2: *e.Ext2.Zero(),
}

c3 := E6{
c3 := &E6{
B0: x.C0.B0,
B1: *e.Ext2.Neg(&x.C1.B0),
B2: *e.Ext2.Neg(&x.C1.B1),
Expand All @@ -93,8 +93,8 @@ func (e *Ext12) Square034(x *E12) *E12 {
B1: x.C1.B1,
B2: *e.Ext2.Zero(),
}
c3 = *e.MulBy01(&c3, &c0.B0, &c0.B1)
c3 = *e.Ext6.Add(&c3, &c2)
c3 = e.MulBy01(c3, &c0.B0, &c0.B1)
c3 = e.Ext6.Add(c3, &c2)

var z E12
z.C1.B0 = *e.Ext2.Add(&c2.B0, &c2.B0)
Expand All @@ -116,16 +116,15 @@ func (e *Ext12) Square034(x *E12) *E12 {
func (e *Ext12) MulBy034(z *E12, c3, c4 *E2) *E12 {

a := z.C0
b := z.C1
b = *e.MulBy01(&b, c3, c4)
b := e.MulBy01(&z.C1, c3, c4)
c3 = e.Ext2.Add(e.Ext2.One(), c3)
d := e.Ext6.Add(&z.C0, &z.C1)
d = e.MulBy01(d, c3, c4)

zC1 := e.Ext6.Add(&a, &b)
zC1 := e.Ext6.Add(&a, b)
zC1 = e.Ext6.Neg(zC1)
zC1 = e.Ext6.Add(zC1, d)
zC0 := e.Ext6.MulByNonResidue(&b)
zC0 := e.Ext6.MulByNonResidue(b)
zC0 = e.Ext6.Add(zC0, &a)

return &E12{
Expand All @@ -147,7 +146,7 @@ func (e *Ext12) MulBy034(z *E12, c3, c4 *E2) *E12 {
// C0: E6{B0: 1, B1: 0, B2: 0},
// C1: E6{B0: d3, B1: d4, B2: 0},
// }
func (e *Ext12) Mul034By034(d3, d4, c3, c4 *E2) *[5]E2 {
func (e *Ext12) Mul034By034(d3, d4, c3, c4 *E2) [5]*E2 {
x3 := e.Ext2.Mul(c3, d3)
x4 := e.Ext2.Mul(c4, d4)
x04 := e.Ext2.Add(c4, d4)
Expand All @@ -165,7 +164,7 @@ func (e *Ext12) Mul034By034(d3, d4, c3, c4 *E2) *[5]E2 {
zC1B0 := x03
zC1B1 := x04

return &[5]E2{*zC0B0, *zC0B1, *zC0B2, *zC1B0, *zC1B1}
return [5]*E2{zC0B0, zC0B1, zC0B2, zC1B0, zC1B1}
}

// MulBy01234 multiplies z by an E12 sparse element of the form
Expand All @@ -174,14 +173,14 @@ func (e *Ext12) Mul034By034(d3, d4, c3, c4 *E2) *[5]E2 {
// C0: E6{B0: c0, B1: c1, B2: c2},
// C1: E6{B0: c3, B1: c4, B2: 0},
// }
func (e *Ext12) MulBy01234(z *E12, x *[5]E2) *E12 {
c0 := &E6{B0: x[0], B1: x[1], B2: x[2]}
c1 := &E6{B0: x[3], B1: x[4], B2: *e.Ext2.Zero()}
func (e *Ext12) MulBy01234(z *E12, x [5]*E2) *E12 {
c0 := &E6{B0: *x[0], B1: *x[1], B2: *x[2]}
c1 := &E6{B0: *x[3], B1: *x[4], B2: *e.Ext2.Zero()}
a := e.Ext6.Add(&z.C0, &z.C1)
b := e.Ext6.Add(c0, c1)
a = e.Ext6.Mul(a, b)
b = e.Ext6.Mul(&z.C0, c0)
c := e.Ext6.MulBy01(&z.C1, &x[3], &x[4])
c := e.Ext6.MulBy01(&z.C1, x[3], x[4])
z1 := e.Ext6.Sub(a, b)
z1 = e.Ext6.Sub(z1, c)
z0 := e.Ext6.MulByNonResidue(c)
Expand All @@ -205,13 +204,13 @@ func (e *Ext12) MulBy01234(z *E12, x *[5]E2) *E12 {
// C0: E6{B0: 1, B1: 0, B2: 0},
// C1: E6{B0: z3, B1: z4, B2: 0},
// }
func (e *Ext12) Mul01234By034(x *[5]E2, z3, z4 *E2) *E12 {
c0 := &E6{B0: x[0], B1: x[1], B2: x[2]}
c1 := &E6{B0: x[3], B1: x[4], B2: *e.Ext2.Zero()}
func (e *Ext12) Mul01234By034(x [5]*E2, z3, z4 *E2) *E12 {
c0 := &E6{B0: *x[0], B1: *x[1], B2: *x[2]}
c1 := &E6{B0: *x[3], B1: *x[4], B2: *e.Ext2.Zero()}
a := e.Ext6.Add(e.Ext6.One(), &E6{B0: *z3, B1: *z4, B2: *e.Ext2.Zero()})
b := e.Ext6.Add(c0, c1)
a = e.Ext6.Mul(a, b)
c := e.Ext6.Mul01By01(z3, z4, &x[3], &x[4])
c := e.Ext6.Mul01By01(z3, z4, x[3], x[4])
z1 := e.Ext6.Sub(a, c0)
z1 = e.Ext6.Sub(z1, c)
z0 := e.Ext6.MulByNonResidue(c)
Expand Down Expand Up @@ -263,7 +262,11 @@ func (e Ext12) DecompressTorus(y *E6) *E12 {
// N.B.: we use MulTorus in the final exponentiation throughout y1 ≠ -y2 always.
func (e Ext12) MulTorus(y1, y2 *E6) *E6 {
n := e.Ext6.Mul(y1, y2)
n.B1 = *e.Ext2.Add(&n.B1, e.Ext2.One())
n = &E6{
B0: n.B0,
B1: *e.Ext2.Add(&n.B1, e.Ext2.One()),
B2: n.B2,
}
d := e.Ext6.Add(y1, y2)
y3 := e.Ext6.DivUnchecked(n, d)
return y3
Expand Down
131 changes: 86 additions & 45 deletions std/algebra/emulated/sw_bls12381/pairing.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,10 @@ func (pr Pairing) finalExponentiation(e *GTEl, unsafe bool) *GTEl {
// the case, the result is 1 in the torus. We assign a dummy value (1) to e.C1
// and proceed further.
selector1 = pr.Ext6.IsZero(&e.C1)
e.C1 = *pr.Ext6.Select(selector1, _dummy, &e.C1)
e = &fields_bls12381.E12{
C0: e.C0,
C1: *pr.Ext6.Select(selector1, _dummy, &e.C1),
}
}

// Torus compression absorbed:
Expand Down Expand Up @@ -358,31 +361,44 @@ func (pr Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error) {
res.C0.B0 = *pr.MulByElement(&l1.R1, yInv[0])
res.C1.B1 = *pr.Ext2.One()
// line evaluation at P[0]
l2.R0 = *pr.MulByElement(&l2.R0, xNegOverY[0])
l2.R1 = *pr.MulByElement(&l2.R1, yInv[0])
l2 = &lineEvaluation{
R0: *pr.MulByElement(&l2.R0, xNegOverY[0]),
R1: *pr.MulByElement(&l2.R1, yInv[0]),
}
// res = ℓ × ℓ
prodLines := *pr.Mul014By014(&l2.R1, &l2.R0, &res.C0.B0, &res.C0.B1)
res.C0.B0 = prodLines[0]
res.C0.B1 = prodLines[1]
res.C0.B2 = prodLines[2]
res.C1.B1 = prodLines[3]
res.C1.B2 = prodLines[4]
prodLines := pr.Mul014By014(&l2.R1, &l2.R0, &res.C0.B0, &res.C0.B1)
res = &fields_bls12381.E12{
C0: fields_bls12381.E6{
B0: *prodLines[0],
B1: *prodLines[1],
B2: *prodLines[2],
},
C1: fields_bls12381.E6{
B0: res.C1.B0,
B1: *prodLines[3],
B2: *prodLines[4],
},
}

for k := 1; k < n; k++ {
// Qacc[k] ← 3Qacc[k],
// l1 the tangent ℓ to 2Q[k]
// l2 the line ℓ passing 2Q[k] and Q[k]
Qacc[k], l1, l2 = pr.tripleStep(Qacc[k])
// line evaluation at P[k]
l1.R0 = *pr.MulByElement(&l1.R0, xNegOverY[k])
l1.R1 = *pr.MulByElement(&l1.R1, yInv[k])
l1 = &lineEvaluation{
R0: *pr.MulByElement(&l1.R0, xNegOverY[k]),
R1: *pr.MulByElement(&l1.R1, yInv[k]),
}
// line evaluation at P[k]
l2.R0 = *pr.MulByElement(&l2.R0, xNegOverY[k])
l2.R1 = *pr.MulByElement(&l2.R1, yInv[k])
l2 = &lineEvaluation{
R0: *pr.MulByElement(&l2.R0, xNegOverY[k]),
R1: *pr.MulByElement(&l2.R1, yInv[k]),
}
// ℓ × ℓ
prodLines = *pr.Mul014By014(&l1.R1, &l1.R0, &l2.R1, &l2.R0)
prodLines = pr.Mul014By014(&l1.R1, &l1.R0, &l2.R1, &l2.R0)
// (ℓ × ℓ) × res
res = pr.MulBy01245(res, &prodLines)
res = pr.MulBy01245(res, prodLines)

}

Expand All @@ -397,8 +413,10 @@ func (pr Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error) {
// Qacc[k] ← 2Qacc[k] and l1 the tangent ℓ passing 2Qacc[k]
Qacc[k], l1 = pr.doubleStep(Qacc[k])
// line evaluation at P[k]
l1.R0 = *pr.MulByElement(&l1.R0, xNegOverY[k])
l1.R1 = *pr.MulByElement(&l1.R1, yInv[k])
l1 = &lineEvaluation{
R0: *pr.MulByElement(&l1.R0, xNegOverY[k]),
R1: *pr.MulByElement(&l1.R1, yInv[k]),
}
// ℓ × res
res = pr.MulBy014(res, &l1.R1, &l1.R0)
}
Expand All @@ -409,15 +427,19 @@ func (pr Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error) {
// l2 the line ℓ passing (Qacc[k]+Q[k]) and Qacc[k]
Qacc[k], l1, l2 = pr.doubleAndAddStep(Qacc[k], Q[k])
// line evaluation at P[k]
l1.R0 = *pr.MulByElement(&l1.R0, xNegOverY[k])
l1.R1 = *pr.MulByElement(&l1.R1, yInv[k])
l1 = &lineEvaluation{
R0: *pr.MulByElement(&l1.R0, xNegOverY[k]),
R1: *pr.MulByElement(&l1.R1, yInv[k]),
}
// line evaluation at P[k]
l2.R0 = *pr.MulByElement(&l2.R0, xNegOverY[k])
l2.R1 = *pr.MulByElement(&l2.R1, yInv[k])
l2 = &lineEvaluation{
R0: *pr.MulByElement(&l2.R0, xNegOverY[k]),
R1: *pr.MulByElement(&l2.R1, yInv[k]),
}
// ℓ × ℓ
prodLines = *pr.Mul014By014(&l1.R1, &l1.R0, &l2.R1, &l2.R0)
prodLines = pr.Mul014By014(&l1.R1, &l1.R0, &l2.R1, &l2.R0)
// (ℓ × ℓ) × res
res = pr.MulBy01245(res, &prodLines)
res = pr.MulBy01245(res, prodLines)
}
}
}
Expand All @@ -428,8 +450,10 @@ func (pr Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error) {
// l1 the tangent ℓ passing 2Qacc[k]
l1 = pr.tangentCompute(Qacc[k])
// line evaluation at P[k]
l1.R0 = *pr.MulByElement(&l1.R0, xNegOverY[k])
l1.R1 = *pr.MulByElement(&l1.R1, yInv[k])
l1 = &lineEvaluation{
R0: *pr.MulByElement(&l1.R0, xNegOverY[k]),
R1: *pr.MulByElement(&l1.R1, yInv[k]),
}
// ℓ × res
res = pr.MulBy014(res, &l1.R1, &l1.R0)
}
Expand Down Expand Up @@ -726,15 +750,24 @@ func (pr Pairing) DoubleMillerLoopFixedQ(P [2]*G1Affine, Q *G2Affine) (*GTEl, er
res.C0.B0 = *pr.MulByElement(&l1.R1, yInv[1])
res.C1.B1 = *pr.Ext2.One()
// line evaluation at P
l2.R0 = *pr.MulByElement(&l2.R0, xNegOverY[1])
l2.R1 = *pr.MulByElement(&l2.R1, yInv[1])
l2 = &lineEvaluation{
R0: *pr.MulByElement(&l2.R0, xNegOverY[1]),
R1: *pr.MulByElement(&l2.R1, yInv[1]),
}
// res = ℓ × ℓ
prodLines := *pr.Mul014By014(&l2.R1, &l2.R0, &res.C0.B0, &res.C0.B1)
res.C0.B0 = prodLines[0]
res.C0.B1 = prodLines[1]
res.C0.B2 = prodLines[2]
res.C1.B1 = prodLines[3]
res.C1.B2 = prodLines[4]
prodLines := pr.Mul014By014(&l2.R1, &l2.R0, &res.C0.B0, &res.C0.B1)
res = &fields_bls12381.E12{
C0: fields_bls12381.E6{
B0: *prodLines[0],
B1: *prodLines[1],
B2: *prodLines[2],
},
C1: fields_bls12381.E6{
B0: res.C1.B0,
B1: *prodLines[3],
B2: *prodLines[4],
},
}

res = pr.MulBy014(res,
pr.MulByElement(&pr.lines[1][62], yInv[0]),
Expand All @@ -759,8 +792,10 @@ func (pr Pairing) DoubleMillerLoopFixedQ(P [2]*G1Affine, Q *G2Affine) (*GTEl, er
// Qacc ← 2Qacc and l1 the tangent ℓ passing 2Qacc
Qacc, l1 = pr.doubleStep(Qacc)
// line evaluation at P
l1.R0 = *pr.MulByElement(&l1.R0, xNegOverY[1])
l1.R1 = *pr.MulByElement(&l1.R1, yInv[1])
l1 = &lineEvaluation{
R0: *pr.MulByElement(&l1.R0, xNegOverY[1]),
R1: *pr.MulByElement(&l1.R1, yInv[1]),
}
// ℓ × res
res = pr.MulBy014(res, &l1.R1, &l1.R0)
} else {
Expand All @@ -777,15 +812,19 @@ func (pr Pairing) DoubleMillerLoopFixedQ(P [2]*G1Affine, Q *G2Affine) (*GTEl, er
// l2 the line ℓ passing (Qacc+Q) and Qacc
Qacc, l1, l2 = pr.doubleAndAddStep(Qacc, Q)
// line evaluation at P
l1.R0 = *pr.MulByElement(&l1.R0, xNegOverY[1])
l1.R1 = *pr.MulByElement(&l1.R1, yInv[1])
l1 = &lineEvaluation{
R0: *pr.MulByElement(&l1.R0, xNegOverY[1]),
R1: *pr.MulByElement(&l1.R1, yInv[1]),
}
// line evaluation at P
l2.R0 = *pr.MulByElement(&l2.R0, xNegOverY[1])
l2.R1 = *pr.MulByElement(&l2.R1, yInv[1])
l2 = &lineEvaluation{
R0: *pr.MulByElement(&l2.R0, xNegOverY[1]),
R1: *pr.MulByElement(&l2.R1, yInv[1]),
}
// ℓ × ℓ
prodLines = *pr.Mul014By014(&l1.R1, &l1.R0, &l2.R1, &l2.R0)
prodLines = pr.Mul014By014(&l1.R1, &l1.R0, &l2.R1, &l2.R0)
// (ℓ × ℓ) × res
res = pr.MulBy01245(res, &prodLines)
res = pr.MulBy01245(res, prodLines)

}
}
Expand All @@ -795,17 +834,19 @@ func (pr Pairing) DoubleMillerLoopFixedQ(P [2]*G1Affine, Q *G2Affine) (*GTEl, er
// l1 the tangent ℓ passing 2Qacc
l1 = pr.tangentCompute(Qacc)
// line evaluation at P
l1.R0 = *pr.MulByElement(&l1.R0, xNegOverY[1])
l1.R1 = *pr.MulByElement(&l1.R1, yInv[1])
l1 = &lineEvaluation{
R0: *pr.MulByElement(&l1.R0, xNegOverY[1]),
R1: *pr.MulByElement(&l1.R1, yInv[1]),
}
// ℓ × ℓ
prodLines = *pr.Mul014By014(
prodLines = pr.Mul014By014(
&l1.R1,
&l1.R0,
pr.MulByElement(&pr.lines[1][0], yInv[0]),
pr.MulByElement(&pr.lines[0][0], xNegOverY[0]),
)
// (ℓ × ℓ) × res
res = pr.MulBy01245(res, &prodLines)
res = pr.MulBy01245(res, prodLines)

// negative x₀
res = pr.Ext12.Conjugate(res)
Expand Down
Loading

0 comments on commit dea5a07

Please sign in to comment.