-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
adding edge case for ecmulmuladd #49
Conversation
I've narrowed it down to a smaller test case the shows the issue: // SPDX-License-Identifier: MIT
pragma solidity >=0.8.19 <0.9.0;
import "forge-std/Test.sol";
import "@solidity/FCL_elliptic.sol";
contract EcmulmulEdge is Test {
function test_EdgeCase() external {
uint256 Qx = 102369864249653057322725350723741461599905180004905897298779971437827381725266;
uint256 Qy = 14047598098721058250371778545974983789701612908526165355421494088134814672697;
uint256 u = 9;
uint256 v = 6;
uint256 r1 = FCL_Elliptic_ZZ.ecZZ_mulmuladd_S_asm(Qx, Qy, u, v);
console.log("r1 = %d", r1);
(uint256 uGx, uint256 uGy) = ecAff_naivemul(u, FCL_Elliptic_ZZ.gx, FCL_Elliptic_ZZ.gy);
(uint256 vQx, uint256 vQy) = ecAff_naivemul(v, Qx, Qy);
(uint256 r2,) = FCL_Elliptic_ZZ.ecAff_add(uGx, uGy, vQx, vQy);
console.log("r2 = %d", r2);
assertEq(r1, r2);
}
function ecAff_naivemul(uint256 a, uint256 x, uint256 y) private view returns (uint256 ax, uint256 ay) {
while (a > 0) {
(ax, ay) = FCL_Elliptic_ZZ.ecAff_add(ax, ay, x, y);
a = a - 1;
}
}
} |
And even smaller one: // SPDX-License-Identifier: MIT
pragma solidity >=0.8.19 <0.9.0;
import "forge-std/Test.sol";
import "@solidity/FCL_ecdsa_utils.sol";
import "@solidity/FCL_elliptic.sol";
contract EcmulmulEdge is Test {
function test_EdgeCase() external {
uint256 s = FCL_Elliptic_ZZ.n - 1;
(uint256 Qx, uint256 Qy) = FCL_ecdsa_utils.ecdsa_derivKpub(s);
console.log("Qx = %d", Qx);
console.log("Qy = %d", Qy);
uint256 u = 3;
uint256 v = 1;
uint256 r1 = FCL_Elliptic_ZZ.ecZZ_mulmuladd_S_asm(Qx, Qy, u, v);
console.log("r1 = %d", r1);
(uint256 uGx, uint256 uGy) = ecAff_naivemul(u, FCL_Elliptic_ZZ.gx, FCL_Elliptic_ZZ.gy);
(uint256 vQx, uint256 vQy) = ecAff_naivemul(v, Qx, Qy);
(uint256 r2,) = FCL_Elliptic_ZZ.ecAff_add(uGx, uGy, vQx, vQy);
console.log("r2 = %d", r2);
(uint256 twoGx, ) = ecAff_naivemul(2, FCL_Elliptic_ZZ.gx, FCL_Elliptic_ZZ.gy);
console.log("2Gx = %d", twoGx);
assertEq(r1, r2);
}
function ecAff_naivemul(uint256 a, uint256 x, uint256 y) private view returns (uint256 ax, uint256 ay) {
while (a > 0) {
(ax, ay) = FCL_Elliptic_ZZ.ecAff_add(ax, ay, x, y);
a = a - 1;
}
}
} I think I have some intuition on what is going on... So this seems to happen for Q where the pk is the order In the second case, we are computing
So it appears that there is some weird interaction where elements of the sum are adding to the point at infinity and causing issues in the implementation. In the previous example, you have something similar noting that I'm sorry if my conjecture is wrong 🙈 - but at least I hope I helped in finding some reduced examples that are causing issues with |
It gonna be easier to patch thx. You understand well, it is what I said about coverage on the other PR. I thought having wycheproofed the code and used forge cover would cover the 'if' section supposed to handle this, (and let the todo undone) FreshCryptoLib/solidity/src/FCL_elliptic.sol Line 438 in e2830cb
Forge cover is not able to proceed 'for loops'. |
adding edge case following #48 issue on Fuzzing