aptos_sdk/crypto/mod.rs
1//! Cryptographic primitives for the Aptos SDK.
2//!
3//! This module provides implementations of the signature schemes supported
4//! by Aptos, including Ed25519, Secp256k1, and Secp256r1 (P-256).
5//!
6//! # Feature Flags
7//!
8//! - `ed25519` (default): Ed25519 signatures
9//! - `secp256k1` (default): Secp256k1 ECDSA signatures
10//! - `secp256r1`: Secp256r1 (P-256) ECDSA signatures
11//! - `bls`: BLS12-381 signatures
12//!
13//! # Security Considerations
14//!
15//! ## Timing Attacks
16//!
17//! The `PartialEq` implementations for cryptographic types use standard byte
18//! comparisons which may not be constant-time. This is generally acceptable
19//! because:
20//!
21//! - Public keys and signatures are not secret material
22//! - Signature verification in the underlying libraries uses constant-time
23//! operations for the actual cryptographic comparisons
24//!
25//! If you need constant-time comparisons for specific use cases (e.g., comparing
26//! against expected signatures in tests), consider using the `subtle` crate's
27//! `ConstantTimeEq` trait.
28//!
29//! ## Key Material Protection
30//!
31//! Private key types implement `Zeroize` and `ZeroizeOnDrop` to clear sensitive
32//! key material from memory when dropped. The underlying cryptographic libraries
33//! (ed25519-dalek, k256, p256) also implement secure key handling.
34//!
35//! # Example
36//!
37//! ```rust,ignore
38//! use aptos_sdk::crypto::{Ed25519PrivateKey, Signer};
39//!
40//! let private_key = Ed25519PrivateKey::generate();
41//! let message = b"hello world";
42//! let signature = private_key.sign(message);
43//!
44//! let public_key = private_key.public_key();
45//! assert!(public_key.verify(message, &signature).is_ok());
46//! ```
47
48mod hash;
49mod traits;
50
51#[cfg(feature = "bls")]
52mod bls12381;
53#[cfg(feature = "ed25519")]
54mod ed25519;
55#[cfg(feature = "ed25519")]
56mod multi_ed25519;
57mod multi_key;
58#[cfg(feature = "secp256k1")]
59mod secp256k1;
60#[cfg(feature = "secp256r1")]
61mod secp256r1;
62
63// Re-export hash functions
64pub use hash::{HashFunction, sha2_256, sha3_256, sha3_256_of, signing_message};
65
66// Re-export traits
67pub use traits::{PublicKey, Signature, Signer, Verifier};
68
69// Re-export Ed25519 types
70#[cfg(feature = "ed25519")]
71pub use ed25519::{
72 ED25519_PRIVATE_KEY_LENGTH, ED25519_PUBLIC_KEY_LENGTH, ED25519_SIGNATURE_LENGTH,
73 Ed25519PrivateKey, Ed25519PublicKey, Ed25519Signature,
74};
75
76// Re-export Multi-Ed25519 types
77#[cfg(feature = "ed25519")]
78pub use multi_ed25519::{
79 MAX_NUM_OF_KEYS, MIN_THRESHOLD, MultiEd25519PublicKey, MultiEd25519Signature,
80};
81
82// Re-export Multi-Key types
83pub use multi_key::{
84 AnyPublicKey, AnyPublicKeyVariant, AnySignature, MAX_NUM_OF_KEYS as MULTI_KEY_MAX_NUM_OF_KEYS,
85 MIN_THRESHOLD as MULTI_KEY_MIN_THRESHOLD, MultiKeyPublicKey, MultiKeySignature,
86};
87
88// Re-export Secp256k1 types
89#[cfg(feature = "secp256k1")]
90pub use secp256k1::{
91 SECP256K1_PRIVATE_KEY_LENGTH, SECP256K1_PUBLIC_KEY_LENGTH,
92 SECP256K1_PUBLIC_KEY_UNCOMPRESSED_LENGTH, SECP256K1_SIGNATURE_LENGTH, Secp256k1PrivateKey,
93 Secp256k1PublicKey, Secp256k1Signature,
94};
95
96// Re-export Secp256r1 types
97#[cfg(feature = "secp256r1")]
98pub use secp256r1::{
99 SECP256R1_PRIVATE_KEY_LENGTH, SECP256R1_PUBLIC_KEY_LENGTH, SECP256R1_SIGNATURE_LENGTH,
100 Secp256r1PrivateKey, Secp256r1PublicKey, Secp256r1Signature,
101};
102
103// Re-export BLS12-381 types
104#[cfg(feature = "bls")]
105pub use bls12381::{
106 BLS12381_POP_LENGTH, BLS12381_PRIVATE_KEY_LENGTH, BLS12381_PUBLIC_KEY_LENGTH,
107 BLS12381_SIGNATURE_LENGTH, Bls12381PrivateKey, Bls12381ProofOfPossession, Bls12381PublicKey,
108 Bls12381Signature,
109};
110
111/// The authentication key scheme byte for Ed25519 single-key accounts.
112pub const ED25519_SCHEME: u8 = 0;
113
114/// The authentication key scheme byte for multi-Ed25519 accounts.
115pub const MULTI_ED25519_SCHEME: u8 = 1;
116
117/// The authentication key scheme byte for single-key accounts (unified).
118pub const SINGLE_KEY_SCHEME: u8 = 2;
119
120/// The authentication key scheme byte for multi-key accounts (unified).
121pub const MULTI_KEY_SCHEME: u8 = 3;
122
123/// The authentication key scheme byte for keyless accounts.
124pub const KEYLESS_SCHEME: u8 = 5;
125
126/// Derives an authentication key from a public key and scheme.
127///
128/// The authentication key is SHA3-256(public_key_bytes || `scheme_byte`).
129pub fn derive_authentication_key(public_key: &[u8], scheme: u8) -> [u8; 32] {
130 use sha3::{Digest, Sha3_256};
131 let mut hasher = Sha3_256::new();
132 hasher.update(public_key);
133 hasher.update([scheme]);
134 let result = hasher.finalize();
135 let mut auth_key = [0u8; 32];
136 auth_key.copy_from_slice(&result);
137 auth_key
138}
139
140/// Derives an account address from a public key and scheme.
141///
142/// For most accounts, the address equals the authentication key.
143pub fn derive_address(public_key: &[u8], scheme: u8) -> crate::types::AccountAddress {
144 let auth_key = derive_authentication_key(public_key, scheme);
145 crate::types::AccountAddress::new(auth_key)
146}