diff --git a/src/hash.rs b/src/hash.rs index 2492322..b3beee6 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -18,9 +18,10 @@ impl Default for HStar { } impl HStar { - /// Add `data` to the hash. - pub fn update(&mut self, data: &[u8]) { + /// Add `data` to the hash, and return `Self` for chaining. + pub fn update(mut self, data: &[u8]) -> Self { self.state.update(data); + self } /// Consume `self` to compute the hash output. diff --git a/src/secret_key.rs b/src/secret_key.rs index 811d763..4370328 100644 --- a/src/secret_key.rs +++ b/src/secret_key.rs @@ -49,22 +49,36 @@ impl SecretKey { pub fn randomize(&self, randomizer: Randomizer) -> PublicKey { unimplemented!(); } -} -impl SecretKey { - /// Create a Zcash `BindingSig` on `msg` using this `SecretKey`. + /// Create a signature of type `T` on `msg` using this `SecretKey`. // Similar to signature::Signer but without boxed errors. - pub fn sign(&self, msg: &[u8]) -> Signature { - // could use sign_inner - unimplemented!(); - } -} - -impl SecretKey { - /// Create a Zcash `SpendAuthSig` on `msg` using this `SecretKey`. - // Similar to signature::Signer but without boxed errors. - pub fn sign(&self, msg: &[u8]) -> Signature { - // could use sign_inner - unimplemented!(); + pub fn sign(&self, mut rng: R, msg: &[u8]) -> Signature { + use crate::HStar; + + // Choose a byte sequence uniformly at random of length + // (\ell_H + 128)/8 bytes. For RedJubjub this is (512 + 128)/8 = 80. + let random_bytes = { + let mut bytes = [0; 80]; + rng.fill_bytes(&mut bytes); + bytes + }; + + let nonce = HStar::default() + .update(&random_bytes[..]) + .update(&self.pk.bytes.bytes[..]) // XXX ugly + .update(msg) + .finalize(); + + let r_bytes = jubjub::AffinePoint::from(&T::basepoint() * &nonce).to_bytes(); + + let c = HStar::default() + .update(&r_bytes[..]) + .update(&self.pk.bytes.bytes[..]) // XXX ugly + .update(msg) + .finalize(); + + let s_bytes = (&nonce + &(&c * &self.sk)).to_bytes(); + + Signature::from_parts(r_bytes, s_bytes) } } diff --git a/src/signature.rs b/src/signature.rs index e902eb1..8514e80 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -23,6 +23,18 @@ impl From> for [u8; 64] { } } +impl Signature { + pub(crate) fn from_parts(r_bytes: [u8; 32], s_bytes: [u8; 32]) -> Self { + let mut bytes = [0; 64]; + bytes[0..32].copy_from_slice(&r_bytes[..]); + bytes[32..64].copy_from_slice(&s_bytes[..]); + Self { + bytes, + _marker: PhantomData, + } + } +} + // These impls all only exist because of array length restrictions. // XXX print the type variable