diff --git a/ecc/bls12-377/g1.go b/ecc/bls12-377/g1.go index a99d6c81d6..9563f30667 100644 --- a/ecc/bls12-377/g1.go +++ b/ecc/bls12-377/g1.go @@ -1161,12 +1161,24 @@ func BatchScalarMultiplicationG1(base *G1Affine, scalars []fr.Element) []G1Affin func batchAddG1Affine[TP pG1Affine, TPP ppG1Affine, TC cG1Affine](R *TPP, P *TP, batchSize int) { var lambda, lambdain TC - // add part + // from https://docs.zkproof.org/pages/standards/accepted-workshop3/proposal-turbo_plonk.pdf + // affine point addition formula + // R(X1, Y1) + P(X2, Y2) = Q(X3, Y3) + // λ = (Y2 - Y1) / (X2 - X1) + // X3 = λ² - (X1 + X2) + // Y3 = λ * (X1 - X3) - Y1 + + // first we compute the 1 / (X2 - X1) for all points using Montgomery batch inversion trick + + // X2 - X1 for j := 0; j < batchSize; j++ { lambdain[j].Sub(&(*P)[j].X, &(*R)[j].X) } - // invert denominator using montgomery batch invert technique + // montgomery batch inversion; + // lambda[0] = 1 / (P[0].X - R[0].X) + // lambda[1] = 1 / (P[1].X - R[1].X) + // ... { var accumulator fp.Element lambda[0].SetOne() @@ -1186,22 +1198,24 @@ func batchAddG1Affine[TP pG1Affine, TPP ppG1Affine, TC cG1Affine](R *TPP, P *TP, lambda[0].Set(&accumulator) } - var d fp.Element - var rr G1Affine + var t fp.Element + var Q G1Affine - // add part for j := 0; j < batchSize; j++ { - // computa lambda - d.Sub(&(*P)[j].Y, &(*R)[j].Y) - lambda[j].Mul(&lambda[j], &d) - - // compute X, Y - rr.X.Square(&lambda[j]) - rr.X.Sub(&rr.X, &(*R)[j].X) - rr.X.Sub(&rr.X, &(*P)[j].X) - d.Sub(&(*R)[j].X, &rr.X) - rr.Y.Mul(&lambda[j], &d) - rr.Y.Sub(&rr.Y, &(*R)[j].Y) - (*R)[j].Set(&rr) + // λ = (Y2 - Y1) / (X2 - X1) + t.Sub(&(*P)[j].Y, &(*R)[j].Y) + lambda[j].Mul(&lambda[j], &t) + + // X3 = λ² - (X1 + X2) + Q.X.Square(&lambda[j]) + Q.X.Sub(&Q.X, &(*R)[j].X) + Q.X.Sub(&Q.X, &(*P)[j].X) + + // Y3 = λ * (X1 - X3) - Y1 + t.Sub(&(*R)[j].X, &Q.X) + Q.Y.Mul(&lambda[j], &t) + Q.Y.Sub(&Q.Y, &(*R)[j].Y) + + (*R)[j].Set(&Q) } } diff --git a/ecc/bls12-377/g2.go b/ecc/bls12-377/g2.go index 3401a43a0f..29bf5e5e9e 100644 --- a/ecc/bls12-377/g2.go +++ b/ecc/bls12-377/g2.go @@ -1087,12 +1087,24 @@ func BatchScalarMultiplicationG2(base *G2Affine, scalars []fr.Element) []G2Affin func batchAddG2Affine[TP pG2Affine, TPP ppG2Affine, TC cG2Affine](R *TPP, P *TP, batchSize int) { var lambda, lambdain TC - // add part + // from https://docs.zkproof.org/pages/standards/accepted-workshop3/proposal-turbo_plonk.pdf + // affine point addition formula + // R(X1, Y1) + P(X2, Y2) = Q(X3, Y3) + // λ = (Y2 - Y1) / (X2 - X1) + // X3 = λ² - (X1 + X2) + // Y3 = λ * (X1 - X3) - Y1 + + // first we compute the 1 / (X2 - X1) for all points using Montgomery batch inversion trick + + // X2 - X1 for j := 0; j < batchSize; j++ { lambdain[j].Sub(&(*P)[j].X, &(*R)[j].X) } - // invert denominator using montgomery batch invert technique + // montgomery batch inversion; + // lambda[0] = 1 / (P[0].X - R[0].X) + // lambda[1] = 1 / (P[1].X - R[1].X) + // ... { var accumulator fptower.E2 lambda[0].SetOne() @@ -1112,23 +1124,25 @@ func batchAddG2Affine[TP pG2Affine, TPP ppG2Affine, TC cG2Affine](R *TPP, P *TP, lambda[0].Set(&accumulator) } - var d fptower.E2 - var rr G2Affine + var t fptower.E2 + var Q G2Affine - // add part for j := 0; j < batchSize; j++ { - // computa lambda - d.Sub(&(*P)[j].Y, &(*R)[j].Y) - lambda[j].Mul(&lambda[j], &d) - - // compute X, Y - rr.X.Square(&lambda[j]) - rr.X.Sub(&rr.X, &(*R)[j].X) - rr.X.Sub(&rr.X, &(*P)[j].X) - d.Sub(&(*R)[j].X, &rr.X) - rr.Y.Mul(&lambda[j], &d) - rr.Y.Sub(&rr.Y, &(*R)[j].Y) - (*R)[j].Set(&rr) + // λ = (Y2 - Y1) / (X2 - X1) + t.Sub(&(*P)[j].Y, &(*R)[j].Y) + lambda[j].Mul(&lambda[j], &t) + + // X3 = λ² - (X1 + X2) + Q.X.Square(&lambda[j]) + Q.X.Sub(&Q.X, &(*R)[j].X) + Q.X.Sub(&Q.X, &(*P)[j].X) + + // Y3 = λ * (X1 - X3) - Y1 + t.Sub(&(*R)[j].X, &Q.X) + Q.Y.Mul(&lambda[j], &t) + Q.Y.Sub(&Q.Y, &(*R)[j].Y) + + (*R)[j].Set(&Q) } } diff --git a/ecc/bls12-381/g1.go b/ecc/bls12-381/g1.go index 88ac32c77a..c626d848f6 100644 --- a/ecc/bls12-381/g1.go +++ b/ecc/bls12-381/g1.go @@ -1162,12 +1162,24 @@ func BatchScalarMultiplicationG1(base *G1Affine, scalars []fr.Element) []G1Affin func batchAddG1Affine[TP pG1Affine, TPP ppG1Affine, TC cG1Affine](R *TPP, P *TP, batchSize int) { var lambda, lambdain TC - // add part + // from https://docs.zkproof.org/pages/standards/accepted-workshop3/proposal-turbo_plonk.pdf + // affine point addition formula + // R(X1, Y1) + P(X2, Y2) = Q(X3, Y3) + // λ = (Y2 - Y1) / (X2 - X1) + // X3 = λ² - (X1 + X2) + // Y3 = λ * (X1 - X3) - Y1 + + // first we compute the 1 / (X2 - X1) for all points using Montgomery batch inversion trick + + // X2 - X1 for j := 0; j < batchSize; j++ { lambdain[j].Sub(&(*P)[j].X, &(*R)[j].X) } - // invert denominator using montgomery batch invert technique + // montgomery batch inversion; + // lambda[0] = 1 / (P[0].X - R[0].X) + // lambda[1] = 1 / (P[1].X - R[1].X) + // ... { var accumulator fp.Element lambda[0].SetOne() @@ -1187,22 +1199,24 @@ func batchAddG1Affine[TP pG1Affine, TPP ppG1Affine, TC cG1Affine](R *TPP, P *TP, lambda[0].Set(&accumulator) } - var d fp.Element - var rr G1Affine + var t fp.Element + var Q G1Affine - // add part for j := 0; j < batchSize; j++ { - // computa lambda - d.Sub(&(*P)[j].Y, &(*R)[j].Y) - lambda[j].Mul(&lambda[j], &d) - - // compute X, Y - rr.X.Square(&lambda[j]) - rr.X.Sub(&rr.X, &(*R)[j].X) - rr.X.Sub(&rr.X, &(*P)[j].X) - d.Sub(&(*R)[j].X, &rr.X) - rr.Y.Mul(&lambda[j], &d) - rr.Y.Sub(&rr.Y, &(*R)[j].Y) - (*R)[j].Set(&rr) + // λ = (Y2 - Y1) / (X2 - X1) + t.Sub(&(*P)[j].Y, &(*R)[j].Y) + lambda[j].Mul(&lambda[j], &t) + + // X3 = λ² - (X1 + X2) + Q.X.Square(&lambda[j]) + Q.X.Sub(&Q.X, &(*R)[j].X) + Q.X.Sub(&Q.X, &(*P)[j].X) + + // Y3 = λ * (X1 - X3) - Y1 + t.Sub(&(*R)[j].X, &Q.X) + Q.Y.Mul(&lambda[j], &t) + Q.Y.Sub(&Q.Y, &(*R)[j].Y) + + (*R)[j].Set(&Q) } } diff --git a/ecc/bls12-381/g2.go b/ecc/bls12-381/g2.go index d4d7fa1c92..38f262cb8c 100644 --- a/ecc/bls12-381/g2.go +++ b/ecc/bls12-381/g2.go @@ -1088,12 +1088,24 @@ func BatchScalarMultiplicationG2(base *G2Affine, scalars []fr.Element) []G2Affin func batchAddG2Affine[TP pG2Affine, TPP ppG2Affine, TC cG2Affine](R *TPP, P *TP, batchSize int) { var lambda, lambdain TC - // add part + // from https://docs.zkproof.org/pages/standards/accepted-workshop3/proposal-turbo_plonk.pdf + // affine point addition formula + // R(X1, Y1) + P(X2, Y2) = Q(X3, Y3) + // λ = (Y2 - Y1) / (X2 - X1) + // X3 = λ² - (X1 + X2) + // Y3 = λ * (X1 - X3) - Y1 + + // first we compute the 1 / (X2 - X1) for all points using Montgomery batch inversion trick + + // X2 - X1 for j := 0; j < batchSize; j++ { lambdain[j].Sub(&(*P)[j].X, &(*R)[j].X) } - // invert denominator using montgomery batch invert technique + // montgomery batch inversion; + // lambda[0] = 1 / (P[0].X - R[0].X) + // lambda[1] = 1 / (P[1].X - R[1].X) + // ... { var accumulator fptower.E2 lambda[0].SetOne() @@ -1113,23 +1125,25 @@ func batchAddG2Affine[TP pG2Affine, TPP ppG2Affine, TC cG2Affine](R *TPP, P *TP, lambda[0].Set(&accumulator) } - var d fptower.E2 - var rr G2Affine + var t fptower.E2 + var Q G2Affine - // add part for j := 0; j < batchSize; j++ { - // computa lambda - d.Sub(&(*P)[j].Y, &(*R)[j].Y) - lambda[j].Mul(&lambda[j], &d) - - // compute X, Y - rr.X.Square(&lambda[j]) - rr.X.Sub(&rr.X, &(*R)[j].X) - rr.X.Sub(&rr.X, &(*P)[j].X) - d.Sub(&(*R)[j].X, &rr.X) - rr.Y.Mul(&lambda[j], &d) - rr.Y.Sub(&rr.Y, &(*R)[j].Y) - (*R)[j].Set(&rr) + // λ = (Y2 - Y1) / (X2 - X1) + t.Sub(&(*P)[j].Y, &(*R)[j].Y) + lambda[j].Mul(&lambda[j], &t) + + // X3 = λ² - (X1 + X2) + Q.X.Square(&lambda[j]) + Q.X.Sub(&Q.X, &(*R)[j].X) + Q.X.Sub(&Q.X, &(*P)[j].X) + + // Y3 = λ * (X1 - X3) - Y1 + t.Sub(&(*R)[j].X, &Q.X) + Q.Y.Mul(&lambda[j], &t) + Q.Y.Sub(&Q.Y, &(*R)[j].Y) + + (*R)[j].Set(&Q) } } diff --git a/ecc/bls24-315/g1.go b/ecc/bls24-315/g1.go index 91d995c8cb..0e1cc2ff8c 100644 --- a/ecc/bls24-315/g1.go +++ b/ecc/bls24-315/g1.go @@ -1163,12 +1163,24 @@ func BatchScalarMultiplicationG1(base *G1Affine, scalars []fr.Element) []G1Affin func batchAddG1Affine[TP pG1Affine, TPP ppG1Affine, TC cG1Affine](R *TPP, P *TP, batchSize int) { var lambda, lambdain TC - // add part + // from https://docs.zkproof.org/pages/standards/accepted-workshop3/proposal-turbo_plonk.pdf + // affine point addition formula + // R(X1, Y1) + P(X2, Y2) = Q(X3, Y3) + // λ = (Y2 - Y1) / (X2 - X1) + // X3 = λ² - (X1 + X2) + // Y3 = λ * (X1 - X3) - Y1 + + // first we compute the 1 / (X2 - X1) for all points using Montgomery batch inversion trick + + // X2 - X1 for j := 0; j < batchSize; j++ { lambdain[j].Sub(&(*P)[j].X, &(*R)[j].X) } - // invert denominator using montgomery batch invert technique + // montgomery batch inversion; + // lambda[0] = 1 / (P[0].X - R[0].X) + // lambda[1] = 1 / (P[1].X - R[1].X) + // ... { var accumulator fp.Element lambda[0].SetOne() @@ -1188,22 +1200,24 @@ func batchAddG1Affine[TP pG1Affine, TPP ppG1Affine, TC cG1Affine](R *TPP, P *TP, lambda[0].Set(&accumulator) } - var d fp.Element - var rr G1Affine + var t fp.Element + var Q G1Affine - // add part for j := 0; j < batchSize; j++ { - // computa lambda - d.Sub(&(*P)[j].Y, &(*R)[j].Y) - lambda[j].Mul(&lambda[j], &d) - - // compute X, Y - rr.X.Square(&lambda[j]) - rr.X.Sub(&rr.X, &(*R)[j].X) - rr.X.Sub(&rr.X, &(*P)[j].X) - d.Sub(&(*R)[j].X, &rr.X) - rr.Y.Mul(&lambda[j], &d) - rr.Y.Sub(&rr.Y, &(*R)[j].Y) - (*R)[j].Set(&rr) + // λ = (Y2 - Y1) / (X2 - X1) + t.Sub(&(*P)[j].Y, &(*R)[j].Y) + lambda[j].Mul(&lambda[j], &t) + + // X3 = λ² - (X1 + X2) + Q.X.Square(&lambda[j]) + Q.X.Sub(&Q.X, &(*R)[j].X) + Q.X.Sub(&Q.X, &(*P)[j].X) + + // Y3 = λ * (X1 - X3) - Y1 + t.Sub(&(*R)[j].X, &Q.X) + Q.Y.Mul(&lambda[j], &t) + Q.Y.Sub(&Q.Y, &(*R)[j].Y) + + (*R)[j].Set(&Q) } } diff --git a/ecc/bls24-315/g2.go b/ecc/bls24-315/g2.go index dd08636ea9..8250d2b5aa 100644 --- a/ecc/bls24-315/g2.go +++ b/ecc/bls24-315/g2.go @@ -1103,12 +1103,24 @@ func BatchScalarMultiplicationG2(base *G2Affine, scalars []fr.Element) []G2Affin func batchAddG2Affine[TP pG2Affine, TPP ppG2Affine, TC cG2Affine](R *TPP, P *TP, batchSize int) { var lambda, lambdain TC - // add part + // from https://docs.zkproof.org/pages/standards/accepted-workshop3/proposal-turbo_plonk.pdf + // affine point addition formula + // R(X1, Y1) + P(X2, Y2) = Q(X3, Y3) + // λ = (Y2 - Y1) / (X2 - X1) + // X3 = λ² - (X1 + X2) + // Y3 = λ * (X1 - X3) - Y1 + + // first we compute the 1 / (X2 - X1) for all points using Montgomery batch inversion trick + + // X2 - X1 for j := 0; j < batchSize; j++ { lambdain[j].Sub(&(*P)[j].X, &(*R)[j].X) } - // invert denominator using montgomery batch invert technique + // montgomery batch inversion; + // lambda[0] = 1 / (P[0].X - R[0].X) + // lambda[1] = 1 / (P[1].X - R[1].X) + // ... { var accumulator fptower.E4 lambda[0].SetOne() @@ -1128,23 +1140,25 @@ func batchAddG2Affine[TP pG2Affine, TPP ppG2Affine, TC cG2Affine](R *TPP, P *TP, lambda[0].Set(&accumulator) } - var d fptower.E4 - var rr G2Affine + var t fptower.E4 + var Q G2Affine - // add part for j := 0; j < batchSize; j++ { - // computa lambda - d.Sub(&(*P)[j].Y, &(*R)[j].Y) - lambda[j].Mul(&lambda[j], &d) - - // compute X, Y - rr.X.Square(&lambda[j]) - rr.X.Sub(&rr.X, &(*R)[j].X) - rr.X.Sub(&rr.X, &(*P)[j].X) - d.Sub(&(*R)[j].X, &rr.X) - rr.Y.Mul(&lambda[j], &d) - rr.Y.Sub(&rr.Y, &(*R)[j].Y) - (*R)[j].Set(&rr) + // λ = (Y2 - Y1) / (X2 - X1) + t.Sub(&(*P)[j].Y, &(*R)[j].Y) + lambda[j].Mul(&lambda[j], &t) + + // X3 = λ² - (X1 + X2) + Q.X.Square(&lambda[j]) + Q.X.Sub(&Q.X, &(*R)[j].X) + Q.X.Sub(&Q.X, &(*P)[j].X) + + // Y3 = λ * (X1 - X3) - Y1 + t.Sub(&(*R)[j].X, &Q.X) + Q.Y.Mul(&lambda[j], &t) + Q.Y.Sub(&Q.Y, &(*R)[j].Y) + + (*R)[j].Set(&Q) } } diff --git a/ecc/bls24-317/g1.go b/ecc/bls24-317/g1.go index 890a7de492..8240303dd9 100644 --- a/ecc/bls24-317/g1.go +++ b/ecc/bls24-317/g1.go @@ -1164,12 +1164,24 @@ func BatchScalarMultiplicationG1(base *G1Affine, scalars []fr.Element) []G1Affin func batchAddG1Affine[TP pG1Affine, TPP ppG1Affine, TC cG1Affine](R *TPP, P *TP, batchSize int) { var lambda, lambdain TC - // add part + // from https://docs.zkproof.org/pages/standards/accepted-workshop3/proposal-turbo_plonk.pdf + // affine point addition formula + // R(X1, Y1) + P(X2, Y2) = Q(X3, Y3) + // λ = (Y2 - Y1) / (X2 - X1) + // X3 = λ² - (X1 + X2) + // Y3 = λ * (X1 - X3) - Y1 + + // first we compute the 1 / (X2 - X1) for all points using Montgomery batch inversion trick + + // X2 - X1 for j := 0; j < batchSize; j++ { lambdain[j].Sub(&(*P)[j].X, &(*R)[j].X) } - // invert denominator using montgomery batch invert technique + // montgomery batch inversion; + // lambda[0] = 1 / (P[0].X - R[0].X) + // lambda[1] = 1 / (P[1].X - R[1].X) + // ... { var accumulator fp.Element lambda[0].SetOne() @@ -1189,22 +1201,24 @@ func batchAddG1Affine[TP pG1Affine, TPP ppG1Affine, TC cG1Affine](R *TPP, P *TP, lambda[0].Set(&accumulator) } - var d fp.Element - var rr G1Affine + var t fp.Element + var Q G1Affine - // add part for j := 0; j < batchSize; j++ { - // computa lambda - d.Sub(&(*P)[j].Y, &(*R)[j].Y) - lambda[j].Mul(&lambda[j], &d) - - // compute X, Y - rr.X.Square(&lambda[j]) - rr.X.Sub(&rr.X, &(*R)[j].X) - rr.X.Sub(&rr.X, &(*P)[j].X) - d.Sub(&(*R)[j].X, &rr.X) - rr.Y.Mul(&lambda[j], &d) - rr.Y.Sub(&rr.Y, &(*R)[j].Y) - (*R)[j].Set(&rr) + // λ = (Y2 - Y1) / (X2 - X1) + t.Sub(&(*P)[j].Y, &(*R)[j].Y) + lambda[j].Mul(&lambda[j], &t) + + // X3 = λ² - (X1 + X2) + Q.X.Square(&lambda[j]) + Q.X.Sub(&Q.X, &(*R)[j].X) + Q.X.Sub(&Q.X, &(*P)[j].X) + + // Y3 = λ * (X1 - X3) - Y1 + t.Sub(&(*R)[j].X, &Q.X) + Q.Y.Mul(&lambda[j], &t) + Q.Y.Sub(&Q.Y, &(*R)[j].Y) + + (*R)[j].Set(&Q) } } diff --git a/ecc/bls24-317/g2.go b/ecc/bls24-317/g2.go index b34c68acd6..9f51ce2141 100644 --- a/ecc/bls24-317/g2.go +++ b/ecc/bls24-317/g2.go @@ -1103,12 +1103,24 @@ func BatchScalarMultiplicationG2(base *G2Affine, scalars []fr.Element) []G2Affin func batchAddG2Affine[TP pG2Affine, TPP ppG2Affine, TC cG2Affine](R *TPP, P *TP, batchSize int) { var lambda, lambdain TC - // add part + // from https://docs.zkproof.org/pages/standards/accepted-workshop3/proposal-turbo_plonk.pdf + // affine point addition formula + // R(X1, Y1) + P(X2, Y2) = Q(X3, Y3) + // λ = (Y2 - Y1) / (X2 - X1) + // X3 = λ² - (X1 + X2) + // Y3 = λ * (X1 - X3) - Y1 + + // first we compute the 1 / (X2 - X1) for all points using Montgomery batch inversion trick + + // X2 - X1 for j := 0; j < batchSize; j++ { lambdain[j].Sub(&(*P)[j].X, &(*R)[j].X) } - // invert denominator using montgomery batch invert technique + // montgomery batch inversion; + // lambda[0] = 1 / (P[0].X - R[0].X) + // lambda[1] = 1 / (P[1].X - R[1].X) + // ... { var accumulator fptower.E4 lambda[0].SetOne() @@ -1128,23 +1140,25 @@ func batchAddG2Affine[TP pG2Affine, TPP ppG2Affine, TC cG2Affine](R *TPP, P *TP, lambda[0].Set(&accumulator) } - var d fptower.E4 - var rr G2Affine + var t fptower.E4 + var Q G2Affine - // add part for j := 0; j < batchSize; j++ { - // computa lambda - d.Sub(&(*P)[j].Y, &(*R)[j].Y) - lambda[j].Mul(&lambda[j], &d) - - // compute X, Y - rr.X.Square(&lambda[j]) - rr.X.Sub(&rr.X, &(*R)[j].X) - rr.X.Sub(&rr.X, &(*P)[j].X) - d.Sub(&(*R)[j].X, &rr.X) - rr.Y.Mul(&lambda[j], &d) - rr.Y.Sub(&rr.Y, &(*R)[j].Y) - (*R)[j].Set(&rr) + // λ = (Y2 - Y1) / (X2 - X1) + t.Sub(&(*P)[j].Y, &(*R)[j].Y) + lambda[j].Mul(&lambda[j], &t) + + // X3 = λ² - (X1 + X2) + Q.X.Square(&lambda[j]) + Q.X.Sub(&Q.X, &(*R)[j].X) + Q.X.Sub(&Q.X, &(*P)[j].X) + + // Y3 = λ * (X1 - X3) - Y1 + t.Sub(&(*R)[j].X, &Q.X) + Q.Y.Mul(&lambda[j], &t) + Q.Y.Sub(&Q.Y, &(*R)[j].Y) + + (*R)[j].Set(&Q) } } diff --git a/ecc/bn254/g1.go b/ecc/bn254/g1.go index 14dfeef86b..e2c4a1d96d 100644 --- a/ecc/bn254/g1.go +++ b/ecc/bn254/g1.go @@ -1133,12 +1133,24 @@ func BatchScalarMultiplicationG1(base *G1Affine, scalars []fr.Element) []G1Affin func batchAddG1Affine[TP pG1Affine, TPP ppG1Affine, TC cG1Affine](R *TPP, P *TP, batchSize int) { var lambda, lambdain TC - // add part + // from https://docs.zkproof.org/pages/standards/accepted-workshop3/proposal-turbo_plonk.pdf + // affine point addition formula + // R(X1, Y1) + P(X2, Y2) = Q(X3, Y3) + // λ = (Y2 - Y1) / (X2 - X1) + // X3 = λ² - (X1 + X2) + // Y3 = λ * (X1 - X3) - Y1 + + // first we compute the 1 / (X2 - X1) for all points using Montgomery batch inversion trick + + // X2 - X1 for j := 0; j < batchSize; j++ { lambdain[j].Sub(&(*P)[j].X, &(*R)[j].X) } - // invert denominator using montgomery batch invert technique + // montgomery batch inversion; + // lambda[0] = 1 / (P[0].X - R[0].X) + // lambda[1] = 1 / (P[1].X - R[1].X) + // ... { var accumulator fp.Element lambda[0].SetOne() @@ -1158,22 +1170,24 @@ func batchAddG1Affine[TP pG1Affine, TPP ppG1Affine, TC cG1Affine](R *TPP, P *TP, lambda[0].Set(&accumulator) } - var d fp.Element - var rr G1Affine + var t fp.Element + var Q G1Affine - // add part for j := 0; j < batchSize; j++ { - // computa lambda - d.Sub(&(*P)[j].Y, &(*R)[j].Y) - lambda[j].Mul(&lambda[j], &d) - - // compute X, Y - rr.X.Square(&lambda[j]) - rr.X.Sub(&rr.X, &(*R)[j].X) - rr.X.Sub(&rr.X, &(*P)[j].X) - d.Sub(&(*R)[j].X, &rr.X) - rr.Y.Mul(&lambda[j], &d) - rr.Y.Sub(&rr.Y, &(*R)[j].Y) - (*R)[j].Set(&rr) + // λ = (Y2 - Y1) / (X2 - X1) + t.Sub(&(*P)[j].Y, &(*R)[j].Y) + lambda[j].Mul(&lambda[j], &t) + + // X3 = λ² - (X1 + X2) + Q.X.Square(&lambda[j]) + Q.X.Sub(&Q.X, &(*R)[j].X) + Q.X.Sub(&Q.X, &(*P)[j].X) + + // Y3 = λ * (X1 - X3) - Y1 + t.Sub(&(*R)[j].X, &Q.X) + Q.Y.Mul(&lambda[j], &t) + Q.Y.Sub(&Q.Y, &(*R)[j].Y) + + (*R)[j].Set(&Q) } } diff --git a/ecc/bn254/g2.go b/ecc/bn254/g2.go index 24561bb28c..54addc34d2 100644 --- a/ecc/bn254/g2.go +++ b/ecc/bn254/g2.go @@ -1092,12 +1092,24 @@ func BatchScalarMultiplicationG2(base *G2Affine, scalars []fr.Element) []G2Affin func batchAddG2Affine[TP pG2Affine, TPP ppG2Affine, TC cG2Affine](R *TPP, P *TP, batchSize int) { var lambda, lambdain TC - // add part + // from https://docs.zkproof.org/pages/standards/accepted-workshop3/proposal-turbo_plonk.pdf + // affine point addition formula + // R(X1, Y1) + P(X2, Y2) = Q(X3, Y3) + // λ = (Y2 - Y1) / (X2 - X1) + // X3 = λ² - (X1 + X2) + // Y3 = λ * (X1 - X3) - Y1 + + // first we compute the 1 / (X2 - X1) for all points using Montgomery batch inversion trick + + // X2 - X1 for j := 0; j < batchSize; j++ { lambdain[j].Sub(&(*P)[j].X, &(*R)[j].X) } - // invert denominator using montgomery batch invert technique + // montgomery batch inversion; + // lambda[0] = 1 / (P[0].X - R[0].X) + // lambda[1] = 1 / (P[1].X - R[1].X) + // ... { var accumulator fptower.E2 lambda[0].SetOne() @@ -1117,23 +1129,25 @@ func batchAddG2Affine[TP pG2Affine, TPP ppG2Affine, TC cG2Affine](R *TPP, P *TP, lambda[0].Set(&accumulator) } - var d fptower.E2 - var rr G2Affine + var t fptower.E2 + var Q G2Affine - // add part for j := 0; j < batchSize; j++ { - // computa lambda - d.Sub(&(*P)[j].Y, &(*R)[j].Y) - lambda[j].Mul(&lambda[j], &d) - - // compute X, Y - rr.X.Square(&lambda[j]) - rr.X.Sub(&rr.X, &(*R)[j].X) - rr.X.Sub(&rr.X, &(*P)[j].X) - d.Sub(&(*R)[j].X, &rr.X) - rr.Y.Mul(&lambda[j], &d) - rr.Y.Sub(&rr.Y, &(*R)[j].Y) - (*R)[j].Set(&rr) + // λ = (Y2 - Y1) / (X2 - X1) + t.Sub(&(*P)[j].Y, &(*R)[j].Y) + lambda[j].Mul(&lambda[j], &t) + + // X3 = λ² - (X1 + X2) + Q.X.Square(&lambda[j]) + Q.X.Sub(&Q.X, &(*R)[j].X) + Q.X.Sub(&Q.X, &(*P)[j].X) + + // Y3 = λ * (X1 - X3) - Y1 + t.Sub(&(*R)[j].X, &Q.X) + Q.Y.Mul(&lambda[j], &t) + Q.Y.Sub(&Q.Y, &(*R)[j].Y) + + (*R)[j].Set(&Q) } } diff --git a/ecc/bw6-633/g1.go b/ecc/bw6-633/g1.go index 196053c960..6491867a3f 100644 --- a/ecc/bw6-633/g1.go +++ b/ecc/bw6-633/g1.go @@ -1186,12 +1186,24 @@ func BatchScalarMultiplicationG1(base *G1Affine, scalars []fr.Element) []G1Affin func batchAddG1Affine[TP pG1Affine, TPP ppG1Affine, TC cG1Affine](R *TPP, P *TP, batchSize int) { var lambda, lambdain TC - // add part + // from https://docs.zkproof.org/pages/standards/accepted-workshop3/proposal-turbo_plonk.pdf + // affine point addition formula + // R(X1, Y1) + P(X2, Y2) = Q(X3, Y3) + // λ = (Y2 - Y1) / (X2 - X1) + // X3 = λ² - (X1 + X2) + // Y3 = λ * (X1 - X3) - Y1 + + // first we compute the 1 / (X2 - X1) for all points using Montgomery batch inversion trick + + // X2 - X1 for j := 0; j < batchSize; j++ { lambdain[j].Sub(&(*P)[j].X, &(*R)[j].X) } - // invert denominator using montgomery batch invert technique + // montgomery batch inversion; + // lambda[0] = 1 / (P[0].X - R[0].X) + // lambda[1] = 1 / (P[1].X - R[1].X) + // ... { var accumulator fp.Element lambda[0].SetOne() @@ -1211,22 +1223,24 @@ func batchAddG1Affine[TP pG1Affine, TPP ppG1Affine, TC cG1Affine](R *TPP, P *TP, lambda[0].Set(&accumulator) } - var d fp.Element - var rr G1Affine + var t fp.Element + var Q G1Affine - // add part for j := 0; j < batchSize; j++ { - // computa lambda - d.Sub(&(*P)[j].Y, &(*R)[j].Y) - lambda[j].Mul(&lambda[j], &d) - - // compute X, Y - rr.X.Square(&lambda[j]) - rr.X.Sub(&rr.X, &(*R)[j].X) - rr.X.Sub(&rr.X, &(*P)[j].X) - d.Sub(&(*R)[j].X, &rr.X) - rr.Y.Mul(&lambda[j], &d) - rr.Y.Sub(&rr.Y, &(*R)[j].Y) - (*R)[j].Set(&rr) + // λ = (Y2 - Y1) / (X2 - X1) + t.Sub(&(*P)[j].Y, &(*R)[j].Y) + lambda[j].Mul(&lambda[j], &t) + + // X3 = λ² - (X1 + X2) + Q.X.Square(&lambda[j]) + Q.X.Sub(&Q.X, &(*R)[j].X) + Q.X.Sub(&Q.X, &(*P)[j].X) + + // Y3 = λ * (X1 - X3) - Y1 + t.Sub(&(*R)[j].X, &Q.X) + Q.Y.Mul(&lambda[j], &t) + Q.Y.Sub(&Q.Y, &(*R)[j].Y) + + (*R)[j].Set(&Q) } } diff --git a/ecc/bw6-633/g2.go b/ecc/bw6-633/g2.go index 611753c678..a6e7268de1 100644 --- a/ecc/bw6-633/g2.go +++ b/ecc/bw6-633/g2.go @@ -1094,12 +1094,24 @@ func BatchScalarMultiplicationG2(base *G2Affine, scalars []fr.Element) []G2Affin func batchAddG2Affine[TP pG2Affine, TPP ppG2Affine, TC cG2Affine](R *TPP, P *TP, batchSize int) { var lambda, lambdain TC - // add part + // from https://docs.zkproof.org/pages/standards/accepted-workshop3/proposal-turbo_plonk.pdf + // affine point addition formula + // R(X1, Y1) + P(X2, Y2) = Q(X3, Y3) + // λ = (Y2 - Y1) / (X2 - X1) + // X3 = λ² - (X1 + X2) + // Y3 = λ * (X1 - X3) - Y1 + + // first we compute the 1 / (X2 - X1) for all points using Montgomery batch inversion trick + + // X2 - X1 for j := 0; j < batchSize; j++ { lambdain[j].Sub(&(*P)[j].X, &(*R)[j].X) } - // invert denominator using montgomery batch invert technique + // montgomery batch inversion; + // lambda[0] = 1 / (P[0].X - R[0].X) + // lambda[1] = 1 / (P[1].X - R[1].X) + // ... { var accumulator fp.Element lambda[0].SetOne() @@ -1119,23 +1131,25 @@ func batchAddG2Affine[TP pG2Affine, TPP ppG2Affine, TC cG2Affine](R *TPP, P *TP, lambda[0].Set(&accumulator) } - var d fp.Element - var rr G2Affine + var t fp.Element + var Q G2Affine - // add part for j := 0; j < batchSize; j++ { - // computa lambda - d.Sub(&(*P)[j].Y, &(*R)[j].Y) - lambda[j].Mul(&lambda[j], &d) - - // compute X, Y - rr.X.Square(&lambda[j]) - rr.X.Sub(&rr.X, &(*R)[j].X) - rr.X.Sub(&rr.X, &(*P)[j].X) - d.Sub(&(*R)[j].X, &rr.X) - rr.Y.Mul(&lambda[j], &d) - rr.Y.Sub(&rr.Y, &(*R)[j].Y) - (*R)[j].Set(&rr) + // λ = (Y2 - Y1) / (X2 - X1) + t.Sub(&(*P)[j].Y, &(*R)[j].Y) + lambda[j].Mul(&lambda[j], &t) + + // X3 = λ² - (X1 + X2) + Q.X.Square(&lambda[j]) + Q.X.Sub(&Q.X, &(*R)[j].X) + Q.X.Sub(&Q.X, &(*P)[j].X) + + // Y3 = λ * (X1 - X3) - Y1 + t.Sub(&(*R)[j].X, &Q.X) + Q.Y.Mul(&lambda[j], &t) + Q.Y.Sub(&Q.Y, &(*R)[j].Y) + + (*R)[j].Set(&Q) } } diff --git a/ecc/bw6-761/g1.go b/ecc/bw6-761/g1.go index beef3e2aca..a25082de81 100644 --- a/ecc/bw6-761/g1.go +++ b/ecc/bw6-761/g1.go @@ -1198,12 +1198,24 @@ func BatchScalarMultiplicationG1(base *G1Affine, scalars []fr.Element) []G1Affin func batchAddG1Affine[TP pG1Affine, TPP ppG1Affine, TC cG1Affine](R *TPP, P *TP, batchSize int) { var lambda, lambdain TC - // add part + // from https://docs.zkproof.org/pages/standards/accepted-workshop3/proposal-turbo_plonk.pdf + // affine point addition formula + // R(X1, Y1) + P(X2, Y2) = Q(X3, Y3) + // λ = (Y2 - Y1) / (X2 - X1) + // X3 = λ² - (X1 + X2) + // Y3 = λ * (X1 - X3) - Y1 + + // first we compute the 1 / (X2 - X1) for all points using Montgomery batch inversion trick + + // X2 - X1 for j := 0; j < batchSize; j++ { lambdain[j].Sub(&(*P)[j].X, &(*R)[j].X) } - // invert denominator using montgomery batch invert technique + // montgomery batch inversion; + // lambda[0] = 1 / (P[0].X - R[0].X) + // lambda[1] = 1 / (P[1].X - R[1].X) + // ... { var accumulator fp.Element lambda[0].SetOne() @@ -1223,22 +1235,24 @@ func batchAddG1Affine[TP pG1Affine, TPP ppG1Affine, TC cG1Affine](R *TPP, P *TP, lambda[0].Set(&accumulator) } - var d fp.Element - var rr G1Affine + var t fp.Element + var Q G1Affine - // add part for j := 0; j < batchSize; j++ { - // computa lambda - d.Sub(&(*P)[j].Y, &(*R)[j].Y) - lambda[j].Mul(&lambda[j], &d) - - // compute X, Y - rr.X.Square(&lambda[j]) - rr.X.Sub(&rr.X, &(*R)[j].X) - rr.X.Sub(&rr.X, &(*P)[j].X) - d.Sub(&(*R)[j].X, &rr.X) - rr.Y.Mul(&lambda[j], &d) - rr.Y.Sub(&rr.Y, &(*R)[j].Y) - (*R)[j].Set(&rr) + // λ = (Y2 - Y1) / (X2 - X1) + t.Sub(&(*P)[j].Y, &(*R)[j].Y) + lambda[j].Mul(&lambda[j], &t) + + // X3 = λ² - (X1 + X2) + Q.X.Square(&lambda[j]) + Q.X.Sub(&Q.X, &(*R)[j].X) + Q.X.Sub(&Q.X, &(*P)[j].X) + + // Y3 = λ * (X1 - X3) - Y1 + t.Sub(&(*R)[j].X, &Q.X) + Q.Y.Mul(&lambda[j], &t) + Q.Y.Sub(&Q.Y, &(*R)[j].Y) + + (*R)[j].Set(&Q) } } diff --git a/ecc/bw6-761/g2.go b/ecc/bw6-761/g2.go index 832811a70e..b14e9da70b 100644 --- a/ecc/bw6-761/g2.go +++ b/ecc/bw6-761/g2.go @@ -1102,12 +1102,24 @@ func BatchScalarMultiplicationG2(base *G2Affine, scalars []fr.Element) []G2Affin func batchAddG2Affine[TP pG2Affine, TPP ppG2Affine, TC cG2Affine](R *TPP, P *TP, batchSize int) { var lambda, lambdain TC - // add part + // from https://docs.zkproof.org/pages/standards/accepted-workshop3/proposal-turbo_plonk.pdf + // affine point addition formula + // R(X1, Y1) + P(X2, Y2) = Q(X3, Y3) + // λ = (Y2 - Y1) / (X2 - X1) + // X3 = λ² - (X1 + X2) + // Y3 = λ * (X1 - X3) - Y1 + + // first we compute the 1 / (X2 - X1) for all points using Montgomery batch inversion trick + + // X2 - X1 for j := 0; j < batchSize; j++ { lambdain[j].Sub(&(*P)[j].X, &(*R)[j].X) } - // invert denominator using montgomery batch invert technique + // montgomery batch inversion; + // lambda[0] = 1 / (P[0].X - R[0].X) + // lambda[1] = 1 / (P[1].X - R[1].X) + // ... { var accumulator fp.Element lambda[0].SetOne() @@ -1127,23 +1139,25 @@ func batchAddG2Affine[TP pG2Affine, TPP ppG2Affine, TC cG2Affine](R *TPP, P *TP, lambda[0].Set(&accumulator) } - var d fp.Element - var rr G2Affine + var t fp.Element + var Q G2Affine - // add part for j := 0; j < batchSize; j++ { - // computa lambda - d.Sub(&(*P)[j].Y, &(*R)[j].Y) - lambda[j].Mul(&lambda[j], &d) - - // compute X, Y - rr.X.Square(&lambda[j]) - rr.X.Sub(&rr.X, &(*R)[j].X) - rr.X.Sub(&rr.X, &(*P)[j].X) - d.Sub(&(*R)[j].X, &rr.X) - rr.Y.Mul(&lambda[j], &d) - rr.Y.Sub(&rr.Y, &(*R)[j].Y) - (*R)[j].Set(&rr) + // λ = (Y2 - Y1) / (X2 - X1) + t.Sub(&(*P)[j].Y, &(*R)[j].Y) + lambda[j].Mul(&lambda[j], &t) + + // X3 = λ² - (X1 + X2) + Q.X.Square(&lambda[j]) + Q.X.Sub(&Q.X, &(*R)[j].X) + Q.X.Sub(&Q.X, &(*P)[j].X) + + // Y3 = λ * (X1 - X3) - Y1 + t.Sub(&(*R)[j].X, &Q.X) + Q.Y.Mul(&lambda[j], &t) + Q.Y.Sub(&Q.Y, &(*R)[j].Y) + + (*R)[j].Set(&Q) } } diff --git a/ecc/secp256k1/g1.go b/ecc/secp256k1/g1.go index d747e4d9bd..c5714c3324 100644 --- a/ecc/secp256k1/g1.go +++ b/ecc/secp256k1/g1.go @@ -1132,12 +1132,24 @@ func BatchScalarMultiplicationG1(base *G1Affine, scalars []fr.Element) []G1Affin func batchAddG1Affine[TP pG1Affine, TPP ppG1Affine, TC cG1Affine](R *TPP, P *TP, batchSize int) { var lambda, lambdain TC - // add part + // from https://docs.zkproof.org/pages/standards/accepted-workshop3/proposal-turbo_plonk.pdf + // affine point addition formula + // R(X1, Y1) + P(X2, Y2) = Q(X3, Y3) + // λ = (Y2 - Y1) / (X2 - X1) + // X3 = λ² - (X1 + X2) + // Y3 = λ * (X1 - X3) - Y1 + + // first we compute the 1 / (X2 - X1) for all points using Montgomery batch inversion trick + + // X2 - X1 for j := 0; j < batchSize; j++ { lambdain[j].Sub(&(*P)[j].X, &(*R)[j].X) } - // invert denominator using montgomery batch invert technique + // montgomery batch inversion; + // lambda[0] = 1 / (P[0].X - R[0].X) + // lambda[1] = 1 / (P[1].X - R[1].X) + // ... { var accumulator fp.Element lambda[0].SetOne() @@ -1157,22 +1169,24 @@ func batchAddG1Affine[TP pG1Affine, TPP ppG1Affine, TC cG1Affine](R *TPP, P *TP, lambda[0].Set(&accumulator) } - var d fp.Element - var rr G1Affine + var t fp.Element + var Q G1Affine - // add part for j := 0; j < batchSize; j++ { - // computa lambda - d.Sub(&(*P)[j].Y, &(*R)[j].Y) - lambda[j].Mul(&lambda[j], &d) - - // compute X, Y - rr.X.Square(&lambda[j]) - rr.X.Sub(&rr.X, &(*R)[j].X) - rr.X.Sub(&rr.X, &(*P)[j].X) - d.Sub(&(*R)[j].X, &rr.X) - rr.Y.Mul(&lambda[j], &d) - rr.Y.Sub(&rr.Y, &(*R)[j].Y) - (*R)[j].Set(&rr) + // λ = (Y2 - Y1) / (X2 - X1) + t.Sub(&(*P)[j].Y, &(*R)[j].Y) + lambda[j].Mul(&lambda[j], &t) + + // X3 = λ² - (X1 + X2) + Q.X.Square(&lambda[j]) + Q.X.Sub(&Q.X, &(*R)[j].X) + Q.X.Sub(&Q.X, &(*P)[j].X) + + // Y3 = λ * (X1 - X3) - Y1 + t.Sub(&(*R)[j].X, &Q.X) + Q.Y.Mul(&lambda[j], &t) + Q.Y.Sub(&Q.Y, &(*R)[j].Y) + + (*R)[j].Set(&Q) } } diff --git a/internal/generator/ecc/template/point.go.tmpl b/internal/generator/ecc/template/point.go.tmpl index 22bf4e6f38..961a9e89b3 100644 --- a/internal/generator/ecc/template/point.go.tmpl +++ b/internal/generator/ecc/template/point.go.tmpl @@ -1739,13 +1739,24 @@ func BatchScalarMultiplication{{ toUpper .PointName }}(base *{{ $TAffine }}, sca func batchAdd{{ $TAffine }}[TP p{{ $TAffine }}, TPP pp{{ $TAffine }}, TC c{{ $TAffine }}](R *TPP,P *TP, batchSize int) { var lambda, lambdain TC + // from https://docs.zkproof.org/pages/standards/accepted-workshop3/proposal-turbo_plonk.pdf + // affine point addition formula + // R(X1, Y1) + P(X2, Y2) = Q(X3, Y3) + // λ = (Y2 - Y1) / (X2 - X1) + // X3 = λ² - (X1 + X2) + // Y3 = λ * (X1 - X3) - Y1 - // add part + // first we compute the 1 / (X2 - X1) for all points using Montgomery batch inversion trick + + // X2 - X1 for j := 0; j < batchSize; j++ { lambdain[j].Sub(&(*P)[j].X, &(*R)[j].X) } - // invert denominator using montgomery batch invert technique + // montgomery batch inversion; + // lambda[0] = 1 / (P[0].X - R[0].X) + // lambda[1] = 1 / (P[1].X - R[1].X) + // ... { var accumulator {{.CoordType}} lambda[0].SetOne() @@ -1765,23 +1776,25 @@ func batchAdd{{ $TAffine }}[TP p{{ $TAffine }}, TPP pp{{ $TAffine }}, TC c{{ $TA lambda[0].Set(&accumulator) } - var d {{.CoordType}} - var rr {{ $TAffine }} + var t {{.CoordType}} + var Q {{ $TAffine }} - // add part for j := 0; j < batchSize; j++ { - // computa lambda - d.Sub(&(*P)[j].Y, &(*R)[j].Y) - lambda[j].Mul(&lambda[j], &d) - - // compute X, Y - rr.X.Square(&lambda[j]) - rr.X.Sub(&rr.X, &(*R)[j].X) - rr.X.Sub(&rr.X, &(*P)[j].X) - d.Sub(&(*R)[j].X, &rr.X) - rr.Y.Mul(&lambda[j], &d) - rr.Y.Sub(&rr.Y, &(*R)[j].Y) - (*R)[j].Set(&rr) + // λ = (Y2 - Y1) / (X2 - X1) + t.Sub(&(*P)[j].Y, &(*R)[j].Y) + lambda[j].Mul(&lambda[j], &t) + + // X3 = λ² - (X1 + X2) + Q.X.Square(&lambda[j]) + Q.X.Sub(&Q.X, &(*R)[j].X) + Q.X.Sub(&Q.X, &(*P)[j].X) + + // Y3 = λ * (X1 - X3) - Y1 + t.Sub(&(*R)[j].X, &Q.X) + Q.Y.Mul(&lambda[j], &t) + Q.Y.Sub(&Q.Y, &(*R)[j].Y) + + (*R)[j].Set(&Q) } }