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