Change terminology to signing, verification keys (#35)

Matches ed25519-zebra.

Resolves #33
This commit is contained in:
Deirdre Connolly 2020-06-25 14:56:29 -04:00 committed by GitHub
parent c933a8eb85
commit f27b9c3c77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 117 additions and 112 deletions

View File

@ -1,19 +1,20 @@
A minimal [RedJubjub][redjubjub] implementation for use in [Zebra][zebra]. A minimal [RedJubjub][redjubjub] implementation for use in [Zebra][zebra].
Two parameterizations of RedJubjub are used in Zcash, one for `BindingSig` Two parameterizations of RedJubjub are used in Zcash, one for
and one for `SpendAuthSig`. This library distinguishes these in the type `BindingSig` and one for `SpendAuthSig`. This library distinguishes
system, using the [sealed] `SigType` trait as a type-level enum. these in the type system, using the [sealed] `SigType` trait as a
type-level enum.
In addition to the usual `Signature`, `SecretKey`, `PublicKey` types, the In addition to the `Signature`, `SigningKey`, `VerificationKey` types,
library also provides `PublicKeyBytes`, a [refinement] of a `[u8; 32]` the library also provides `VerificationKeyBytes`, a [refinement] of a
indicating that bytes represent an encoding of a RedJubjub public key. This `[u8; 32]` indicating that bytes represent an encoding of a RedJubjub
allows the `PublicKey` type to cache verification checks related to the verification key. This allows the `VerificationKey` type to cache
public key encoding. verification checks related to the verification key encoding.
## Examples ## Examples
Creating a `BindingSig`, serializing and deserializing it, and verifying the Creating a `BindingSig`, serializing and deserializing it, and
signature: verifying the signature:
``` ```
# use std::convert::TryFrom; # use std::convert::TryFrom;
@ -23,17 +24,17 @@ use redjubjub::*;
let msg = b"Hello!"; let msg = b"Hello!";
// Generate a secret key and sign the message // Generate a secret key and sign the message
let sk = SecretKey::<Binding>::new(thread_rng()); let sk = SigningKey::<Binding>::new(thread_rng());
let sig = sk.sign(thread_rng(), msg); let sig = sk.sign(thread_rng(), msg);
// Types can be converted to raw byte arrays using From/Into // Types can be converted to raw byte arrays using From/Into
let sig_bytes: [u8; 64] = sig.into(); let sig_bytes: [u8; 64] = sig.into();
let pk_bytes: [u8; 32] = PublicKey::from(&sk).into(); let pk_bytes: [u8; 32] = VerificationKey::from(&sk).into();
// Deserialize and verify the signature. // Deserialize and verify the signature.
let sig: Signature<Binding> = sig_bytes.into(); let sig: Signature<Binding> = sig_bytes.into();
assert!( assert!(
PublicKey::try_from(pk_bytes) VerificationKey::try_from(pk_bytes)
.and_then(|pk| pk.verify(msg, &sig)) .and_then(|pk| pk.verify(msg, &sig))
.is_ok() .is_ok()
); );

View File

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

View File

@ -8,9 +8,9 @@
mod constants; mod constants;
mod error; mod error;
mod hash; mod hash;
mod public_key;
mod secret_key;
mod signature; mod signature;
mod signing_key;
mod verification_key;
/// An element of the JubJub scalar field used for randomization of public and secret keys. /// An element of the JubJub scalar field used for randomization of public and secret keys.
pub type Randomizer = jubjub::Fr; pub type Randomizer = jubjub::Fr;
@ -22,9 +22,9 @@ type Scalar = jubjub::Fr;
use hash::HStar; use hash::HStar;
pub use error::Error; pub use error::Error;
pub use public_key::{PublicKey, PublicKeyBytes};
pub use secret_key::SecretKey;
pub use signature::Signature; pub use signature::Signature;
pub use signing_key::SigningKey;
pub use verification_key::{VerificationKey, VerificationKeyBytes};
/// Abstracts over different RedJubJub parameter choices, [`Binding`] /// Abstracts over different RedJubJub parameter choices, [`Binding`]
/// and [`SpendAuth`]. /// and [`SpendAuth`].

View File

@ -3,34 +3,34 @@ use std::{
marker::PhantomData, marker::PhantomData,
}; };
use crate::{Error, PublicKey, Randomizer, Scalar, SigType, Signature, SpendAuth}; use crate::{Error, Randomizer, Scalar, SigType, Signature, SpendAuth, VerificationKey};
use rand_core::{CryptoRng, RngCore}; use rand_core::{CryptoRng, RngCore};
/// A RedJubJub secret key. /// A RedJubJub signing key.
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(try_from = "SerdeHelper"))] #[cfg_attr(feature = "serde", serde(try_from = "SerdeHelper"))]
#[cfg_attr(feature = "serde", serde(into = "SerdeHelper"))] #[cfg_attr(feature = "serde", serde(into = "SerdeHelper"))]
#[cfg_attr(feature = "serde", serde(bound = "T: SigType"))] #[cfg_attr(feature = "serde", serde(bound = "T: SigType"))]
pub struct SecretKey<T: SigType> { pub struct SigningKey<T: SigType> {
sk: Scalar, sk: Scalar,
pk: PublicKey<T>, pk: VerificationKey<T>,
} }
impl<'a, T: SigType> From<&'a SecretKey<T>> for PublicKey<T> { impl<'a, T: SigType> From<&'a SigningKey<T>> for VerificationKey<T> {
fn from(sk: &'a SecretKey<T>) -> PublicKey<T> { fn from(sk: &'a SigningKey<T>) -> VerificationKey<T> {
sk.pk.clone() sk.pk.clone()
} }
} }
impl<T: SigType> From<SecretKey<T>> for [u8; 32] { impl<T: SigType> From<SigningKey<T>> for [u8; 32] {
fn from(sk: SecretKey<T>) -> [u8; 32] { fn from(sk: SigningKey<T>) -> [u8; 32] {
sk.sk.to_bytes() sk.sk.to_bytes()
} }
} }
impl<T: SigType> TryFrom<[u8; 32]> for SecretKey<T> { impl<T: SigType> TryFrom<[u8; 32]> for SigningKey<T> {
type Error = Error; type Error = Error;
fn try_from(bytes: [u8; 32]) -> Result<Self, Self::Error> { fn try_from(bytes: [u8; 32]) -> Result<Self, Self::Error> {
@ -38,10 +38,10 @@ impl<T: SigType> TryFrom<[u8; 32]> for SecretKey<T> {
let maybe_sk = Scalar::from_bytes(&bytes); let maybe_sk = Scalar::from_bytes(&bytes);
if maybe_sk.is_some().into() { if maybe_sk.is_some().into() {
let sk = maybe_sk.unwrap(); let sk = maybe_sk.unwrap();
let pk = PublicKey::from_secret(&sk); let pk = VerificationKey::from(&sk);
Ok(SecretKey { sk, pk }) Ok(SigningKey { sk, pk })
} else { } else {
Err(Error::MalformedSecretKey) Err(Error::MalformedSigningKey)
} }
} }
} }
@ -49,7 +49,7 @@ impl<T: SigType> TryFrom<[u8; 32]> for SecretKey<T> {
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
struct SerdeHelper([u8; 32]); struct SerdeHelper([u8; 32]);
impl<T: SigType> TryFrom<SerdeHelper> for SecretKey<T> { impl<T: SigType> TryFrom<SerdeHelper> for SigningKey<T> {
type Error = Error; type Error = Error;
fn try_from(helper: SerdeHelper) -> Result<Self, Self::Error> { fn try_from(helper: SerdeHelper) -> Result<Self, Self::Error> {
@ -57,34 +57,34 @@ impl<T: SigType> TryFrom<SerdeHelper> for SecretKey<T> {
} }
} }
impl<T: SigType> From<SecretKey<T>> for SerdeHelper { impl<T: SigType> From<SigningKey<T>> for SerdeHelper {
fn from(sk: SecretKey<T>) -> Self { fn from(sk: SigningKey<T>) -> Self {
Self(sk.into()) Self(sk.into())
} }
} }
impl SecretKey<SpendAuth> { impl SigningKey<SpendAuth> {
/// Randomize this public key with the given `randomizer`. /// Randomize this public key with the given `randomizer`.
pub fn randomize(&self, randomizer: &Randomizer) -> SecretKey<SpendAuth> { pub fn randomize(&self, randomizer: &Randomizer) -> SigningKey<SpendAuth> {
let sk = &self.sk + randomizer; let sk = &self.sk + randomizer;
let pk = PublicKey::from_secret(&sk); let pk = VerificationKey::from(&sk);
SecretKey { sk, pk } SigningKey { sk, pk }
} }
} }
impl<T: SigType> SecretKey<T> { impl<T: SigType> SigningKey<T> {
/// Generate a new secret key. /// Generate a new signing key.
pub fn new<R: RngCore + CryptoRng>(mut rng: R) -> SecretKey<T> { pub fn new<R: RngCore + CryptoRng>(mut rng: R) -> SigningKey<T> {
let sk = { let sk = {
let mut bytes = [0; 64]; let mut bytes = [0; 64];
rng.fill_bytes(&mut bytes); rng.fill_bytes(&mut bytes);
Scalar::from_bytes_wide(&bytes) Scalar::from_bytes_wide(&bytes)
}; };
let pk = PublicKey::from_secret(&sk); let pk = VerificationKey::from(&sk);
SecretKey { sk, pk } SigningKey { sk, pk }
} }
/// Create a signature of type `T` on `msg` using this `SecretKey`. /// Create a signature of type `T` on `msg` using this `SigningKey`.
// Similar to signature::Signer but without boxed errors. // Similar to signature::Signer but without boxed errors.
pub fn sign<R: RngCore + CryptoRng>(&self, mut rng: R, msg: &[u8]) -> Signature<T> { pub fn sign<R: RngCore + CryptoRng>(&self, mut rng: R, msg: &[u8]) -> Signature<T> {
use crate::HStar; use crate::HStar;

View File

@ -3,126 +3,126 @@ use std::{convert::TryFrom, marker::PhantomData};
use crate::{Error, Randomizer, Scalar, SigType, Signature, SpendAuth}; use crate::{Error, Randomizer, Scalar, SigType, Signature, SpendAuth};
/// A refinement type for `[u8; 32]` indicating that the bytes represent /// A refinement type for `[u8; 32]` indicating that the bytes represent
/// an encoding of a RedJubJub public key. /// an encoding of a RedJubJub verification key.
/// ///
/// This is useful for representing a compressed public key; the /// This is useful for representing a compressed verification key; the
/// [`PublicKey`] type in this library holds other decompressed state /// [`VerificationKey`] type in this library holds other decompressed state
/// used in signature verification. /// used in signature verification.
#[derive(Copy, Clone, PartialEq, Eq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct PublicKeyBytes<T: SigType> { pub struct VerificationKeyBytes<T: SigType> {
pub(crate) bytes: [u8; 32], pub(crate) bytes: [u8; 32],
pub(crate) _marker: PhantomData<T>, pub(crate) _marker: PhantomData<T>,
} }
impl<T: SigType> From<[u8; 32]> for PublicKeyBytes<T> { impl<T: SigType> From<[u8; 32]> for VerificationKeyBytes<T> {
fn from(bytes: [u8; 32]) -> PublicKeyBytes<T> { fn from(bytes: [u8; 32]) -> VerificationKeyBytes<T> {
PublicKeyBytes { VerificationKeyBytes {
bytes, bytes,
_marker: PhantomData, _marker: PhantomData,
} }
} }
} }
impl<T: SigType> From<PublicKeyBytes<T>> for [u8; 32] { impl<T: SigType> From<VerificationKeyBytes<T>> for [u8; 32] {
fn from(refined: PublicKeyBytes<T>) -> [u8; 32] { fn from(refined: VerificationKeyBytes<T>) -> [u8; 32] {
refined.bytes refined.bytes
} }
} }
/// A valid RedJubJub public key. /// A valid RedJubJub verification key.
/// ///
/// This type holds decompressed state used in signature verification; if the /// This type holds decompressed state used in signature verification; if the
/// public key may not be used immediately, it is probably better to use /// verification key may not be used immediately, it is probably better to use
/// [`PublicKeyBytes`], which is a refinement type for `[u8; 32]`. /// [`VerificationKeyBytes`], which is a refinement type for `[u8; 32]`.
/// ///
/// ## Consensus properties /// ## Consensus properties
/// ///
/// The `TryFrom<PublicKeyBytes>` conversion performs the following Zcash /// The `TryFrom<VerificationKeyBytes>` conversion performs the following Zcash
/// consensus rule checks: /// consensus rule checks:
/// ///
/// 1. The check that the bytes are a canonical encoding of a public key; /// 1. The check that the bytes are a canonical encoding of a verification key;
/// 2. The check that the public key is not a point of small order. /// 2. The check that the verification key is not a point of small order.
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(try_from = "PublicKeyBytes<T>"))] #[cfg_attr(feature = "serde", serde(try_from = "VerificationKeyBytes<T>"))]
#[cfg_attr(feature = "serde", serde(into = "PublicKeyBytes<T>"))] #[cfg_attr(feature = "serde", serde(into = "VerificationKeyBytes<T>"))]
#[cfg_attr(feature = "serde", serde(bound = "T: SigType"))] #[cfg_attr(feature = "serde", serde(bound = "T: SigType"))]
pub struct PublicKey<T: SigType> { pub struct VerificationKey<T: SigType> {
// XXX-jubjub: this should just be Point // XXX-jubjub: this should just be Point
pub(crate) point: jubjub::ExtendedPoint, pub(crate) point: jubjub::ExtendedPoint,
pub(crate) bytes: PublicKeyBytes<T>, pub(crate) bytes: VerificationKeyBytes<T>,
} }
impl<T: SigType> From<PublicKey<T>> for PublicKeyBytes<T> { impl<T: SigType> From<VerificationKey<T>> for VerificationKeyBytes<T> {
fn from(pk: PublicKey<T>) -> PublicKeyBytes<T> { fn from(pk: VerificationKey<T>) -> VerificationKeyBytes<T> {
pk.bytes pk.bytes
} }
} }
impl<T: SigType> From<PublicKey<T>> for [u8; 32] { impl<T: SigType> From<VerificationKey<T>> for [u8; 32] {
fn from(pk: PublicKey<T>) -> [u8; 32] { fn from(pk: VerificationKey<T>) -> [u8; 32] {
pk.bytes.bytes pk.bytes.bytes
} }
} }
impl<T: SigType> TryFrom<PublicKeyBytes<T>> for PublicKey<T> { impl<T: SigType> TryFrom<VerificationKeyBytes<T>> for VerificationKey<T> {
type Error = Error; type Error = Error;
fn try_from(bytes: PublicKeyBytes<T>) -> Result<Self, Self::Error> { fn try_from(bytes: VerificationKeyBytes<T>) -> Result<Self, Self::Error> {
// XXX-jubjub: this should not use CtOption // XXX-jubjub: this should not use CtOption
// XXX-jubjub: this takes ownership of bytes, while Fr doesn't. // XXX-jubjub: this takes ownership of bytes, while Fr doesn't.
// This checks that the encoding is canonical... // This checks that the encoding is canonical...
let maybe_point = jubjub::AffinePoint::from_bytes(bytes.bytes); let maybe_point = jubjub::AffinePoint::from_bytes(bytes.bytes);
if maybe_point.is_some().into() { if maybe_point.is_some().into() {
let point: jubjub::ExtendedPoint = maybe_point.unwrap().into(); let point: jubjub::ExtendedPoint = maybe_point.unwrap().into();
// This checks that the public key is not of small order. // This checks that the verification key is not of small order.
if <bool>::from(point.is_small_order()) == false { if <bool>::from(point.is_small_order()) == false {
Ok(PublicKey { point, bytes }) Ok(VerificationKey { point, bytes })
} else { } else {
Err(Error::MalformedPublicKey) Err(Error::MalformedVerificationKey)
} }
} else { } else {
Err(Error::MalformedPublicKey) Err(Error::MalformedVerificationKey)
} }
} }
} }
impl<T: SigType> TryFrom<[u8; 32]> for PublicKey<T> { impl<T: SigType> TryFrom<[u8; 32]> for VerificationKey<T> {
type Error = Error; type Error = Error;
fn try_from(bytes: [u8; 32]) -> Result<Self, Self::Error> { fn try_from(bytes: [u8; 32]) -> Result<Self, Self::Error> {
use std::convert::TryInto; use std::convert::TryInto;
PublicKeyBytes::from(bytes).try_into() VerificationKeyBytes::from(bytes).try_into()
} }
} }
impl PublicKey<SpendAuth> { impl VerificationKey<SpendAuth> {
/// Randomize this public key with the given `randomizer`. /// Randomize this verification key with the given `randomizer`.
/// ///
/// Randomization is only supported for `SpendAuth` keys. /// Randomization is only supported for `SpendAuth` keys.
pub fn randomize(&self, randomizer: &Randomizer) -> PublicKey<SpendAuth> { pub fn randomize(&self, randomizer: &Randomizer) -> VerificationKey<SpendAuth> {
use crate::private::Sealed; use crate::private::Sealed;
let point = &self.point + &(&SpendAuth::basepoint() * randomizer); let point = &self.point + &(&SpendAuth::basepoint() * randomizer);
let bytes = PublicKeyBytes { let bytes = VerificationKeyBytes {
bytes: jubjub::AffinePoint::from(&point).to_bytes(), bytes: jubjub::AffinePoint::from(&point).to_bytes(),
_marker: PhantomData, _marker: PhantomData,
}; };
PublicKey { bytes, point } VerificationKey { bytes, point }
} }
} }
impl<T: SigType> PublicKey<T> { impl<T: SigType> VerificationKey<T> {
pub(crate) fn from_secret(s: &Scalar) -> PublicKey<T> { pub(crate) fn from(s: &Scalar) -> VerificationKey<T> {
let point = &T::basepoint() * s; let point = &T::basepoint() * s;
let bytes = PublicKeyBytes { let bytes = VerificationKeyBytes {
bytes: jubjub::AffinePoint::from(&point).to_bytes(), bytes: jubjub::AffinePoint::from(&point).to_bytes(),
_marker: PhantomData, _marker: PhantomData,
}; };
PublicKey { bytes, point } VerificationKey { bytes, point }
} }
/// Verify a purported `signature` over `msg` made by this public key. /// Verify a purported `signature` over `msg` made by this verification key.
// This is similar to impl signature::Verifier but without boxed errors // This is similar to impl signature::Verifier but without boxed errors
pub fn verify(&self, msg: &[u8], signature: &Signature<T>) -> Result<(), Error> { pub fn verify(&self, msg: &[u8], signature: &Signature<T>) -> Result<(), Error> {
#![allow(non_snake_case)] #![allow(non_snake_case)]

View File

@ -9,16 +9,16 @@ proptest! {
fn secretkey_serialization( fn secretkey_serialization(
bytes in prop::array::uniform32(any::<u8>()), bytes in prop::array::uniform32(any::<u8>()),
) { ) {
let sk_result_from = SecretKey::<SpendAuth>::try_from(bytes); let sk_result_from = SigningKey::<SpendAuth>::try_from(bytes);
let sk_result_bincode: Result<SecretKey::<SpendAuth>, _> let sk_result_bincode: Result<SigningKey::<SpendAuth>, _>
= bincode::deserialize(&bytes[..]); = bincode::deserialize(&bytes[..]);
// Check 1: both decoding methods should agree // Check 1: both decoding methods should agree
match (sk_result_from, sk_result_bincode) { match (sk_result_from, sk_result_bincode) {
// Both agree on success // Both agree on success
(Ok(sk_from), Ok(sk_bincode)) => { (Ok(sk_from), Ok(sk_bincode)) => {
let pk_bytes_from = PublicKeyBytes::from(PublicKey::from(&sk_from)); let pk_bytes_from = VerificationKeyBytes::from(VerificationKey::from(&sk_from));
let pk_bytes_bincode = PublicKeyBytes::from(PublicKey::from(&sk_bincode)); let pk_bytes_bincode = VerificationKeyBytes::from(VerificationKey::from(&sk_bincode));
assert_eq!(pk_bytes_from, pk_bytes_bincode); assert_eq!(pk_bytes_from, pk_bytes_bincode);
// Check 2: bincode encoding should match original bytes. // Check 2: bincode encoding should match original bytes.
@ -39,8 +39,8 @@ proptest! {
fn publickeybytes_serialization( fn publickeybytes_serialization(
bytes in prop::array::uniform32(any::<u8>()), bytes in prop::array::uniform32(any::<u8>()),
) { ) {
let pk_bytes_from = PublicKeyBytes::<SpendAuth>::from(bytes); let pk_bytes_from = VerificationKeyBytes::<SpendAuth>::from(bytes);
let pk_bytes_bincode: PublicKeyBytes::<SpendAuth> let pk_bytes_bincode: VerificationKeyBytes::<SpendAuth>
= bincode::deserialize(&bytes[..]).unwrap(); = bincode::deserialize(&bytes[..]).unwrap();
// Check 1: both decoding methods should have the same result. // Check 1: both decoding methods should have the same result.
@ -59,8 +59,8 @@ proptest! {
fn publickey_serialization( fn publickey_serialization(
bytes in prop::array::uniform32(any::<u8>()), bytes in prop::array::uniform32(any::<u8>()),
) { ) {
let pk_result_try_from = PublicKey::<SpendAuth>::try_from(bytes); let pk_result_try_from = VerificationKey::<SpendAuth>::try_from(bytes);
let pk_result_bincode: Result<PublicKey::<SpendAuth>, _> let pk_result_bincode: Result<VerificationKey::<SpendAuth>, _>
= bincode::deserialize(&bytes[..]); = bincode::deserialize(&bytes[..]);
// Check 1: both decoding methods should have the same result // Check 1: both decoding methods should have the same result

View File

@ -8,7 +8,7 @@ use redjubjub::*;
#[test] #[test]
fn verify_librustzcash_spendauth() { fn verify_librustzcash_spendauth() {
for (msg, sig, pk_bytes) in LIBRUSTZCASH_SPENDAUTH_SIGS.iter() { for (msg, sig, pk_bytes) in LIBRUSTZCASH_SPENDAUTH_SIGS.iter() {
assert!(PublicKey::try_from(*pk_bytes) assert!(VerificationKey::try_from(*pk_bytes)
.and_then(|pk| pk.verify(&msg, &sig)) .and_then(|pk| pk.verify(&msg, &sig))
.is_ok()); .is_ok());
} }
@ -17,14 +17,18 @@ fn verify_librustzcash_spendauth() {
#[test] #[test]
fn verify_librustzcash_binding() { fn verify_librustzcash_binding() {
for (msg, sig, pk_bytes) in LIBRUSTZCASH_BINDING_SIGS.iter() { for (msg, sig, pk_bytes) in LIBRUSTZCASH_BINDING_SIGS.iter() {
assert!(PublicKey::try_from(*pk_bytes) assert!(VerificationKey::try_from(*pk_bytes)
.and_then(|pk| pk.verify(&msg, &sig)) .and_then(|pk| pk.verify(&msg, &sig))
.is_ok()); .is_ok());
} }
} }
lazy_static! { lazy_static! {
static ref LIBRUSTZCASH_SPENDAUTH_SIGS: [(Vec<u8>, Signature<SpendAuth>, PublicKeyBytes<SpendAuth>); 32] = [ static ref LIBRUSTZCASH_SPENDAUTH_SIGS: [(
Vec<u8>,
Signature<SpendAuth>,
VerificationKeyBytes<SpendAuth>
); 32] = [
( (
[ [
16, 28, 190, 75, 156, 66, 96, 79, 4, 199, 3, 195, 150, 247, 136, 198, 203, 45, 109, 16, 28, 190, 75, 156, 66, 96, 79, 4, 199, 3, 195, 150, 247, 136, 198, 203, 45, 109,
@ -634,7 +638,7 @@ lazy_static! {
.into(), .into(),
), ),
]; ];
static ref LIBRUSTZCASH_BINDING_SIGS: [(Vec<u8>, Signature<Binding>, PublicKeyBytes<Binding>); 32] = [ static ref LIBRUSTZCASH_BINDING_SIGS: [(Vec<u8>, Signature<Binding>, VerificationKeyBytes<Binding>); 32] = [
( (
[ [
16, 28, 190, 75, 156, 66, 96, 79, 4, 199, 3, 195, 150, 247, 136, 198, 203, 45, 109, 16, 28, 190, 75, 156, 66, 96, 79, 4, 199, 3, 195, 150, 247, 136, 198, 203, 45, 109,

View File

@ -10,7 +10,7 @@ use redjubjub::*;
struct SignatureCase<T: SigType> { struct SignatureCase<T: SigType> {
msg: Vec<u8>, msg: Vec<u8>,
sig: Signature<T>, sig: Signature<T>,
pk_bytes: PublicKeyBytes<T>, pk_bytes: VerificationKeyBytes<T>,
is_valid: bool, is_valid: bool,
} }
@ -37,9 +37,9 @@ enum Tweak {
impl<T: SigType> SignatureCase<T> { impl<T: SigType> SignatureCase<T> {
fn new<R: RngCore + CryptoRng>(mut rng: R, msg: Vec<u8>) -> Self { fn new<R: RngCore + CryptoRng>(mut rng: R, msg: Vec<u8>) -> Self {
let sk = SecretKey::new(&mut rng); let sk = SigningKey::new(&mut rng);
let sig = sk.sign(&mut rng, &msg); let sig = sk.sign(&mut rng, &msg);
let pk_bytes = PublicKey::from(&sk).into(); let pk_bytes = VerificationKey::from(&sk).into();
Self { Self {
msg, msg,
sig, sig,
@ -58,12 +58,12 @@ impl<T: SigType> SignatureCase<T> {
}; };
let pk_bytes = { let pk_bytes = {
let bytes: [u8; 32] = self.pk_bytes.into(); let bytes: [u8; 32] = self.pk_bytes.into();
PublicKeyBytes::<T>::from(bytes) VerificationKeyBytes::<T>::from(bytes)
}; };
// Check that signature validation has the expected result. // Check that signature validation has the expected result.
self.is_valid self.is_valid
== PublicKey::try_from(pk_bytes) == VerificationKey::try_from(pk_bytes)
.and_then(|pk| pk.verify(&self.msg, &sig)) .and_then(|pk| pk.verify(&self.msg, &sig))
.is_ok() .is_ok()
} }
@ -142,14 +142,14 @@ proptest! {
Randomizer::from_bytes_wide(&bytes) Randomizer::from_bytes_wide(&bytes)
}; };
let sk = SecretKey::<SpendAuth>::new(&mut rng); let sk = SigningKey::<SpendAuth>::new(&mut rng);
let pk = PublicKey::from(&sk); let pk = VerificationKey::from(&sk);
let sk_r = sk.randomize(&r); let sk_r = sk.randomize(&r);
let pk_r = pk.randomize(&r); let pk_r = pk.randomize(&r);
let pk_r_via_sk_rand: [u8; 32] = PublicKeyBytes::from(PublicKey::from(&sk_r)).into(); let pk_r_via_sk_rand: [u8; 32] = VerificationKeyBytes::from(VerificationKey::from(&sk_r)).into();
let pk_r_via_pk_rand: [u8; 32] = PublicKeyBytes::from(pk_r).into(); let pk_r_via_pk_rand: [u8; 32] = VerificationKeyBytes::from(pk_r).into();
assert_eq!(pk_r_via_pk_rand, pk_r_via_sk_rand); assert_eq!(pk_r_via_pk_rand, pk_r_via_sk_rand);
} }

View File

@ -10,6 +10,6 @@ fn smallorder_publickey_fails() {
let order4 = AffinePoint::from_raw_unchecked(Fq::one(), Fq::zero()); let order4 = AffinePoint::from_raw_unchecked(Fq::one(), Fq::zero());
assert_eq!(<bool>::from(order4.is_small_order()), true); assert_eq!(<bool>::from(order4.is_small_order()), true);
let bytes = order4.to_bytes(); let bytes = order4.to_bytes();
let pk_bytes = PublicKeyBytes::<SpendAuth>::from(bytes); let pk_bytes = VerificationKeyBytes::<SpendAuth>::from(bytes);
assert!(PublicKey::<SpendAuth>::try_from(pk_bytes).is_err()); assert!(VerificationKey::<SpendAuth>::try_from(pk_bytes).is_err());
} }