cairo_vm/hint_processor/builtin_hint_processor/vrf/
pack.rs1use num_bigint::BigInt;
2use num_integer::Integer;
3use num_traits::One;
4
5use crate::hint_processor::builtin_hint_processor::secp::bigint_utils::BigInt3;
6use crate::hint_processor::builtin_hint_processor::secp::secp_utils::SECP_P_V2;
7use crate::hint_processor::hint_processor_definition::HintReference;
8use crate::math_utils::div_mod;
9use crate::serde::deserialize_program::ApTracking;
10use crate::stdlib::collections::HashMap;
11use crate::stdlib::prelude::String;
12use crate::types::exec_scope::ExecutionScopes;
13use crate::vm::errors::hint_errors::HintError;
14use crate::vm::vm_core::VirtualMachine;
15
16pub fn ed25519_is_zero_pack(
24 vm: &mut VirtualMachine,
25 exec_scopes: &mut ExecutionScopes,
26 ids_data: &HashMap<String, HintReference>,
27 ap_tracking: &ApTracking,
28) -> Result<(), HintError> {
29 let x = BigInt3::from_var_name("x", vm, ids_data, ap_tracking)?.pack86();
30 exec_scopes.insert_value("x", x.mod_floor(&SECP_P_V2));
31 exec_scopes.insert_value("SECP_P", SECP_P_V2.clone());
32
33 Ok(())
34}
35
36pub fn ed25519_reduce(
44 vm: &mut VirtualMachine,
45 exec_scopes: &mut ExecutionScopes,
46 ids_data: &HashMap<String, HintReference>,
47 ap_tracking: &ApTracking,
48) -> Result<(), HintError> {
49 let x = BigInt3::from_var_name("x", vm, ids_data, ap_tracking)?.pack86();
50 exec_scopes.insert_value("value", x.mod_floor(&SECP_P_V2));
51 exec_scopes.insert_value("SECP_P", SECP_P_V2.clone());
52
53 Ok(())
54}
55
56pub fn ed25519_is_zero_assign_scope_vars(
64 exec_scopes: &mut ExecutionScopes,
65) -> Result<(), HintError> {
66 let x = exec_scopes.get::<BigInt>("x")?;
67 let x_inv = div_mod(&BigInt::one(), &x, &SECP_P_V2)?;
68 exec_scopes.insert_value("x_inv", x_inv.clone());
69 exec_scopes.insert_value("value", x_inv);
70 exec_scopes.insert_value("SECP_P", SECP_P_V2.clone());
71
72 Ok(())
73}
74
75#[cfg(test)]
76mod test {
77 use crate::any_box;
78 use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor;
79 use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData;
80 use crate::hint_processor::builtin_hint_processor::hint_code;
81 use crate::hint_processor::builtin_hint_processor::secp::secp_utils::SECP_P_V2;
82 use crate::hint_processor::hint_processor_definition::HintProcessorLogic;
83 use crate::hint_processor::hint_processor_definition::HintReference;
84 use crate::stdlib::collections::HashMap;
85 use crate::types::exec_scope::ExecutionScopes;
86 use crate::utils::test_utils::*;
87 use num_bigint::BigInt;
88 use num_traits::One;
89 use num_traits::Zero;
90
91 static SECP_P_D0: i128 = 77371252455336267181195245_i128;
92 static SECP_P_D1: i128 = 77371252455336267181195263_i128;
93 static SECP_P_D2: i128 = 9671406556917033397649407_i128;
94
95 fn assert_is_zero_pack_ed25519_equals(x_d0: i128, x_d1: i128, x_d2: i128, expected: BigInt) {
96 let ids_data = non_continuous_ids_data![("x", 0)];
97
98 let mut vm = vm!();
99 vm.run_context.fp = 0;
100
101 vm.segments = segments![((1, 0), x_d0), ((1, 1), x_d1), ((1, 2), x_d2)];
102
103 let mut exec_scopes = scope![];
104 assert!(run_hint!(
105 vm,
106 ids_data,
107 hint_code::IS_ZERO_PACK_ED25519,
108 &mut exec_scopes
109 )
110 .is_ok());
111
112 check_scope!(
113 &exec_scopes,
114 [("x", expected), ("SECP_P", SECP_P_V2.clone())]
115 );
116 }
117
118 fn assert_reduce_ed25519_equals(x_d0: i128, x_d1: i128, x_d2: i128, expected: BigInt) {
119 let ids_data = non_continuous_ids_data![("x", 0)];
120
121 let mut vm = vm!();
122 vm.run_context.fp = 0;
123
124 vm.segments = segments![((1, 0), x_d0), ((1, 1), x_d1), ((1, 2), x_d2)];
125
126 let mut exec_scopes = scope![];
127
128 assert!(run_hint!(vm, ids_data, hint_code::REDUCE_ED25519, &mut exec_scopes).is_ok());
129
130 check_scope!(
131 &exec_scopes,
132 [("value", expected), ("SECP_P", SECP_P_V2.clone())]
133 );
134 }
135
136 #[test]
137 fn test_is_zero_pack_ed25519_with_zero() {
138 assert_is_zero_pack_ed25519_equals(0, 0, 0, BigInt::zero());
139 }
140
141 #[test]
142 fn test_is_zero_pack_ed25519_with_secp_prime_minus_one() {
143 assert_is_zero_pack_ed25519_equals(
144 SECP_P_D0 - 1,
145 SECP_P_D1,
146 SECP_P_D2,
147 SECP_P_V2.clone() - 1,
148 );
149 }
150
151 #[test]
152 fn test_is_zero_pack_ed25519_with_secp_prime() {
153 assert_is_zero_pack_ed25519_equals(SECP_P_D0, SECP_P_D1, SECP_P_D2, BigInt::zero());
154 }
155
156 #[test]
157 fn test_reduce_ed25519_with_zero() {
158 assert_reduce_ed25519_equals(0, 0, 0, BigInt::zero());
159 }
160
161 #[test]
162 fn test_reduce_ed25519_with_prime_minus_one() {
163 assert_reduce_ed25519_equals(SECP_P_D0 - 1, SECP_P_D1, SECP_P_D2, SECP_P_V2.clone() - 1);
164 }
165
166 #[test]
167 fn test_reduce_ed25519_with_prime() {
168 assert_reduce_ed25519_equals(SECP_P_D0, SECP_P_D1, SECP_P_D2, BigInt::zero());
169 }
170
171 #[test]
172 fn test_is_zero_assign_scope_vars_ed25519_with_one() {
173 let mut vm = vm!();
174 vm.run_context.fp = 0;
175
176 let mut exec_scopes = scope![("x", BigInt::one())];
177
178 assert!(run_hint!(
179 vm,
180 HashMap::default(),
181 hint_code::IS_ZERO_ASSIGN_SCOPE_VARS_ED25519,
182 &mut exec_scopes
183 )
184 .is_ok());
185
186 check_scope!(
187 &exec_scopes,
188 [
189 ("x_inv", BigInt::one()),
190 ("value", BigInt::one()),
191 ("SECP_P", SECP_P_V2.clone())
192 ]
193 );
194 }
195}