wamu_core/
test_utils.rs

1//! Test utilities.
2
3use k256::ecdsa::{signature::Signer, SigningKey};
4
5use crate::crypto::{
6    EllipticCurve, KeyEncoding, MessageDigest, Signature, SignatureAlgorithm, SignatureEncoding,
7    VerifyingKey,
8};
9use crate::IdentityProvider;
10
11/// A mock ECDSA/Secp256k1/SHA-256 based identity provider.
12#[derive(Debug, Clone)]
13pub struct MockECDSAIdentityProvider {
14    secret: SigningKey,
15}
16
17impl MockECDSAIdentityProvider {
18    /// Generates an ECDSA/Secp256k1/SHA-256 signing key.
19    pub fn generate() -> Self {
20        let mut rng = rand::thread_rng();
21        Self {
22            // `k256::ecdsa::SigningKey` uses `Secp256k1` and `SHA-256`.
23            secret: SigningKey::random(&mut rng),
24        }
25    }
26}
27
28impl IdentityProvider for MockECDSAIdentityProvider {
29    /// Computes and serializes the ECDSA/Secp256k1 verifying key (in SEC1 format).
30    fn verifying_key(&self) -> VerifyingKey {
31        VerifyingKey {
32            // `k256::ecdsa::SigningKey` uses `Secp256k1` and `SHA-256`.
33            key: k256::ecdsa::VerifyingKey::from(&self.secret)
34                .to_sec1_bytes()
35                .to_vec(),
36            algo: SignatureAlgorithm::ECDSA,
37            curve: EllipticCurve::Secp256k1,
38            enc: KeyEncoding::SEC1,
39        }
40    }
41
42    /// Computes and serializes (in DER format) the ECDSA/Secp256k1/SHA-256 signature of a message .
43    fn sign(&self, msg: &[u8]) -> Signature {
44        // `k256::ecdsa::SigningKey` uses `Secp256k1` and `SHA-256`.
45        let signature: k256::ecdsa::Signature = self.secret.sign(msg);
46        Signature {
47            sig: signature.to_der().as_bytes().to_vec(),
48            algo: SignatureAlgorithm::ECDSA,
49            curve: EllipticCurve::Secp256k1,
50            hash: MessageDigest::SHA256,
51            enc: SignatureEncoding::DER,
52        }
53    }
54
55    /// Computes the ECDSA/Secp256k1/SHA-256 signature for a message and returns (`r`, `s`) as (`[u8; 32]`, `[u8; 32]`).
56    fn sign_message_share(&self, msg: &[u8]) -> ([u8; 32], [u8; 32]) {
57        // `k256::ecdsa::SigningKey` uses `Secp256k1` and `SHA-256`.
58        let signature: k256::ecdsa::Signature = self.secret.sign(msg);
59        let (r, s) = signature.split_bytes();
60        (r.into(), s.into())
61    }
62}
63
64impl MockECDSAIdentityProvider {
65    /// Returns the byte representation of the secret key.
66    // Used only for testing and demos.
67    pub fn export(&self) -> Vec<u8> {
68        self.secret.to_bytes().to_vec()
69    }
70}
71
72#[cfg(test)]
73mod tests {
74    use super::*;
75    use crate::crypto;
76
77    #[test]
78    fn local_identity_provider_works() {
79        // Message to sign.
80        let msg = b"Hello, world!";
81
82        // Generate identity provider.
83        let identity_provider = MockECDSAIdentityProvider::generate();
84
85        // Signing.
86        let signature = identity_provider.sign(msg);
87
88        // Verifying.
89        assert!(
90            crypto::verify_signature(&identity_provider.verifying_key(), msg, &signature).is_ok()
91        );
92    }
93}