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 {}