literate-crypto 0.0.3

Literate Cryptography by 12hbender
Documentation
use std::fmt;

pub mod ecc;

use docext::docext;
pub use ecc::{
    Ecdsa,
    EcdsaSignature,
    InvalidPrivateKey,
    MultiSchnorr,
    Schnorr,
    SchnorrRandomness,
    SchnorrSag,
    SchnorrSagSignature,
    SchnorrSignature,
    Secp256k1,
};

// TODO Probably split these interfaces into different modules
// TODO Also do Pedersen commitments

/// A signature scheme is a method by which an actor proves that he generated a
/// message.
///
/// The actor first creates two keys. The _private key_ is kept secret, and if
/// revealed the identity of the actor becomes compromised. The _public key_ is
/// derived from the private key, and is not secret. The actor can publicly
/// announce this key and tie his identity to it, with the ability to
/// use his private key to prove that identity.
///
/// The actor _signs_ messages with his private key, thereby vouching that
/// they are authentic to him. Anybody can use the public key to _verify_ that
/// the signature was indeed generated by the corresponding private key, and
/// hence by the corresponding actor. Because the private key is secret, and
/// it's impossible to generate a signature without the private key, signatures
/// cannot be faked.
///
/// Signatures are typically short, and usually message [hashes](crate::Hash)
/// are signed rather than the raw message text.
pub trait SignatureScheme {
    type PublicKey;
    type PrivateKey;
    type Signature;

    /// Sign the given message with the given private key.
    fn sign(&mut self, key: Self::PrivateKey, msg: &[u8]) -> Self::Signature;

    /// Verify that the given message was signed by the private key
    /// corresponding to the given public key. If verification fails, an
    /// [`InvalidSignature`] error is returned.
    fn verify(
        &mut self,
        key: Self::PublicKey,
        msg: &[u8],
        sig: &Self::Signature,
    ) -> Result<(), InvalidSignature>;
}

/// A multisig scheme is similar to a [regular signature](SignatureScheme),
/// except that it is signed by multiple private keys and verified with multiple
/// public keys.
///
/// A multisig scheme allows multiple actors to collaboratively sign a message,
/// and allows any verifier to reject the message unless every actor contributed
/// his signature. This is useful, for example, for implementing a shared bank
/// account on which transactions can only go though with the approval of every
/// owner.
pub trait MultisigScheme {
    type Multisig: Default;
    type PublicKey;
    type PrivateKey;

    /// Sign the given message with the given private key and append the
    /// individual signature to the given multisig.
    fn sign(&mut self, key: Self::PrivateKey, msg: &[u8], sig: Self::Multisig) -> Self::Multisig;

    /// Verify the given multisig.
    fn verify(
        &mut self,
        keys: &[Self::PublicKey],
        msg: &[u8],
        sig: &Self::Multisig,
    ) -> Result<(), InvalidSignature>;
}

/// Ring signature scheme.
///
/// Given randomly selected _decoy pubkeys_ $P_1, P_2, \dots, P_{n-1}$ and a
/// real private key $p_n$ with the corresponding pubkey $P_n$, a ring signature
/// can be verified to have been singed by a private key corresponding to one of
/// $P_1, P_2, \dots, P_n$ without knowing which private key was actually used.
///
/// This allows an actor to make a signature on behalf of a group, effectively
/// proving that _somebody_ from that group is making a statement without
/// revealing who it is.
///
/// For example, a disgruntled employee can blow a whistle on his company, using
/// a ring signature which includes all employee pubkeys as decoys. This way he
/// can prove that the whistle is indeed coming from a company employee, without
/// revealing his true identity.
#[docext]
pub trait RingScheme {
    type RingSignature;
    type PublicKey;
    type PrivateKey;

    fn sign(
        &mut self,
        key: Self::PrivateKey,
        decoys: &[Self::PublicKey],
        msg: &[u8],
    ) -> Self::RingSignature;

    fn verify(&mut self, msg: &[u8], sig: &Self::RingSignature) -> Result<(), InvalidSignature>;
}

/// Error indicating that a signature is invalid.
#[derive(Debug, Clone, Copy)]
pub struct InvalidSignature;

impl fmt::Display for InvalidSignature {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "invalid signature")
    }
}

impl std::error::Error for InvalidSignature {}