commonware_cryptography/
lib.rs

1//! Generate keys, sign arbitrary messages, and deterministically verify signatures.
2//!
3//! # Status
4//!
5//! `commonware-cryptography` is **ALPHA** software and is not yet recommended for production use. Developers should
6//! expect breaking changes and occasional instability.
7
8use commonware_utils::Array;
9use rand::{CryptoRng, Rng, RngCore, SeedableRng};
10use std::fmt::Debug;
11use thiserror::Error;
12
13pub mod bls12381;
14pub use bls12381::Bls12381;
15pub mod ed25519;
16pub use ed25519::{Ed25519, Ed25519Batch};
17pub mod sha256;
18pub use sha256::{hash, Sha256};
19pub mod secp256r1;
20pub use secp256r1::Secp256r1;
21
22/// Errors that can occur when interacting with cryptographic primitives.
23#[derive(Error, Debug, PartialEq)]
24pub enum Error {
25    #[error("invalid digest length")]
26    InvalidDigestLength,
27    #[error("invalid private key")]
28    InvalidPrivateKey,
29    #[error("invalid private key length")]
30    InvalidPrivateKeyLength,
31    #[error("invalid public key")]
32    InvalidPublicKey,
33    #[error("invalid public key length")]
34    InvalidPublicKeyLength,
35    #[error("invalid signature")]
36    InvalidSignature,
37    #[error("invalid signature length")]
38    InvalidSignatureLength,
39}
40
41/// Interface that commonware crates rely on for most cryptographic operations.
42pub trait Scheme: Clone + Send + Sync + 'static {
43    /// Private key used for signing.
44    type PrivateKey: Array;
45
46    /// Public key used for verifying signatures.
47    type PublicKey: Array;
48
49    /// Signature generated by signing a message.
50    type Signature: Array;
51
52    /// Returns a new instance of the scheme.
53    fn new<R: Rng + CryptoRng>(rng: &mut R) -> Self;
54
55    /// Returns a new instance of the scheme from a secret key.
56    fn from(private_key: Self::PrivateKey) -> Option<Self>;
57
58    /// Returns a new instance of the scheme from a provided seed.
59    ///
60    /// # Warning
61    ///
62    /// This function is insecure and should only be used for examples
63    /// and testing.
64    fn from_seed(seed: u64) -> Self {
65        let mut rng = rand::rngs::StdRng::seed_from_u64(seed);
66        Self::new(&mut rng)
67    }
68
69    /// Returns the private key of the signer.
70    fn private_key(&self) -> Self::PrivateKey;
71
72    /// Returns the public key of the signer.
73    fn public_key(&self) -> Self::PublicKey;
74
75    /// Sign the given message.
76    ///
77    /// The message should not be hashed prior to calling this function. If a particular scheme
78    /// requires a payload to be hashed before it is signed, it will be done internally.
79    ///
80    /// A namespace should be used to prevent replay attacks. It will be prepended to the message so
81    /// that a signature meant for one context cannot be used unexpectedly in another (i.e. signing
82    /// a message on the network layer can't accidentally spend funds on the execution layer). See
83    /// [union_unique](commonware_utils::union_unique) for details.
84    fn sign(&mut self, namespace: Option<&[u8]>, message: &[u8]) -> Self::Signature;
85
86    /// Check that a signature is valid for the given message and public key.
87    ///
88    /// The message should not be hashed prior to calling this function. If a particular
89    /// scheme requires a payload to be hashed before it is signed, it will be done internally.
90    ///
91    /// Because namespace is prepended to message before signing, the namespace provided here must
92    /// match the namespace provided during signing.
93    fn verify(
94        namespace: Option<&[u8]>,
95        message: &[u8],
96        public_key: &Self::PublicKey,
97        signature: &Self::Signature,
98    ) -> bool;
99}
100
101/// Interface that commonware crates rely on for batched cryptographic operations.
102pub trait BatchScheme {
103    /// Public key used for verifying signatures.
104    type PublicKey: Array;
105
106    /// Signature generated by signing a message.
107    type Signature: Array;
108
109    /// Create a new batch scheme.
110    fn new() -> Self;
111
112    /// Append item to the batch.
113    ///
114    /// The message should not be hashed prior to calling this function. If a particular scheme
115    /// requires a payload to be hashed before it is signed, it will be done internally.
116    ///
117    /// A namespace should be used to prevent replay attacks. It will be prepended to the message so
118    /// that a signature meant for one context cannot be used unexpectedly in another (i.e. signing
119    /// a message on the network layer can't accidentally spend funds on the execution layer). See
120    /// [union_unique](commonware_utils::union_unique) for details.
121    fn add(
122        &mut self,
123        namespace: Option<&[u8]>,
124        message: &[u8],
125        public_key: &Self::PublicKey,
126        signature: &Self::Signature,
127    ) -> bool;
128
129    /// Verify all items added to the batch.
130    ///
131    /// Returns `true` if all items are valid, `false` otherwise.
132    ///
133    /// # Why Randomness?
134    ///
135    /// When performing batch verification, it is often important to add some randomness
136    /// to prevent an attacker from constructing a malicious batch of signatures that pass
137    /// batch verification but are invalid individually. Abstractly, think of this as
138    /// there existing two valid signatures (`c_1` and `c_2`) and an attacker proposing
139    /// (`c_1 + d` and `c_2 - d`).
140    ///
141    /// You can read more about this [here](https://ethresear.ch/t/security-of-bls-batch-verification/10748#the-importance-of-randomness-4).
142    fn verify<R: RngCore + CryptoRng>(self, rng: &mut R) -> bool;
143}
144
145/// Interface that commonware crates rely on for hashing.
146///
147/// Hash functions in commonware primitives are not typically hardcoded
148/// to a specific algorithm (e.g. SHA-256) because different hash functions
149/// may work better with different cryptographic schemes, may be more efficient
150/// to use in STARK/SNARK proofs, or provide different levels of security (with some
151/// performance/size penalty).
152///
153/// This trait is required to implement the `Clone` trait because it is often
154/// part of a struct that is cloned. In practice, implementations do not actually
155/// clone the hasher state but users should not rely on this behavior and call `reset`
156/// after cloning.
157pub trait Hasher: Clone + Send + Sync + 'static {
158    /// Digest generated by the hasher.
159    type Digest: Array;
160
161    /// Create a new hasher.
162    fn new() -> Self;
163
164    /// Append message to previously recorded data.
165    fn update(&mut self, message: &[u8]);
166
167    /// Hash all recorded data and reset the hasher
168    /// to the initial state.
169    fn finalize(&mut self) -> Self::Digest;
170
171    /// Reset the hasher without generating a hash.
172    ///
173    /// This function does not need to be called after `finalize`.
174    fn reset(&mut self);
175
176    /// Generate a random digest.
177    ///
178    /// # Warning
179    ///
180    /// This function is typically used for testing and is not recommended
181    /// for production use.
182    fn random<R: Rng + CryptoRng>(rng: &mut R) -> Self::Digest;
183}
184
185#[cfg(test)]
186mod tests {
187    use super::*;
188    use commonware_utils::SizedSerialize;
189    use rand::rngs::OsRng;
190
191    fn test_validate<C: Scheme>() {
192        let signer = C::new(&mut OsRng);
193        let public_key = signer.public_key();
194        assert!(C::PublicKey::try_from(public_key.as_ref()).is_ok());
195    }
196
197    fn test_from_valid_private_key<C: Scheme>() {
198        let signer = C::new(&mut OsRng);
199        let private_key = signer.private_key();
200        let public_key = signer.public_key();
201        let signer = C::from(private_key).unwrap();
202        assert_eq!(public_key, signer.public_key());
203    }
204
205    fn test_validate_invalid_public_key<C: Scheme>()
206    where
207        C::PublicKey: TryFrom<Vec<u8>, Error = Error>,
208    {
209        let result = C::PublicKey::try_from(vec![0; 1024]);
210        assert_eq!(result, Err(Error::InvalidPublicKeyLength));
211    }
212
213    fn test_sign_and_verify<C: Scheme>() {
214        let mut signer = C::from_seed(0);
215        let namespace = Some(&b"test_namespace"[..]);
216        let message = b"test_message";
217        let signature = signer.sign(namespace, message);
218        let public_key = signer.public_key();
219        assert!(C::verify(namespace, message, &public_key, &signature));
220    }
221
222    fn test_sign_and_verify_wrong_message<C: Scheme>() {
223        let mut signer = C::from_seed(0);
224        let namespace: Option<&[u8]> = Some(&b"test_namespace"[..]);
225        let message = b"test_message";
226        let wrong_message = b"wrong_message";
227        let signature = signer.sign(namespace, message);
228        let public_key = signer.public_key();
229        assert!(!C::verify(
230            namespace,
231            wrong_message,
232            &public_key,
233            &signature
234        ));
235    }
236
237    fn test_sign_and_verify_wrong_namespace<C: Scheme>() {
238        let mut signer = C::from_seed(0);
239        let namespace = Some(&b"test_namespace"[..]);
240        let wrong_namespace = Some(&b"wrong_namespace"[..]);
241        let message = b"test_message";
242        let signature = signer.sign(namespace, message);
243        let public_key = signer.public_key();
244        assert!(!C::verify(
245            wrong_namespace,
246            message,
247            &public_key,
248            &signature
249        ));
250    }
251
252    fn test_empty_vs_none_namespace<C: Scheme>() {
253        let mut signer = C::from_seed(0);
254        let empty_namespace = Some(&b""[..]);
255        let message = b"test_message";
256        let signature = signer.sign(empty_namespace, message);
257        let public_key = signer.public_key();
258        assert!(C::verify(empty_namespace, message, &public_key, &signature));
259        assert!(!C::verify(None, message, &public_key, &signature));
260    }
261
262    fn test_signature_determinism<C: Scheme>() {
263        let mut signer_1 = C::from_seed(0);
264        let mut signer_2 = C::from_seed(0);
265        let namespace = Some(&b"test_namespace"[..]);
266        let message = b"test_message";
267        let signature_1 = signer_1.sign(namespace, message);
268        let signature_2 = signer_2.sign(namespace, message);
269        assert_eq!(signer_1.public_key(), signer_2.public_key());
270        assert_eq!(signature_1, signature_2);
271    }
272
273    fn test_invalid_signature_publickey_pair<C: Scheme>() {
274        let mut signer = C::from_seed(0);
275        let signer_2 = C::from_seed(1);
276        let namespace = Some(&b"test_namespace"[..]);
277        let message = b"test_message";
278        let signature = signer.sign(namespace, message);
279        let public_key = signer_2.public_key();
280        assert!(!C::verify(namespace, message, &public_key, &signature));
281    }
282
283    #[test]
284    fn test_ed25519_validate() {
285        test_validate::<Ed25519>();
286    }
287
288    #[test]
289    fn test_ed25519_validate_invalid_public_key() {
290        test_validate_invalid_public_key::<Ed25519>();
291    }
292
293    #[test]
294    fn test_ed25519_from_valid_private_key() {
295        test_from_valid_private_key::<Ed25519>();
296    }
297
298    #[test]
299    fn test_ed25519_sign_and_verify() {
300        test_sign_and_verify::<Ed25519>();
301    }
302
303    #[test]
304    fn test_ed25519_sign_and_verify_wrong_message() {
305        test_sign_and_verify_wrong_message::<Ed25519>();
306    }
307
308    #[test]
309    fn test_ed25519_sign_and_verify_wrong_namespace() {
310        test_sign_and_verify_wrong_namespace::<Ed25519>();
311    }
312
313    #[test]
314    fn test_ed25519_empty_vs_none_namespace() {
315        test_empty_vs_none_namespace::<Ed25519>();
316    }
317
318    #[test]
319    fn test_ed25519_signature_determinism() {
320        test_signature_determinism::<Ed25519>();
321    }
322
323    #[test]
324    fn test_ed25519_invalid_signature_publickey_pair() {
325        test_invalid_signature_publickey_pair::<Ed25519>();
326    }
327
328    #[test]
329    fn test_ed25519_len() {
330        assert_eq!(<Ed25519 as Scheme>::PublicKey::SERIALIZED_LEN, 32);
331        assert_eq!(<Ed25519 as Scheme>::Signature::SERIALIZED_LEN, 64);
332    }
333
334    #[test]
335    fn test_bls12381_validate() {
336        test_validate::<Bls12381>();
337    }
338
339    #[test]
340    fn test_bls12381_validate_invalid_public_key() {
341        test_validate_invalid_public_key::<Bls12381>();
342    }
343
344    #[test]
345    fn test_bls12381_from_valid_private_key() {
346        test_from_valid_private_key::<Bls12381>();
347    }
348
349    #[test]
350    fn test_bls12381_sign_and_verify() {
351        test_sign_and_verify::<Bls12381>();
352    }
353
354    #[test]
355    fn test_bls12381_sign_and_verify_wrong_message() {
356        test_sign_and_verify_wrong_message::<Bls12381>();
357    }
358
359    #[test]
360    fn test_bls12381_sign_and_verify_wrong_namespace() {
361        test_sign_and_verify_wrong_namespace::<Bls12381>();
362    }
363
364    #[test]
365    fn test_bls12381_empty_vs_none_namespace() {
366        test_empty_vs_none_namespace::<Bls12381>();
367    }
368
369    #[test]
370    fn test_bls12381_signature_determinism() {
371        test_signature_determinism::<Bls12381>();
372    }
373
374    #[test]
375    fn test_bls12381_invalid_signature_publickey_pair() {
376        test_invalid_signature_publickey_pair::<Bls12381>();
377    }
378
379    #[test]
380    fn test_bls12381_len() {
381        assert_eq!(<Bls12381 as Scheme>::PublicKey::SERIALIZED_LEN, 48);
382        assert_eq!(<Bls12381 as Scheme>::Signature::SERIALIZED_LEN, 96);
383    }
384
385    #[test]
386    fn test_secp256r1_validate() {
387        test_validate::<Secp256r1>();
388    }
389
390    #[test]
391    fn test_secp256r1_validate_invalid_public_key() {
392        test_validate_invalid_public_key::<Secp256r1>();
393    }
394
395    #[test]
396    fn test_secp256r1_from_valid_private_key() {
397        test_from_valid_private_key::<Secp256r1>();
398    }
399
400    #[test]
401    fn test_secp256r1_sign_and_verify() {
402        test_sign_and_verify::<Secp256r1>();
403    }
404
405    #[test]
406    fn test_secp256r1_sign_and_verify_wrong_message() {
407        test_sign_and_verify_wrong_message::<Secp256r1>();
408    }
409
410    #[test]
411    fn test_secp256r1_sign_and_verify_wrong_namespace() {
412        test_sign_and_verify_wrong_namespace::<Secp256r1>();
413    }
414
415    #[test]
416    fn test_secp256r1_empty_vs_none_namespace() {
417        test_empty_vs_none_namespace::<Secp256r1>();
418    }
419
420    #[test]
421    fn test_secp256r1_signature_determinism() {
422        test_signature_determinism::<Secp256r1>();
423    }
424
425    #[test]
426    fn test_secp256r1_invalid_signature_publickey_pair() {
427        test_invalid_signature_publickey_pair::<Secp256r1>();
428    }
429
430    #[test]
431    fn test_secp256r1_len() {
432        assert_eq!(<Secp256r1 as Scheme>::PublicKey::SERIALIZED_LEN, 33);
433        assert_eq!(<Secp256r1 as Scheme>::Signature::SERIALIZED_LEN, 64);
434    }
435
436    fn test_hasher_multiple_runs<H: Hasher>() {
437        // Generate initial hash
438        let mut hasher = H::new();
439        hasher.update(b"hello world");
440        let digest = hasher.finalize();
441        assert!(H::Digest::try_from(digest.as_ref()).is_ok());
442        assert_eq!(digest.as_ref().len(), H::Digest::SERIALIZED_LEN);
443
444        // Reuse hasher without reset
445        hasher.update(b"hello world");
446        let digest_again = hasher.finalize();
447        assert!(H::Digest::try_from(digest_again.as_ref()).is_ok());
448        assert_eq!(digest, digest_again);
449
450        // Reuse hasher with reset
451        hasher.update(b"hello mars");
452        hasher.reset();
453        hasher.update(b"hello world");
454        let digest_reset = hasher.finalize();
455        assert!(H::Digest::try_from(digest_reset.as_ref()).is_ok());
456        assert_eq!(digest, digest_reset);
457
458        // Hash different data
459        hasher.update(b"hello mars");
460        let digest_mars = hasher.finalize();
461        assert!(H::Digest::try_from(digest_mars.as_ref()).is_ok());
462        assert_ne!(digest, digest_mars);
463    }
464
465    fn test_hasher_multiple_updates<H: Hasher>() {
466        // Generate initial hash
467        let mut hasher = H::new();
468        hasher.update(b"hello");
469        hasher.update(b" world");
470        let digest = hasher.finalize();
471        assert!(H::Digest::try_from(digest.as_ref()).is_ok());
472
473        // Generate hash in oneshot
474        let mut hasher = H::new();
475        hasher.update(b"hello world");
476        let digest_oneshot = hasher.finalize();
477        assert!(H::Digest::try_from(digest_oneshot.as_ref()).is_ok());
478        assert_eq!(digest, digest_oneshot);
479    }
480
481    fn test_hasher_empty_input<H: Hasher>() {
482        let mut hasher = H::new();
483        let digest = hasher.finalize();
484        assert!(H::Digest::try_from(digest.as_ref()).is_ok());
485    }
486
487    fn test_hasher_large_input<H: Hasher>() {
488        let mut hasher = H::new();
489        let data = vec![1; 1024];
490        hasher.update(&data);
491        let digest = hasher.finalize();
492        assert!(H::Digest::try_from(digest.as_ref()).is_ok());
493    }
494
495    #[test]
496    fn test_sha256_hasher_multiple_runs() {
497        test_hasher_multiple_runs::<Sha256>();
498    }
499
500    #[test]
501    fn test_sha256_hasher_multiple_updates() {
502        test_hasher_multiple_updates::<Sha256>();
503    }
504
505    #[test]
506    fn test_sha256_hasher_empty_input() {
507        test_hasher_empty_input::<Sha256>();
508    }
509
510    #[test]
511    fn test_sha256_hasher_large_input() {
512        test_hasher_large_input::<Sha256>();
513    }
514}