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
8#![doc(
9    html_logo_url = "https://commonware.xyz/imgs/rustdoc_logo.svg",
10    html_favicon_url = "https://commonware.xyz/favicon.ico"
11)]
12#![cfg_attr(not(feature = "std"), no_std)]
13
14#[cfg(not(feature = "std"))]
15extern crate alloc;
16
17use commonware_codec::{Encode, ReadExt};
18use commonware_utils::Array;
19use rand::{CryptoRng, Rng, RngCore, SeedableRng as _};
20use rand_chacha::ChaCha20Rng;
21
22pub mod bls12381;
23pub mod ed25519;
24pub mod sha256;
25pub use sha256::{CoreSha256, Sha256};
26pub mod blake3;
27pub use blake3::{Blake3, CoreBlake3};
28pub mod bloomfilter;
29pub use bloomfilter::BloomFilter;
30pub mod lthash;
31pub use lthash::LtHash;
32pub mod secp256r1;
33
34/// Produces [Signature]s over messages that can be verified with a corresponding [PublicKey].
35pub trait Signer: Send + Sync + Clone + 'static {
36    /// The type of [Signature] produced by this [Signer].
37    type Signature: Signature;
38
39    /// The corresponding [PublicKey] type.
40    type PublicKey: PublicKey<Signature = Self::Signature>;
41
42    /// Returns the [PublicKey] corresponding to this [Signer].
43    fn public_key(&self) -> Self::PublicKey;
44
45    /// Sign a message with the given namespace.
46    ///
47    /// The message should not be hashed prior to calling this function. If a particular scheme
48    /// requires a payload to be hashed before it is signed, it will be done internally.
49    ///
50    /// A namespace should be used to prevent cross-domain attacks (where a signature can be reused
51    /// in a different context). It must be prepended to the message so that a signature meant for
52    /// one context cannot be used unexpectedly in another (i.e. signing a message on the network
53    /// layer can't accidentally spend funds on the execution layer). See
54    /// [commonware_utils::union_unique] for details.
55    fn sign(&self, namespace: Option<&[u8]>, msg: &[u8]) -> Self::Signature;
56}
57
58/// A [Signer] that can be serialized/deserialized.
59pub trait PrivateKey: Signer + Sized + ReadExt + Encode + PartialEq + Array {}
60
61/// A [PrivateKey] that can be generated from a seed or RNG.
62pub trait PrivateKeyExt: PrivateKey {
63    /// Create a [PrivateKey] from a seed.
64    ///
65    /// # Warning
66    ///
67    /// This function is insecure and should only be used for examples
68    /// and testing.
69    fn from_seed(seed: u64) -> Self {
70        let mut rng = ChaCha20Rng::seed_from_u64(seed);
71        Self::from_rng(&mut rng)
72    }
73
74    /// Create a fresh [PrivateKey] using the supplied RNG.
75    fn from_rng<R: Rng + CryptoRng>(rng: &mut R) -> Self;
76}
77
78/// Verifies [Signature]s over messages.
79pub trait Verifier {
80    /// The type of [Signature] that this verifier can verify.
81    type Signature: Signature;
82
83    /// Verify that a [Signature] is a valid over a given message.
84    ///
85    /// The message should not be hashed prior to calling this function. If a particular
86    /// scheme requires a payload to be hashed before it is signed, it will be done internally.
87    ///
88    /// Because namespace is prepended to message before signing, the namespace provided here must
89    /// match the namespace provided during signing.
90    fn verify(&self, namespace: Option<&[u8]>, msg: &[u8], sig: &Self::Signature) -> bool;
91}
92
93/// A [PublicKey], able to verify [Signature]s.
94pub trait PublicKey: Verifier + Sized + ReadExt + Encode + PartialEq + Array {}
95
96/// A [Signature] over a message.
97pub trait Signature: Sized + Clone + ReadExt + Encode + PartialEq + Array {}
98
99/// Verifies whether all [Signature]s are correct or that some [Signature] is incorrect.
100pub trait BatchVerifier<K: PublicKey> {
101    /// Create a new batch verifier.
102    fn new() -> Self;
103
104    /// Append item to the batch.
105    ///
106    /// The message should not be hashed prior to calling this function. If a particular scheme
107    /// requires a payload to be hashed before it is signed, it will be done internally.
108    ///
109    /// A namespace should be used to prevent replay attacks. It will be prepended to the message so
110    /// that a signature meant for one context cannot be used unexpectedly in another (i.e. signing
111    /// a message on the network layer can't accidentally spend funds on the execution layer). See
112    /// [commonware_utils::union_unique] for details.
113    fn add(
114        &mut self,
115        namespace: Option<&[u8]>,
116        message: &[u8],
117        public_key: &K,
118        signature: &K::Signature,
119    ) -> bool;
120
121    /// Verify all items added to the batch.
122    ///
123    /// Returns `true` if all items are valid, `false` otherwise.
124    ///
125    /// # Why Randomness?
126    ///
127    /// When performing batch verification, it is often important to add some randomness
128    /// to prevent an attacker from constructing a malicious batch of signatures that pass
129    /// batch verification but are invalid individually. Abstractly, think of this as
130    /// there existing two valid signatures (`c_1` and `c_2`) and an attacker proposing
131    /// (`c_1 + d` and `c_2 - d`).
132    ///
133    /// You can read more about this [here](https://ethresear.ch/t/security-of-bls-batch-verification/10748#the-importance-of-randomness-4).
134    fn verify<R: RngCore + CryptoRng>(self, rng: &mut R) -> bool;
135}
136
137/// Specializes the [commonware_utils::Array] trait with the Copy trait for cryptographic digests
138/// (which should be cheap to clone).
139pub trait Digest: Array + Copy {
140    /// Generate a random [Digest].
141    ///
142    /// # Warning
143    ///
144    /// This function is typically used for testing and is not recommended
145    /// for production use.
146    fn random<R: RngCore + CryptoRng>(rng: &mut R) -> Self;
147}
148
149/// An object that can be uniquely represented as a [Digest].
150pub trait Digestible: Clone + Sized + Send + Sync + 'static {
151    /// The type of digest produced by this object.
152    type Digest: Digest;
153
154    /// Returns a unique representation of the object as a [Digest].
155    ///
156    /// If many objects with [Digest]s are related (map to some higher-level
157    /// group [Digest]), you should also implement [Committable].
158    fn digest(&self) -> Self::Digest;
159}
160
161/// An object that can produce a commitment of itself.
162pub trait Committable: Clone + Sized + Send + Sync + 'static {
163    /// The type of commitment produced by this object.
164    type Commitment: Digest;
165
166    /// Returns the unique commitment of the object as a [Digest].
167    ///
168    /// For simple objects (like a block), this is often just the digest of the object
169    /// itself. For more complex objects, however, this may represent some root or base
170    /// of a proof structure (where many unique objects map to the same commitment).
171    ///
172    /// # Warning
173    ///
174    /// It must not be possible for two objects with the same [Digest] to map
175    /// to different commitments. Primitives assume there is a one-to-one
176    /// relation between digest and commitment and a one-to-many relation
177    /// between commitment and digest.
178    fn commitment(&self) -> Self::Commitment;
179}
180
181/// Interface that commonware crates rely on for hashing.
182///
183/// Hash functions in commonware primitives are not typically hardcoded
184/// to a specific algorithm (e.g. SHA-256) because different hash functions
185/// may work better with different cryptographic schemes, may be more efficient
186/// to use in STARK/SNARK proofs, or provide different levels of security (with some
187/// performance/size penalty).
188///
189/// This trait is required to implement the `Clone` trait because it is often
190/// part of a struct that is cloned. In practice, implementations do not actually
191/// clone the hasher state but users should not rely on this behavior and call `reset`
192/// after cloning.
193pub trait Hasher: Clone + Send + Sync + 'static {
194    /// Digest generated by the hasher.
195    type Digest: Digest;
196
197    /// Create a new hasher.
198    fn new() -> Self;
199
200    /// Append message to previously recorded data.
201    fn update(&mut self, message: &[u8]) -> &mut Self;
202
203    /// Hash all recorded data and reset the hasher
204    /// to the initial state.
205    fn finalize(&mut self) -> Self::Digest;
206
207    /// Reset the hasher without generating a hash.
208    ///
209    /// This function does not need to be called after `finalize`.
210    fn reset(&mut self) -> &mut Self;
211
212    /// Return result of hashing nothing.
213    fn empty() -> Self::Digest;
214
215    /// Hash a single message with a one-time-use hasher.
216    fn hash(message: &[u8]) -> Self::Digest {
217        Self::new().update(message).finalize()
218    }
219}
220
221#[cfg(test)]
222mod tests {
223    use super::*;
224    use commonware_codec::{DecodeExt, FixedSize};
225    use rand::rngs::OsRng;
226
227    fn test_validate<C: PrivateKeyExt>() {
228        let private_key = C::from_rng(&mut OsRng);
229        let public_key = private_key.public_key();
230        assert!(C::PublicKey::decode(public_key.as_ref()).is_ok());
231    }
232
233    fn test_validate_invalid_public_key<C: Signer>() {
234        let result = C::PublicKey::decode(vec![0; 1024].as_ref());
235        assert!(result.is_err());
236    }
237
238    fn test_sign_and_verify<C: PrivateKeyExt>() {
239        let private_key = C::from_seed(0);
240        let namespace = Some(&b"test_namespace"[..]);
241        let message = b"test_message";
242        let signature = private_key.sign(namespace, message);
243        let public_key = private_key.public_key();
244        assert!(public_key.verify(namespace, message, &signature));
245    }
246
247    fn test_sign_and_verify_wrong_message<C: PrivateKeyExt>() {
248        let private_key = C::from_seed(0);
249        let namespace: Option<&[u8]> = Some(&b"test_namespace"[..]);
250        let message = b"test_message";
251        let wrong_message = b"wrong_message";
252        let signature = private_key.sign(namespace, message);
253        let public_key = private_key.public_key();
254        assert!(!public_key.verify(namespace, wrong_message, &signature));
255    }
256
257    fn test_sign_and_verify_wrong_namespace<C: PrivateKeyExt>() {
258        let private_key = C::from_seed(0);
259        let namespace = Some(&b"test_namespace"[..]);
260        let wrong_namespace = Some(&b"wrong_namespace"[..]);
261        let message = b"test_message";
262        let signature = private_key.sign(namespace, message);
263        let public_key = private_key.public_key();
264        assert!(!public_key.verify(wrong_namespace, message, &signature));
265    }
266
267    fn test_empty_vs_none_namespace<C: PrivateKeyExt>() {
268        let private_key = C::from_seed(0);
269        let empty_namespace = Some(&b""[..]);
270        let message = b"test_message";
271        let signature = private_key.sign(empty_namespace, message);
272        let public_key = private_key.public_key();
273        assert!(public_key.verify(empty_namespace, message, &signature));
274        assert!(!public_key.verify(None, message, &signature));
275    }
276
277    fn test_signature_determinism<C: PrivateKeyExt>() {
278        let private_key_1 = C::from_seed(0);
279        let private_key_2 = C::from_seed(0);
280        let namespace = Some(&b"test_namespace"[..]);
281        let message = b"test_message";
282        let signature_1 = private_key_1.sign(namespace, message);
283        let signature_2 = private_key_2.sign(namespace, message);
284        assert_eq!(private_key_1.public_key(), private_key_2.public_key());
285        assert_eq!(signature_1, signature_2);
286    }
287
288    fn test_invalid_signature_publickey_pair<C: PrivateKeyExt>() {
289        let private_key = C::from_seed(0);
290        let private_key_2 = C::from_seed(1);
291        let namespace = Some(&b"test_namespace"[..]);
292        let message = b"test_message";
293        let signature = private_key.sign(namespace, message);
294        let public_key = private_key_2.public_key();
295        assert!(!public_key.verify(namespace, message, &signature));
296    }
297
298    #[test]
299    fn test_ed25519_validate() {
300        test_validate::<ed25519::PrivateKey>();
301    }
302
303    #[test]
304    fn test_ed25519_validate_invalid_public_key() {
305        test_validate_invalid_public_key::<ed25519::PrivateKey>();
306    }
307
308    #[test]
309    fn test_ed25519_sign_and_verify() {
310        test_sign_and_verify::<ed25519::PrivateKey>();
311    }
312
313    #[test]
314    fn test_ed25519_sign_and_verify_wrong_message() {
315        test_sign_and_verify_wrong_message::<ed25519::PrivateKey>();
316    }
317
318    #[test]
319    fn test_ed25519_sign_and_verify_wrong_namespace() {
320        test_sign_and_verify_wrong_namespace::<ed25519::PrivateKey>();
321    }
322
323    #[test]
324    fn test_ed25519_empty_vs_none_namespace() {
325        test_empty_vs_none_namespace::<ed25519::PrivateKey>();
326    }
327
328    #[test]
329    fn test_ed25519_signature_determinism() {
330        test_signature_determinism::<ed25519::PrivateKey>();
331    }
332
333    #[test]
334    fn test_ed25519_invalid_signature_publickey_pair() {
335        test_invalid_signature_publickey_pair::<ed25519::PrivateKey>();
336    }
337
338    #[test]
339    fn test_ed25519_len() {
340        assert_eq!(ed25519::PublicKey::SIZE, 32);
341        assert_eq!(ed25519::Signature::SIZE, 64);
342    }
343
344    #[test]
345    fn test_bls12381_validate() {
346        test_validate::<bls12381::PrivateKey>();
347    }
348
349    #[test]
350    fn test_bls12381_validate_invalid_public_key() {
351        test_validate_invalid_public_key::<bls12381::PrivateKey>();
352    }
353
354    #[test]
355    fn test_bls12381_sign_and_verify() {
356        test_sign_and_verify::<bls12381::PrivateKey>();
357    }
358
359    #[test]
360    fn test_bls12381_sign_and_verify_wrong_message() {
361        test_sign_and_verify_wrong_message::<bls12381::PrivateKey>();
362    }
363
364    #[test]
365    fn test_bls12381_sign_and_verify_wrong_namespace() {
366        test_sign_and_verify_wrong_namespace::<bls12381::PrivateKey>();
367    }
368
369    #[test]
370    fn test_bls12381_empty_vs_none_namespace() {
371        test_empty_vs_none_namespace::<bls12381::PrivateKey>();
372    }
373
374    #[test]
375    fn test_bls12381_signature_determinism() {
376        test_signature_determinism::<bls12381::PrivateKey>();
377    }
378
379    #[test]
380    fn test_bls12381_invalid_signature_publickey_pair() {
381        test_invalid_signature_publickey_pair::<bls12381::PrivateKey>();
382    }
383
384    #[test]
385    fn test_bls12381_len() {
386        assert_eq!(bls12381::PublicKey::SIZE, 48);
387        assert_eq!(bls12381::Signature::SIZE, 96);
388    }
389
390    #[test]
391    fn test_secp256r1_validate() {
392        test_validate::<secp256r1::PrivateKey>();
393    }
394
395    #[test]
396    fn test_secp256r1_validate_invalid_public_key() {
397        test_validate_invalid_public_key::<secp256r1::PrivateKey>();
398    }
399
400    #[test]
401    fn test_secp256r1_sign_and_verify() {
402        test_sign_and_verify::<secp256r1::PrivateKey>();
403    }
404
405    #[test]
406    fn test_secp256r1_sign_and_verify_wrong_message() {
407        test_sign_and_verify_wrong_message::<secp256r1::PrivateKey>();
408    }
409
410    #[test]
411    fn test_secp256r1_sign_and_verify_wrong_namespace() {
412        test_sign_and_verify_wrong_namespace::<secp256r1::PrivateKey>();
413    }
414
415    #[test]
416    fn test_secp256r1_empty_vs_none_namespace() {
417        test_empty_vs_none_namespace::<secp256r1::PrivateKey>();
418    }
419
420    #[test]
421    fn test_secp256r1_signature_determinism() {
422        test_signature_determinism::<secp256r1::PrivateKey>();
423    }
424
425    #[test]
426    fn test_secp256r1_invalid_signature_publickey_pair() {
427        test_invalid_signature_publickey_pair::<secp256r1::PrivateKey>();
428    }
429
430    #[test]
431    fn test_secp256r1_len() {
432        assert_eq!(secp256r1::PublicKey::SIZE, 33);
433        assert_eq!(secp256r1::Signature::SIZE, 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::decode(digest.as_ref()).is_ok());
442        assert_eq!(digest.as_ref().len(), H::Digest::SIZE);
443
444        // Reuse hasher without reset
445        hasher.update(b"hello world");
446        let digest_again = hasher.finalize();
447        assert!(H::Digest::decode(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::decode(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::decode(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::decode(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::decode(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::decode(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::decode(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}