Skip to content

Commit c65c691

Browse files
committed
Finished taking into account the review comments.
1 parent 9f851d7 commit c65c691

File tree

10 files changed

+310
-262
lines changed

10 files changed

+310
-262
lines changed

mithril-stm/benches/multi_sig.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use blake2::{Blake2b, Digest, digest::consts::U64};
22
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
3-
use mithril_stm::{BlsSignature, BlsSigningKey, BlsVerificationKey};
43
use rand_chacha::ChaCha20Rng;
54
use rand_core::{RngCore, SeedableRng};
65

6+
use mithril_stm::{BlsSignature, BlsSigningKey, BlsVerificationKey};
7+
78
fn batch_benches(c: &mut Criterion, array_batches: &[usize], nr_sigs: usize) {
89
let mut group = c.benchmark_group("MultiSig".to_string());
910
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
@@ -66,7 +67,7 @@ fn aggregate_and_verify(c: &mut Criterion, nr_sigs: usize) {
6667
})
6768
});
6869

69-
group.bench_function(BenchmarkId::new("Individual verif", nr_sigs), |b| {
70+
group.bench_function(BenchmarkId::new("Verification", nr_sigs), |b| {
7071
b.iter(|| {
7172
for (vk, sig) in mvks.iter().zip(sigs.iter()) {
7273
assert!(sig.verify(&msg, vk).is_ok());
@@ -97,7 +98,7 @@ fn batch_bls_benches(c: &mut Criterion) {
9798
criterion_group!(name = benches;
9899
config = Criterion::default().nresamples(1000);
99100
targets =
100-
// batch_multi_sig_benches,
101+
batch_multi_sig_benches,
101102
batch_bls_benches
102103
);
103104
criterion_main!(benches);

mithril-stm/benches/schnorr_sig.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
22
use dusk_jubjub::Fq as JubjubBase;
33
use dusk_poseidon::{Domain, Hash};
4-
5-
use mithril_stm::{SchnorrSigningKey, SchnorrVerificationKey};
64
use rand_chacha::ChaCha20Rng;
75
use rand_core::{RngCore, SeedableRng};
86

7+
use mithril_stm::{SchnorrSigningKey, SchnorrVerificationKey};
8+
99
fn dusk_poseidon_hash(c: &mut Criterion, nr_sigs: usize) {
1010
let mut group = c.benchmark_group("Schnorr".to_string());
1111

@@ -45,7 +45,7 @@ fn sign_and_verify(c: &mut Criterion, nr_sigs: usize) {
4545
let mut msks = Vec::new();
4646
let mut sigs = Vec::new();
4747
for _ in 0..nr_sigs {
48-
let sk = SchnorrSigningKey::generate(&mut rng).unwrap();
48+
let sk = SchnorrSigningKey::try_generate(&mut rng).unwrap();
4949
let vk = SchnorrVerificationKey::from(&sk);
5050
let sig = sk.sign(&msg, &mut rng_sig).unwrap();
5151
sigs.push(sig);

mithril-stm/benches/size_benches.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@ use blake2::{
33
Blake2b, Digest,
44
digest::consts::{U32, U64},
55
};
6-
use mithril_stm::{
7-
AggregateSignatureType, BasicVerifier, Clerk, Initializer, KeyRegistration, Parameters, Signer,
8-
SingleSignature, SingleSignatureWithRegisteredParty, Stake, VerificationKey,
9-
};
106
use rand_chacha::ChaCha20Rng;
117
use rand_core::{RngCore, SeedableRng};
128
use rayon::iter::ParallelIterator;
139
use rayon::prelude::{IntoParallelIterator, IntoParallelRefIterator};
1410

11+
use mithril_stm::{
12+
AggregateSignatureType, BasicVerifier, Clerk, Initializer, KeyRegistration, Parameters, Signer,
13+
SingleSignature, SingleSignatureWithRegisteredParty, Stake, VerificationKey,
14+
};
15+
1516
fn size<H>(k: u64, m: u64, nparties: usize, hash_name: &str)
1617
where
1718
H: Digest + Clone + Sync + Send + Default + FixedOutput,

mithril-stm/src/error.rs

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ use crate::aggregate_signature::AggregateSignatureType;
77
use crate::bls_multi_signature::{
88
BlsSignature, BlsVerificationKey, BlsVerificationKeyProofOfPossession,
99
};
10-
#[cfg(feature = "future_snark")]
11-
use crate::{SchnorrSignature, SchnorrVerificationKey};
1210

1311
/// Error types for multi signatures.
1412
#[derive(Debug, thiserror::Error, Eq, PartialEq)]
@@ -42,27 +40,6 @@ pub enum MultiSignatureError {
4240
VerificationKeyInfinity(Box<BlsVerificationKey>),
4341
}
4442

45-
/// Error types for Schnorr signatures.
46-
#[cfg(feature = "future_snark")]
47-
#[derive(Debug, thiserror::Error, Eq, PartialEq)]
48-
pub enum SchnorrSignatureError {
49-
/// Invalid Single signature
50-
#[error("Invalid Schnorr single signature")]
51-
SignatureInvalid(Box<SchnorrSignature>),
52-
53-
/// Invalid Verification key
54-
#[error("Invalid Schnorr Verification key")]
55-
VerificationKeyInvalid(Box<SchnorrVerificationKey>),
56-
57-
/// This error occurs when the serialization of the raw bytes failed
58-
#[error("Invalid bytes")]
59-
SerializationError,
60-
61-
/// This error occurs when the signing key fails to generate
62-
#[error("Invalid generation of the signing key")]
63-
SigningKeyGenerationError,
64-
}
65-
6643
/// Error types related to merkle trees.
6744
#[derive(Debug, Clone, thiserror::Error)]
6845
pub enum MerkleTreeError {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#[cfg(feature = "future_snark")]
2+
use crate::{SchnorrSignature, SchnorrVerificationKey};
3+
4+
/// Error types for Schnorr signatures.
5+
#[cfg(feature = "future_snark")]
6+
#[derive(Debug, thiserror::Error, Eq, PartialEq)]
7+
pub enum SchnorrSignatureError {
8+
/// Invalid Single signature
9+
#[error("Invalid Schnorr single signature")]
10+
SignatureInvalid(Box<SchnorrSignature>),
11+
12+
/// Invalid Verification key
13+
#[error("Invalid Schnorr Verification key")]
14+
VerificationKeyInvalid(Box<SchnorrVerificationKey>),
15+
16+
/// This error occurs when the serialization of the raw bytes failed
17+
#[error("Invalid bytes")]
18+
SerializationError,
19+
20+
/// This error occurs when the signing key fails to generate
21+
#[error("Failed generation of the signing key")]
22+
SigningKeyGenerationError,
23+
24+
/// This error occurs when the random scalar fails to generate during the signature
25+
#[error("Failed generation of the signature's random scalar")]
26+
RandomScalarGenerationError,
27+
}
Lines changed: 3 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,16 @@
1-
// TODO: Remove
2-
#![allow(dead_code)]
3-
1+
mod error;
42
mod signature;
53
mod signing_key;
64
mod utils;
75
mod verification_key;
86

7+
pub use error::*;
98
pub use signature::*;
109
pub use signing_key::*;
11-
pub use utils::*;
10+
pub(crate) use utils::*;
1211
pub use verification_key::*;
1312

1413
use dusk_jubjub::Fq as JubjubBase;
1514

1615
/// A DST (Domain Separation Tag) to distinguish between use of Poseidon hash
1716
const DST_SIGNATURE: JubjubBase = JubjubBase::from_raw([0u64, 0, 0, 0]);
18-
19-
#[cfg(test)]
20-
mod tests {
21-
22-
use super::*;
23-
use dusk_jubjub::SubgroupPoint as JubjubSubgroup;
24-
use ff::Field;
25-
use rand_chacha::ChaCha20Rng;
26-
use rand_core::SeedableRng;
27-
28-
use crate::schnorr_signature::{SchnorrSigningKey, SchnorrVerificationKey};
29-
30-
#[test]
31-
fn sign_and_verify() {
32-
let msg = vec![0, 0, 0, 1];
33-
let seed = [0u8; 32];
34-
let mut rng = ChaCha20Rng::from_seed(seed);
35-
let sk = SchnorrSigningKey::generate(&mut rng).unwrap();
36-
let vk = SchnorrVerificationKey::from(&sk);
37-
38-
let sig = sk.sign(&msg, &mut rng).unwrap();
39-
40-
sig.verify(&msg, &vk).unwrap();
41-
}
42-
43-
#[test]
44-
fn invalid_sig() {
45-
let msg = vec![0, 0, 0, 1];
46-
let msg2 = vec![0, 0, 0, 2];
47-
let seed = [0u8; 32];
48-
let mut rng = ChaCha20Rng::from_seed(seed);
49-
let sk = SchnorrSigningKey::generate(&mut rng).unwrap();
50-
let vk = SchnorrVerificationKey::from(&sk);
51-
let sk2 = SchnorrSigningKey::generate(&mut rng).unwrap();
52-
let vk2 = SchnorrVerificationKey::from(&sk2);
53-
54-
let sig = sk.sign(&msg, &mut rng).unwrap();
55-
let sig2 = sk.sign(&msg2, &mut rng).unwrap();
56-
57-
// Wrong verification key is used
58-
let result1 = sig.verify(&msg, &vk2);
59-
let result2 = sig2.verify(&msg, &vk);
60-
61-
assert!(
62-
result1.is_err(),
63-
"Wrong verfication key used, test should fail."
64-
);
65-
// Wrong message is verified
66-
assert!(result2.is_err(), "Wrong message used, test should fail.");
67-
}
68-
69-
#[test]
70-
fn verify_fail_verification_key_not_on_curve() {
71-
let msg = vec![0, 0, 0, 1];
72-
let seed = [0u8; 32];
73-
let mut rng = ChaCha20Rng::from_seed(seed);
74-
let sk = SchnorrSigningKey::generate(&mut rng).unwrap();
75-
let vk1 = SchnorrVerificationKey::from(&sk);
76-
let sig = sk.sign(&msg, &mut rng).unwrap();
77-
let vk2 = SchnorrVerificationKey(JubjubSubgroup::from_raw_unchecked(
78-
JubjubBase::ONE,
79-
JubjubBase::ONE,
80-
));
81-
82-
let result1 = sig.verify(&msg, &vk1);
83-
let result2 = sig.verify(&msg, &vk2);
84-
85-
assert!(
86-
result1.is_ok(),
87-
"Correct verification key used, test should pass."
88-
);
89-
assert!(
90-
result2.is_err(),
91-
"Invalid verification key used, test should fail."
92-
);
93-
}
94-
}

mithril-stm/src/schnorr_signature/signature.rs

Lines changed: 75 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
use anyhow::{Context, anyhow};
22
use dusk_jubjub::{
3-
ExtendedPoint as JubjubExtended, Fr as JubjubScalar, SubgroupPoint as JubjubSubgroup,
3+
ExtendedPoint as JubjubExtended, Fq as JubjubBase, Fr as JubjubScalar,
4+
SubgroupPoint as JubjubSubgroup,
45
};
56
use dusk_poseidon::{Domain, Hash};
67
use group::{Group, GroupEncoding};
78

89
use crate::{
910
StmResult,
10-
error::SchnorrSignatureError,
1111
schnorr_signature::{
12-
DST_SIGNATURE, SchnorrVerificationKey, get_coordinates_several_points, is_on_curve,
12+
DST_SIGNATURE, SchnorrSignatureError, SchnorrVerificationKey,
13+
get_coordinates_several_points, is_on_curve,
1314
},
1415
};
1516

@@ -25,7 +26,6 @@ pub struct SchnorrSignature {
2526
/// Part of the Schnorr signature depending on the secret key
2627
pub(crate) signature: JubjubScalar,
2728
/// Part of the Schnorr signature NOT depending on the secret key
28-
// pub(crate) challenge: JubjubBase,
2929
pub(crate) challenge: JubjubScalar,
3030
}
3131

@@ -48,7 +48,7 @@ impl SchnorrSignature {
4848
/// || sigma || random_point_1_recomputed || random_point_2_recomputed)
4949
///
5050
/// Check: challenge == challenge_recomputed
51-
///
51+
///
5252
pub fn verify(&self, msg: &[u8], verification_key: &SchnorrVerificationKey) -> StmResult<()> {
5353
// Check that the verification key is on the curve
5454
if !is_on_curve(verification_key.0.into()) {
@@ -83,7 +83,12 @@ impl SchnorrSignature {
8383
]);
8484

8585
let mut poseidon_input = vec![DST_SIGNATURE];
86-
poseidon_input.extend(points_coordinates);
86+
poseidon_input.extend(
87+
points_coordinates
88+
.into_iter()
89+
.flat_map(|(x, y)| [x, y])
90+
.collect::<Vec<JubjubBase>>(),
91+
);
8792

8893
let challenge_recomputed = Hash::digest_truncated(Domain::Other, &poseidon_input)[0];
8994

@@ -96,7 +101,7 @@ impl SchnorrSignature {
96101
Ok(())
97102
}
98103

99-
/// Convert an `SchnorrSignature` to a byte representation.
104+
/// Convert an `SchnorrSignature` into bytes.
100105
pub fn to_bytes(self) -> [u8; 96] {
101106
let mut out = [0; 96];
102107
out[0..32].copy_from_slice(&self.sigma.to_bytes());
@@ -106,9 +111,7 @@ impl SchnorrSignature {
106111
out
107112
}
108113

109-
/// Convert a string of bytes into a `SchnorrSignature`.
110-
///
111-
/// Not sure the sigma, s and c creation can fail if the 96 bytes are correctly extracted.
114+
/// Convert bytes into a `SchnorrSignature`.
112115
pub fn from_bytes(bytes: &[u8]) -> StmResult<Self> {
113116
if bytes.len() < 96 {
114117
return Err(anyhow!(SchnorrSignatureError::SerializationError))
@@ -151,18 +154,41 @@ impl SchnorrSignature {
151154
}
152155

153156
#[cfg(test)]
154-
mod test {
157+
mod tests {
155158

156-
use crate::{SchnorrSignature, SchnorrSigningKey};
159+
use crate::{SchnorrSignature, SchnorrSigningKey, SchnorrVerificationKey};
157160
use rand_chacha::ChaCha20Rng;
158161
use rand_core::SeedableRng;
159162

163+
#[test]
164+
fn invalid_sig() {
165+
let msg = vec![0, 0, 0, 1];
166+
let msg2 = vec![0, 0, 0, 2];
167+
let seed = [0u8; 32];
168+
let mut rng = ChaCha20Rng::from_seed(seed);
169+
let sk = SchnorrSigningKey::try_generate(&mut rng).unwrap();
170+
let vk = SchnorrVerificationKey::from(&sk);
171+
let sk2 = SchnorrSigningKey::try_generate(&mut rng).unwrap();
172+
let vk2 = SchnorrVerificationKey::from(&sk2);
173+
174+
let sig = sk.sign(&msg, &mut rng).unwrap();
175+
let sig2 = sk.sign(&msg2, &mut rng).unwrap();
176+
177+
// Wrong verification key is used
178+
let result1 = sig.verify(&msg, &vk2);
179+
let result2 = sig2.verify(&msg, &vk);
180+
181+
result1.expect_err("Wrong verification key used, test should fail.");
182+
// Wrong message is verified
183+
result2.expect_err("Wrong message used, test should fail.");
184+
}
185+
160186
#[test]
161187
fn serialize_deserialize_signature() {
162188
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
163189

164190
let msg = vec![0, 0, 0, 1];
165-
let sk = SchnorrSigningKey::generate(&mut rng).unwrap();
191+
let sk = SchnorrSigningKey::try_generate(&mut rng).unwrap();
166192

167193
let sig = sk.sign(&msg, &mut rng).unwrap();
168194
let sig_bytes: [u8; 96] = sig.to_bytes();
@@ -177,6 +203,41 @@ mod test {
177203

178204
let result = SchnorrSignature::from_bytes(&msg);
179205

180-
assert!(result.is_err());
206+
result.expect_err("Not enough bytes.");
207+
}
208+
209+
mod golden {
210+
211+
use rand_chacha::ChaCha20Rng;
212+
use rand_core::SeedableRng;
213+
214+
use crate::schnorr_signature::{SchnorrSignature, SchnorrSigningKey};
215+
216+
const GOLDEN_BYTES: &[u8; 96] = &[
217+
143, 53, 198, 62, 178, 1, 88, 253, 21, 92, 100, 13, 72, 180, 198, 127, 39, 175, 102,
218+
69, 147, 249, 244, 224, 122, 121, 248, 68, 217, 242, 158, 113, 94, 57, 200, 241, 208,
219+
145, 251, 8, 92, 119, 163, 38, 81, 85, 54, 36, 193, 221, 254, 242, 21, 129, 110, 161,
220+
142, 184, 107, 156, 100, 34, 190, 9, 200, 20, 178, 142, 61, 253, 193, 11, 5, 180, 97,
221+
73, 125, 88, 162, 36, 30, 177, 225, 52, 136, 21, 138, 93, 81, 23, 19, 64, 82, 78, 229,
222+
3,
223+
];
224+
225+
fn golden_value() -> SchnorrSignature {
226+
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
227+
let sk = SchnorrSigningKey::try_generate(&mut rng).unwrap();
228+
let msg = [0u8; 32];
229+
sk.sign(&msg, &mut rng).unwrap()
230+
}
231+
232+
#[test]
233+
fn golden_conversions() {
234+
let value = SchnorrSignature::from_bytes(GOLDEN_BYTES)
235+
.expect("This from bytes should not fail");
236+
assert_eq!(golden_value(), value);
237+
238+
let serialized = SchnorrSignature::to_bytes(value);
239+
let golden_serialized = SchnorrSignature::to_bytes(golden_value());
240+
assert_eq!(golden_serialized, serialized);
241+
}
181242
}
182243
}

0 commit comments

Comments
 (0)