Skip to content

Commit a80fee1

Browse files
Bump cairo-lang to 0.13.5 (#1959) (#2118)
* Update cairo-lang versin * Update changelog * Add new hints * Specify prime in new hints * Only apply mod floor if prime is not CAIRO_PRIME * Properly implement pack for a different prime * Fix pack in compute_doubling_slope * Add negative_points.cairo test * Add try_get_point_from_x for negative points * Add double_x test for negative points * Allow to many arguments * Add codecov to cairo-0-secp-hints feature Co-authored-by: Julian Gonzalez Calderon <[email protected]>
1 parent b350c1f commit a80fee1

File tree

9 files changed

+298
-18
lines changed

9 files changed

+298
-18
lines changed
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
%builtins range_check
2+
3+
from starkware.cairo.common.secp256r1.ec import (
4+
EcPoint,
5+
)
6+
from starkware.cairo.common.secp256r1.bigint import nondet_bigint3
7+
from starkware.cairo.common.cairo_secp.bigint3 import BigInt3
8+
9+
func main{range_check_ptr: felt}() {
10+
let point = EcPoint(
11+
BigInt3(1, 2, 3),
12+
BigInt3(-1, -2, -3),
13+
);
14+
15+
let slope = compute_doubling_slope_prime(point);
16+
assert slope = BigInt3(
17+
15487438216801236710343013, 27596288489803578791625491, 8178446608657045587339469
18+
);
19+
20+
let slope = compute_doubling_slope_secp256r1(point);
21+
assert slope = BigInt3(
22+
56511396263956479754791421, 38561311687768998103117219, 2015104701319196654781984
23+
);
24+
25+
let x = BigInt3(-1,-2,-3);
26+
let y = try_get_point_from_x_prime(x, 0);
27+
assert y = BigInt3(
28+
39197606747300743094893670, 38008389934708701866119639, 2071781356858789560884686
29+
);
30+
31+
let x = BigInt3(-1,-2,-3);
32+
let y = try_get_point_from_x_secp256r1(x, 0);
33+
assert y = BigInt3(
34+
56004882917990234964232380, 17943756516348761157632108, 3811440313376405071875160
35+
);
36+
37+
let slope = BigInt3(-1,-2,-3);
38+
let x = ec_double_x_prime(point, slope);
39+
assert x = BigInt3(
40+
648518346341351470, 77370588372549613637288996, 18662792551970020321619971
41+
);
42+
43+
let slope = BigInt3(-1,-2,-3);
44+
let x = ec_double_x_secp256r1(point, slope);
45+
assert x = BigInt3(
46+
21299552074028835321108137, 50187220174510023990904347, 2291813387120727975022296
47+
);
48+
49+
return ();
50+
}
51+
52+
func compute_doubling_slope_prime{range_check_ptr}(point: EcPoint) -> BigInt3 {
53+
%{
54+
from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA, SECP256R1_P
55+
from starkware.cairo.common.cairo_secp.secp_utils import pack
56+
from starkware.python.math_utils import ec_double_slope
57+
58+
# Compute the slope.
59+
x = pack(ids.point.x, PRIME)
60+
y = pack(ids.point.y, PRIME)
61+
value = slope = ec_double_slope(point=(x, y), alpha=SECP256R1_ALPHA, p=SECP256R1_P)
62+
%}
63+
let (slope: BigInt3) = nondet_bigint3();
64+
return slope;
65+
}
66+
67+
func compute_doubling_slope_secp256r1{range_check_ptr}(point: EcPoint) -> BigInt3 {
68+
%{
69+
from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA, SECP256R1_P
70+
from starkware.cairo.common.cairo_secp.secp_utils import pack
71+
from starkware.python.math_utils import ec_double_slope
72+
73+
# Compute the slope.
74+
x = pack(ids.point.x, SECP256R1_P)
75+
y = pack(ids.point.y, SECP256R1_P)
76+
value = slope = ec_double_slope(point=(x, y), alpha=SECP256R1_ALPHA, p=SECP256R1_P)
77+
%}
78+
let (slope: BigInt3) = nondet_bigint3();
79+
return slope;
80+
}
81+
82+
func try_get_point_from_x_prime{range_check_ptr}(x: BigInt3, v: felt) -> BigInt3 {
83+
%{
84+
from starkware.cairo.common.cairo_secp.secp_utils import SECP256R1, pack
85+
from starkware.python.math_utils import y_squared_from_x
86+
87+
y_square_int = y_squared_from_x(
88+
x=pack(ids.x, PRIME),
89+
alpha=SECP256R1.alpha,
90+
beta=SECP256R1.beta,
91+
field_prime=SECP256R1.prime,
92+
)
93+
94+
# Note that (y_square_int ** ((SECP256R1.prime + 1) / 4)) ** 2 =
95+
# = y_square_int ** ((SECP256R1.prime + 1) / 2) =
96+
# = y_square_int ** ((SECP256R1.prime - 1) / 2 + 1) =
97+
# = y_square_int * y_square_int ** ((SECP256R1.prime - 1) / 2) = y_square_int * {+/-}1.
98+
y = pow(y_square_int, (SECP256R1.prime + 1) // 4, SECP256R1.prime)
99+
100+
# We need to decide whether to take y or prime - y.
101+
if ids.v % 2 == y % 2:
102+
value = y
103+
else:
104+
value = (-y) % SECP256R1.prime
105+
%}
106+
let (y: BigInt3) = nondet_bigint3();
107+
return y;
108+
}
109+
110+
func try_get_point_from_x_secp256r1{range_check_ptr}(x: BigInt3, v: felt) -> BigInt3 {
111+
%{
112+
from starkware.cairo.common.cairo_secp.secp_utils import SECP256R1, pack
113+
from starkware.python.math_utils import y_squared_from_x
114+
115+
y_square_int = y_squared_from_x(
116+
x=pack(ids.x, SECP256R1.prime),
117+
alpha=SECP256R1.alpha,
118+
beta=SECP256R1.beta,
119+
field_prime=SECP256R1.prime,
120+
)
121+
122+
# Note that (y_square_int ** ((SECP256R1.prime + 1) / 4)) ** 2 =
123+
# = y_square_int ** ((SECP256R1.prime + 1) / 2) =
124+
# = y_square_int ** ((SECP256R1.prime - 1) / 2 + 1) =
125+
# = y_square_int * y_square_int ** ((SECP256R1.prime - 1) / 2) = y_square_int * {+/-}1.
126+
y = pow(y_square_int, (SECP256R1.prime + 1) // 4, SECP256R1.prime)
127+
128+
# We need to decide whether to take y or prime - y.
129+
if ids.v % 2 == y % 2:
130+
value = y
131+
else:
132+
value = (-y) % SECP256R1.prime
133+
%}
134+
let (y: BigInt3) = nondet_bigint3();
135+
return y;
136+
}
137+
138+
139+
func ec_double_x_prime{range_check_ptr}(point: EcPoint, slope: BigInt3) -> BigInt3 {
140+
%{
141+
from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_P
142+
from starkware.cairo.common.cairo_secp.secp_utils import pack
143+
144+
slope = pack(ids.slope, PRIME)
145+
x = pack(ids.point.x, PRIME)
146+
y = pack(ids.point.y, PRIME)
147+
148+
value = new_x = (pow(slope, 2, SECP256R1_P) - 2 * x) % SECP256R1_P
149+
%}
150+
let (new_x: BigInt3) = nondet_bigint3();
151+
return new_x;
152+
}
153+
154+
func ec_double_x_secp256r1{range_check_ptr}(point: EcPoint, slope: BigInt3) -> BigInt3 {
155+
%{
156+
from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_P
157+
from starkware.cairo.common.cairo_secp.secp_utils import pack
158+
159+
slope = pack(ids.slope, SECP256R1_P)
160+
x = pack(ids.point.x, SECP256R1_P)
161+
y = pack(ids.point.y, SECP256R1_P)
162+
163+
value = new_x = (pow(slope, 2, SECP256R1_P) - 2 * x) % SECP256R1_P
164+
%}
165+
let (new_x: BigInt3) = nondet_bigint3();
166+
return new_x;
167+
}

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ bitarray==2.7.3
33
fastecdsa==2.3.2
44
sympy==1.11.1
55
typeguard==2.13.3
6-
cairo-lang==0.13.3
6+
cairo-lang==0.13.5

vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
#[cfg(feature = "cairo-0-secp-hints")]
2-
use super::secp::cairo0_hints;
1+
use super::blake2s_utils::example_blake2s_compress;
32
use super::{
43
blake2s_utils::{blake2s_unpack_felts, finalize_blake2s_v3, is_less_than_63_bits_and_not_end},
54
ec_recover::{
@@ -25,6 +24,10 @@ use super::{
2524
},
2625
};
2726
use crate::Felt252;
27+
use crate::{
28+
hint_processor::builtin_hint_processor::secp::secp_utils::{SECP256R1_ALPHA, SECP256R1_P},
29+
utils::CAIRO_PRIME,
30+
};
2831
use crate::{
2932
hint_processor::{
3033
builtin_hint_processor::secp::ec_utils::{
@@ -117,17 +120,14 @@ use crate::{
117120
vm::{errors::hint_errors::HintError, vm_core::VirtualMachine},
118121
};
119122

123+
#[cfg(feature = "cairo-0-secp-hints")]
124+
use crate::hint_processor::builtin_hint_processor::secp::cairo0_hints;
120125
#[cfg(feature = "test_utils")]
121-
use crate::hint_processor::builtin_hint_processor::skip_next_instruction::skip_next_instruction;
122-
123-
#[cfg(feature = "test_utils")]
124-
use crate::hint_processor::builtin_hint_processor::print::{print_array, print_dict, print_felt};
125-
use crate::hint_processor::builtin_hint_processor::secp::secp_utils::{
126-
SECP256R1_ALPHA, SECP256R1_P,
126+
use crate::hint_processor::builtin_hint_processor::{
127+
print::{print_array, print_dict, print_felt},
128+
skip_next_instruction::skip_next_instruction,
127129
};
128130

129-
use super::blake2s_utils::example_blake2s_compress;
130-
131131
pub struct HintProcessorData {
132132
pub code: String,
133133
pub ap_tracking: ApTracking,
@@ -523,6 +523,7 @@ impl HintProcessorLogic for BuiltinHintProcessor {
523523
&hint_data.ids_data,
524524
&hint_data.ap_tracking,
525525
"point",
526+
&CAIRO_PRIME,
526527
&SECP_P,
527528
&ALPHA,
528529
),
@@ -532,6 +533,7 @@ impl HintProcessorLogic for BuiltinHintProcessor {
532533
&hint_data.ids_data,
533534
&hint_data.ap_tracking,
534535
"point",
536+
&CAIRO_PRIME,
535537
&SECP_P_V2,
536538
&ALPHA_V2,
537539
),
@@ -541,6 +543,7 @@ impl HintProcessorLogic for BuiltinHintProcessor {
541543
&hint_data.ids_data,
542544
&hint_data.ap_tracking,
543545
"pt",
546+
&CAIRO_PRIME,
544547
&SECP_P,
545548
&ALPHA,
546549
),
@@ -550,6 +553,17 @@ impl HintProcessorLogic for BuiltinHintProcessor {
550553
&hint_data.ids_data,
551554
&hint_data.ap_tracking,
552555
"point",
556+
SECP256R1_P.magnitude(),
557+
&SECP256R1_P,
558+
&SECP256R1_ALPHA,
559+
),
560+
hint_code::EC_DOUBLE_SLOPE_V5 => compute_doubling_slope(
561+
vm,
562+
exec_scopes,
563+
&hint_data.ids_data,
564+
&hint_data.ap_tracking,
565+
"point",
566+
&CAIRO_PRIME,
553567
&SECP256R1_P,
554568
&SECP256R1_ALPHA,
555569
),
@@ -905,6 +919,16 @@ impl HintProcessorLogic for BuiltinHintProcessor {
905919
&hint_data.ids_data,
906920
&hint_data.ap_tracking,
907921
constants,
922+
SECP256R1_P.magnitude(),
923+
),
924+
#[cfg(feature = "cairo-0-secp-hints")]
925+
cairo0_hints::SECP_DOUBLE_ASSIGN_NEW_X_V2 => cairo0_hints::secp_double_assign_new_x(
926+
vm,
927+
exec_scopes,
928+
&hint_data.ids_data,
929+
&hint_data.ap_tracking,
930+
constants,
931+
&CAIRO_PRIME,
908932
),
909933
#[cfg(feature = "cairo-0-secp-hints")]
910934
cairo0_hints::FAST_SECP_ADD_ASSIGN_NEW_Y => cairo0_hints::fast_secp_add_assign_new_y(
@@ -954,6 +978,17 @@ impl HintProcessorLogic for BuiltinHintProcessor {
954978
&hint_data.ids_data,
955979
&hint_data.ap_tracking,
956980
constants,
981+
SECP256R1_P.magnitude(),
982+
),
983+
984+
#[cfg(feature = "cairo-0-secp-hints")]
985+
cairo0_hints::SECP_R1_GET_POINT_FROM_X_V2 => cairo0_hints::r1_get_point_from_x(
986+
vm,
987+
exec_scopes,
988+
&hint_data.ids_data,
989+
&hint_data.ap_tracking,
990+
constants,
991+
&CAIRO_PRIME,
957992
),
958993

959994
#[cfg(feature = "cairo-0-secp-hints")]

vm/src/hint_processor/builtin_hint_processor/hint_code.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,14 @@ from starkware.python.math_utils import ec_double_slope
620620
x = pack(ids.point.x, SECP256R1_P)
621621
y = pack(ids.point.y, SECP256R1_P)
622622
value = slope = ec_double_slope(point=(x, y), alpha=SECP256R1_ALPHA, p=SECP256R1_P)"#}),
623+
(EC_DOUBLE_SLOPE_V5, indoc! {r#"from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA, SECP256R1_P
624+
from starkware.cairo.common.cairo_secp.secp_utils import pack
625+
from starkware.python.math_utils import ec_double_slope
626+
627+
# Compute the slope.
628+
x = pack(ids.point.x, PRIME)
629+
y = pack(ids.point.y, PRIME)
630+
value = slope = ec_double_slope(point=(x, y), alpha=SECP256R1_ALPHA, p=SECP256R1_P)"#}),
623631
(EC_DOUBLE_SLOPE_EXTERNAL_CONSTS, indoc! {r#"from starkware.cairo.common.cairo_secp.secp_utils import pack
624632
from starkware.python.math_utils import ec_double_slope
625633

vm/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,17 @@ impl<const NUM_LIMBS: usize> BigIntN<'_, NUM_LIMBS> {
9595
.sum()
9696
}
9797

98+
pub(crate) fn pack86_for_prime(self, prime: &BigUint) -> BigInt {
99+
self.limbs
100+
.into_iter()
101+
.take(3)
102+
.enumerate()
103+
.map(|(idx, value)| {
104+
crate::math_utils::signed_felt_for_prime(*value, prime).shl(idx * 86)
105+
})
106+
.sum()
107+
}
108+
98109
pub(crate) fn split(num: &BigUint) -> Self {
99110
let limbs = split(num, 128);
100111
Self::from_values(limbs)

0 commit comments

Comments
 (0)