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