Skip to content

Commit

Permalink
First implementation of subgroup check with NAF representation
Browse files Browse the repository at this point in the history
  • Loading branch information
IAvecilla committed Apr 20, 2024
1 parent ec9a700 commit a8afbb5
Showing 1 changed file with 48 additions and 6 deletions.
54 changes: 48 additions & 6 deletions precompiles/EcPairing.yul
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ object "EcPairing" {
ret := 4965661367192848881
}

/// @notice Constant function for the alt_bn128 curve seed (parameter `x`).
/// @dev See https://eips.ethereum.org/EIPS/eip-196 for further details.
/// @return ret The alt_bn128 curve seed.
function X_NAF() -> ret {
// NAF in binary form
// 010000001000000000010001000000000100000100100001000100010000010000000100100010001000010001000010000100010010000001000100000001
ret := 21433887637311709106367829048077848833
}

/// @notice Constant function for decimal representation of the NAF for the Millers Loop.
/// @dev Millers loop uses to iterate the NAF representation of the value t = 6x^2. Where x = 4965661367192848881 is a parameter of the BN 256 curve.
Expand Down Expand Up @@ -489,16 +497,50 @@ object "EcPairing" {
/// @param xp0, xp1 The x coordinate of the point.
/// @param zp0, zp1 The z coordinate of the point.
/// @return ret True if the point is in the subgroup, false otherwise.
function g2IsInSubGroup(xp0, xp1, yp0, yp1, zp0, zp1) -> ret {
function g2IsInSubGroup(xp0, xp1, yp0, yp1) -> ret {
// P * X
let px_xp0, px_xp1, px_yp0, px_yp1, px_zp0, px_zp1 := g2ScalarMul(xp0, xp1, yp0, yp1, zp0, zp1, X())
// let px_xp0, px_xp1, px_yp0, px_yp1, px_zp0, px_zp1 := g2ScalarMul(xp0, xp1, yp0, yp1, zp0, zp1, X())
let mp00, mp01, mp10, mp11 := g2AffineNeg(xp0, xp1, yp0, yp1)
let t00, t01, t10, t11, t20, t21 := g2ProjectiveFromAffine(xp0, xp1, yp0, yp1)
let xp0_a, xp1_a, yp0_a, yp1_a, zp0_a, zp1_a := g2ProjectiveFromAffine(xp0, xp1, yp0, yp1)
// let f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := FP12_ONE()
let l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51
let naf := X_NAF()
let n_iter := 63
for {let i := 0} lt(i, n_iter) { i := add(i, 1) } {
// f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := fp12Square(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121)

l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51, t00, t01, t10, t11, t20, t21 := doubleStep(t00, t01, t10, t11, t20, t21)
// l00, l01 := fp2ScalarMul(l00, l01, yp)
// l30, l31 := fp2ScalarMul(l30, l31, xp)
// f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := fp12Mul(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121, l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51)

// naf digit = 1
if and(naf, 1) {
l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51, t00, t01, t10, t11, t20, t21 := mixedAdditionStep(xp0, xp1, yp0, yp1, t00, t01, t10, t11, t20, t21)
// l00, l01 := fp2ScalarMul(l00, l01, yp)
// l30, l31 := fp2ScalarMul(l30, l31, xp)
// f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := fp12Mul(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121, l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51)
}

// naf digit = -1
if and(naf, 2) {
l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51, t00, t01, t10, t11, t20, t21 := mixedAdditionStep(mp00, mp01, mp10, mp11, t00, t01, t10, t11, t20, t21)
// l00, l01 := fp2ScalarMul(l00, l01, yp)
// l30, l31 := fp2ScalarMul(l30, l31, xp)
// f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := fp12Mul(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121, l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51)
}

naf := shr(2, naf)
}

// P * (X + 1)
let px1_xp0, px1_xp1, px1_yp0, px1_yp1, px1_zp0, px1_zp1 := g2JacobianAdd(px_xp0, px_xp1, px_yp0, px_yp1, px_zp0, px_zp1, xp0, xp1, yp0, yp1, zp0, zp1)
let px1_xp0, px1_xp1, px1_yp0, px1_yp1, px1_zp0, px1_zp1 := g2JacobianAdd(t00, t01, t10, t11, t20, t21, xp0_a, xp1_a, yp0_a, yp1_a, zp0_a, zp1_a)
// P * 2X
let p2x_xp0, p2x_xp1, p2x_yp0, p2x_yp1, p2x_zp0, p2x_zp1 := g2JacobianDouble(px_xp0, px_xp1, px_yp0, px_yp1, px_zp0, px_zp1)
let p2x_xp0, p2x_xp1, p2x_yp0, p2x_yp1, p2x_zp0, p2x_zp1 := g2JacobianDouble(t00, t01, t10, t11, t20, t21)

// phi(P * X)
let e_px_xp0, e_px_xp1, e_px_yp0, e_px_yp1, e_px_zp0, e_px_zp1 := endomorphism(px_xp0, px_xp1, px_yp0, px_yp1, px_zp0, px_zp1)
let e_px_xp0, e_px_xp1, e_px_yp0, e_px_yp1, e_px_zp0, e_px_zp1 := endomorphism(t00, t01, t10, t11, t20, t21)
// phi(phi(P * X))
let e2_px_xp0, e2_px_xp1, e2_px_yp0, e2_px_yp1, e2_px_zp0, e2_px_zp1 := endomorphism(e_px_xp0, e_px_xp1, e_px_yp0, e_px_yp1, e_px_zp0, e_px_zp1)

Expand Down Expand Up @@ -1700,7 +1742,7 @@ object "EcPairing" {
g2_y0 := intoMontgomeryForm(g2_y0)
g2_y1 := intoMontgomeryForm(g2_y1)

if iszero(g2IsInSubGroup(g2_x0,g2_x1, g2_y0, g2_y1, MONTGOMERY_ONE(), 0)) {
if iszero(g2IsInSubGroup(g2_x0,g2_x1, g2_y0, g2_y1)) {
burnGas()
}

Expand Down

0 comments on commit a8afbb5

Please sign in to comment.