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        ed_on_bls12_381::EdwardsAffine as JubJub, groups::Group, test_rng, to_bytes, ToBytes,
 58        UniformRand,
 59    };
 60    use blake2::Blake2s;
 61
 62    fn sign_and_verify<S: SignatureScheme>(message: &[u8]) {
 63        let rng = &mut test_rng();
 64        let parameters = S::setup::<_>(rng).unwrap();
 65        let (pk, sk) = S::keygen(&parameters, rng).unwrap();
 66        let sig = S::sign(&parameters, &sk, &message, rng).unwrap();
 67        assert!(S::verify(&parameters, &pk, &message, &sig).unwrap());
 68    }
 69
 70    fn failed_verification<S: SignatureScheme>(message: &[u8], bad_message: &[u8]) {
 71        let rng = &mut test_rng();
 72        let parameters = S::setup::<_>(rng).unwrap();
 73        let (pk, sk) = S::keygen(&parameters, rng).unwrap();
 74        let sig = S::sign(&parameters, &sk, message, rng).unwrap();
 75        assert!(!S::verify(&parameters, &pk, bad_message, &sig).unwrap());
 76    }
 77
 78    fn randomize_and_verify<S: SignatureScheme>(message: &[u8], randomness: &[u8]) {
 79        let rng = &mut test_rng();
 80        let parameters = S::setup::<_>(rng).unwrap();
 81        let (pk, sk) = S::keygen(&parameters, rng).unwrap();
 82        let sig = S::sign(&parameters, &sk, message, rng).unwrap();
 83        assert!(S::verify(&parameters, &pk, message, &sig).unwrap());
 84        let randomized_pk = S::randomize_public_key(&parameters, &pk, randomness).unwrap();
 85        let randomized_sig = S::randomize_signature(&parameters, &sig, randomness).unwrap();
 86        assert!(S::verify(&parameters, &randomized_pk, &message, &randomized_sig).unwrap());
 87    }
 88
 89    #[test]
 90    fn schnorr_signature_test() {
 91        let message = "Hi, I am a Schnorr signature!";
 92        let rng = &mut test_rng();
 93        sign_and_verify::<SchnorrSignature<JubJub, Blake2s>>(message.as_bytes());
 94        failed_verification::<SchnorrSignature<JubJub, Blake2s>>(
 95            message.as_bytes(),
 96            "Bad message".as_bytes(),
 97        );
 98        let random_scalar = to_bytes!(<JubJub as Group>::ScalarField::rand(rng)).unwrap();
 99        randomize_and_verify::<SchnorrSignature<JubJub, Blake2s>>(
100            message.as_bytes(),
101            &random_scalar.as_slice(),
102        );
103    }
104}