Skip to content

Fix secp-hints CI jobs #2118

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

Merged
merged 1 commit into from
Jun 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 31 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,37 @@ jobs:
key: codecov-cache-test-no_std-mod_builtin-${{ github.sha }}
fail-on-cache-miss: true

- name: Fetch results for tests with stdlib (w/cairo-0-secp-hints; part. 1)
uses: actions/cache/restore@v3
with:
path: lcov-test#1-cairo-0-secp-hints.info
key: codecov-cache-test#1-cairo-0-secp-hints-${{ github.sha }}
fail-on-cache-miss: true
- name: Fetch results for tests with stdlib (w/cairo-0-secp-hints; part. 2)
uses: actions/cache/restore@v3
with:
path: lcov-test#2-cairo-0-secp-hints.info
key: codecov-cache-test#2-cairo-0-secp-hints-${{ github.sha }}
fail-on-cache-miss: true
- name: Fetch results for tests with stdlib (w/cairo-0-secp-hints; part. 3)
uses: actions/cache/restore@v3
with:
path: lcov-test#3-cairo-0-secp-hints.info
key: codecov-cache-test#3-cairo-0-secp-hints-${{ github.sha }}
fail-on-cache-miss: true
- name: Fetch results for tests with stdlib (w/cairo-0-secp-hints; part. 4)
uses: actions/cache/restore@v3
with:
path: lcov-test#4-cairo-0-secp-hints.info
key: codecov-cache-test#4-cairo-0-secp-hints-${{ github.sha }}
fail-on-cache-miss: true
- name: Fetch results for tests without stdlib (w/cairo-0-secp-hints)
uses: actions/cache/restore@v3
with:
path: lcov-no_std-cairo-0-secp-hints.info
key: codecov-cache-test-no_std-cairo-0-secp-hints-${{ github.sha }}
fail-on-cache-miss: true

- name: Upload coverage to codecov.io
uses: codecov/codecov-action@v3
with:
Expand Down
167 changes: 167 additions & 0 deletions cairo_programs/cairo-0-secp-hints-feature/negative_points.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
%builtins range_check

from starkware.cairo.common.secp256r1.ec import (
EcPoint,
)
from starkware.cairo.common.secp256r1.bigint import nondet_bigint3
from starkware.cairo.common.cairo_secp.bigint3 import BigInt3

func main{range_check_ptr: felt}() {
let point = EcPoint(
BigInt3(1, 2, 3),
BigInt3(-1, -2, -3),
);

let slope = compute_doubling_slope_prime(point);
assert slope = BigInt3(
15487438216801236710343013, 27596288489803578791625491, 8178446608657045587339469
);

let slope = compute_doubling_slope_secp256r1(point);
assert slope = BigInt3(
56511396263956479754791421, 38561311687768998103117219, 2015104701319196654781984
);

let x = BigInt3(-1,-2,-3);
let y = try_get_point_from_x_prime(x, 0);
assert y = BigInt3(
39197606747300743094893670, 38008389934708701866119639, 2071781356858789560884686
);

let x = BigInt3(-1,-2,-3);
let y = try_get_point_from_x_secp256r1(x, 0);
assert y = BigInt3(
56004882917990234964232380, 17943756516348761157632108, 3811440313376405071875160
);

let slope = BigInt3(-1,-2,-3);
let x = ec_double_x_prime(point, slope);
assert x = BigInt3(
648518346341351470, 77370588372549613637288996, 18662792551970020321619971
);

let slope = BigInt3(-1,-2,-3);
let x = ec_double_x_secp256r1(point, slope);
assert x = BigInt3(
21299552074028835321108137, 50187220174510023990904347, 2291813387120727975022296
);

return ();
}

func compute_doubling_slope_prime{range_check_ptr}(point: EcPoint) -> BigInt3 {
%{
from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA, SECP256R1_P
from starkware.cairo.common.cairo_secp.secp_utils import pack
from starkware.python.math_utils import ec_double_slope

# Compute the slope.
x = pack(ids.point.x, PRIME)
y = pack(ids.point.y, PRIME)
value = slope = ec_double_slope(point=(x, y), alpha=SECP256R1_ALPHA, p=SECP256R1_P)
%}
let (slope: BigInt3) = nondet_bigint3();
return slope;
}

func compute_doubling_slope_secp256r1{range_check_ptr}(point: EcPoint) -> BigInt3 {
%{
from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA, SECP256R1_P
from starkware.cairo.common.cairo_secp.secp_utils import pack
from starkware.python.math_utils import ec_double_slope

# Compute the slope.
x = pack(ids.point.x, SECP256R1_P)
y = pack(ids.point.y, SECP256R1_P)
value = slope = ec_double_slope(point=(x, y), alpha=SECP256R1_ALPHA, p=SECP256R1_P)
%}
let (slope: BigInt3) = nondet_bigint3();
return slope;
}

