forked from lambdaclass/cairo-vm
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: SECP related hints (lambdaclass#1829)
* feat: secp-related hints Problem: we need an implementation of the hints used by the Starknet OS in the secp syscalls. These hints rely on private primitives in `cairo-vm` and need to be implemented here. Solution: this PR adds an implementation of all the hints that require `cairo-vm` primitives in the `cairo-vm` repository. * PR link in changelog * fix: handle unwraps in secp hints with HintError variants * add: cairo-0-secp-hints to allow enabling secp related hints * lint: clippy replace `.get(0)` with `.first()` * tests: add integration tests for cairo-0-secp hints * fix: add missing feature `cairo-0-secp-hints` in tests * fix: get the ec_cairo test running * fix: move the test programs to own dir and update Makefile * fix: remove some test remnants * fix: move cairo-0-secp-hints to special_features matrix * lint: cargo fmt * fix: remove unneeed recipes * fix: remove SECP_CAIRO0_HINTS_PROOF_TESTS * fix: remove unused error variant * fix: use div_mod_floor instead of div_rem * revert: use div_mod_floor instead of div_rem * changelog: add this PR to upcoming changes * fix: remove unnecessary newline --------- Co-authored-by: whichqua <[email protected]> Co-authored-by: Herman Obst Demaestri <[email protected]>
- Loading branch information
1 parent
4e55e35
commit 577f744
Showing
20 changed files
with
1,179 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
cairo_programs/cairo-0-secp-hints-feature/secp_cairo0_compute_q_mod_prime.cairo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
%builtins range_check | ||
|
||
from starkware.cairo.common.cairo_secp.bigint import BigInt3, nondet_bigint3, UnreducedBigInt3 | ||
|
||
const BASE = 2 ** 86; | ||
const SECP_REM = 19; | ||
|
||
func test_q_mod_prime{range_check_ptr: felt}(val: UnreducedBigInt3) { | ||
let q = [ap]; | ||
%{ | ||
from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_P | ||
from starkware.cairo.common.cairo_secp.secp_utils import pack | ||
q, r = divmod(pack(ids.val, PRIME), SECP256R1_P) | ||
assert r == 0, f"verify_zero: Invalid input {ids.val.d0, ids.val.d1, ids.val.d2}." | ||
ids.q = q % PRIME | ||
%} | ||
let q_biased = [ap + 1]; | ||
q_biased = q + 2 ** 127, ap++; | ||
[range_check_ptr] = q_biased, ap++; | ||
// This implies that q is in the range [-2**127, 2**127). | ||
|
||
tempvar r1 = (val.d0 + q * SECP_REM) / BASE; | ||
assert [range_check_ptr + 1] = r1 + 2 ** 127; | ||
// This implies that r1 is in the range [-2**127, 2**127). | ||
// Therefore, r1 * BASE is in the range [-2**213, 2**213). | ||
// By the soundness assumption, val.d0 is in the range (-2**250, 2**250). | ||
// This implies that r1 * BASE = val.d0 + q * SECP_REM (as integers). | ||
|
||
tempvar r2 = (val.d1 + r1) / BASE; | ||
assert [range_check_ptr + 2] = r2 + 2 ** 127; | ||
// Similarly, this implies that r2 * BASE = val.d1 + r1 (as integers). | ||
// Therefore, r2 * BASE**2 = val.d1 * BASE + r1 * BASE. | ||
|
||
assert val.d2 = q * (BASE / 8) - r2; | ||
// Similarly, this implies that q * BASE / 4 = val.d2 + r2 (as integers). | ||
// Therefore, | ||
// q * BASE**3 / 4 = val.d2 * BASE**2 + r2 * BASE ** 2 = | ||
// val.d2 * BASE**2 + val.d1 * BASE + r1 * BASE = | ||
// val.d2 * BASE**2 + val.d1 * BASE + val.d0 + q * SECP_REM = | ||
// val + q * SECP_REM. | ||
// Hence, val = q * (BASE**3 / 4 - SECP_REM) = q * (2**256 - SECP_REM) = q * secp256k1_prime. | ||
|
||
let range_check_ptr = range_check_ptr + 3; | ||
return (); | ||
} | ||
|
||
func main{range_check_ptr: felt}() { | ||
let val = UnreducedBigInt3(0, 0, 0); | ||
test_q_mod_prime(val); | ||
return (); | ||
} |
105 changes: 105 additions & 0 deletions
105
cairo_programs/cairo-0-secp-hints-feature/secp_cairo0_ec.cairo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
%builtins range_check | ||
|
||
// Tests: | ||
// - cairo0_hints::COMPUTE_Q_MOD_PRIME | ||
// - cairo0_hints::COMPUTE_IDS_HIGH_LOW | ||
// - cairo0_hints::SECP_DOUBLE_ASSIGN_NEW_X | ||
// - cairo0_hints::FAST_SECP_ADD_ASSIGN_NEW_Y | ||
|
||
from starkware.cairo.common.secp256r1.ec import ( | ||
EcPoint, | ||
compute_doubling_slope, | ||
compute_slope, | ||
ec_double, | ||
fast_ec_add, | ||
ec_mul_inner, | ||
) | ||
from starkware.cairo.common.cairo_secp.bigint3 import BigInt3 | ||
|
||
func main{range_check_ptr: felt}() { | ||
let x = BigInt3(1, 5, 10); | ||
let y = BigInt3(2, 4, 20); | ||
|
||
|
||
let point_a = EcPoint(x, y); | ||
|
||
let point_b = EcPoint( | ||
BigInt3(1, 5, 10), | ||
BigInt3(77371252455336262886226989, 77371252455336267181195259, 19342813113834066795298795), | ||
); | ||
|
||
// let (point_c) = ec_negate(EcPoint(BigInt3(156, 6545, 100010), BigInt3(1123, -1325, 910))); | ||
let point_c = EcPoint( | ||
BigInt3(156, 6545, 100010), | ||
BigInt3(77371252455336262886225868, 1324, 19342813113834066795297906), | ||
); | ||
|
||
// compute_doubling_slope | ||
let (slope_a) = compute_doubling_slope(point_b); | ||
assert slope_a = BigInt3( | ||
64839545681970757313529612, 5953360968438044038987377, 13253714962539897079325475 | ||
); | ||
|
||
let (slope_b) = compute_doubling_slope( | ||
EcPoint(BigInt3(1231, 51235643, 100000), BigInt3(77371252455, 7737125245, 19342813113)) | ||
); | ||
assert slope_b = BigInt3( | ||
61129622008745017597879703, 29315582959606925875642332, 13600923539144215962821694 | ||
); | ||
|
||
// compute_slope | ||
let (slope_c) = compute_slope(point_a, point_c); | ||
assert slope_c = BigInt3( | ||
69736698275759322439409874, 45955733659898858347886847, 18034242868575077772302310 | ||
); | ||
|
||
let (slope_d) = compute_slope(point_c, point_b); | ||
assert slope_d = BigInt3( | ||
66872739393348882319301304, 44057296979296181456999622, 6628179500048909995474229 | ||
); | ||
|
||
// ec_double | ||
let (point_d) = ec_double(point_a); | ||
assert point_d = EcPoint( | ||
BigInt3(62951442591564288805558802, 32562108923955565608466346, 18605500881547971871596634), | ||
BigInt3(32147810383256899543807670, 5175857156528420748725791, 6618806236944685895112117), | ||
); | ||
|
||
let (point_e) = ec_double( | ||
EcPoint(BigInt3(156, 6545, 100010), BigInt3(5336262886225868, 1324, 113834066795297906)) | ||
); | ||
assert point_e = EcPoint( | ||
BigInt3(47503316700827173496989353, 17218105161352860131668522, 527908748911931938599018), | ||
BigInt3(50964737623371959432443726, 60451660835701602854498663, 5043009036652075489876599), | ||
); | ||
|
||
// fast_ec_add | ||
let (point_f) = fast_ec_add(point_a, point_e); | ||
assert point_f = EcPoint( | ||
BigInt3(29666922781464823323928071, 37719311829566792810003084, 9541551049028573381125035), | ||
BigInt3(12938160206947174373897851, 22954464827120147659997987, 2690642098017756659925259), | ||
); | ||
|
||
let (point_g) = fast_ec_add( | ||
EcPoint(BigInt3(89712, 56, 7348489324), BigInt3(980126, 10, 8793)), | ||
EcPoint(BigInt3(16451, 5967, 2171381), BigInt3(12364564, 123654, 193)), | ||
); | ||
assert point_g = EcPoint( | ||
BigInt3(14771767859485410664249539, 62406103981610765545970487, 8912032684309792565082157), | ||
BigInt3(25591125893919304137822981, 54543895003572926651874352, 18968003584818937876851951), | ||
); | ||
|
||
// ec_mul_inner | ||
let (pow2, res) = ec_mul_inner( | ||
EcPoint( | ||
BigInt3(65162296, 359657, 04862662171381), BigInt3(5166641367474701, 63029418, 793) | ||
), | ||
123, | ||
298, | ||
); | ||
assert pow2 = EcPoint( | ||
BigInt3(73356165220405599685396595, 44054642183803477920871071, 5138516367480965019117743), | ||
BigInt3(40256732918865941543909206, 68107624737772931608959283, 1842118797516663063623771), | ||
); | ||
return (); | ||
} |
26 changes: 26 additions & 0 deletions
26
cairo_programs/cairo-0-secp-hints-feature/secp_cairo0_ec_double_assign_new_x.cairo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
%builtins range_check | ||
|
||
from starkware.cairo.common.secp256r1.ec import ( | ||
EcPoint, | ||
ec_double | ||
) | ||
from starkware.cairo.common.cairo_secp.bigint import BigInt3 | ||
|
||
func main{range_check_ptr}() { | ||
let x = BigInt3(235, 522, 111); | ||
let y = BigInt3(1323, 15124, 796759); | ||
|
||
let point = EcPoint(x, y); | ||
|
||
let (r) = ec_double(point); | ||
|
||
assert r.x.d0 = 64413149096815403908768532; | ||
assert r.x.d1 = 28841630551789071202278393; | ||
assert r.x.d2 = 11527965423300397026710769; | ||
|
||
assert r.y.d0 = 6162628527473476058419904; | ||
assert r.y.d1 = 69076668518034904023852368; | ||
assert r.y.d2 = 10886445027049641070037760; | ||
|
||
return (); | ||
} |
26 changes: 26 additions & 0 deletions
26
cairo_programs/cairo-0-secp-hints-feature/secp_cairo0_ec_mul_by_uint256.cairo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
%builtins range_check | ||
|
||
from starkware.cairo.common.secp256r1.ec import ( | ||
EcPoint, | ||
ec_mul_by_uint256 | ||
) | ||
from starkware.cairo.common.uint256 import Uint256 | ||
from starkware.cairo.common.cairo_secp.bigint import BigInt3 | ||
|
||
func main{range_check_ptr: felt}() { | ||
let x = BigInt3(235, 522, 111); | ||
let y = BigInt3(1323, 15124, 796759); | ||
|
||
let point = EcPoint(x, y); | ||
|
||
let scalar = Uint256( | ||
143186476941636880901214103594843510573, 124026708105846590725274683684370988502 | ||
); | ||
let (res) = ec_mul_by_uint256(point, scalar); | ||
|
||
assert res = EcPoint( | ||
BigInt3(31454759005629465428788733, 35370111304581841775514461, 13535495107675380502530193), | ||
BigInt3(18078210390106977421552565, 53503834862379828768870254, 3887397808398301655656699), | ||
); | ||
return (); | ||
} |
31 changes: 31 additions & 0 deletions
31
cairo_programs/cairo-0-secp-hints-feature/secp_cairo0_get_point_from_x.cairo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
%builtins range_check | ||
|
||
from starkware.cairo.common.alloc import alloc | ||
from starkware.cairo.common.cairo_secp.bigint3 import BigInt3 | ||
from starkware.cairo.common.cairo_secp.ec_point import EcPoint | ||
from starkware.cairo.common.secp256r1.ec import ( | ||
try_get_point_from_x | ||
) | ||
from starkware.cairo.common.uint256 import Uint256 | ||
|
||
|
||
func main{range_check_ptr: felt}() { | ||
let zero = BigInt3( | ||
0, 0, 0 | ||
); | ||
let result: EcPoint* = alloc(); | ||
let (is_on_curve) = try_get_point_from_x(zero, 0, result); | ||
assert is_on_curve = 1; | ||
|
||
let x = BigInt3(512,2412,133); | ||
let result: EcPoint* = alloc(); | ||
let (is_on_curve) = try_get_point_from_x(x, 1, result); | ||
assert is_on_curve = 1; | ||
|
||
let x = BigInt3(64,0,6546); | ||
|
||
let result: EcPoint* = alloc(); | ||
let (is_on_curve) = try_get_point_from_x(x, 1, result); | ||
assert is_on_curve = 0; | ||
return (); | ||
} |
39 changes: 39 additions & 0 deletions
39
cairo_programs/cairo-0-secp-hints-feature/secp_cairo0_reduce_value.cairo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
%builtins range_check | ||
|
||
from starkware.cairo.common.cairo_secp.bigint import BigInt3, nondet_bigint3, UnreducedBigInt3 | ||
|
||
func reduce_value{range_check_ptr}(x: UnreducedBigInt3) -> (res: BigInt3) { | ||
%{ | ||
from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_P | ||
from starkware.cairo.common.cairo_secp.secp_utils import pack | ||
value = pack(ids.x, PRIME) % SECP256R1_P | ||
%} | ||
let (res) = nondet_bigint3(); | ||
return (res=res); | ||
} | ||
|
||
func test_reduce_value{range_check_ptr: felt}() { | ||
let x = UnreducedBigInt3(0, 0, 0); | ||
let (reduce_a) = reduce_value(x); | ||
assert reduce_a = BigInt3( | ||
0, 0, 0 | ||
); | ||
|
||
let y = UnreducedBigInt3(12354, 745634534, 81298789312879123); | ||
let (reduce_b) = reduce_value(y); | ||
assert reduce_b = BigInt3( | ||
12354, 745634534, 81298789312879123 | ||
); | ||
|
||
let z = UnreducedBigInt3(12354812987893128791212331231233, 7453123123123123312634534, 8129224990312325879); | ||
let (reduce_c) = reduce_value(z); | ||
assert reduce_c = BigInt3( | ||
16653320122975184709085185, 7453123123123123312794216, 8129224990312325879 | ||
); | ||
return (); | ||
} | ||
|
||
func main{range_check_ptr: felt}() { | ||
test_reduce_value(); | ||
return (); | ||
} |
39 changes: 39 additions & 0 deletions
39
cairo_programs/cairo-0-secp-hints-feature/secp_cairo0_reduce_x.cairo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
%builtins range_check | ||
|
||
from starkware.cairo.common.cairo_secp.bigint import BigInt3, nondet_bigint3, UnreducedBigInt3 | ||
|
||
func reduce_x{range_check_ptr}(x: UnreducedBigInt3) -> (res: BigInt3) { | ||
%{ | ||
from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_P | ||
from starkware.cairo.common.cairo_secp.secp_utils import pack | ||
value = pack(ids.x, PRIME) % SECP256R1_P | ||
%} | ||
let (res) = nondet_bigint3(); | ||
return (res=res); | ||
} | ||
|
||
func test_reduce_x{range_check_ptr: felt}() { | ||
let x = UnreducedBigInt3(0, 0, 0); | ||
let (reduce_a) = reduce_x(x); | ||
assert reduce_a = BigInt3( | ||
0, 0, 0 | ||
); | ||
|
||
let y = UnreducedBigInt3(12354, 745634534, 81298789312879123); | ||
let (reduce_b) = reduce_x(y); | ||
assert reduce_b = BigInt3( | ||
12354, 745634534, 81298789312879123 | ||
); | ||
|
||
let z = UnreducedBigInt3(12354812987893128791212331231233, 7453123123123123312634534, 8129224990312325879); | ||
let (reduce_c) = reduce_x(z); | ||
assert reduce_c = BigInt3( | ||
16653320122975184709085185, 7453123123123123312794216, 8129224990312325879 | ||
); | ||
return (); | ||
} | ||
|
||
func main{range_check_ptr: felt}() { | ||
test_reduce_x(); | ||
return (); | ||
} |
Oops, something went wrong.