1use std::collections::HashMap;
4
5use serde::{Deserialize, Serialize};
6
7use crate::hash::impl_domain_separator;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
11pub struct KeyAlgId(u8);
12
13impl KeyAlgId {
14 pub const K256: Self = Self(1);
16 pub const P256: Self = Self(2);
18
19 pub const fn new(id: u8) -> Self {
29 assert!(id >= 128, "key algorithm id range 0-127 is reserved");
30
31 Self(id)
32 }
33
34 pub const fn as_u8(&self) -> u8 {
36 self.0
37 }
38}
39
40impl std::fmt::Display for KeyAlgId {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 match *self {
43 KeyAlgId::K256 => write!(f, "k256"),
44 KeyAlgId::P256 => write!(f, "p256"),
45 _ => write!(f, "custom({:02x})", self.0),
46 }
47 }
48}
49
50#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
52pub struct SignatureAlgId(u8);
53
54impl SignatureAlgId {
55 pub const SECP256K1: Self = Self(1);
57 pub const SECP256R1: Self = Self(2);
59 pub const SECP256K1ETH: Self = Self(3);
64
65 pub const fn new(id: u8) -> Self {
75 assert!(id >= 128, "signature algorithm id range 0-127 is reserved");
76
77 Self(id)
78 }
79
80 pub const fn as_u8(&self) -> u8 {
82 self.0
83 }
84}
85
86impl std::fmt::Display for SignatureAlgId {
87 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88 match *self {
89 SignatureAlgId::SECP256K1 => write!(f, "secp256k1"),
90 SignatureAlgId::SECP256R1 => write!(f, "secp256r1"),
91 SignatureAlgId::SECP256K1ETH => write!(f, "secp256k1eth"),
92 _ => write!(f, "custom({:02x})", self.0),
93 }
94 }
95}
96
97#[derive(Debug, thiserror::Error)]
99#[error("unknown signature algorithm id: {0:?}")]
100pub struct UnknownSignatureAlgId(SignatureAlgId);
101
102#[derive(Default)]
104pub struct SignerProvider {
105 signers: HashMap<SignatureAlgId, Box<dyn Signer + Send + Sync>>,
106}
107
108impl SignerProvider {
109 pub fn supported_algs(&self) -> impl Iterator<Item = SignatureAlgId> + '_ {
111 self.signers.keys().copied()
112 }
113
114 pub fn set_signer(&mut self, signer: Box<dyn Signer + Send + Sync>) {
116 self.signers.insert(signer.alg_id(), signer);
117 }
118
119 pub fn set_secp256k1(&mut self, key: &[u8]) -> Result<&mut Self, SignerError> {
121 self.set_signer(Box::new(Secp256k1Signer::new(key)?));
122
123 Ok(self)
124 }
125
126 pub fn set_secp256r1(&mut self, key: &[u8]) -> Result<&mut Self, SignerError> {
128 self.set_signer(Box::new(Secp256r1Signer::new(key)?));
129
130 Ok(self)
131 }
132
133 pub fn set_secp256k1eth(&mut self, key: &[u8]) -> Result<&mut Self, SignerError> {
135 self.set_signer(Box::new(Secp256k1EthSigner::new(key)?));
136
137 Ok(self)
138 }
139
140 pub(crate) fn get(
142 &self,
143 alg: &SignatureAlgId,
144 ) -> Result<&(dyn Signer + Send + Sync), UnknownSignatureAlgId> {
145 self.signers
146 .get(alg)
147 .map(|s| &**s)
148 .ok_or(UnknownSignatureAlgId(*alg))
149 }
150}
151
152#[derive(Debug, thiserror::Error)]
154#[error("signer error: {0}")]
155pub struct SignerError(String);
156
157pub trait Signer {
159 fn alg_id(&self) -> SignatureAlgId;
161
162 fn sign(&self, msg: &[u8]) -> Result<Signature, SignatureError>;
164
165 fn verifying_key(&self) -> VerifyingKey;
167}
168
169pub struct SignatureVerifierProvider {
171 verifiers: HashMap<SignatureAlgId, Box<dyn SignatureVerifier + Send + Sync>>,
172}
173
174impl Default for SignatureVerifierProvider {
175 fn default() -> Self {
176 let mut verifiers = HashMap::new();
177
178 verifiers.insert(SignatureAlgId::SECP256K1, Box::new(Secp256k1Verifier) as _);
179 verifiers.insert(SignatureAlgId::SECP256R1, Box::new(Secp256r1Verifier) as _);
180 verifiers.insert(
181 SignatureAlgId::SECP256K1ETH,
182 Box::new(Secp256k1EthVerifier) as _,
183 );
184
185 Self { verifiers }
186 }
187}
188
189impl SignatureVerifierProvider {
190 pub fn set_verifier(&mut self, verifier: Box<dyn SignatureVerifier + Send + Sync>) {
192 self.verifiers.insert(verifier.alg_id(), verifier);
193 }
194
195 pub(crate) fn get(
197 &self,
198 alg: &SignatureAlgId,
199 ) -> Result<&(dyn SignatureVerifier + Send + Sync), UnknownSignatureAlgId> {
200 self.verifiers
201 .get(alg)
202 .map(|s| &**s)
203 .ok_or(UnknownSignatureAlgId(*alg))
204 }
205}
206
207pub trait SignatureVerifier {
209 fn alg_id(&self) -> SignatureAlgId;
211
212 fn verify(&self, key: &VerifyingKey, msg: &[u8], sig: &[u8]) -> Result<(), SignatureError>;
214}
215
216#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
218pub struct VerifyingKey {
219 pub alg: KeyAlgId,
221 pub data: Vec<u8>,
223}
224
225impl_domain_separator!(VerifyingKey);
226
227#[derive(Debug, thiserror::Error)]
229#[error("signature verification failed: {0}")]
230pub struct SignatureError(String);
231
232#[derive(Debug, Clone, Deserialize, Serialize)]
234pub struct Signature {
235 pub alg: SignatureAlgId,
237 pub data: Vec<u8>,
239}
240
241mod secp256k1 {
242 use std::sync::{Arc, Mutex};
243
244 use k256::ecdsa::{
245 signature::{SignerMut, Verifier},
246 Signature as Secp256K1Signature, SigningKey,
247 };
248
249 use super::*;
250
251 pub struct Secp256k1Signer(Arc<Mutex<SigningKey>>);
253
254 impl Secp256k1Signer {
255 pub fn new(key: &[u8]) -> Result<Self, SignerError> {
257 SigningKey::from_slice(key)
258 .map(|key| Self(Arc::new(Mutex::new(key))))
259 .map_err(|_| SignerError("invalid key".to_string()))
260 }
261 }
262
263 impl Signer for Secp256k1Signer {
264 fn alg_id(&self) -> SignatureAlgId {
265 SignatureAlgId::SECP256K1
266 }
267
268 fn sign(&self, msg: &[u8]) -> Result<Signature, SignatureError> {
269 let sig: Secp256K1Signature = self.0.lock().unwrap().sign(msg);
270
271 Ok(Signature {
272 alg: SignatureAlgId::SECP256K1,
273 data: sig.to_vec(),
274 })
275 }
276
277 fn verifying_key(&self) -> VerifyingKey {
278 let key = self.0.lock().unwrap().verifying_key().to_sec1_bytes();
279
280 VerifyingKey {
281 alg: KeyAlgId::K256,
282 data: key.to_vec(),
283 }
284 }
285 }
286
287 pub struct Secp256k1Verifier;
289
290 impl SignatureVerifier for Secp256k1Verifier {
291 fn alg_id(&self) -> SignatureAlgId {
292 SignatureAlgId::SECP256K1
293 }
294
295 fn verify(&self, key: &VerifyingKey, msg: &[u8], sig: &[u8]) -> Result<(), SignatureError> {
296 if key.alg != KeyAlgId::K256 {
297 return Err(SignatureError("key algorithm is not k256".to_string()));
298 }
299
300 let key = k256::ecdsa::VerifyingKey::from_sec1_bytes(&key.data)
301 .map_err(|_| SignatureError("invalid k256 key".to_string()))?;
302
303 let sig = Secp256K1Signature::from_slice(sig)
304 .map_err(|_| SignatureError("invalid secp256k1 signature".to_string()))?;
305
306 key.verify(msg, &sig).map_err(|_| {
307 SignatureError("secp256k1 signature verification failed".to_string())
308 })?;
309
310 Ok(())
311 }
312 }
313}
314
315pub use secp256k1::{Secp256k1Signer, Secp256k1Verifier};
316
317mod secp256r1 {
318 use std::sync::{Arc, Mutex};
319
320 use p256::ecdsa::{
321 signature::{SignerMut, Verifier},
322 Signature as Secp256R1Signature, SigningKey,
323 };
324
325 use super::*;
326
327 pub struct Secp256r1Signer(Arc<Mutex<SigningKey>>);
329
330 impl Secp256r1Signer {
331 pub fn new(key: &[u8]) -> Result<Self, SignerError> {
333 SigningKey::from_slice(key)
334 .map(|key| Self(Arc::new(Mutex::new(key))))
335 .map_err(|_| SignerError("invalid key".to_string()))
336 }
337 }
338
339 impl Signer for Secp256r1Signer {
340 fn alg_id(&self) -> SignatureAlgId {
341 SignatureAlgId::SECP256R1
342 }
343
344 fn sign(&self, msg: &[u8]) -> Result<Signature, SignatureError> {
345 let sig: Secp256R1Signature = self.0.lock().unwrap().sign(msg);
346
347 Ok(Signature {
348 alg: SignatureAlgId::SECP256R1,
349 data: sig.to_vec(),
350 })
351 }
352
353 fn verifying_key(&self) -> VerifyingKey {
354 let key = self.0.lock().unwrap().verifying_key().to_sec1_bytes();
355
356 VerifyingKey {
357 alg: KeyAlgId::P256,
358 data: key.to_vec(),
359 }
360 }
361 }
362
363 pub struct Secp256r1Verifier;
365
366 impl SignatureVerifier for Secp256r1Verifier {
367 fn alg_id(&self) -> SignatureAlgId {
368 SignatureAlgId::SECP256R1
369 }
370
371 fn verify(&self, key: &VerifyingKey, msg: &[u8], sig: &[u8]) -> Result<(), SignatureError> {
372 if key.alg != KeyAlgId::P256 {
373 return Err(SignatureError("key algorithm is not p256".to_string()));
374 }
375
376 let key = p256::ecdsa::VerifyingKey::from_sec1_bytes(&key.data)
377 .map_err(|_| SignatureError("invalid p256 key".to_string()))?;
378
379 let sig = Secp256R1Signature::from_slice(sig)
380 .map_err(|_| SignatureError("invalid secp256r1 signature".to_string()))?;
381
382 key.verify(msg, &sig).map_err(|_| {
383 SignatureError("secp256r1 signature verification failed".to_string())
384 })?;
385
386 Ok(())
387 }
388 }
389}
390
391pub use secp256r1::{Secp256r1Signer, Secp256r1Verifier};
392
393mod secp256k1eth {
394 use std::sync::{Arc, Mutex};
395
396 use k256::ecdsa::{
397 signature::hazmat::PrehashVerifier, Signature as Secp256K1Signature, SigningKey,
398 };
399 use tiny_keccak::{Hasher, Keccak};
400
401 use super::*;
402
403 pub struct Secp256k1EthSigner(Arc<Mutex<SigningKey>>);
405
406 impl Secp256k1EthSigner {
407 pub fn new(key: &[u8]) -> Result<Self, SignerError> {
409 SigningKey::from_slice(key)
410 .map(|key| Self(Arc::new(Mutex::new(key))))
411 .map_err(|_| SignerError("invalid key".to_string()))
412 }
413 }
414
415 impl Signer for Secp256k1EthSigner {
416 fn alg_id(&self) -> SignatureAlgId {
417 SignatureAlgId::SECP256K1ETH
418 }
419
420 fn sign(&self, msg: &[u8]) -> Result<Signature, SignatureError> {
421 let mut hasher = Keccak::v256();
423 hasher.update(msg);
424 let mut output = vec![0; 32];
425 hasher.finalize(&mut output);
426
427 let (signature, recid) = self
428 .0
429 .lock()
430 .unwrap()
431 .sign_prehash_recoverable(&output)
432 .map_err(|_| SignatureError("error in sign_prehash_recoverable".to_string()))?;
433
434 let mut sig = signature.to_vec();
435 let recid = recid.to_byte();
436
437 if recid > 1 {
439 return Err(SignatureError(format!(
440 "expected recovery id 0 or 1, got {:?}",
441 recid
442 )));
443 }
444 sig.push(recid + 27);
446
447 Ok(Signature {
448 alg: SignatureAlgId::SECP256K1ETH,
449 data: sig,
450 })
451 }
452
453 fn verifying_key(&self) -> VerifyingKey {
454 let key = self.0.lock().unwrap().verifying_key().to_sec1_bytes();
455
456 VerifyingKey {
457 alg: KeyAlgId::K256,
458 data: key.to_vec(),
459 }
460 }
461 }
462
463 pub struct Secp256k1EthVerifier;
465
466 impl SignatureVerifier for Secp256k1EthVerifier {
467 fn alg_id(&self) -> SignatureAlgId {
468 SignatureAlgId::SECP256K1ETH
469 }
470
471 fn verify(&self, key: &VerifyingKey, msg: &[u8], sig: &[u8]) -> Result<(), SignatureError> {
472 if key.alg != KeyAlgId::K256 {
473 return Err(SignatureError("key algorithm is not k256".to_string()));
474 }
475
476 if sig.len() != 65 {
477 return Err(SignatureError(
478 "ethereum signature length must be 65 bytes".to_string(),
479 ));
480 }
481
482 let key = k256::ecdsa::VerifyingKey::from_sec1_bytes(&key.data)
483 .map_err(|_| SignatureError("invalid k256 key".to_string()))?;
484
485 let sig = Secp256K1Signature::from_slice(&sig[..64])
488 .map_err(|_| SignatureError("invalid secp256k1 signature".to_string()))?;
489
490 let mut hasher = Keccak::v256();
492 hasher.update(msg);
493 let mut output = vec![0; 32];
494 hasher.finalize(&mut output);
495
496 key.verify_prehash(&output, &sig).map_err(|_| {
497 SignatureError("secp256k1 signature verification failed".to_string())
498 })?;
499
500 Ok(())
501 }
502 }
503}
504
505pub use secp256k1eth::{Secp256k1EthSigner, Secp256k1EthVerifier};
506
507#[cfg(test)]
508mod test {
509 use alloy_primitives::utils::eip191_message;
510 use alloy_signer::SignerSync;
511 use alloy_signer_local::PrivateKeySigner;
512 use rand06_compat::Rand0_6CompatExt;
513 use rstest::{fixture, rstest};
514
515 use super::*;
516
517 #[fixture]
518 #[once]
519 fn secp256k1_pair() -> (Box<dyn Signer>, Box<dyn SignatureVerifier>) {
520 let signing_key = k256::ecdsa::SigningKey::random(&mut rand::rng().compat());
521 (
522 Box::new(Secp256k1Signer::new(&signing_key.to_bytes()).unwrap()),
523 Box::new(Secp256k1Verifier {}),
524 )
525 }
526
527 #[fixture]
528 #[once]
529 fn secp256r1_pair() -> (Box<dyn Signer>, Box<dyn SignatureVerifier>) {
530 let signing_key = p256::ecdsa::SigningKey::random(&mut rand::rng().compat());
531 (
532 Box::new(Secp256r1Signer::new(&signing_key.to_bytes()).unwrap()),
533 Box::new(Secp256r1Verifier {}),
534 )
535 }
536
537 #[fixture]
538 #[once]
539 fn secp256k1eth_pair() -> (Box<dyn Signer>, Box<dyn SignatureVerifier>) {
540 let signing_key = k256::ecdsa::SigningKey::random(&mut rand::rng().compat());
541 (
542 Box::new(Secp256k1EthSigner::new(&signing_key.to_bytes()).unwrap()),
543 Box::new(Secp256k1EthVerifier {}),
544 )
545 }
546
547 #[rstest]
548 #[case::r1(secp256r1_pair(), SignatureAlgId::SECP256R1)]
549 #[case::k1(secp256k1_pair(), SignatureAlgId::SECP256K1)]
550 #[case::k1eth(secp256k1eth_pair(), SignatureAlgId::SECP256K1ETH)]
551 fn test_success(
552 #[case] pair: (Box<dyn Signer>, Box<dyn SignatureVerifier>),
553 #[case] alg: SignatureAlgId,
554 ) {
555 let (signer, verifier) = pair;
556 assert_eq!(signer.alg_id(), alg);
557
558 let msg = "test payload";
559 let signature = signer.sign(msg.as_bytes()).unwrap();
560 let verifying_key = signer.verifying_key();
561
562 assert_eq!(verifier.alg_id(), alg);
563 let result = verifier.verify(&verifying_key, msg.as_bytes(), &signature.data);
564 assert!(result.is_ok());
565 }
566
567 #[rstest]
568 #[case::r1(secp256r1_pair())]
569 #[case::k1eth(secp256k1eth_pair())]
570 fn test_wrong_signer(#[case] pair: (Box<dyn Signer>, Box<dyn SignatureVerifier>)) {
571 let (signer, _) = pair;
572
573 let msg = "test payload";
574 let signature = signer.sign(msg.as_bytes()).unwrap();
575 let verifying_key = signer.verifying_key();
576
577 let verifier = Secp256k1Verifier {};
578 let result = verifier.verify(&verifying_key, msg.as_bytes(), &signature.data);
579 assert!(result.is_err());
580 }
581
582 #[rstest]
583 #[case::corrupted_signature_r1(secp256r1_pair(), true, false)]
584 #[case::corrupted_signature_k1(secp256k1_pair(), true, false)]
585 #[case::corrupted_signature_k1eth(secp256k1eth_pair(), true, false)]
586 #[case::wrong_signature_r1(secp256r1_pair(), false, true)]
587 #[case::wrong_signature_k1(secp256k1_pair(), false, true)]
588 #[case::wrong_signature_k1eth(secp256k1eth_pair(), false, true)]
589 fn test_failure(
590 #[case] pair: (Box<dyn Signer>, Box<dyn SignatureVerifier>),
591 #[case] corrupted_signature: bool,
592 #[case] wrong_signature: bool,
593 ) {
594 let (signer, verifier) = pair;
595
596 let msg = "test payload";
597 let mut signature = signer.sign(msg.as_bytes()).unwrap();
598 let verifying_key = signer.verifying_key();
599
600 if corrupted_signature {
601 signature.data.push(0);
602 }
603
604 if wrong_signature {
605 signature = signer.sign("different payload".as_bytes()).unwrap();
606 }
607
608 let result = verifier.verify(&verifying_key, msg.as_bytes(), &signature.data);
609 assert!(result.is_err());
610 }
611
612 #[test]
613 fn test_secp256k1eth_sig() {
615 let sk = vec![1; 32];
617 let mut msg = "test message".as_bytes().to_vec();
618
619 let signer: Secp256k1EthSigner = Secp256k1EthSigner::new(&sk).unwrap();
620
621 for i in 0..10 {
623 msg.push(i);
624 let sig = signer.sign(&eip191_message(&msg)).unwrap().data;
626
627 assert_eq!(sig, reference_eth_signature(&sk, &msg));
628 }
629 }
630
631 fn reference_eth_signature(sk: &[u8], msg: &[u8]) -> Vec<u8> {
633 let signer = PrivateKeySigner::from_slice(sk).unwrap();
634 signer.sign_message_sync(msg).unwrap().as_bytes().to_vec()
635 }
636}