From bb03c0a84388960fb988cf06bdc039ce1769f34a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Litteri?= Date: Thu, 28 Sep 2023 17:03:16 -0300 Subject: [PATCH 1/9] Add wGLV implementation --- precompiles/EcMul.yul | 240 +++++++++++++++++++++++++++++++++--------- 1 file changed, 190 insertions(+), 50 deletions(-) diff --git a/precompiles/EcMul.yul b/precompiles/EcMul.yul index 82a8c8a5..37c05bfa 100644 --- a/precompiles/EcMul.yul +++ b/precompiles/EcMul.yul @@ -20,6 +20,24 @@ object "EcMul" { m_three := 19052624634359457937016868847204597229365286637454337178037183604060995791063 } + function MONTGOMERY_GLV_BASIS() -> v10, v11, v20, v21, det, b1, b2 { + v10 := 9467151881811383727216712387251582584038710124949150773810224174953673958495 + v11 := 7832780885517429488914881362264053307162815318423880121458870703782468606792 + v20 := 17299932767328813216131593749515635891201525443373030895269094878736142565287 + v21 := 9467151881811383727216712387251582584038710124949150773810224174953673958495 + det := 17171738990013410148209280487843271955783777084671648589027996831129432963265 + b1 := 1999550452416974871140046113947404043388591104517078921953891555888361342916 + b2 := 2348897689843608674094128271148469530883240042839830706128860949317525936861 + } + + function DIV_LATTICE_DETERMINANT() -> ret { + ret := 512 + } + + function MONTGOMERY_THIRD_ROOT() -> ret { + ret := 20006444479023397533370224967097343182639219473961804911780625968796493078869 + } + /// @notice Constant function for value 3*b (i.e. 9) in Montgomery form. /// @dev This value was precomputed using Python. /// @return m_b3 The value 9 in Montgomery form. @@ -359,6 +377,91 @@ object "EcMul" { xr := montgomeryAdd(xr, xr) } + function phi(xp, yp, zp) -> xr, yr, zr { + xr := montgomeryMul(xp, MONTGOMERY_THIRD_ROOT()) + yr := yp + zr := zp + } + + function splitScalar(scalar, v10, v11, v20, v21, det, b1, b2) -> v0, v1 { + let k1 := montgomeryMul(scalar, b1) + let k2 := montgomeryMul(scalar, b2) + k2 := montgomerySub(0, k2) + // n := 2 * ((l.Det.BitLen()+32)>>6)<<6) + let n := DIV_LATTICE_DETERMINANT() + k1 := shr(n, k1) + k2 := shr(n, k2) + v0, v1 := getVector(v10, v11, v20, v21, k1, k2) + v0 := montgomerySub(scalar, v0) + v1 := montgomerySub(0, v1) + } + + function getVector(v10, v11, v20, v21, k1, k2) -> v0, v1 { + let tmp := montgomeryMul(k2, v20) + v0 := montgomeryMul(v20, k1) + v0 := montgomeryAdd(v0, tmp) + tmp := montgomeryMul(k2, v21) + v1 := montgomeryMul(k1, v11) + v1 := montgomeryAdd(v1, tmp) + } + + function addProjective(xq, yq, zq, xp, yp, zp) -> xr, yr, zr { + let flag := 1 + let qIsInfinity := projectivePointIsInfinity(xq, yq, zq) + let pIsInfinity := projectivePointIsInfinity(xp, yp, zp) + if and(and(pIsInfinity, qIsInfinity), flag) { + // Infinity + Infinity = Infinity + xr := 0 + yr := MONTGOMERY_ONE() + zr := 0 + flag := 0 + } + if and(pIsInfinity, flag) { + // Infinity + P = P + xr := xq + yr := yq + zr := zq + flag := 0 + } + if and(qIsInfinity, flag) { + // P + Infinity = P + xr := xp + yr := yp + zr := zp + flag := 0 + } + if and(and(and(eq(xp, xq), eq(montgomerySub(0, yp), yq)), eq(zp, zq)), flag) { + // P + (-P) = Infinity + xr := 0 + yr := MONTGOMERY_ONE() + zr := 0 + flag := 0 + } + if and(and(and(eq(xp, xq), eq(yp, yq)), eq(zp, zq)), flag) { + // P + P = 2P + xr, yr, zr := projectiveDouble(xp, yp, zp) + flag := 0 + } + + // P1 + P2 = P3 + if flag { + let t0 := montgomeryMul(yq, zp) + let t1 := montgomeryMul(yp, zq) + let t := montgomerySub(t0, t1) + let u0 := montgomeryMul(xq, zp) + let u1 := montgomeryMul(xp, zq) + let u := montgomerySub(u0, u1) + let u2 := montgomeryMul(u, u) + let u3 := montgomeryMul(u2, u) + let v := montgomeryMul(zq, zp) + let w := montgomerySub(montgomeryMul(montgomeryMul(t, t), v), montgomeryMul(u2, montgomeryAdd(u0, u1))) + + xr := montgomeryMul(u, w) + yr := montgomerySub(montgomeryMul(t, montgomerySub(montgomeryMul(u0, u2), w)), montgomeryMul(t0, u3)) + zr := montgomeryMul(u3, v) + } + } + //////////////////////////////////////////////////////////////// // FALLBACK //////////////////////////////////////////////////////////////// @@ -413,62 +516,99 @@ object "EcMul" { return(0x00, 0x40) } - let xq := xp - let yq := yp - let zq := zp let xr := 0 let yr := MONTGOMERY_ONE() let zr := 0 - for {} scalar {} { - if lsbIsOne(scalar) { - let rIsInfinity := projectivePointIsInfinity(xr, yr, zr) - - if rIsInfinity { - // Infinity + P = P - xr := xq - yr := yq - zr := zq - - xq, yq, zq := projectiveDouble(xq, yq, zq) - // Check next bit - scalar := shr(1, scalar) - continue - } - - let t0 := montgomeryMul(yq, zr) - let t1 := montgomeryMul(yr, zq) - let t := montgomerySub(t0, t1) - let u0 := montgomeryMul(xq, zr) - let u1 := montgomeryMul(xr, zq) - let u := montgomerySub(u0, u1) - // t = (yq*zr - yr*zq); u = (xq*zr - xr*zq) - if iszero(or(t, u)) { - // P + P = 2P - xr, yr, zr := projectiveDouble(xr, yr, zr) - - xq := xr - yq := yr - zq := zr - // Check next bit - scalar := shr(1, scalar) - continue + let table00 := xp + let table01 := yp + let table02 := zp + let table30, table31, table32 := phi(xp, yp, zp) + + let v10, v11, v20, v21, det, b1, b2 := MONTGOMERY_GLV_BASIS() + let k1, k2 := splitScalar(intoMontgomeryForm(scalar), v10, v11, v20, v21, det, b1, b2) + + let table10, table11, table12 := addProjective(table00, table01, table02, table00, table01, table02) + let table20, table21, table22 := addProjective(table10, table11, table12, table00, table01, table02) + let table40, table41, table42 := addProjective(table30, table31, table32, table00, table01, table02) + let table50, table51, table52 := addProjective(table30, table31, table32, table10, table11, table12) + let table60, table61, table62 := addProjective(table20, table21, table22, table30, table31, table32) + let table70, table71, table72 := projectiveDouble(table30, table31, table32) + let table80, table81, table82 := addProjective(table70, table71, table72, table00, table01, table02) + let table90, table91, table92 := addProjective(table70, table71, table72, table10, table11, table12) + let table100, table101, table102 := addProjective(table70, table71, table72, table20, table21, table22) + let table110, table111, table112 := addProjective(table70, table71, table72, table30, table31, table32) + let table120, table121, table122 := addProjective(table110, table111, table112, table00, table01, table02) + let table130, table131, table132 := addProjective(table110, table111, table112, table10, table11, table12) + let table140, table141, table142 := addProjective(table110, table111, table112, table20, table21, table22) + + // let k1BitLen := bitLen(outOfMontgomeryForm(k1)) + // let k2BitLen := bitLen(outOfMontgomeryForm(k2)) + // let maxBit := k1BitLen + // if gt(k2BitLen, maxBit) { + // maxBit := k2BitLen + // } + + k1 := outOfMontgomeryForm(k1) + k2 := outOfMontgomeryForm(k2) + let f := 254 + let mask := shl(f, 3) + for { let j := 0 } lt(j, 128) { j := add(j, 1) } { + xr, yr, zr := projectiveDouble(xr, yr, zr) + xr, yr, zr := projectiveDouble(xr, yr, zr) + let shift := sub(f, add(j, j)) + let b1 := shr(shift, and(k1, mask)) + let b2 := shr(shift, and(k2, mask)) + if or(b1, b2) { + let s := or(shl(2, b2), b1) + switch sub(s, 1) + case 0 { + xr, yr, zr := addProjective(xr, yr, zr, table00, table01, table02) + } + case 1 { + xr, yr, zr := addProjective(xr, yr, zr, table10, table11, table12) + } + case 2 { + xr, yr, zr := addProjective(xr, yr, zr, table20, table21, table22) + } + case 3 { + xr, yr, zr := addProjective(xr, yr, zr, table30, table31, table32) + } + case 4 { + xr, yr, zr := addProjective(xr, yr, zr, table40, table41, table42) + } + case 5 { + xr, yr, zr := addProjective(xr, yr, zr, table50, table51, table52) + } + case 6 { + xr, yr, zr := addProjective(xr, yr, zr, table60, table61, table62) + } + case 7 { + xr, yr, zr := addProjective(xr, yr, zr, table70, table71, table72) + } + case 8 { + xr, yr, zr := addProjective(xr, yr, zr, table80, table81, table82) + } + case 9 { + xr, yr, zr := addProjective(xr, yr, zr, table90, table91, table92) + } + case 10 { + xr, yr, zr := addProjective(xr, yr, zr, table100, table101, table102) + } + case 11 { + xr, yr, zr := addProjective(xr, yr, zr, table110, table111, table112) + } + case 12 { + xr, yr, zr := addProjective(xr, yr, zr, table120, table121, table122) + } + case 13 { + xr, yr, zr := addProjective(xr, yr, zr, table130, table131, table132) + } + case 14 { + xr, yr, zr := addProjective(xr, yr, zr, table140, table141, table142) } - - // P1 + P2 = P3 - let u2 := montgomeryMul(u, u) - let u3 := montgomeryMul(u2, u) - let v := montgomeryMul(zq, zr) - let w := montgomerySub(montgomeryMul(montgomeryMul(t, t), v), montgomeryMul(u2, montgomeryAdd(u0, u1))) - - xr := montgomeryMul(u, w) - yr := montgomerySub(montgomeryMul(t, montgomerySub(montgomeryMul(u0, u2), w)), montgomeryMul(t0, u3)) - zr := montgomeryMul(u3, v) } - - xq, yq, zq := projectiveDouble(xq, yq, zq) - // Check next bit - scalar := shr(1, scalar) + mask := shr(2, mask) } xr, yr := projectiveIntoAffine(xr, yr, zr) From 91eba499a1f84301beb373ce3fb74f8535136d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Litteri?= Date: Thu, 28 Sep 2023 18:10:45 -0300 Subject: [PATCH 2/9] Add changes --- precompiles/EcMul.yul | 56 ++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/precompiles/EcMul.yul b/precompiles/EcMul.yul index 37c05bfa..2974d619 100644 --- a/precompiles/EcMul.yul +++ b/precompiles/EcMul.yul @@ -20,14 +20,14 @@ object "EcMul" { m_three := 19052624634359457937016868847204597229365286637454337178037183604060995791063 } - function MONTGOMERY_GLV_BASIS() -> v10, v11, v20, v21, det, b1, b2 { - v10 := 9467151881811383727216712387251582584038710124949150773810224174953673958495 - v11 := 7832780885517429488914881362264053307162815318423880121458870703782468606792 - v20 := 17299932767328813216131593749515635891201525443373030895269094878736142565287 - v21 := 9467151881811383727216712387251582584038710124949150773810224174953673958495 - det := 17171738990013410148209280487843271955783777084671648589027996831129432963265 - b1 := 1999550452416974871140046113947404043388591104517078921953891555888361342916 - b2 := 2348897689843608674094128271148469530883240042839830706128860949317525936861 + function GLV_BASIS() -> v10, v11, v20, v21, det, b1, b2 { + v10 := 9931322734385697763 + v11 := 147946756881789319000765030803803410728 + v20 := 147946756881789319010696353538189108491 + v21 := 9931322734385697763 + det := 21888242871839275222246405745257275088548364400416034343698204186575808495617 + b1 := 14543540530720168141288635243388629919715755786477002759840454263230943838258 + b2 := 12705133846569304976684616152979546432541976507551503015265861210005237258542 } function DIV_LATTICE_DETERMINANT() -> ret { @@ -384,25 +384,27 @@ object "EcMul" { } function splitScalar(scalar, v10, v11, v20, v21, det, b1, b2) -> v0, v1 { - let k1 := montgomeryMul(scalar, b1) - let k2 := montgomeryMul(scalar, b2) - k2 := montgomerySub(0, k2) + let k1 := mul(scalar, b1) + let k2 := mul(scalar, b2) + k2 := sub(0, k2) // n := 2 * ((l.Det.BitLen()+32)>>6)<<6) let n := DIV_LATTICE_DETERMINANT() k1 := shr(n, k1) k2 := shr(n, k2) v0, v1 := getVector(v10, v11, v20, v21, k1, k2) - v0 := montgomerySub(scalar, v0) - v1 := montgomerySub(0, v1) + console_log(v0) + console_log(v1) + v0 := sub(scalar, v0) + v1 := sub(0, v1) } function getVector(v10, v11, v20, v21, k1, k2) -> v0, v1 { - let tmp := montgomeryMul(k2, v20) - v0 := montgomeryMul(v20, k1) - v0 := montgomeryAdd(v0, tmp) - tmp := montgomeryMul(k2, v21) - v1 := montgomeryMul(k1, v11) - v1 := montgomeryAdd(v1, tmp) + let tmp := mul(k2, v20) + v0 := mul(v20, k1) + v0 := add(v0, tmp) + tmp := mul(k2, v21) + v1 := mul(k1, v11) + v1 := add(v1, tmp) } function addProjective(xq, yq, zq, xp, yp, zp) -> xr, yr, zr { @@ -525,8 +527,18 @@ object "EcMul" { let table02 := zp let table30, table31, table32 := phi(xp, yp, zp) - let v10, v11, v20, v21, det, b1, b2 := MONTGOMERY_GLV_BASIS() + let v10, v11, v20, v21, det, b1, b2 := GLV_BASIS() let k1, k2 := splitScalar(intoMontgomeryForm(scalar), v10, v11, v20, v21, det, b1, b2) + console_log(k1) + console_log(k2) + if shr(255, k1) { + k1 := sub(P(), k1) + table00, table01, table02 := projectiveNeg(table00, table01, table02) + } + if shr(255, k2) { + k2 := sub(P(), k2) + table30, table31, table32 := projectiveNeg(table30, table31, table32) + } let table10, table11, table12 := addProjective(table00, table01, table02, table00, table01, table02) let table20, table21, table22 := addProjective(table10, table11, table12, table00, table01, table02) @@ -549,8 +561,8 @@ object "EcMul" { // maxBit := k2BitLen // } - k1 := outOfMontgomeryForm(k1) - k2 := outOfMontgomeryForm(k2) + // k1 := outOfMontgomeryForm(k1) + // k2 := outOfMontgomeryForm(k2) let f := 254 let mask := shl(f, 3) for { let j := 0 } lt(j, 128) { j := add(j, 1) } { From 3e1b70e6516228442d70b391e2a881c1f5e1e9dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Litteri?= Date: Thu, 28 Sep 2023 18:12:18 -0300 Subject: [PATCH 3/9] Add projectiveNeg --- precompiles/EcMul.yul | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/precompiles/EcMul.yul b/precompiles/EcMul.yul index 2974d619..7951fd89 100644 --- a/precompiles/EcMul.yul +++ b/precompiles/EcMul.yul @@ -464,6 +464,12 @@ object "EcMul" { } } + function projectiveNeg(xp, yp, zp) -> xr, yr, zr { + xr := xp + yr := montgomerySub(0, yp) + zr := zp + } + //////////////////////////////////////////////////////////////// // FALLBACK //////////////////////////////////////////////////////////////// From bb5b511ac42d0052ce76acb674454cfb9060f677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Litteri?= Date: Thu, 28 Sep 2023 18:13:03 -0300 Subject: [PATCH 4/9] Remove console logs --- precompiles/EcMul.yul | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/precompiles/EcMul.yul b/precompiles/EcMul.yul index 7951fd89..aa28bfa1 100644 --- a/precompiles/EcMul.yul +++ b/precompiles/EcMul.yul @@ -392,8 +392,6 @@ object "EcMul" { k1 := shr(n, k1) k2 := shr(n, k2) v0, v1 := getVector(v10, v11, v20, v21, k1, k2) - console_log(v0) - console_log(v1) v0 := sub(scalar, v0) v1 := sub(0, v1) } @@ -535,8 +533,7 @@ object "EcMul" { let v10, v11, v20, v21, det, b1, b2 := GLV_BASIS() let k1, k2 := splitScalar(intoMontgomeryForm(scalar), v10, v11, v20, v21, det, b1, b2) - console_log(k1) - console_log(k2) + if shr(255, k1) { k1 := sub(P(), k1) table00, table01, table02 := projectiveNeg(table00, table01, table02) From ee544729a807b27915cc7457ca916b713f968f81 Mon Sep 17 00:00:00 2001 From: IAvecilla Date: Fri, 29 Sep 2023 13:41:14 -0300 Subject: [PATCH 5/9] Comment check for k1 and k2 signs --- precompiles/EcMul.yul | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/precompiles/EcMul.yul b/precompiles/EcMul.yul index aa28bfa1..8e55c982 100644 --- a/precompiles/EcMul.yul +++ b/precompiles/EcMul.yul @@ -532,16 +532,16 @@ object "EcMul" { let table30, table31, table32 := phi(xp, yp, zp) let v10, v11, v20, v21, det, b1, b2 := GLV_BASIS() - let k1, k2 := splitScalar(intoMontgomeryForm(scalar), v10, v11, v20, v21, det, b1, b2) + let k1, k2 := splitScalar(scalar, v10, v11, v20, v21, det, b1, b2) - if shr(255, k1) { - k1 := sub(P(), k1) - table00, table01, table02 := projectiveNeg(table00, table01, table02) - } - if shr(255, k2) { - k2 := sub(P(), k2) - table30, table31, table32 := projectiveNeg(table30, table31, table32) - } + // if shr(255, k1) { + // k1 := sub(P(), k1) + // table00, table01, table02 := projectiveNeg(table00, table01, table02) + // } + // if shr(255, k2) { + // k2 :=sub(P(), k2) + // table30, table31, table32 := projectiveNeg(table30, table31, table32) + // } let table10, table11, table12 := addProjective(table00, table01, table02, table00, table01, table02) let table20, table21, table22 := addProjective(table10, table11, table12, table00, table01, table02) From b085369fb955e3727e53c10a66034babe98fbe3d Mon Sep 17 00:00:00 2001 From: IAvecilla Date: Mon, 2 Oct 2023 18:31:13 -0300 Subject: [PATCH 6/9] Reduce iterations for scalar with zeroes --- precompiles/EcMul.yul | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/precompiles/EcMul.yul b/precompiles/EcMul.yul index 8e55c982..9e4dbe83 100644 --- a/precompiles/EcMul.yul +++ b/precompiles/EcMul.yul @@ -468,6 +468,14 @@ object "EcMul" { zr := zp } + function bitLen(n) -> ret { + ret := 0 + for {} gt(n, 0) {} { + n := shr(1, n) + ret := add(ret, 1) + } + } + //////////////////////////////////////////////////////////////// // FALLBACK //////////////////////////////////////////////////////////////// @@ -557,18 +565,19 @@ object "EcMul" { let table130, table131, table132 := addProjective(table110, table111, table112, table10, table11, table12) let table140, table141, table142 := addProjective(table110, table111, table112, table20, table21, table22) - // let k1BitLen := bitLen(outOfMontgomeryForm(k1)) - // let k2BitLen := bitLen(outOfMontgomeryForm(k2)) - // let maxBit := k1BitLen - // if gt(k2BitLen, maxBit) { - // maxBit := k2BitLen - // } + let k1BitLen := bitLen(k1) + let k2BitLen := bitLen(k2) + let maxBit := k1BitLen + if gt(k2BitLen, maxBit) { + maxBit := k2BitLen + } // k1 := outOfMontgomeryForm(k1) // k2 := outOfMontgomeryForm(k2) - let f := 254 + let f := sub(maxBit, 2) let mask := shl(f, 3) - for { let j := 0 } lt(j, 128) { j := add(j, 1) } { + + for { let j := 0 } lt(j, div(maxBit, 2)) { j := add(j, 1) } { xr, yr, zr := projectiveDouble(xr, yr, zr) xr, yr, zr := projectiveDouble(xr, yr, zr) let shift := sub(f, add(j, j)) From 04ec49d181596a153184fbd9934d431124775060 Mon Sep 17 00:00:00 2001 From: IAvecilla Date: Tue, 3 Oct 2023 12:58:47 -0300 Subject: [PATCH 7/9] Handle edge case where scalar has an odd number of bits --- precompiles/EcMul.yul | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/precompiles/EcMul.yul b/precompiles/EcMul.yul index 9e4dbe83..2682d3e1 100644 --- a/precompiles/EcMul.yul +++ b/precompiles/EcMul.yul @@ -542,15 +542,6 @@ object "EcMul" { let v10, v11, v20, v21, det, b1, b2 := GLV_BASIS() let k1, k2 := splitScalar(scalar, v10, v11, v20, v21, det, b1, b2) - // if shr(255, k1) { - // k1 := sub(P(), k1) - // table00, table01, table02 := projectiveNeg(table00, table01, table02) - // } - // if shr(255, k2) { - // k2 :=sub(P(), k2) - // table30, table31, table32 := projectiveNeg(table30, table31, table32) - // } - let table10, table11, table12 := addProjective(table00, table01, table02, table00, table01, table02) let table20, table21, table22 := addProjective(table10, table11, table12, table00, table01, table02) let table40, table41, table42 := addProjective(table30, table31, table32, table00, table01, table02) @@ -572,8 +563,10 @@ object "EcMul" { maxBit := k2BitLen } - // k1 := outOfMontgomeryForm(k1) - // k2 := outOfMontgomeryForm(k2) + if mod(maxBit, 2) { + maxBit := add(maxBit, 1) + } + let f := sub(maxBit, 2) let mask := shl(f, 3) From 26ab85921d72e152f1aacde0d00d22426e52efc3 Mon Sep 17 00:00:00 2001 From: IAvecilla Date: Tue, 3 Oct 2023 16:58:00 -0300 Subject: [PATCH 8/9] Optimize way of skipping scalar zeros --- precompiles/EcMul.yul | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/precompiles/EcMul.yul b/precompiles/EcMul.yul index 2682d3e1..171f99fa 100644 --- a/precompiles/EcMul.yul +++ b/precompiles/EcMul.yul @@ -468,14 +468,6 @@ object "EcMul" { zr := zp } - function bitLen(n) -> ret { - ret := 0 - for {} gt(n, 0) {} { - n := shr(1, n) - ret := add(ret, 1) - } - } - //////////////////////////////////////////////////////////////// // FALLBACK //////////////////////////////////////////////////////////////// @@ -556,21 +548,23 @@ object "EcMul" { let table130, table131, table132 := addProjective(table110, table111, table112, table10, table11, table12) let table140, table141, table142 := addProjective(table110, table111, table112, table20, table21, table22) - let k1BitLen := bitLen(k1) - let k2BitLen := bitLen(k2) - let maxBit := k1BitLen - if gt(k2BitLen, maxBit) { - maxBit := k2BitLen - } + let f := 254 + let mask := shl(f, 3) + let startIndex := 0 - if mod(maxBit, 2) { - maxBit := add(maxBit, 1) + for { let j := 0 } lt(j, 128) { j := add(j, 1) } { + let kAux := shr(sub(f, add(j, j)), k1) + if iszero(kAux) { + mask := shr(2, mask) + continue + } + if kAux { + startIndex := j + break + } } - let f := sub(maxBit, 2) - let mask := shl(f, 3) - - for { let j := 0 } lt(j, div(maxBit, 2)) { j := add(j, 1) } { + for { let j := startIndex } lt(j, 128) { j := add(j, 1) } { xr, yr, zr := projectiveDouble(xr, yr, zr) xr, yr, zr := projectiveDouble(xr, yr, zr) let shift := sub(f, add(j, j)) From e0c0fc1673d5c9738b43e3de7799b78911b1ac14 Mon Sep 17 00:00:00 2001 From: IAvecilla Date: Tue, 3 Oct 2023 17:05:27 -0300 Subject: [PATCH 9/9] Add comments for split scalar function --- precompiles/EcMul.yul | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/precompiles/EcMul.yul b/precompiles/EcMul.yul index 171f99fa..b0f3d4f3 100644 --- a/precompiles/EcMul.yul +++ b/precompiles/EcMul.yul @@ -384,14 +384,20 @@ object "EcMul" { } function splitScalar(scalar, v10, v11, v20, v21, det, b1, b2) -> v0, v1 { + // This multiplications overflows, multiplication of big integers is needed. let k1 := mul(scalar, b1) let k2 := mul(scalar, b2) + k2 := sub(0, k2) - // n := 2 * ((l.Det.BitLen()+32)>>6)<<6) let n := DIV_LATTICE_DETERMINANT() + + // This shift always result in k2 and k1 being 0. k1 := shr(n, k1) k2 := shr(n, k2) + v0, v1 := getVector(v10, v11, v20, v21, k1, k2) + + // This is not working as expected, v1 is always 0 and v0 is the whole scalar. v0 := sub(scalar, v0) v1 := sub(0, v1) } @@ -531,7 +537,10 @@ object "EcMul" { let table02 := zp let table30, table31, table32 := phi(xp, yp, zp) + // Some of this values need to be represented as big integers. let v10, v11, v20, v21, det, b1, b2 := GLV_BASIS() + + // This is not working as expected, k2 is always 0. let k1, k2 := splitScalar(scalar, v10, v11, v20, v21, det, b1, b2) let table10, table11, table12 := addProjective(table00, table01, table02, table00, table01, table02) @@ -552,6 +561,7 @@ object "EcMul" { let mask := shl(f, 3) let startIndex := 0 + // Skipping the zeros in the beginning of the scalar in big-endian representation. for { let j := 0 } lt(j, 128) { j := add(j, 1) } { let kAux := shr(sub(f, add(j, j)), k1) if iszero(kAux) {