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