snarkvm_console_account/signature/
verify.rs1use super::*;
17
18impl<N: Network> Signature<N> {
19 pub fn verify(&self, address: &Address<N>, message: &[Field<N>]) -> bool {
22 if message.len() > N::MAX_DATA_SIZE_IN_FIELDS as usize {
24 eprintln!("Cannot sign the signature: the signed message exceeds maximum allowed size");
25 return false;
26 }
27
28 let pk_sig = self.compute_key.pk_sig();
30 let pr_sig = self.compute_key.pr_sig();
32
33 let g_r = N::g_scalar_multiply(&self.response) + (pk_sig * self.challenge);
35
36 let mut preimage = Vec::with_capacity(4 + message.len());
38 preimage.extend([g_r, pk_sig, pr_sig, **address].map(|point| point.to_x_coordinate()));
39 preimage.extend(message);
40
41 let candidate_challenge = match N::hash_to_scalar_psd8(&preimage) {
43 Ok(candidate_challenge) => candidate_challenge,
45 Err(_) => return false,
47 };
48
49 let candidate_address = match Address::try_from(self.compute_key) {
51 Ok(candidate_address) => candidate_address,
53 Err(_) => return false,
55 };
56
57 self.challenge == candidate_challenge && *address == candidate_address
59 }
60
61 pub fn verify_bytes(&self, address: &Address<N>, message: &[u8]) -> bool {
63 self.verify_bits(address, &message.to_bits_le())
65 }
66
67 pub fn verify_bits(&self, address: &Address<N>, message: &[bool]) -> bool {
69 match message.chunks(Field::<N>::size_in_data_bits()).map(Field::from_bits_le).collect::<Result<Vec<_>>>() {
71 Ok(fields) => self.verify(address, &fields),
72 Err(error) => {
73 eprintln!("Failed to verify signature: {error}");
74 false
75 }
76 }
77 }
78}
79
80#[cfg(test)]
81#[cfg(feature = "private_key")]
82mod tests {
83 use super::*;
84 use snarkvm_console_network::MainnetV0;
85
86 type CurrentNetwork = MainnetV0;
87
88 const ITERATIONS: u64 = 100;
89
90 #[test]
91 fn test_sign_and_verify() -> Result<()> {
92 let rng = &mut TestRng::default();
93
94 for i in 0..ITERATIONS {
95 let private_key = PrivateKey::<CurrentNetwork>::new(rng)?;
97 let address = Address::try_from(&private_key)?;
98
99 let message: Vec<_> = (0..i).map(|_| Uniform::rand(rng)).collect();
101 let signature = Signature::sign(&private_key, &message, rng)?;
102 assert!(signature.verify(&address, &message));
103
104 let failure_message: Vec<_> = (0..i).map(|_| Uniform::rand(rng)).collect();
106 if message != failure_message {
107 assert!(!signature.verify(&address, &failure_message));
108 }
109 }
110 Ok(())
111 }
112
113 #[test]
114 fn test_sign_and_verify_bytes() -> Result<()> {
115 let rng = &mut TestRng::default();
116
117 for i in 0..ITERATIONS {
118 let private_key = PrivateKey::<CurrentNetwork>::new(rng)?;
120 let address = Address::try_from(&private_key)?;
121
122 let message: Vec<_> = (0..i).map(|_| Uniform::rand(rng)).collect();
124 let signature = Signature::sign_bytes(&private_key, &message, rng)?;
125 assert!(signature.verify_bytes(&address, &message));
126
127 let failure_message: Vec<_> = (0..i).map(|_| Uniform::rand(rng)).collect();
129 if message != failure_message {
130 assert!(!signature.verify_bytes(&address, &failure_message));
131 }
132 }
133 Ok(())
134 }
135
136 #[test]
137 fn test_sign_and_verify_bits() -> Result<()> {
138 let rng = &mut TestRng::default();
139
140 for i in 0..ITERATIONS {
141 let private_key = PrivateKey::<CurrentNetwork>::new(rng)?;
143 let address = Address::try_from(&private_key)?;
144
145 let message: Vec<_> = (0..i).map(|_| Uniform::rand(rng)).collect();
147 let signature = Signature::sign_bits(&private_key, &message, rng)?;
148 assert!(signature.verify_bits(&address, &message));
149
150 let failure_message: Vec<_> = (0..i).map(|_| Uniform::rand(rng)).collect();
152 if message != failure_message {
153 assert!(!signature.verify_bits(&address, &failure_message));
154 }
155 }
156 Ok(())
157 }
158}