1use crate::Algorithm;
3use crate::did::parse_did_key;
4use crate::error::{Error, Result};
5use ecdsa::der::{MaxOverhead, MaxSize};
6use ecdsa::elliptic_curve::{
7 AffinePoint, CurveArithmetic, FieldBytesSize, PrimeCurve,
8 generic_array::ArrayLength,
9 sec1::{FromEncodedPoint, ModulusSize, ToEncodedPoint},
10};
11use ecdsa::hazmat::{DigestPrimitive, VerifyPrimitive};
12use ecdsa::{SignatureSize, VerifyingKey};
13use k256::Secp256k1;
14use p256::NistP256;
15use std::ops::Add;
16
17pub fn verify_signature(did_key: &str, msg: &[u8], signature: &[u8]) -> Result<()> {
37 let (alg, public_key) = parse_did_key(did_key)?;
38 Verifier::default().verify(alg, &public_key, msg, signature)
39}
40
41#[derive(Debug, Default)]
49pub struct Verifier {
50 allow_malleable: bool,
51}
52
53impl Verifier {
54 pub fn new(allow_malleable: bool) -> Self {
56 Self { allow_malleable }
57 }
58 pub fn verify(
61 &self,
62 algorithm: Algorithm,
63 public_key: &[u8],
64 msg: &[u8],
65 signature: &[u8],
66 ) -> Result<()> {
67 match algorithm {
68 Algorithm::P256 => self.verify_inner::<NistP256>(public_key, msg, signature),
69 Algorithm::Secp256k1 => self.verify_inner::<Secp256k1>(public_key, msg, signature),
70 }
71 }
72 pub fn verify_inner<C>(&self, public_key: &[u8], msg: &[u8], bytes: &[u8]) -> Result<()>
75 where
76 C: PrimeCurve + CurveArithmetic + DigestPrimitive,
77 AffinePoint<C>: VerifyPrimitive<C> + FromEncodedPoint<C> + ToEncodedPoint<C>,
78 FieldBytesSize<C>: ModulusSize,
79 SignatureSize<C>: ArrayLength<u8>,
80 MaxSize<C>: ArrayLength<u8>,
81 <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
82 {
83 let verifying_key = VerifyingKey::<C>::from_sec1_bytes(public_key)?;
84 if let Ok(mut signature) = ecdsa::Signature::from_slice(bytes) {
85 if let Some(normalized) = signature.normalize_s() {
86 if !self.allow_malleable {
87 return Err(Error::LowSSignatureNotAllowed);
88 }
89 signature = normalized
90 }
91 Ok(ecdsa::signature::Verifier::verify(&verifying_key, msg, &signature)?)
92 }
93 else if self.allow_malleable {
95 let signature = ecdsa::der::Signature::from_bytes(bytes)?;
96 Ok(ecdsa::signature::Verifier::verify(&verifying_key, msg, &signature)?)
97 } else {
98 Err(Error::InvalidSignature)
99 }
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106 use multibase::Base;
107 use serde::{Deserialize, Serialize};
108 use std::{fs::File, path::PathBuf};
109
110 #[derive(Debug, Serialize, Deserialize)]
111 enum Algorithm {
112 ES256,
113 ES256K,
114 }
115
116 #[derive(Debug, Serialize, Deserialize)]
117 #[serde(rename_all = "camelCase")]
118 struct TestVector {
119 comment: String,
120 message_base64: String,
121 algorithm: Algorithm,
122 public_key_multibase: String,
123 public_key_did: String,
124 signature_base64: String,
125 valid_signature: bool,
126 tags: Vec<String>,
127 }
128
129 fn test_vectors(cond: Option<&str>) -> Vec<TestVector> {
130 let data_path =
131 PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/data/signature-fixtures.json");
132 let file = File::open(data_path).expect("opening test data should succeed");
133 let v = serde_json::from_reader::<_, Vec<TestVector>>(file)
134 .expect("parsing test data should succeed");
135 v.into_iter()
136 .filter(|v| if let Some(s) = cond { v.tags.contains(&s.to_string()) } else { true })
137 .collect()
138 }
139
140 #[test]
141 fn verify() {
142 let vectors = test_vectors(None);
143 assert!(!vectors.is_empty());
144 let verifier = Verifier::default();
145 for vector in vectors {
146 let message = Base::Base64
147 .decode(vector.message_base64)
148 .expect("decoding message should succeed");
149 let signature = Base::Base64
150 .decode(vector.signature_base64)
151 .expect("decoding signature should succeed");
152
153 let (base, decoded_key) = multibase::decode(vector.public_key_multibase)
154 .expect("decoding multibase public key should succeed");
155 assert_eq!(base, Base::Base58Btc);
156 let (alg, parsed_key) =
157 parse_did_key(&vector.public_key_did).expect("parsing DID key should succeed");
158
159 match vector.algorithm {
161 Algorithm::ES256 => assert_eq!(alg, crate::Algorithm::P256),
162 Algorithm::ES256K => assert_eq!(alg, crate::Algorithm::Secp256k1),
163 }
164 assert_eq!(
165 verifier.verify(alg, &decoded_key, &message, &signature).is_ok(),
166 vector.valid_signature
167 );
168 assert_eq!(
169 verifier.verify(alg, &parsed_key, &message, &signature).is_ok(),
170 vector.valid_signature
171 );
172 }
173 }
174
175 #[test]
176 fn verify_high_s() {
177 let vectors = test_vectors(Some("high-s"));
178 assert!(vectors.len() >= 2);
179 let verifier = Verifier::new(true);
180 for vector in vectors {
181 let message = Base::Base64
182 .decode(vector.message_base64)
183 .expect("decoding message should succeed");
184 let signature = Base::Base64
185 .decode(vector.signature_base64)
186 .expect("decoding signature should succeed");
187
188 let (base, decoded_key) = multibase::decode(vector.public_key_multibase)
189 .expect("decoding multibase public key should succeed");
190 assert_eq!(base, Base::Base58Btc);
191 let (alg, parsed_key) =
192 parse_did_key(&vector.public_key_did).expect("parsing DID key should succeed");
193
194 match vector.algorithm {
196 Algorithm::ES256 => assert_eq!(alg, crate::Algorithm::P256),
197 Algorithm::ES256K => assert_eq!(alg, crate::Algorithm::Secp256k1),
198 }
199 assert!(!vector.valid_signature);
200 assert!(verifier.verify(alg, &decoded_key, &message, &signature).is_ok());
201 assert!(verifier.verify(alg, &parsed_key, &message, &signature).is_ok());
202 }
203 }
204
205 #[test]
206 fn verify_der_encoded() {
207 let vectors = test_vectors(Some("der-encoded"));
208 assert!(vectors.len() >= 2);
209 let verifier = Verifier::new(true);
210 for vector in vectors {
211 let message = Base::Base64
212 .decode(vector.message_base64)
213 .expect("decoding message should succeed");
214 let signature = Base::Base64
215 .decode(vector.signature_base64)
216 .expect("decoding signature should succeed");
217
218 let (base, decoded_key) = multibase::decode(vector.public_key_multibase)
219 .expect("decoding multibase public key should succeed");
220 assert_eq!(base, Base::Base58Btc);
221 let (alg, parsed_key) =
222 parse_did_key(&vector.public_key_did).expect("parsing DID key should succeed");
223
224 match vector.algorithm {
226 Algorithm::ES256 => assert_eq!(alg, crate::Algorithm::P256),
227 Algorithm::ES256K => assert_eq!(alg, crate::Algorithm::Secp256k1),
228 }
229 assert!(!vector.valid_signature);
230 assert!(verifier.verify(alg, &decoded_key, &message, &signature).is_ok());
231 assert!(verifier.verify(alg, &parsed_key, &message, &signature).is_ok());
232 }
233 }
234}