literate_crypto/
pubkey.rs

1use std::fmt;
2
3pub mod ecc;
4
5use docext::docext;
6pub use ecc::{
7    Ecdsa,
8    EcdsaSignature,
9    InvalidPrivateKey,
10    MultiSchnorr,
11    Schnorr,
12    SchnorrRandomness,
13    SchnorrSag,
14    SchnorrSagSignature,
15    SchnorrSignature,
16    Secp256k1,
17};
18
19// TODO Probably split these interfaces into different modules
20// TODO Also do Pedersen commitments
21
22/// A signature scheme is a method by which an actor proves that he generated a
23/// message.
24///
25/// The actor first creates two keys. The _private key_ is kept secret, and if
26/// revealed the identity of the actor becomes compromised. The _public key_ is
27/// derived from the private key, and is not secret. The actor can publicly
28/// announce this key and tie his identity to it, with the ability to
29/// use his private key to prove that identity.
30///
31/// The actor _signs_ messages with his private key, thereby vouching that
32/// they are authentic to him. Anybody can use the public key to _verify_ that
33/// the signature was indeed generated by the corresponding private key, and
34/// hence by the corresponding actor. Because the private key is secret, and
35/// it's impossible to generate a signature without the private key, signatures
36/// cannot be faked.
37///
38/// Signatures are typically short, and usually message [hashes](crate::Hash)
39/// are signed rather than the raw message text.
40pub trait SignatureScheme {
41    type PublicKey;
42    type PrivateKey;
43    type Signature;
44
45    /// Sign the given message with the given private key.
46    fn sign(&mut self, key: Self::PrivateKey, msg: &[u8]) -> Self::Signature;
47
48    /// Verify that the given message was signed by the private key
49    /// corresponding to the given public key. If verification fails, an
50    /// [`InvalidSignature`] error is returned.
51    fn verify(
52        &mut self,
53        key: Self::PublicKey,
54        msg: &[u8],
55        sig: &Self::Signature,
56    ) -> Result<(), InvalidSignature>;
57}
58
59/// A multisig scheme is similar to a [regular signature](SignatureScheme),
60/// except that it is signed by multiple private keys and verified with multiple
61/// public keys.
62///
63/// A multisig scheme allows multiple actors to collaboratively sign a message,
64/// and allows any verifier to reject the message unless every actor contributed
65/// his signature. This is useful, for example, for implementing a shared bank
66/// account on which transactions can only go though with the approval of every
67/// owner.
68pub trait MultisigScheme {
69    type Multisig: Default;
70    type PublicKey;
71    type PrivateKey;
72
73    /// Sign the given message with the given private key and append the
74    /// individual signature to the given multisig.
75    fn sign(&mut self, key: Self::PrivateKey, msg: &[u8], sig: Self::Multisig) -> Self::Multisig;
76
77    /// Verify the given multisig.
78    fn verify(
79        &mut self,
80        keys: &[Self::PublicKey],
81        msg: &[u8],
82        sig: &Self::Multisig,
83    ) -> Result<(), InvalidSignature>;
84}
85
86/// Ring signature scheme.
87///
88/// Given randomly selected _decoy pubkeys_ $P_1, P_2, \dots, P_{n-1}$ and a
89/// real private key $p_n$ with the corresponding pubkey $P_n$, a ring signature
90/// can be verified to have been singed by a private key corresponding to one of
91/// $P_1, P_2, \dots, P_n$ without knowing which private key was actually used.
92///
93/// This allows an actor to make a signature on behalf of a group, effectively
94/// proving that _somebody_ from that group is making a statement without
95/// revealing who it is.
96///
97/// For example, a disgruntled employee can blow a whistle on his company, using
98/// a ring signature which includes all employee pubkeys as decoys. This way he
99/// can prove that the whistle is indeed coming from a company employee, without
100/// revealing his true identity.
101#[docext]
102pub trait RingScheme {
103    type RingSignature;
104    type PublicKey;
105    type PrivateKey;
106
107    fn sign(
108        &mut self,
109        key: Self::PrivateKey,
110        decoys: &[Self::PublicKey],
111        msg: &[u8],
112    ) -> Self::RingSignature;
113
114    fn verify(&mut self, msg: &[u8], sig: &Self::RingSignature) -> Result<(), InvalidSignature>;
115}
116
117/// Error indicating that a signature is invalid.
118#[derive(Debug, Clone, Copy)]
119pub struct InvalidSignature;
120
121impl fmt::Display for InvalidSignature {
122    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123        write!(f, "invalid signature")
124    }
125}
126
127impl std::error::Error for InvalidSignature {}