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