aptos_sdk/account/
secp256k1.rs1use crate::account::account::{Account, AuthenticationKey};
4use crate::crypto::{
5 SINGLE_KEY_SCHEME, Secp256k1PrivateKey, Secp256k1PublicKey, derive_authentication_key,
6};
7use crate::error::AptosResult;
8use crate::types::AccountAddress;
9use std::fmt;
10
11#[derive(Clone)]
24pub struct Secp256k1Account {
25 private_key: Secp256k1PrivateKey,
26 public_key: Secp256k1PublicKey,
27 address: AccountAddress,
28}
29
30impl Secp256k1Account {
31 pub fn generate() -> Self {
33 let private_key = Secp256k1PrivateKey::generate();
34 Self::from_private_key(private_key)
35 }
36
37 pub fn from_private_key(private_key: Secp256k1PrivateKey) -> Self {
39 let public_key = private_key.public_key();
40 let address = public_key.to_address();
41 Self {
42 private_key,
43 public_key,
44 address,
45 }
46 }
47
48 pub fn from_private_key_bytes(bytes: &[u8]) -> AptosResult<Self> {
54 let private_key = Secp256k1PrivateKey::from_bytes(bytes)?;
55 Ok(Self::from_private_key(private_key))
56 }
57
58 pub fn from_private_key_hex(hex_str: &str) -> AptosResult<Self> {
66 let private_key = Secp256k1PrivateKey::from_hex(hex_str)?;
67 Ok(Self::from_private_key(private_key))
68 }
69
70 pub fn address(&self) -> AccountAddress {
72 self.address
73 }
74
75 pub fn public_key(&self) -> &Secp256k1PublicKey {
77 &self.public_key
78 }
79
80 pub fn private_key(&self) -> &Secp256k1PrivateKey {
82 &self.private_key
83 }
84
85 pub fn sign_message(&self, message: &[u8]) -> crate::crypto::Secp256k1Signature {
87 self.private_key.sign(message)
88 }
89}
90
91impl Account for Secp256k1Account {
92 fn address(&self) -> AccountAddress {
93 self.address
94 }
95
96 fn authentication_key(&self) -> AuthenticationKey {
97 let uncompressed = self.public_key.to_uncompressed_bytes();
99 let mut bcs_bytes = Vec::with_capacity(1 + 1 + uncompressed.len());
100 bcs_bytes.push(0x01); bcs_bytes.push(65); bcs_bytes.extend_from_slice(&uncompressed);
103 let key = derive_authentication_key(&bcs_bytes, SINGLE_KEY_SCHEME);
104 AuthenticationKey::new(key)
105 }
106
107 fn sign(&self, message: &[u8]) -> crate::error::AptosResult<Vec<u8>> {
108 Ok(self.private_key.sign(message).to_bytes().to_vec())
109 }
110
111 fn public_key_bytes(&self) -> Vec<u8> {
112 self.public_key.to_uncompressed_bytes()
114 }
115
116 fn signature_scheme(&self) -> u8 {
117 SINGLE_KEY_SCHEME
118 }
119}
120
121impl fmt::Debug for Secp256k1Account {
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123 f.debug_struct("Secp256k1Account")
124 .field("address", &self.address)
125 .field("public_key", &self.public_key)
126 .finish_non_exhaustive()
127 }
128}
129
130#[cfg(test)]
131mod tests {
132 use super::*;
133 use crate::account::Account;
134
135 #[test]
136 fn test_generate() {
137 let account = Secp256k1Account::generate();
138 assert!(!account.address().is_zero());
139 }
140
141 #[test]
142 fn test_from_private_key_roundtrip() {
143 let account = Secp256k1Account::generate();
144 let bytes = account.private_key().to_bytes();
145
146 let restored = Secp256k1Account::from_private_key_bytes(&bytes).unwrap();
147 assert_eq!(account.address(), restored.address());
148 }
149
150 #[test]
151 fn test_sign_and_verify() {
152 let account = Secp256k1Account::generate();
153 let message = b"hello world";
154
155 let signature = account.sign_message(message);
156 assert!(account.public_key().verify(message, &signature).is_ok());
157 }
158
159 #[test]
160 fn test_from_private_key() {
161 let original = Secp256k1Account::generate();
162 let private_key = original.private_key().clone();
163 let restored = Secp256k1Account::from_private_key(private_key);
164 assert_eq!(original.address(), restored.address());
165 }
166
167 #[test]
168 fn test_from_private_key_hex() {
169 let original = Secp256k1Account::generate();
170 let hex = original.private_key().to_hex();
171 let restored = Secp256k1Account::from_private_key_hex(&hex).unwrap();
172 assert_eq!(original.address(), restored.address());
173 }
174
175 #[test]
176 fn test_authentication_key() {
177 let account = Secp256k1Account::generate();
178 let auth_key = account.authentication_key();
179 assert_eq!(auth_key.as_bytes().len(), 32);
180 }
181
182 #[test]
183 fn test_public_key_bytes() {
184 let account = Secp256k1Account::generate();
185 let bytes = account.public_key_bytes();
186 assert_eq!(bytes.len(), 65); }
188
189 #[test]
190 fn test_signature_scheme() {
191 let account = Secp256k1Account::generate();
192 assert_eq!(account.signature_scheme(), SINGLE_KEY_SCHEME);
193 }
194
195 #[test]
196 fn test_sign_trait() {
197 let account = Secp256k1Account::generate();
198 let message = b"test message";
199 let sig_bytes = account.sign(message).unwrap();
200 assert_eq!(sig_bytes.len(), 64);
201 }
202
203 #[test]
204 fn test_debug_output() {
205 let account = Secp256k1Account::generate();
206 let debug = format!("{account:?}");
207 assert!(debug.contains("Secp256k1Account"));
208 assert!(debug.contains("address"));
209 }
210
211 #[test]
212 fn test_invalid_private_key_bytes() {
213 let result = Secp256k1Account::from_private_key_bytes(&[0u8; 16]);
214 assert!(result.is_err());
215 }
216
217 #[test]
218 fn test_invalid_private_key_hex() {
219 let result = Secp256k1Account::from_private_key_hex("invalid");
220 assert!(result.is_err());
221 }
222}