Implement verification.

This commit is contained in:
Henry de Valence 2019-12-03 22:32:30 -08:00
parent d3b20d0f21
commit d761316579
4 changed files with 52 additions and 16 deletions

View File

@ -1,7 +1,7 @@
use thiserror::Error;
/// An error related to RedJubJub signatures.
#[derive(Error, Debug)]
#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
pub enum Error {
/// The encoding of a secret key was malformed.
#[error("Malformed secret key encoding.")]
@ -9,4 +9,7 @@ pub enum Error {
/// The encoding of a public key was malformed.
#[error("Malformed public key encoding.")]
MalformedPublicKey,
/// Signature verification failed.
#[error("Invalid signature.")]
InvalidSignature,
}

View File

@ -75,22 +75,50 @@ impl<T: SigType> PublicKey<T> {
pub fn randomize(&self, randomizer: Randomizer) -> PublicKey<T> {
unimplemented!();
}
}
impl PublicKey<Binding> {
/// Verify a Zcash `BindingSig` over `msg` made by this public key.
/// Verify a purported `signature` over `msg` made by this public key.
// This is similar to impl signature::Verifier but without boxed errors
pub fn verify(&self, msg: &[u8], signature: &Signature<Binding>) -> Result<(), Error> {
// this lets us specialize the basepoint parameter, could call a verify_inner
unimplemented!();
}
}
use crate::HStar;
impl PublicKey<SpendAuth> {
/// Verify a Zcash `SpendAuthSig` over `msg` made by this public key.
// This is similar to impl signature::Verifier but without boxed errors
pub fn verify(&self, msg: &[u8], signature: &Signature<SpendAuth>) -> Result<(), Error> {
// this lets us specialize the basepoint parameter, could call a verify_inner
unimplemented!();
let r = {
// XXX-jubjub: should not use CtOption here
// XXX-jubjub: inconsistent ownership in from_bytes
let maybe_point = jubjub::AffinePoint::from_bytes(signature.r_bytes);
if maybe_point.is_some().into() {
jubjub::ExtendedPoint::from(maybe_point.unwrap())
} else {
return Err(Error::InvalidSignature);
}
};
let s = {
// XXX-jubjub: should not use CtOption here
let maybe_scalar = Scalar::from_bytes(&signature.s_bytes);
if maybe_scalar.is_some().into() {
maybe_scalar.unwrap()
} else {
return Err(Error::InvalidSignature);
}
};
let c = HStar::default()
.update(&signature.r_bytes[..])
.update(&self.bytes.bytes[..]) // XXX ugly
.update(msg)
.finalize();
// XXX rewrite as normal double scalar mul
// Verify check is h * ( - s * B + R + c * A) == 0
// h * ( s * B - c * A - R) == 0
let sB = &T::basepoint() * &s;
let cA = &self.point * &c;
let check = sB - cA - r;
if check.is_small_order().into() {
Ok(())
} else {
Err(Error::InvalidSignature)
}
}
}

View File

@ -13,6 +13,12 @@ pub struct SecretKey<T: SigType> {
pk: PublicKey<T>,
}
impl<'a, T: SigType> From<&'a SecretKey<T>> for PublicKey<T> {
fn from(sk: &'a SecretKey<T>) -> PublicKey<T> {
sk.pk.clone()
}
}
impl<T: SigType> From<SecretKey<T>> for [u8; 32] {
fn from(sk: SecretKey<T>) -> [u8; 32] {
sk.sk.to_bytes()
@ -79,7 +85,7 @@ impl<T: SigType> SecretKey<T> {
let s_bytes = (&nonce + &(&c * &self.sk)).to_bytes();
Signature{
Signature {
r_bytes,
s_bytes,
_marker: PhantomData,

View File

@ -32,4 +32,3 @@ impl<T: SigType> From<Signature<T>> for [u8; 64] {
bytes
}
}