Skip to content

Commit 0013261

Browse files
committed
Added to/from bytes for SchnorrSignature and started adding tests.
1 parent 7fc900d commit 0013261

File tree

5 files changed

+109
-85
lines changed

5 files changed

+109
-85
lines changed

mithril-stm/src/schnorr_signatures/helper.rs

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,12 @@
1-
use midnight_circuits::{
2-
ecc::{
3-
hash_to_curve::HashToCurveGadget,
4-
native::EccChip,
5-
},
6-
hash::poseidon::PoseidonChip,
7-
instructions::{
8-
HashToCurveCPU,
9-
hash::HashCPU,
10-
},
11-
types::AssignedNative,
12-
};
13-
141
pub use midnight_curves::{
15-
Bls12, EDWARDS_D, Fq as JubjubBase, Fq as BlsScalar, Fr as JubjubScalar,
16-
G1Affine as BlstG1Affine, G1Projective as BlstG1, G2Affine as BlstG2Affine, JubjubAffine,
17-
JubjubExtended as Jubjub, JubjubExtended, JubjubSubgroup, MODULUS,
2+
EDWARDS_D, Fq as JubjubBase, Fr as JubjubScalar,
3+
JubjubAffine, JubjubExtended, JubjubSubgroup,
184
};
195

20-
21-
226
use ff::Field;
23-
use group::Group;
24-
use rand_core::{CryptoRng, RngCore};
257
use subtle::{Choice, ConstantTimeEq};
26-
use thiserror::Error;
27-
28-
// use crate::schnorr_signatures::{get_coordinates, jubjub_base_to_scalar, is_on_curve};
298

9+
use std::slice;
3010

3111

