1use ed25519_dalek::Signer;
4use sha2::{Digest, Sha256};
5use signature::SignatureEncoding;
6
7pub enum EdwardsVerifyingKey {
9 Ed25519(ed25519_dalek::VerifyingKey),
11 Ed448(ed448_goldilocks::VerifyingKey),
13}
14
15#[expect(clippy::large_enum_variant)]
17pub enum EdwardsSigningKey {
18 Ed25519(ed25519_dalek::SigningKey),
20 Ed448(ed448_goldilocks::SigningKey),
22}
23
24impl EdwardsVerifyingKey {
25 pub fn raw_key(&self) -> Vec<u8> {
27 match &self {
28 Self::Ed25519(key) => key.as_bytes().to_vec(),
29 Self::Ed448(key) => key.as_bytes().to_vec(),
30 }
31 }
32
33 pub fn verifies(&self, signature: &[u8], message: &[u8]) -> bool {
35 match &self {
36 Self::Ed25519(key) => {
37 let Ok(signature) = ed25519_dalek::Signature::from_slice(signature) else {
38 return false;
39 };
40 key.verify_strict(message, &signature).is_ok()
41 }
42
43 Self::Ed448(key) => {
44 let Ok(signature) = ed448_goldilocks::Signature::from_slice(signature) else {
45 return false;
46 };
47 key.verify_raw(&signature, message).is_ok()
48 }
49 }
50 }
51
52 pub fn from_raw_key(raw_key: &[u8]) -> Option<Self> {
54 match raw_key.len() {
55 ed25519_dalek::PUBLIC_KEY_LENGTH => {
56 #[allow(clippy::missing_panics_doc)]
57 let raw_key: &[u8; ed25519_dalek::PUBLIC_KEY_LENGTH] = raw_key
58 .try_into()
59 .expect("<&[u8;T]>::try_from(&[u8]) should succeed if <&[u8]>::len() == T");
60 let key = ed25519_dalek::VerifyingKey::from_bytes(raw_key).ok()?;
61 Some(Self::Ed25519(key))
62 }
63 ed448_goldilocks::PUBLIC_KEY_LENGTH => {
64 #[allow(clippy::missing_panics_doc)]
65 let raw_key: &[u8; ed448_goldilocks::PUBLIC_KEY_LENGTH] = raw_key
66 .try_into()
67 .expect("<&[u8;T]>::try_from(&[u8]) should succeed if <&[u8]>::len() == T");
68 let key = ed448_goldilocks::VerifyingKey::from_bytes(raw_key).ok()?;
69 Some(Self::Ed448(key))
70 }
71 _ => None,
72 }
73 }
74
75 pub fn key_id(&self) -> Vec<u8> {
77 let key = self.raw_key();
78 let digest = Sha256::digest(key);
79 digest.to_vec()
80 }
81}
82
83impl EdwardsSigningKey {
84 pub fn sign(&self, message: &[u8]) -> Vec<u8> {
86 match &self {
87 Self::Ed25519(key) => key.sign(message).to_vec(),
88 Self::Ed448(key) => key.sign_raw(message).to_bytes().to_vec(),
89 }
90 }
91
92 pub fn verifying_key(&self) -> EdwardsVerifyingKey {
94 match &self {
95 Self::Ed25519(key) => EdwardsVerifyingKey::Ed25519(key.verifying_key()),
96 Self::Ed448(key) => EdwardsVerifyingKey::Ed448(key.verifying_key()),
97 }
98 }
99}