arnaucube
arnaucube/ark-r1cs-stdPublic Self-hosted repository
ark-r1cs-std/crypto-primitives/src/signature/mod.rs
crypto-primitives/src/signature/mod.rsRaw
  1use crate::Error;
  2use algebra_core::bytes::ToBytes;
  3use core::hash::Hash;
  4use rand::Rng;
  5
  6#[cfg(feature = "r1cs")]
  7pub mod constraints;
  8#[cfg(feature = "r1cs")]
  9pub use constraints::*;
 10
 11pub mod schnorr;
 12
 13pub trait SignatureScheme {
 14    type Parameters: Clone + Send + Sync;
 15    type PublicKey: ToBytes + Hash + Eq + Clone + Default + Send + Sync;
 16    type SecretKey: ToBytes + Clone + Default;
 17    type Signature: Clone + Default + Send + Sync;
 18
 19    fn setup<R: Rng>(rng: &mut R) -> Result<Self::Parameters, Error>;
 20
 21    fn keygen<R: Rng>(
 22        pp: &Self::Parameters,
 23        rng: &mut R,
 24    ) -> Result<(Self::PublicKey, Self::SecretKey), Error>;
 25
 26    fn sign<R: Rng>(
 27        pp: &Self::Parameters,
 28        sk: &Self::SecretKey,
 29        message: &[u8],
 30        rng: &mut R,
 31    ) -> Result<Self::Signature, Error>;
 32
 33    fn verify(
 34        pp: &Self::Parameters,
 35        pk: &Self::PublicKey,
 36        message: &[u8],
 37        signature: &Self::Signature,
 38    ) -> Result<bool, Error>;
 39
 40    fn randomize_public_key(
 41        pp: &Self::Parameters,
 42        public_key: &Self::PublicKey,
 43        randomness: &[u8],
 44    ) -> Result<Self::PublicKey, Error>;
 45
 46    fn randomize_signature(
 47        pp: &Self::Parameters,
 48        signature: &Self::Signature,
 49        randomness: &[u8],
 50    ) -> Result<Self::Signature, Error>;
 51}
 52
 53#[cfg(test)]
 54mod test {
 55    use crate::{signature::schnorr::SchnorrSignature, SignatureScheme};
 56    use algebra::{
 57        groups::Group, jubjub::JubJubAffine as JubJub, test_rng, to_bytes, ToBytes, UniformRand,
 58    };
 59    use blake2::Blake2s;
 60
 61    fn sign_and_verify<S: SignatureScheme>(message: &[u8]) {
 62        let rng = &mut test_rng();
 63        let parameters = S::setup::<_>(rng).unwrap();
 64        let (pk, sk) = S::keygen(&parameters, rng).unwrap();
 65        let sig = S::sign(&parameters, &sk, &message, rng).unwrap();
 66        assert!(S::verify(&parameters, &pk, &message, &sig).unwrap());
 67    }
 68
 69    fn failed_verification<S: SignatureScheme>(message: &[u8], bad_message: &[u8]) {
 70        let rng = &mut test_rng();
 71        let parameters = S::setup::<_>(rng).unwrap();
 72        let (pk, sk) = S::keygen(&parameters, rng).unwrap();
 73        let sig = S::sign(&parameters, &sk, message, rng).unwrap();
 74        assert!(!S::verify(&parameters, &pk, bad_message, &sig).unwrap());
 75    }
 76
 77    fn randomize_and_verify<S: SignatureScheme>(message: &[u8], randomness: &[u8]) {
 78        let rng = &mut test_rng();
 79        let parameters = S::setup::<_>(rng).unwrap();
 80        let (pk, sk) = S::keygen(&parameters, rng).unwrap();
 81        let sig = S::sign(&parameters, &sk, message, rng).unwrap();
 82        assert!(S::verify(&parameters, &pk, message, &sig).unwrap());
 83        let randomized_pk = S::randomize_public_key(&parameters, &pk, randomness).unwrap();
 84        let randomized_sig = S::randomize_signature(&parameters, &sig, randomness).unwrap();
 85        assert!(S::verify(&parameters, &randomized_pk, &message, &randomized_sig).unwrap());
 86    }
 87
 88    #[test]
 89    fn schnorr_signature_test() {
 90        let message = "Hi, I am a Schnorr signature!";
 91        let rng = &mut test_rng();
 92        sign_and_verify::<SchnorrSignature<JubJub, Blake2s>>(message.as_bytes());
 93        failed_verification::<SchnorrSignature<JubJub, Blake2s>>(
 94            message.as_bytes(),
 95            "Bad message".as_bytes(),
 96        );
 97        let random_scalar = to_bytes!(<JubJub as Group>::ScalarField::rand(rng)).unwrap();
 98        randomize_and_verify::<SchnorrSignature<JubJub, Blake2s>>(
 99            message.as_bytes(),
100            &random_scalar.as_slice(),
101        );
102    }
103}