3212
pub fn get_coordinates(point: JubjubSubgroup) -> (JubjubBase, JubjubBase) {

mithril-stm/src/schnorr_signatures/mod.rs

Lines changed: 71 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ type JubjubHashToCurve = HashToCurveGadget<
4444

4545
type PoseidonHash = PoseidonChip<JubjubBase>;
4646

47-
pub const DST_SIGNATURE: JubjubBase = JubjubBase::from_raw([2u64, 0, 0, 0]);
47+
pub(crate) const DST_SIGNATURE: JubjubBase = JubjubBase::from_raw([2u64, 0, 0, 0]);
4848

4949

5050
#[derive(Debug, Error)]
@@ -58,59 +58,81 @@ pub enum SignatureError {
5858

5959

6060

61-
6261
#[cfg(test)]
6362
mod tests {
63+
// use blst::{blst_p1, blst_p2};
64+
use proptest::prelude::*;
65+
use rand_chacha::ChaCha20Rng;
66+
use rand_core::{RngCore, SeedableRng, OsRng};
67+
68+
// use crate::bls_multi_signature::helper::unsafe_helpers::{p1_affine_to_sig, p2_affine_to_vk};
69+
use crate::error::{MultiSignatureError, RegisterError};
70+
use crate::key_registration::KeyRegistration;
71+
6472
use super::*;
65-
use rand_core::OsRng;
66-
67-
/// Test signing functionality.
68-
#[test]
69-
fn test_signature_verification_valid() {
70-
let mut rng = OsRng;
71-
let sk = SigningKey::generate(&mut rng);
72-
let msg = JubjubBase::random(&mut rng);
73-
74-
// Sign the message
75-
let signature = sk.sign(msg, &mut rng);
76-
77-
// Ensure the components of the signature are non-default values
78-
assert_ne!(
79-
signature.sigma,
80-
JubjubSubgroup::identity(),
81-
"Signature sigma should not be the identity element."
82-
);
83-
assert_ne!(
84-
signature.s,
85-
JubjubScalar::ZERO,
86-
"Signature s component should not be zero."
87-
);
88-
assert_ne!(
89-
signature.c,
90-
JubjubBase::ZERO,
91-
"Signature c component should not be zero."
92-
);
93-
94-
signature.verify(msg, &VerificationKey::from(&sk)).unwrap();
73+
74+
impl PartialEq for SchnorrSigningKey {
75+
fn eq(&self, other: &Self) -> bool {
76+
self.to_bytes() == other.to_bytes()
77+
}
9578
}
9679

97-
#[test]
98-
fn test_signature_verification_invalid_signature() {
99-
let mut rng = OsRng;
100-
let sk = SigningKey::generate(&mut rng);
101-
let msg = JubjubBase::random(&mut rng);
102-
let vk: VerificationKey = (&sk).into();
103-
104-
// Generate signature and tamper with it
105-
let mut signature = sk.sign(msg, &mut rng);
106-
signature.s = JubjubScalar::random(&mut rng); // Modify `s` component
107-
108-
// Verify the modified signature
109-
let result = signature.verify(msg, &vk);
110-
assert!(
111-
result.is_err(),
112-
"Invalid signature should fail verification, but it passed."
113-
);
80+
// impl Eq for SchnorrSigningKey {}
81+
82+
proptest! {
83+
#![proptest_config(ProptestConfig::with_cases(1000))]
84+
85+
/// Test signing functionality.
86+
#[test]
87+
fn test_signature_verification_valid(seed in any::<u64>()) {
88+
let mut rng = OsRng;
89+
let sk = SchnorrSigningKey::generate(&mut rng);
90+
let msg = JubjubBase::random(&mut rng);
91+
92+
// Sign the message
93+
let signature = sk.sign(msg, &mut rng);
94+
95+
// Ensure the components of the signature are non-default values
96+
assert_ne!(
97+
signature.sigma,
98+
JubjubSubgroup::identity(),
99+
"Signature sigma should not be the identity element."
100+
);
101+
assert_ne!(
102+
signature.s,
103+
JubjubScalar::ZERO,
104+
"Signature s component should not be zero."
105+
);
106+
assert_ne!(
107+
signature.c,
108+
JubjubBase::ZERO,
109+
"Signature c component should not be zero."
110+
);
111+
112+
signature.verify(msg, &SchnorrVerificationKey::from(&sk)).unwrap();
113+
}
114+
115+
#[test]
116+
fn test_signature_verification_invalid_signature(seed in any::<u64>()) {
117+
let mut rng = OsRng;
118+
let sk = SchnorrSigningKey::generate(&mut rng);
119+
let msg = JubjubBase::random(&mut rng);
120+
let vk: SchnorrVerificationKey = (&sk).into();
121+
122+
// Generate signature and tamper with it
123+
let mut signature = sk.sign(msg, &mut rng);
124+
signature.s = JubjubScalar::random(&mut rng); // Modify `s` component
125+
126+
// Verify the modified signature
127+
let result = signature.verify(msg, &vk);
128+
assert!(
129+
result.is_err(),
130+
"Invalid signature should fail verification, but it passed."
131+
);
132+
}
133+
134+
114135
}
115136

137+
116138
}

mithril-stm/src/schnorr_signatures/signature.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub struct SchnorrSignature {
2929

3030
impl SchnorrSignature {
3131
/// Verify a signature against a verification key.
32-
pub fn verify(&self, msg: JubjubBase, vk: &VerificationKey) -> Result<(), SignatureError> {
32+
pub fn verify(&self, msg: JubjubBase, vk: &SchnorrVerificationKey) -> Result<(), SignatureError> {
3333
let g = JubjubSubgroup::generator();
3434
let hash = JubjubHashToCurve::hash_to_curve(&[msg]);
3535
let c_scalar = jubjub_base_to_scalar(self.c);

mithril-stm/src/schnorr_signatures/signing_key.rs

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
pub use midnight_curves::{Fq as JubjubBase, Fr as JubjubScalar,
3-
JubjubExtended as Jubjub, JubjubExtended, JubjubSubgroup,
3+
JubjubExtended as Jubjub, JubjubExtended, JubjubSubgroup
44
};
55
use midnight_circuits::{
66
instructions::{
@@ -12,9 +12,10 @@ use midnight_circuits::{
1212
use ff::Field;
1313
use group::Group;
1414
use rand_core::{CryptoRng, RngCore};
15+
use subtle::CtOption;
1516
use thiserror::Error;
1617

17-
use crate::schnorr_signatures::helper::{get_coordinates, jubjub_base_to_scalar, is_on_curve};
18+
use crate::{error::MultiSignatureError, schnorr_signatures::helper::{get_coordinates, is_on_curve, jubjub_base_to_scalar}};
1819
use crate::schnorr_signatures::verification_key::*;
1920
use crate::schnorr_signatures::signature::*;
2021

@@ -24,13 +25,13 @@ use crate::schnorr_signatures::{JubjubHashToCurve, SignatureError, PoseidonHash,
2425

2526
/// The signing key is a scalar from the Jubjub scalar field
2627
#[derive(Debug, Clone)]
27-
pub struct SigningKey(JubjubScalar);
28+
pub struct SchnorrSigningKey(JubjubScalar);
2829

2930
/// Implementation of the Schnorr signature scheme using the Jubjub curve
30-
impl SigningKey {
31+
impl SchnorrSigningKey {
3132
pub fn generate(rng: &mut (impl RngCore + CryptoRng)) -> Self {
3233
let sk = JubjubScalar::random(rng);
33-
SigningKey(sk)
34+
SchnorrSigningKey(sk)
3435
}
3536

3637
/// A slightly modified version of the regular Schnorr signature (I think)
@@ -71,13 +72,34 @@ impl SigningKey {
7172
SchnorrSignature { sigma, s, c }
7273
}
7374

74-
}
75+
/// Convert the schnorr secret key into byte string.
76+
/// Uses midnight curve implem for the conversion
77+
pub fn to_bytes(&self) -> [u8; 32] {
78+
self.0.to_bytes()
79+
}
7580

81+
/// Convert a string of bytes into a `SchnorrSigningKey`.
82+
///
83+
/// # Error
84+
/// Fails if the byte string represents a scalar larger than the group order.
85+
pub fn from_bytes(bytes: &[u8]) -> Result<Self, MultiSignatureError> {
86+
// This is a bit ugly, I'll try to find a better way to do it
87+
let bytes = bytes.get(..32).ok_or(MultiSignatureError::SerializationError)?.try_into().unwrap();
88+
// Jubjub returs a CtChoice so I convert it to an option that looses the const time property
89+
match JubjubScalar::from_bytes(bytes).into_option().ok_or(MultiSignatureError::SerializationError) {
90+
Ok(sk) => Ok(Self(sk)),
91+
// the error should be updated
92+
Err(e) => Err(e)
93+
}
94+
}
95+
96+
}
7697

77-
impl From<&SigningKey> for VerificationKey {
78-
fn from(sk: &SigningKey) -> Self {
98+
// Should we have this implementation?
99+
impl From<&SchnorrSigningKey> for SchnorrVerificationKey {
100+
fn from(sk: &SchnorrSigningKey) -> Self {
79101
let g = JubjubSubgroup::generator();
80102
let vk = &g * &sk.0;
81-
VerificationKey(vk)
103+
SchnorrVerificationKey(vk)
82104
}
83105
}

mithril-stm/src/schnorr_signatures/verification_key.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ use crate::schnorr_signatures::{JubjubHashToCurve, SignatureError, PoseidonHash,
2727

2828

2929
#[derive(Debug, Clone, Copy, Default)]
30-
pub struct VerificationKey(pub JubjubSubgroup);
30+
pub struct SchnorrVerificationKey(pub JubjubSubgroup);
3131

3232

33-
impl VerificationKey {
33+
impl SchnorrVerificationKey {
3434
pub fn to_field(&self) -> [JubjubBase; 2] {
3535
let (x, y) = get_coordinates(self.0);
3636
[x, y]
@@ -66,6 +66,6 @@ impl VerificationKey {
6666
return Err(SignatureError::SerializationError);
6767
}
6868

69-
Ok(VerificationKey(point))
69+
Ok(SchnorrVerificationKey(point))
7070
}
7171
}

0 commit comments

Comments
 (0)