Skip to content
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

feat: SECP related hints #1829

Merged
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
92cbf06
feat: secp-related hints
whichqua Aug 2, 2024
40ebe36
PR link in changelog
odesenfans Aug 29, 2024
5337a25
Merge branch 'main' into gm/secp-hints-main-latest
HermanObst Sep 26, 2024
be51042
Merge branch 'main' into gm/secp-hints-main-latest
whichqua Oct 16, 2024
b3db7d4
fix: handle unwraps in secp hints with HintError variants
whichqua Oct 16, 2024
eaccbb8
add: cairo-0-secp-hints to allow enabling secp related hints
whichqua Oct 16, 2024
f56cb5c
lint: clippy replace `.get(0)` with `.first()`
whichqua Oct 16, 2024
667c8cb
tests: add integration tests for cairo-0-secp hints
whichqua Nov 5, 2024
eac7211
Merge branch 'main' into gm/secp-hints-main-latest
whichqua Nov 5, 2024
a1d9fc9
Merge branch 'main' into gm/secp-hints-main-latest
whichqua Nov 14, 2024
3a4054d
fix: add missing feature `cairo-0-secp-hints` in tests
whichqua Nov 14, 2024
f77fb56
fix: get the ec_cairo test running
whichqua Nov 19, 2024
8ad71a3
Merge branch 'main' into gm/secp-hints-main-latest
whichqua Nov 20, 2024
20a0e46
fix: move the test programs to own dir and update Makefile
whichqua Nov 21, 2024
cef84f6
fix: remove some test remnants
whichqua Nov 21, 2024
e316f50
Merge branch 'main' into gm/secp-hints-main-latest
whichqua Nov 21, 2024
cb374e7
fix: move cairo-0-secp-hints to special_features matrix
whichqua Nov 21, 2024
8dc35db
lint: cargo fmt
whichqua Nov 21, 2024
7ae6e5d
Merge branch 'main' into gm/secp-hints-main-latest
whichqua Nov 26, 2024
3b4c144
fix: remove unneeed recipes
whichqua Nov 26, 2024
ad9c5fe
fix: remove SECP_CAIRO0_HINTS_PROOF_TESTS
whichqua Nov 26, 2024
a3f295b
fix: remove unused error variant
whichqua Nov 27, 2024
d15c4ab
fix: use div_mod_floor instead of div_rem
whichqua Nov 27, 2024
3ec48e7
Merge branch 'main' into gm/secp-hints-main-latest
whichqua Nov 27, 2024
dc3bf18
revert: use div_mod_floor instead of div_rem
whichqua Nov 27, 2024
6e5227c
changelog: add this PR to upcoming changes
whichqua Dec 2, 2024
e81850a
Merge branch 'main' into gm/secp-hints-main-latest
whichqua Dec 2, 2024
ef13273
fix: remove unnecessary newline
whichqua Dec 3, 2024
875e2c0
Merge branch 'main' into gm/secp-hints-main-latest
whichqua Dec 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ jobs:
strategy:
fail-fast: false
matrix:
special_features: ["", "extensive_hints", "mod_builtin"]
special_features: ["", "extensive_hints", "mod_builtin", "cairo-0-secp-hints"]
target: [ test#1, test#2, test#3, test#4, test-no_std#1, test-no_std#2, test-no_std#3, test-no_std#4, test-wasm ]
name: Run tests
runs-on: ubuntu-22.04
Expand Down Expand Up @@ -370,7 +370,7 @@ jobs:
'test')
cargo llvm-cov nextest --lcov --output-path lcov-${{ matrix.target }}-${{ matrix.special_features }}.info \
--partition count:${PARTITION}/4 \
--workspace --features "cairo-1-hints, test_utils, ${{ matrix.special_features }}"
JulianGCalderon marked this conversation as resolved.
Show resolved Hide resolved
--workspace --features "cairo-1-hints, test_utils, ${{ matrix.special_features }}"
;;
'test-no_std')
cargo llvm-cov nextest --lcov --output-path lcov-${{ matrix.target }}-${{ matrix.special_features }}.info \
Expand Down Expand Up @@ -844,4 +844,3 @@ jobs:

