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
8 changes: 4 additions & 4 deletions internal/stats/latest_stats.csv
Original file line number Diff line number Diff line change
Expand Up @@ -153,14 +153,14 @@ pairing_bls12377,bls24_315,plonk,0,0
pairing_bls12377,bls24_317,plonk,0,0
pairing_bls12377,bw6_761,plonk,51280,51280
pairing_bls12377,bw6_633,plonk,0,0
pairing_bls12381,bn254,groth16,949275,1570529
pairing_bls12381,bn254,groth16,949313,1570566
pairing_bls12381,bls12_377,groth16,0,0
pairing_bls12381,bls12_381,groth16,0,0
pairing_bls12381,bls24_315,groth16,0,0
pairing_bls12381,bls24_317,groth16,0,0
pairing_bls12381,bw6_761,groth16,0,0
pairing_bls12381,bw6_633,groth16,0,0
pairing_bls12381,bn254,plonk,3648951,3239243
pairing_bls12381,bn254,plonk,3649018,3239309
pairing_bls12381,bls12_377,plonk,0,0
pairing_bls12381,bls12_381,plonk,0,0
pairing_bls12381,bls24_315,plonk,0,0
Expand All @@ -181,14 +181,14 @@ pairing_bls24315,bls24_315,plonk,0,0
pairing_bls24315,bls24_317,plonk,0,0
pairing_bls24315,bw6_761,plonk,0,0
pairing_bls24315,bw6_633,plonk,141249,141249
pairing_bn254,bn254,groth16,607313,994993
pairing_bn254,bn254,groth16,607339,995018
pairing_bn254,bls12_377,groth16,0,0
pairing_bn254,bls12_381,groth16,0,0
pairing_bn254,bls24_315,groth16,0,0
pairing_bn254,bls24_317,groth16,0,0
pairing_bn254,bw6_761,groth16,0,0
pairing_bn254,bw6_633,groth16,0,0
pairing_bn254,bn254,plonk,2328923,2039005
pairing_bn254,bn254,plonk,2328968,2039049
pairing_bn254,bls12_377,plonk,0,0
pairing_bn254,bls12_381,plonk,0,0
pairing_bn254,bls24_315,plonk,0,0
Expand Down
16 changes: 16 additions & 0 deletions std/algebra/emulated/sw_bls12381/g1.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,17 @@ func (g1 G1) doubleAndAdd(p, q *G1Affine) *G1Affine {
}

func (g1 *G1) scalarMulBySeedSquare(q *G1Affine) *G1Affine {
// It computes the scalar multiplication by the seed square. It is used to
// verify if a point is in the subgroup of G1. However, it uses incomplete
// formulas and as such doesn't work for point at infinity as we get a
// division by zero. But as we represent the point at infinity as (0,0),
// then in this case we can run the computations using a dummy point (1,1)
// and then later replace it again with the point at infinity.
isInfinity := g1.api.And(g1.curveF.IsZero(&q.X), g1.curveF.IsZero(&q.Y))
q = &G1Affine{
X: *g1.curveF.Select(isInfinity, g1.curveF.One(), &q.X),
Y: *g1.curveF.Select(isInfinity, g1.curveF.One(), &q.Y),
}
Comment thread
ivokub marked this conversation as resolved.
z := g1.double(q)
z = g1.add(q, z)
z = g1.double(z)
Expand All @@ -169,6 +180,11 @@ func (g1 *G1) scalarMulBySeedSquare(q *G1Affine) *G1Affine {
z = g1.doubleAndAdd(z, q)
z = g1.doubleN(z, 32)

z = &G1Affine{
X: *g1.curveF.Select(isInfinity, g1.curveF.Zero(), &z.X),
Y: *g1.curveF.Select(isInfinity, g1.curveF.Zero(), &z.Y),
}

return z
}

Expand Down
26 changes: 19 additions & 7 deletions std/algebra/emulated/sw_bls12381/pairing.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,13 +315,24 @@ func (pr Pairing) AssertIsOnG1(P *G1Affine) {
// IsOnG1 returns a boolean indicating if the G1 point is on the curve and in
// the prime subgroup.
Comment thread
ivokub marked this conversation as resolved.
func (pr Pairing) IsOnG1(P *G1Affine) frontend.Variable {
// 1 - is Q on curve
// To check that a point P is on G1, we need to check it is of prime order r.
// This means that we need to check:
// [r]P == 0
// Instead of computing a big scalar multiplication, we check the equivalent condition:
// P + [x^2]ϕ(P) == 0
// where ϕ is the endomorphism of G1, and x is the seed of the curve.
// The last equation is equivalent of checking that:
// P = -[x^2]ϕ(P)

// 1 - is P on curve
isOnCurve := pr.IsOnCurve(P)
// 2 - is Q in the subgroup
// 2- Check P has the right subgroup order
// [x²]ϕ(P)
Comment thread
ivokub marked this conversation as resolved.
phiP := pr.g1.phi(P)
_P := pr.g1.scalarMulBySeedSquare(phiP)
_P = pr.curve.Neg(_P)
isInSubgroup := pr.g1.IsEqual(_P, phiP)
// [r]P == 0 <==> P = -[x²]ϕ(P)
isInSubgroup := pr.g1.IsEqual(_P, P)
return pr.api.And(isOnCurve, isInSubgroup)
}

Expand Down Expand Up @@ -399,10 +410,11 @@ func (pr Pairing) millerLoopLines(P []*G1Affine, lines []lineEvaluations, init *
xNegOverY := make([]*baseEl, n)

for k := 0; k < n; k++ {
// P are supposed to be on G1 respectively of prime order r.
// The point (x,0) is of order 2. But this function does not check
// subgroup membership.
yInv[k] = pr.curveF.Inverse(&P[k].Y)
// If we have point at infinity, we set yInv[k] to 0 manually to avoid
// undefined inversion of 0.
isYZero := pr.curveF.IsZero(&P[k].Y)
y := pr.curveF.Select(isYZero, pr.curveF.One(), &P[k].Y)
yInv[k] = pr.curveF.Select(isYZero, pr.curveF.Zero(), pr.curveF.Inverse(y))
xNegOverY[k] = pr.curveF.MulMod(&P[k].X, yInv[k])
xNegOverY[k] = pr.curveF.Neg(xNegOverY[k])
}
Expand Down
Loading