bundlr_sdk/signers/
aptos.rs

1use crate::error::BundlrError;
2use crate::Signer as SignerTrait;
3use crate::Verifier as VerifierTrait;
4use crate::{index::SignerMap, Ed25519Signer};
5
6use bytes::Bytes;
7use ed25519_dalek::{Keypair, Verifier, PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH};
8use num::Integer;
9
10pub struct AptosSigner {
11    signer: Ed25519Signer,
12}
13
14impl AptosSigner {
15    pub fn new(keypair: Keypair) -> Self {
16        Self {
17            signer: Ed25519Signer::new(keypair),
18        }
19    }
20
21    pub fn from_base58(s: &str) -> Result<Self, BundlrError> {
22        Ok(Self {
23            signer: Ed25519Signer::from_base58(s)?,
24        })
25    }
26}
27
28const SIG_TYPE: SignerMap = SignerMap::InjectedAptos;
29const SIG_LENGTH: u16 = SIGNATURE_LENGTH as u16;
30const PUB_LENGTH: u16 = PUBLIC_KEY_LENGTH as u16;
31
32impl SignerTrait for AptosSigner {
33    fn sign(&self, message: bytes::Bytes) -> Result<bytes::Bytes, crate::error::BundlrError> {
34        let aptos_message =
35            Bytes::copy_from_slice(&[b"APTOS\nmessage: ".as_ref(), &message[..]].concat());
36        let nonce = Bytes::from(b"\nnonce: bundlr".to_vec());
37        let full_msg = Bytes::from([aptos_message, nonce].concat());
38        self.signer.sign(full_msg)
39    }
40
41    fn pub_key(&self) -> bytes::Bytes {
42        self.signer.pub_key()
43    }
44
45    fn sig_type(&self) -> SignerMap {
46        SIG_TYPE
47    }
48    fn get_sig_length(&self) -> u16 {
49        SIG_LENGTH
50    }
51    fn get_pub_length(&self) -> u16 {
52        PUB_LENGTH
53    }
54}
55
56impl VerifierTrait for AptosSigner {
57    fn verify(
58        pk: Bytes,
59        message: Bytes,
60        signature: Bytes,
61    ) -> Result<(), crate::error::BundlrError> {
62        let public_key =
63            ed25519_dalek::PublicKey::from_bytes(&pk).map_err(BundlrError::ED25519Error)?;
64        let sig =
65            ed25519_dalek::Signature::from_bytes(&signature).map_err(BundlrError::ED25519Error)?;
66        let aptos_message =
67            Bytes::copy_from_slice(&[b"APTOS\nmessage: ".as_ref(), &message[..]].concat());
68        let nonce = Bytes::from(b"\nnonce: bundlr".to_vec());
69        let full_msg = Bytes::from([aptos_message, nonce].concat());
70
71        public_key
72            .verify(&full_msg, &sig)
73            .map_err(|_err| BundlrError::InvalidSignature)
74    }
75}
76
77const SIG_TYPE_M: SignerMap = SignerMap::MultiAptos;
78const SIG_LENGTH_M: u16 = (SIGNATURE_LENGTH * 32 + 4) as u16; // max 32 64 byte signatures, +4 for 32-bit bitmap
79const PUB_LENGTH_M: u16 = (PUBLIC_KEY_LENGTH * 32 + 1) as u16; // max 64 32 byte keys, +1 for 8-bit threshold value
80
81pub struct MultiAptosSigner {
82    signer: Ed25519Signer,
83}
84
85impl MultiAptosSigner {
86    pub fn collect_signatures(
87        &self,
88        _eamessage: bytes::Bytes,
89    ) -> Result<(Vec<bytes::Bytes>, Vec<u64>), crate::error::BundlrError> {
90        //TODO: implement
91        todo!()
92    }
93}
94
95impl MultiAptosSigner {
96    pub fn new(keypair: Keypair) -> Self {
97        Self {
98            signer: Ed25519Signer::new(keypair),
99        }
100    }
101
102    pub fn from_base58(s: &str) -> Result<Self, BundlrError> {
103        Ok(Self {
104            signer: Ed25519Signer::from_base58(s)?,
105        })
106    }
107}
108
109impl SignerTrait for MultiAptosSigner {
110    fn sign(&self, message: bytes::Bytes) -> Result<bytes::Bytes, crate::error::BundlrError> {
111        //TODO: implement
112        let (_signatures, _bitmap) = self.collect_signatures(message)?;
113        todo!()
114    }
115
116    fn pub_key(&self) -> bytes::Bytes {
117        self.signer.pub_key()
118    }
119
120    fn sig_type(&self) -> SignerMap {
121        SIG_TYPE_M
122    }
123    fn get_sig_length(&self) -> u16 {
124        SIG_LENGTH_M
125    }
126    fn get_pub_length(&self) -> u16 {
127        PUB_LENGTH_M
128    }
129}
130
131impl VerifierTrait for MultiAptosSigner {
132    fn verify(
133        pk: Bytes,
134        message: Bytes,
135        signature: Bytes,
136    ) -> Result<(), crate::error::BundlrError> {
137        let sig_len = SIG_LENGTH_M;
138        let bitmap_pos = sig_len - 4;
139        let signatures = signature.slice(0..(bitmap_pos as usize));
140        let encode_bitmap = signature.slice((bitmap_pos as usize)..signature.len());
141
142        let mut one_false = false;
143        for i in 0..32 {
144            let bucket = i.div_floor(&8);
145            let bucket_pos = i - bucket * 8;
146            let sig_included = (encode_bitmap[bucket] & (128 >> bucket_pos)) != 0;
147
148            if sig_included {
149                let signature = signatures.slice((i * 64)..((i + 1) * 64));
150                let pub_key_slc = pk.slice((i * 32)..((i + 1) * 32));
151                let public_key = ed25519_dalek::PublicKey::from_bytes(&pub_key_slc)
152                    .map_err(BundlrError::ED25519Error)?;
153                let sig = ed25519_dalek::Signature::from_bytes(&signature)
154                    .map_err(BundlrError::ED25519Error)?;
155                match public_key.verify(&message, &sig) {
156                    Ok(()) => (),
157                    Err(_err) => one_false = false,
158                }
159            }
160        }
161
162        if one_false {
163            Err(BundlrError::InvalidSignature)
164        } else {
165            Ok(())
166        }
167    }
168}
169
170#[cfg(test)]
171mod tests {
172    use crate::{AptosSigner, Signer, Verifier};
173    use bytes::Bytes;
174    use ed25519_dalek::Keypair;
175
176    #[test]
177    fn should_sign_and_verify() {
178        let msg = Bytes::from(b"Message".to_vec());
179
180        let base58_secret_key = "kNykCXNxgePDjFbDWjPNvXQRa8U12Ywc19dFVaQ7tebUj3m7H4sF4KKdJwM7yxxb3rqxchdjezX9Szh8bLcQAjb";
181        let signer = AptosSigner::from_base58(base58_secret_key).unwrap();
182        let sig = signer.sign(msg.clone()).unwrap();
183        let pub_key = signer.pub_key();
184        println!("{:?}", pub_key.to_vec());
185        assert!(AptosSigner::verify(pub_key, msg.clone(), sig).is_ok());
186
187        let keypair = Keypair::from_bytes(&[
188            237, 158, 92, 107, 132, 192, 1, 57, 8, 20, 213, 108, 29, 227, 37, 8, 3, 105, 196, 244,
189            8, 221, 184, 199, 62, 253, 98, 131, 33, 165, 165, 215, 14, 7, 46, 23, 221, 242, 240,
190            226, 94, 79, 161, 31, 192, 163, 13, 25, 106, 53, 34, 215, 83, 124, 162, 156, 8, 97,
191            194, 180, 213, 179, 33, 68,
192        ])
193        .unwrap();
194        let signer = AptosSigner::new(keypair);
195        let sig = signer.sign(msg.clone()).unwrap();
196        let pub_key = signer.pub_key();
197
198        assert!(AptosSigner::verify(pub_key, msg, sig).is_ok());
199    }
200
201    #[test]
202    fn should_sign_and_verify_multisig() {
203        //TODO: implement
204    }
205}