func try_get_point_from_x_prime{range_check_ptr}(x: BigInt3, v: felt) -> BigInt3 {
%{
from starkware.cairo.common.cairo_secp.secp_utils import SECP256R1, pack
from starkware.python.math_utils import y_squared_from_x

y_square_int = y_squared_from_x(
x=pack(ids.x, PRIME),
alpha=SECP256R1.alpha,
beta=SECP256R1.beta,
field_prime=SECP256R1.prime,
)

# Note that (y_square_int ** ((SECP256R1.prime + 1) / 4)) ** 2 =
# = y_square_int ** ((SECP256R1.prime + 1) / 2) =
# = y_square_int ** ((SECP256R1.prime - 1) / 2 + 1) =
# = y_square_int * y_square_int ** ((SECP256R1.prime - 1) / 2) = y_square_int * {+/-}1.
y = pow(y_square_int, (SECP256R1.prime + 1) // 4, SECP256R1.prime)

# We need to decide whether to take y or prime - y.
if ids.v % 2 == y % 2:
value = y
else:
value = (-y) % SECP256R1.prime
%}
let (y: BigInt3) = nondet_bigint3();
return y;
}

func try_get_point_from_x_secp256r1{range_check_ptr}(x: BigInt3, v: felt) -> BigInt3 {
%{
from starkware.cairo.common.cairo_secp.secp_utils import SECP256R1, pack
from starkware.python.math_utils import y_squared_from_x

y_square_int = y_squared_from_x(
x=pack(ids.x, SECP256R1.prime),
alpha=SECP256R1.alpha,
beta=SECP256R1.beta,
field_prime=SECP256R1.prime,
)

# Note that (y_square_int ** ((SECP256R1.prime + 1) / 4)) ** 2 =
# = y_square_int ** ((SECP256R1.prime + 1) / 2) =
# = y_square_int ** ((SECP256R1.prime - 1) / 2 + 1) =
# = y_square_int * y_square_int ** ((SECP256R1.prime - 1) / 2) = y_square_int * {+/-}1.
y = pow(y_square_int, (SECP256R1.prime + 1) // 4, SECP256R1.prime)

# We need to decide whether to take y or prime - y.
if ids.v % 2 == y % 2:
value = y
else:
value = (-y) % SECP256R1.prime
%}
let (y: BigInt3) = nondet_bigint3();
return y;
}


func ec_double_x_prime{range_check_ptr}(point: EcPoint, slope: BigInt3) -> BigInt3 {
%{
from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_P
from starkware.cairo.common.cairo_secp.secp_utils import pack

slope = pack(ids.slope, PRIME)
x = pack(ids.point.x, PRIME)
y = pack(ids.point.y, PRIME)

value = new_x = (pow(slope, 2, SECP256R1_P) - 2 * x) % SECP256R1_P
%}
let (new_x: BigInt3) = nondet_bigint3();
return new_x;
}

func ec_double_x_secp256r1{range_check_ptr}(point: EcPoint, slope: BigInt3) -> BigInt3 {
%{
from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_P
from starkware.cairo.common.cairo_secp.secp_utils import pack

slope = pack(ids.slope, SECP256R1_P)
x = pack(ids.point.x, SECP256R1_P)
y = pack(ids.point.y, SECP256R1_P)

value = new_x = (pow(slope, 2, SECP256R1_P) - 2 * x) % SECP256R1_P
%}
let (new_x: BigInt3) = nondet_bigint3();
return new_x;
}
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ bitarray==2.7.3
fastecdsa==2.3.2
sympy==1.11.1
typeguard==2.13.3
cairo-lang==0.13.3
cairo-lang==0.13.5
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#[cfg(feature = "cairo-0-secp-hints")]
use super::secp::cairo0_hints;
use super::blake2s_utils::example_blake2s_compress;
use super::{
blake2s_utils::{blake2s_unpack_felts, finalize_blake2s_v3, is_less_than_63_bits_and_not_end},
ec_recover::{
Expand All @@ -25,6 +24,10 @@ use super::{
},
};
use crate::Felt252;
use crate::{
hint_processor::builtin_hint_processor::secp::secp_utils::{SECP256R1_ALPHA, SECP256R1_P},
utils::CAIRO_PRIME,
};
use crate::{
hint_processor::{
builtin_hint_processor::secp::ec_utils::{
Expand Down Expand Up @@ -117,17 +120,14 @@ use crate::{
vm::{errors::hint_errors::HintError, vm_core::VirtualMachine},
};

#[cfg(feature = "cairo-0-secp-hints")]
use crate::hint_processor::builtin_hint_processor::secp::cairo0_hints;
#[cfg(feature = "test_utils")]
use crate::hint_processor::builtin_hint_processor::skip_next_instruction::skip_next_instruction;

#[cfg(feature = "test_utils")]
use crate::hint_processor::builtin_hint_processor::print::{print_array, print_dict, print_felt};
use crate::hint_processor::builtin_hint_processor::secp::secp_utils::{
SECP256R1_ALPHA, SECP256R1_P,
use crate::hint_processor::builtin_hint_processor::{
print::{print_array, print_dict, print_felt},
skip_next_instruction::skip_next_instruction,
};

use super::blake2s_utils::example_blake2s_compress;

pub struct HintProcessorData {
pub code: String,
pub ap_tracking: ApTracking,
Expand Down Expand Up @@ -523,6 +523,7 @@ impl HintProcessorLogic for BuiltinHintProcessor {
&hint_data.ids_data,
&hint_data.ap_tracking,
"point",
&CAIRO_PRIME,
&SECP_P,
&ALPHA,
),
Expand All @@ -532,6 +533,7 @@ impl HintProcessorLogic for BuiltinHintProcessor {
&hint_data.ids_data,
&hint_data.ap_tracking,
"point",
&CAIRO_PRIME,
&SECP_P_V2,
&ALPHA_V2,
),
Expand All @@ -541,6 +543,7 @@ impl HintProcessorLogic for BuiltinHintProcessor {
&hint_data.ids_data,
&hint_data.ap_tracking,
"pt",
&CAIRO_PRIME,
&SECP_P,
&ALPHA,
),
Expand All @@ -550,6 +553,17 @@ impl HintProcessorLogic for BuiltinHintProcessor {
&hint_data.ids_data,
&hint_data.ap_tracking,
"point",
SECP256R1_P.magnitude(),
&SECP256R1_P,
&SECP256R1_ALPHA,
),
hint_code::EC_DOUBLE_SLOPE_V5 => compute_doubling_slope(
vm,
exec_scopes,
&hint_data.ids_data,
&hint_data.ap_tracking,
"point",
&CAIRO_PRIME,
&SECP256R1_P,
&SECP256R1_ALPHA,
),
Expand Down Expand Up @@ -905,6 +919,16 @@ impl HintProcessorLogic for BuiltinHintProcessor {
&hint_data.ids_data,
&hint_data.ap_tracking,
constants,
SECP256R1_P.magnitude(),
),
#[cfg(feature = "cairo-0-secp-hints")]
cairo0_hints::SECP_DOUBLE_ASSIGN_NEW_X_V2 => cairo0_hints::secp_double_assign_new_x(
vm,
exec_scopes,
&hint_data.ids_data,
&hint_data.ap_tracking,
constants,
&CAIRO_PRIME,
),
#[cfg(feature = "cairo-0-secp-hints")]
cairo0_hints::FAST_SECP_ADD_ASSIGN_NEW_Y => cairo0_hints::fast_secp_add_assign_new_y(
Expand Down Expand Up @@ -954,6 +978,17 @@ impl HintProcessorLogic for BuiltinHintProcessor {
&hint_data.ids_data,
&hint_data.ap_tracking,
constants,
SECP256R1_P.magnitude(),
),

#[cfg(feature = "cairo-0-secp-hints")]
cairo0_hints::SECP_R1_GET_POINT_FROM_X_V2 => cairo0_hints::r1_get_point_from_x(
vm,
exec_scopes,
&hint_data.ids_data,
&hint_data.ap_tracking,
constants,
&CAIRO_PRIME,
),

#[cfg(feature = "cairo-0-secp-hints")]
Expand Down
8 changes: 8 additions & 0 deletions vm/src/hint_processor/builtin_hint_processor/hint_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,14 @@ from starkware.python.math_utils import ec_double_slope
x = pack(ids.point.x, SECP256R1_P)
y = pack(ids.point.y, SECP256R1_P)
value = slope = ec_double_slope(point=(x, y), alpha=SECP256R1_ALPHA, p=SECP256R1_P)"#}),
(EC_DOUBLE_SLOPE_V5, indoc! {r#"from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA, SECP256R1_P
from starkware.cairo.common.cairo_secp.secp_utils import pack
from starkware.python.math_utils import ec_double_slope

# Compute the slope.
x = pack(ids.point.x, PRIME)
y = pack(ids.point.y, PRIME)
value = slope = ec_double_slope(point=(x, y), alpha=SECP256R1_ALPHA, p=SECP256R1_P)"#}),
(EC_DOUBLE_SLOPE_EXTERNAL_CONSTS, indoc! {r#"from starkware.cairo.common.cairo_secp.secp_utils import pack
from starkware.python.math_utils import ec_double_slope

Expand Down
11 changes: 11 additions & 0 deletions vm/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,17 @@ impl<const NUM_LIMBS: usize> BigIntN<'_, NUM_LIMBS> {
.sum()
}

pub(crate) fn pack86_for_prime(self, prime: &BigUint) -> BigInt {
self.limbs
.into_iter()
.take(3)
.enumerate()
.map(|(idx, value)| {
crate::math_utils::signed_felt_for_prime(*value, prime).shl(idx * 86)
})
.sum()
}

pub(crate) fn split(num: &BigUint) -> Self {
let limbs = split(num, 128);
Self::from_values(limbs)
Expand Down
Loading
Loading