Skip to content

Commit

Permalink
Implement NAF multiplication in a separate function
Browse files Browse the repository at this point in the history
  • Loading branch information
jrchatruc committed Apr 20, 2024
1 parent a8afbb5 commit 70386c4
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 36 deletions.
70 changes: 34 additions & 36 deletions precompiles/EcPairing.yul
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ object "EcPairing" {
/// @return ret The alt_bn128 curve seed.
function X_NAF() -> ret {
// NAF in binary form
// 010000001000000000010001000000000100000100100001000100010000010000000100100010001000010001000010000100010010000001000100000001
ret := 21433887637311709106367829048077848833
// 010000000100010000100001000100100000010001001000100010000100000001000001000100010010000100000100000000010001000000001000000001
ret := 21356084665891114007971320526050427393
}

/// @notice Constant function for decimal representation of the NAF for the Millers Loop.
Expand Down Expand Up @@ -475,6 +475,37 @@ object "EcPairing" {
xi1 := intoMontgomeryForm(10307601595873709700152284273816112264069230130616436755625194854815875713954)
}

/// @notice Multiplies a given G2 point by X in NAF form.
/// @dev The given G2 point is in affine coordinates and Montgomery Form.
/// @return ret G2 Point multiplied by X in Montgomery Form.
function g2TimesXNAF(pa00, pa01, pa10, pa11) -> q00, q01, q10, q11, q20, q21 {
let pan00, pan01, pan10, pan11 := g2AffineNeg(pa00, pa01, pa10, pa11)
let p00, p01, p10, p11, p20, p21 := g2ProjectiveFromAffine(pa00, pa01, pa10, pa11)
let pn00, pn01, pn10, pn11, pn20, pn21 := g2ProjectiveFromAffine(pan00, pan01, pan10, pan11)

q00, q01, q10, q11, q20, q21 := G2_INFINITY()

let naf := X_NAF()
let n_iter := 63

for {let i := 0} lt(i, n_iter) { i := add(i, 1) } {
// naf digit = 1
if and(naf, 1) {
q00, q01, q10, q11, q20, q21 := g2JacobianAdd(q00, q01, q10, q11, q20, q21, p00, p01, p10, p11, p20, p21)
}

// naf digit = -1
if and(naf, 2) {
q00, q01, q10, q11, q20, q21 := g2JacobianAdd(q00, q01, q10, q11, q20, q21, pn00, pn01, pn10, pn11, pn20, pn21)
}

p00, p01, p10, p11, p20, p21 := g2JacobianDouble(p00, p01, p10, p11, p20, p21)
pn00, pn01, pn10, pn11, pn20, pn21 := g2JacobianDouble(pn00, pn01, pn10, pn11, pn20, pn21)

naf := shr(2, naf)
}
}

/// @notice Frobenius endomophism used to G2 sub group check for twisted curve.
/// @dev For more datail see https://eprint.iacr.org/2022/348.pdf
/// @param xp0, xp1 The x coordinate of the point on twisted curve.
Expand All @@ -498,41 +529,8 @@ object "EcPairing" {
/// @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) -> 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 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)
}
let t00, t01, t10, t11, t20, t21 := g2TimesXNAF(xp0, xp1, yp0, yp1)

// P * (X + 1)
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)
Expand Down
45 changes: 45 additions & 0 deletions scripts/pairing_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,48 @@ def is_in_twisted_curve(x0, x1, y0, y1):
b = fp2.add(*b, *TWISTED_CURVE_COEFFS)
c = fp2.exp(y0, y1, 2)
return b == c

def naf(E):
Z = []
i = 0
while E > 0:
if E % 2 == 1:
zi = 2 - (E % 4)
E -= zi
else:
zi = 0
E //= 2
i += 1
Z.append(zi)
Z.reverse()
return Z

def naf_aux(naf):
a = []
for n in naf:
if n == 0:
a.append("00")
elif n == 1:
a.append("01")
elif n == -1:
a.append("10")
b = "".join(a)
return b

def naf_aux_to_naf(naf_aux):
naf = []
for i in range(0, len(naf_aux), 2):
if naf_aux[i] == "0" and naf_aux[i+1] == "0":
naf.append(0)
elif naf_aux[i] == "0" and naf_aux[i+1] == "1":
naf.append(1)
elif naf_aux[i] == "1" and naf_aux[i+1] == "0":
naf.append(-1)
return naf

x_naf = naf(4965661367192848881)
print(x_naf)
naf_yul_rep = naf_aux(x_naf)
print(naf_yul_rep)
original_naf = naf_aux_to_naf(naf_yul_rep)
print(original_naf)

0 comments on commit 70386c4

Please sign in to comment.