bundlr_sdk/signers/
ed25519.rs

1use std::array::TryFromSliceError;
2
3use crate::error::BundlrError;
4use crate::index::SignerMap;
5use crate::Signer as SignerTrait;
6use crate::Verifier as VerifierTrait;
7
8use bytes::Bytes;
9use ed25519_dalek::{Keypair, Signer, Verifier, PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH};
10
11pub struct Ed25519Signer {
12    keypair: Keypair,
13}
14
15//TODO: add validation for secret keys
16impl Ed25519Signer {
17    pub fn new(keypair: Keypair) -> Ed25519Signer {
18        Ed25519Signer { keypair }
19    }
20
21    pub fn from_base58(s: &str) -> Result<Self, BundlrError> {
22        let k = bs58::decode(s)
23            .into_vec()
24            .map_err(|err| BundlrError::ParseError(err.to_string()))?;
25        let key: &[u8; 64] = k
26            .as_slice()
27            .try_into()
28            .map_err(|err: TryFromSliceError| BundlrError::ParseError(err.to_string()))?;
29
30        Ok(Self {
31            keypair: Keypair::from_bytes(key).map_err(BundlrError::ED25519Error)?,
32        })
33    }
34}
35
36const SIG_TYPE: SignerMap = SignerMap::ED25519;
37const SIG_LENGTH: u16 = SIGNATURE_LENGTH as u16;
38const PUB_LENGTH: u16 = PUBLIC_KEY_LENGTH as u16;
39
40impl SignerTrait for Ed25519Signer {
41    fn sign(&self, message: bytes::Bytes) -> Result<bytes::Bytes, crate::error::BundlrError> {
42        Ok(Bytes::copy_from_slice(
43            &self.keypair.sign(&message).to_bytes(),
44        ))
45    }
46
47    fn pub_key(&self) -> bytes::Bytes {
48        Bytes::copy_from_slice(&self.keypair.public.to_bytes())
49    }
50
51    fn sig_type(&self) -> SignerMap {
52        SIG_TYPE
53    }
54    fn get_sig_length(&self) -> u16 {
55        SIG_LENGTH
56    }
57    fn get_pub_length(&self) -> u16 {
58        PUB_LENGTH
59    }
60}
61
62impl VerifierTrait for Ed25519Signer {
63    fn verify(
64        pk: Bytes,
65        message: Bytes,
66        signature: Bytes,
67    ) -> Result<(), crate::error::BundlrError> {
68        let public_key =
69            ed25519_dalek::PublicKey::from_bytes(&pk).map_err(BundlrError::ED25519Error)?;
70        let sig =
71            ed25519_dalek::Signature::from_bytes(&signature).map_err(BundlrError::ED25519Error)?;
72        public_key
73            .verify(&message, &sig)
74            .map_err(|_| BundlrError::InvalidSignature)
75    }
76}
77
78#[cfg(test)]
79mod tests {
80    use crate::{Ed25519Signer, Signer, Verifier};
81    use bytes::Bytes;
82    use ed25519_dalek::Keypair;
83
84    #[test]
85    fn should_sign_and_verify() {
86        let msg = Bytes::from(b"Message".to_vec());
87
88        let base58_secret_key = "kNykCXNxgePDjFbDWjPNvXQRa8U12Ywc19dFVaQ7tebUj3m7H4sF4KKdJwM7yxxb3rqxchdjezX9Szh8bLcQAjb";
89        let signer = Ed25519Signer::from_base58(base58_secret_key).unwrap();
90        let sig = signer.sign(msg.clone()).unwrap();
91        let pub_key = signer.pub_key();
92        println!("{:?}", pub_key.to_vec());
93        assert!(Ed25519Signer::verify(pub_key, msg.clone(), sig).is_ok());
94
95        let keypair = Keypair::from_bytes(&[
96            237, 158, 92, 107, 132, 192, 1, 57, 8, 20, 213, 108, 29, 227, 37, 8, 3, 105, 196, 244,
97            8, 221, 184, 199, 62, 253, 98, 131, 33, 165, 165, 215, 14, 7, 46, 23, 221, 242, 240,
98            226, 94, 79, 161, 31, 192, 163, 13, 25, 106, 53, 34, 215, 83, 124, 162, 156, 8, 97,
99            194, 180, 213, 179, 33, 68,
100        ])
101        .unwrap();
102        let signer = Ed25519Signer::new(keypair);
103        let sig = signer.sign(msg.clone()).unwrap();
104        let pub_key = signer.pub_key();
105
106        assert!(Ed25519Signer::verify(pub_key, msg, sig).is_ok());
107    }
108}