ark-r1cs-std/crypto-primitives/src/signature/mod.rs
crypto-primitives/src/signature/mod.rsRaw
1use crate::Error;
2use algebra::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 curves::edwards_sw6::EdwardsAffine as Edwards, 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(¶meters, rng).unwrap();
66 let sig = S::sign(¶meters, &sk, &message, rng).unwrap();
67 assert!(S::verify(¶meters, &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(¶meters, rng).unwrap();
74 let sig = S::sign(¶meters, &sk, message, rng).unwrap();
75 assert!(!S::verify(¶meters, &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(¶meters, rng).unwrap();
82 let sig = S::sign(¶meters, &sk, message, rng).unwrap();
83 assert!(S::verify(¶meters, &pk, message, &sig).unwrap());
84 let randomized_pk = S::randomize_public_key(¶meters, &pk, randomness).unwrap();
85 let randomized_sig = S::randomize_signature(¶meters, &sig, randomness).unwrap();
86 assert!(S::verify(¶meters, &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<Edwards, Blake2s>>(message.as_bytes());
94 failed_verification::<SchnorrSignature<Edwards, Blake2s>>(
95 message.as_bytes(),
96 "Bad message".as_bytes(),
97 );
98 let random_scalar = to_bytes!(<Edwards as Group>::ScalarField::rand(rng)).unwrap();
99 randomize_and_verify::<SchnorrSignature<Edwards, Blake2s>>(
100 message.as_bytes(),
101 &random_scalar.as_slice(),
102 );
103 }
104}