Implement signing.

This commit is contained in:
Henry de Valence 2019-12-03 19:19:36 -08:00
parent 710ac6fba9
commit 2b37c71b57
3 changed files with 44 additions and 17 deletions

View File

@ -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.

View File

@ -49,22 +49,36 @@ impl<T: SigType> SecretKey<T> {
pub fn randomize(&self, randomizer: Randomizer) -> PublicKey<T> {
unimplemented!();
}
}
impl SecretKey<Binding> {
/// 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<Binding> {
// could use sign_inner
unimplemented!();
}
}
impl SecretKey<SpendAuth> {
/// Create a Zcash `SpendAuthSig` on `msg` using this `SecretKey`.
// Similar to signature::Signer but without boxed errors.
pub fn sign(&self, msg: &[u8]) -> Signature<SpendAuth> {
// could use sign_inner
unimplemented!();
pub fn sign<R: RngCore + CryptoRng>(&self, mut rng: R, msg: &[u8]) -> Signature<T> {
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)
}
}

View File

@ -23,6 +23,18 @@ impl<T: SigType> From<Signature<T>> for [u8; 64] {
}
}
impl<T: SigType> Signature<T> {
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