Skip to main content

chains_sdk/
traits.rs

1//! Unified trait interfaces for all signing algorithms.
2//!
3//! Every chain module implements these traits, providing a consistent API
4//! regardless of the underlying cryptographic algorithm.
5
6use zeroize::Zeroizing;
7
8/// A type that can produce cryptographic signatures.
9pub trait Signer {
10    /// The signature type produced by this signer.
11    type Signature;
12    /// The error type returned on failure.
13    type Error;
14
15    /// Sign a raw message. The implementation applies chain-specific hashing internally
16    /// (e.g., Keccak-256 for Ethereum, double-SHA-256 for Bitcoin).
17    fn sign(&self, message: &[u8]) -> Result<Self::Signature, Self::Error>;
18
19    /// Sign a pre-hashed digest directly. The caller is responsible for applying
20    /// the correct hash function. Returns `InvalidHashLength` if the digest
21    /// length doesn't match the expected hash output size.
22    fn sign_prehashed(&self, digest: &[u8]) -> Result<Self::Signature, Self::Error>;
23
24    /// Return the public key as bytes (compressed format where applicable).
25    /// - ECDSA (secp256k1, P-256): 33 bytes (SEC1 compressed)
26    /// - Ed25519: 32 bytes
27    /// - BIP-340 Schnorr: 32 bytes (x-only)
28    /// - BLS12-381: 48 bytes (compressed G1)
29    fn public_key_bytes(&self) -> Vec<u8>;
30
31    /// Return the public key in uncompressed format.
32    /// - ECDSA (secp256k1, P-256): 65 bytes (`04 || x || y`)
33    /// - Ed25519 / Schnorr / BLS: same as `public_key_bytes()` (no uncompressed form)
34    fn public_key_bytes_uncompressed(&self) -> Vec<u8>;
35}
36
37/// A type that can verify cryptographic signatures.
38pub trait Verifier {
39    /// The signature type this verifier accepts.
40    type Signature;
41    /// The error type returned on failure.
42    type Error;
43
44    /// Verify a signature against a raw message. The implementation applies
45    /// chain-specific hashing internally.
46    fn verify(&self, message: &[u8], signature: &Self::Signature) -> Result<bool, Self::Error>;
47
48    /// Verify a signature against a pre-hashed digest.
49    fn verify_prehashed(
50        &self,
51        digest: &[u8],
52        signature: &Self::Signature,
53    ) -> Result<bool, Self::Error>;
54}
55
56/// A type that represents a cryptographic key pair capable of signing.
57pub trait KeyPair: Signer {
58    /// Generate a new random key pair using OS entropy (CSPRNG).
59    fn generate() -> Result<Self, <Self as Signer>::Error>
60    where
61        Self: Sized;
62
63    /// Reconstruct a key pair from raw private key bytes (32 bytes).
64    fn from_bytes(private_key: &[u8]) -> Result<Self, <Self as Signer>::Error>
65    where
66        Self: Sized;
67
68    /// Export the private key as auto-zeroizing bytes.
69    /// The returned `Zeroizing<Vec<u8>>` will scrub the memory on drop.
70    fn private_key_bytes(&self) -> Zeroizing<Vec<u8>>;
71
72    /// Reconstruct a key pair from a 64-byte expanded keypair (seed ∥ pubkey).
73    /// Default impl uses only the first 32 bytes (seed).
74    fn from_keypair_bytes(keypair: &[u8]) -> Result<Self, <Self as Signer>::Error>
75    where
76        Self: Sized,
77    {
78        if keypair.len() < 32 {
79            return Self::from_bytes(keypair); // will error with proper message
80        }
81        Self::from_bytes(&keypair[..32])
82    }
83
84    /// Export the full keypair as `private_key ∥ public_key`.
85    /// Default: 32B seed + compressed pubkey.
86    fn keypair_bytes(&self) -> Zeroizing<Vec<u8>> {
87        let priv_key = self.private_key_bytes();
88        let pub_key = self.public_key_bytes();
89        let mut kp = Vec::with_capacity(priv_key.len() + pub_key.len());
90        kp.extend_from_slice(&priv_key);
91        kp.extend_from_slice(&pub_key);
92        Zeroizing::new(kp)
93    }
94}