- name: Run comparison
run: ./vm/src/tests/compare_all_pie_outputs.sh

2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#### Upcoming Changes

* feat: Implement `SECP related` hints [#1829](https://github.com/lambdaclass/cairo-vm/pull/1829)

#### [2.0.0-rc1] - 2024-11-20

* feat: add `EvalCircuit` and `TestLessThanOrEqualAddress` hints [#1843](https://github.com/lambdaclass/cairo-vm/pull/1843)
Expand Down
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ BAD_TEST_DIR=cairo_programs/bad_programs
BAD_TEST_FILES:=$(wildcard $(BAD_TEST_DIR)/*.cairo)
COMPILED_BAD_TESTS:=$(patsubst $(BAD_TEST_DIR)/%.cairo, $(BAD_TEST_DIR)/%.json, $(BAD_TEST_FILES))

SECP_CAIRO0_HINTS_DIR=cairo_programs/cairo-0-secp-hints-feature
SECP_CAIRO0_HINTS_FILES:=$(wildcard $(SECP_CAIRO0_HINTS_DIR)/*.cairo)
COMPILED_SECP_CAIRO0_HINTS:=$(patsubst $(SECP_CAIRO0_HINTS_DIR)/%.cairo, $(SECP_CAIRO0_HINTS_DIR)/%.json, $(SECP_CAIRO0_HINTS_FILES))

PRINT_TEST_DIR=cairo_programs/print_feature
PRINT_TEST_FILES:=$(wildcard $(PRINT_TEST_DIR)/*.cairo)
COMPILED_PRINT_TESTS:=$(patsubst $(PRINT_TEST_DIR)/%.cairo, $(PRINT_TEST_DIR)/%.json, $(PRINT_TEST_FILES))
Expand Down Expand Up @@ -239,7 +243,7 @@ run:
check:
cargo check

cairo_test_programs: $(COMPILED_TESTS) $(COMPILED_BAD_TESTS) $(COMPILED_NORETROCOMPAT_TESTS) $(COMPILED_PRINT_TESTS) $(COMPILED_MOD_BUILTIN_TESTS)
cairo_test_programs: $(COMPILED_TESTS) $(COMPILED_BAD_TESTS) $(COMPILED_NORETROCOMPAT_TESTS) $(COMPILED_PRINT_TESTS) $(COMPILED_MOD_BUILTIN_TESTS) $(COMPILED_SECP_CAIRO0_HINTS)
cairo_proof_programs: $(COMPILED_PROOF_TESTS) $(COMPILED_MOD_BUILTIN_PROOF_TESTS)
cairo_bench_programs: $(COMPILED_BENCHES)
cairo_1_test_contracts: $(CAIRO_1_COMPILED_CASM_CONTRACTS)
Expand All @@ -264,7 +268,7 @@ test-wasm: cairo_proof_programs cairo_test_programs
# NOTE: release mode is needed to avoid "too many locals" error
wasm-pack test --release --node vm --no-default-features
test-extensive_hints: cairo_proof_programs cairo_test_programs
$(TEST_COMMAND) --workspace --features "test_utils, cairo-1-hints, extensive_hints"
$(TEST_COMMAND) --workspace --features "test_utils, cairo-1-hints, cairo-0-secp-hints, extensive_hints"

check-fmt:
cargo fmt --all -- --check
Expand Down Expand Up @@ -344,6 +348,7 @@ clean:
rm -f $(TEST_DIR)/*.pie
rm -f $(BENCH_DIR)/*.json
rm -f $(BAD_TEST_DIR)/*.json
rm -f $(SECP_CAIRO0_HINTS_DIR)/*.json
rm -f $(PRINT_TEST_DIR)/*.json
rm -f $(CAIRO_1_CONTRACTS_TEST_DIR)/*.sierra
rm -f $(CAIRO_1_CONTRACTS_TEST_DIR)/*.casm
Expand Down
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 cairo_programs/cairo-0-secp-hints-feature/secp_cairo0_ec.cairo
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 ();
}
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 ();
}
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 ();
}
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 ();
}
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 ();
}
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 ();
}
Loading
Loading