diff --git a/src/crypto/diffie_hellman.rs b/src/crypto/diffie_hellman.rs index 9dc2b45fa..b5d613b5e 100644 --- a/src/crypto/diffie_hellman.rs +++ b/src/crypto/diffie_hellman.rs @@ -29,4 +29,3 @@ fn kdf_sapling(dhsecret: jubjub::SubgroupPoint, epk: &jubjub::ExtendedPoint) -> .update(&epk.to_bytes()) .finalize() } - diff --git a/src/crypto/schnorr.rs b/src/crypto/schnorr.rs index ff81e505e..fbbd61696 100644 --- a/src/crypto/schnorr.rs +++ b/src/crypto/schnorr.rs @@ -4,22 +4,52 @@ use rand::rngs::OsRng; use super::util::hash_to_scalar; -#[test] -fn test_schnorr() { - let secret = jubjub::Fr::random(&mut OsRng); - let public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret; +pub struct SecretKey(pub jubjub::Fr); - let mask = jubjub::Fr::random(&mut OsRng); - let commit = zcash_primitives::constants::SPENDING_KEY_GENERATOR * mask; +impl SecretKey { + pub fn random() -> Self { + Self(jubjub::Fr::random(&mut OsRng)) + } - let msg = b"Foo bar"; - let challenge = hash_to_scalar(b"DarkFi_Schnorr", &commit.to_bytes(), &msg[..]); + pub fn sign(&self, message: &[u8]) -> Signature { + let mask = jubjub::Fr::random(&mut OsRng); + let commit = zcash_primitives::constants::SPENDING_KEY_GENERATOR * mask; - let response = mask + challenge * secret; + let challenge = hash_to_scalar(b"DarkFi_Schnorr", &commit.to_bytes(), message); - // Verify signature + let response = mask + challenge * self.0; - assert_eq!( - zcash_primitives::constants::SPENDING_KEY_GENERATOR * response - public * challenge, commit); + Signature { commit, response } + } + + pub fn public_key(&self) -> PublicKey { + let public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * self.0; + PublicKey(public) + } +} + +pub struct PublicKey(pub jubjub::SubgroupPoint); + +pub struct Signature { + commit: jubjub::SubgroupPoint, + response: jubjub::Fr, +} + +impl PublicKey { + pub fn verify(&self, message: &[u8], signature: &Signature) -> bool { + let challenge = hash_to_scalar(b"DarkFi_Schnorr", &signature.commit.to_bytes(), message); + zcash_primitives::constants::SPENDING_KEY_GENERATOR * signature.response + - self.0 * challenge + == signature.commit + } +} + +#[test] +fn test_schnorr() { + let secret = SecretKey::random(); + let message = b"Foo bar"; + let signature = secret.sign(&message[..]); + let public = secret.public_key(); + assert!(public.verify(&message[..], &signature)); } diff --git a/src/crypto/util.rs b/src/crypto/util.rs index 683a8a535..6271cc9c1 100644 --- a/src/crypto/util.rs +++ b/src/crypto/util.rs @@ -7,4 +7,3 @@ pub fn hash_to_scalar(persona: &[u8], a: &[u8], b: &[u8]) -> jubjub::Fr { let ret = hasher.finalize(); jubjub::Fr::from_bytes_wide(ret.as_array()) } -