cairo_vm/hint_processor/builtin_hint_processor/
signature.rs1use crate::stdlib::{boxed::Box, collections::HashMap, prelude::*};
2
3use crate::{
4 hint_processor::{
5 builtin_hint_processor::hint_utils::{get_integer_from_var_name, get_ptr_from_var_name},
6 hint_processor_definition::HintReference,
7 },
8 serde::deserialize_program::ApTracking,
9 types::instance_definitions::ecdsa_instance_def::CELLS_PER_SIGNATURE,
10 vm::{
11 errors::{hint_errors::HintError, vm_errors::VirtualMachineError},
12 vm_core::VirtualMachine,
13 },
14};
15
16pub fn verify_ecdsa_signature(
17 vm: &mut VirtualMachine,
18 ids_data: &HashMap<String, HintReference>,
19 ap_tracking: &ApTracking,
20) -> Result<(), HintError> {
21 let signature_r = get_integer_from_var_name("signature_r", vm, ids_data, ap_tracking)?;
22 let signature_s = get_integer_from_var_name("signature_s", vm, ids_data, ap_tracking)?;
23 let ecdsa_ptr = get_ptr_from_var_name("ecdsa_ptr", vm, ids_data, ap_tracking)?;
24 let ecdsa_builtin = &mut vm.get_signature_builtin()?;
25 if ecdsa_ptr.segment_index != ecdsa_builtin.base() as isize {
26 return Err(HintError::AddSignatureWrongEcdsaPtr(Box::new(ecdsa_ptr)));
27 }
28 if !num_integer::Integer::is_multiple_of(&ecdsa_ptr.offset, &(CELLS_PER_SIGNATURE as usize)) {
29 return Err(HintError::AddSignatureNotAPublicKey(Box::new(ecdsa_ptr)));
30 }
31 ecdsa_builtin
32 .add_signature(ecdsa_ptr, &(signature_r, signature_s))
33 .map_err(VirtualMachineError::Memory)?;
34 Ok(())
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40
41 use crate::{
42 any_box,
43 hint_processor::{
44 builtin_hint_processor::{
45 builtin_hint_processor_definition::{BuiltinHintProcessor, HintProcessorData},
46 hint_code::VERIFY_ECDSA_SIGNATURE,
47 },
48 hint_processor_definition::HintProcessorLogic,
49 },
50 utils::test_utils::*,
51 vm::runners::builtin_runner::SignatureBuiltinRunner,
52 };
53 use assert_matches::assert_matches;
54
55 #[cfg(target_arch = "wasm32")]
56 use wasm_bindgen_test::*;
57
58 #[test]
59 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
60 fn verify_ecdsa_signature_valid() {
61 let mut vm = vm!();
62 vm.builtin_runners = vec![SignatureBuiltinRunner::new(Some(512), true).into()];
63 vm.segments = segments![
64 ((1, 0), (0, 0)),
65 (
66 (1, 1),
67 (
68 "3086480810278599376317923499561306189851900463386393948998357832163236918254",
69 10
70 )
71 ),
72 (
73 (1, 2),
74 (
75 "598673427589502599949712887611119751108407514580626464031881322743364689811",
76 10
77 )
78 )
79 ];
80 vm.run_context.fp = 3;
81 let ids_data = ids_data!["ecdsa_ptr", "signature_r", "signature_s"];
82 assert_matches!(run_hint!(vm, ids_data, VERIFY_ECDSA_SIGNATURE), Ok(()));
83 }
84
85 #[test]
86 fn verify_ecdsa_signature_invalid_ecdsa_ptr() {
87 let mut vm = vm!();
88 vm.builtin_runners = vec![SignatureBuiltinRunner::new(Some(512), true).into()];
89 vm.segments = segments![
90 ((1, 0), (3, 0)),
91 (
92 (1, 1),
93 (
94 "3086480810278599376317923499561306189851900463386393948998357832163236918254",
95 10
96 )
97 ),
98 (
99 (1, 2),
100 (
101 "598673427589502599949712887611119751108407514580626464031881322743364689811",
102 10
103 )
104 )
105 ];
106 vm.run_context.fp = 3;
107 let ids_data = ids_data!["ecdsa_ptr", "signature_r", "signature_s"];
108 assert_matches!(run_hint!(vm, ids_data, VERIFY_ECDSA_SIGNATURE), Err(HintError::AddSignatureWrongEcdsaPtr(bx)) if *bx == (3,0).into());
109 }
110
111 #[test]
112 fn verify_ecdsa_signature_invalid_input_cell() {
113 let mut vm = vm!();
114 vm.builtin_runners = vec![SignatureBuiltinRunner::new(Some(512), true).into()];
115 vm.segments = segments![
116 ((1, 0), (0, 3)),
117 (
118 (1, 1),
119 (
120 "3086480810278599376317923499561306189851900463386393948998357832163236918254",
121 10
122 )
123 ),
124 (
125 (1, 2),
126 (
127 "598673427589502599949712887611119751108407514580626464031881322743364689811",
128 10
129 )
130 )
131 ];
132 vm.run_context.fp = 3;
133 let ids_data = ids_data!["ecdsa_ptr", "signature_r", "signature_s"];
134 assert_matches!(run_hint!(vm, ids_data, VERIFY_ECDSA_SIGNATURE), Err(HintError::AddSignatureNotAPublicKey(bx)) if *bx == (0,3).into());
135 }
136}