Merge pull request #9 from ZcashFoundation/parameterize
Make the signature type be a type parameter.
This commit is contained in:
commit
1b7f1b0047
28
src/lib.rs
28
src/lib.rs
|
@ -17,6 +17,34 @@ pub use public_key::{PublicKey, PublicKeyBytes};
|
||||||
pub use secret_key::{SecretKey, SecretKeyBytes};
|
pub use secret_key::{SecretKey, SecretKeyBytes};
|
||||||
pub use signature::Signature;
|
pub use signature::Signature;
|
||||||
|
|
||||||
|
/// Abstracts over different RedJubJub parameter choices.
|
||||||
|
///
|
||||||
|
/// As described [at the end of §5.4.6][concretereddsa] of the Zcash
|
||||||
|
/// protocol specification, the generator used in RedJubjub is left as
|
||||||
|
/// an unspecified parameter, chosen differently for each of
|
||||||
|
/// `BindingSig` and `SpendAuthSig`.
|
||||||
|
///
|
||||||
|
/// To handle this, we encode the parameter choice as a genuine type
|
||||||
|
/// parameter.
|
||||||
|
///
|
||||||
|
/// [concretereddsa]: https://zips.z.cash/protocol/protocol.pdf#concretereddsa
|
||||||
|
pub trait SigType: private::Sealed {}
|
||||||
|
|
||||||
|
/// A type variable corresponding to Zcash's `BindingSig`.
|
||||||
|
pub struct Binding {}
|
||||||
|
impl SigType for Binding {}
|
||||||
|
|
||||||
|
/// A type variable corresponding to Zcash's `SpendAuthSig`.
|
||||||
|
pub struct SpendAuth {}
|
||||||
|
impl SigType for SpendAuth {}
|
||||||
|
|
||||||
|
mod private {
|
||||||
|
use super::*;
|
||||||
|
pub trait Sealed {}
|
||||||
|
impl Sealed for Binding {}
|
||||||
|
impl Sealed for SpendAuth {}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -1,54 +1,70 @@
|
||||||
use std::convert::TryFrom;
|
use std::{convert::TryFrom, marker::PhantomData};
|
||||||
|
|
||||||
use crate::{Error, Randomizer, Signature};
|
use crate::{Error, SigType, SpendAuth, Binding, Randomizer, Signature};
|
||||||
|
|
||||||
/// A refinement type indicating that the inner `[u8; 32]` represents an
|
/// A refinement type indicating that the inner `[u8; 32]` represents an
|
||||||
/// encoding of a RedJubJub public key.
|
/// encoding of a RedJubJub public key.
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
pub struct PublicKeyBytes(pub [u8; 32]);
|
pub struct PublicKeyBytes<T: SigType> {
|
||||||
|
bytes: [u8; 32],
|
||||||
|
_marker: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
impl From<[u8; 32]> for PublicKeyBytes {
|
impl<T: SigType> From<[u8; 32]> for PublicKeyBytes<T> {
|
||||||
fn from(raw: [u8; 32]) -> PublicKeyBytes {
|
fn from(bytes: [u8; 32]) -> PublicKeyBytes<T> {
|
||||||
PublicKeyBytes(raw)
|
PublicKeyBytes { bytes, _marker: PhantomData }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PublicKeyBytes> for [u8; 32] {
|
impl<T: SigType> From<PublicKeyBytes<T>> for [u8; 32] {
|
||||||
fn from(refined: PublicKeyBytes) -> [u8; 32] {
|
fn from(refined: PublicKeyBytes<T>) -> [u8; 32] {
|
||||||
refined.0
|
refined.bytes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A RedJubJub public key.
|
/// A RedJubJub public key.
|
||||||
// XXX PartialEq, Eq?
|
// XXX PartialEq, Eq?
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct PublicKey {
|
pub struct PublicKey<T: SigType> {
|
||||||
// fields
|
// fields
|
||||||
|
_marker: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PublicKey> for PublicKeyBytes {
|
impl<T: SigType> From<PublicKey<T>> for PublicKeyBytes<T> {
|
||||||
fn from(pk: PublicKey) -> PublicKeyBytes {
|
fn from(pk: PublicKey<T>) -> PublicKeyBytes<T> {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<PublicKeyBytes> for PublicKey {
|
impl<T: SigType> TryFrom<PublicKeyBytes<T>> for PublicKey<T> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn try_from(bytes: PublicKeyBytes) -> Result<Self, Self::Error> {
|
fn try_from(bytes: PublicKeyBytes<T>) -> Result<Self, Self::Error> {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PublicKey {
|
impl<T: SigType> PublicKey<T> {
|
||||||
/// Randomize this public key with the given `randomizer`.
|
/// Randomize this public key with the given `randomizer`.
|
||||||
pub fn randomize(&self, randomizer: Randomizer) -> PublicKey {
|
pub fn randomize(&self, randomizer: Randomizer) -> PublicKey<T> {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/// Verify a supposed `signature` over `msg` made by this public key.
|
|
||||||
// This is similar to impl signature::Verifier but without boxed errors
|
impl PublicKey<Binding> {
|
||||||
pub fn verify(&self, msg: &[u8], signature: &Signature) -> Result<(), Error> {
|
/// Verify a Zcash `BindingSig` 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!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,61 +1,77 @@
|
||||||
use std::convert::TryFrom;
|
use std::{convert::TryFrom, marker::PhantomData};
|
||||||
|
|
||||||
use crate::{Error, Randomizer, PublicKey, Signature};
|
use crate::{Error, PublicKey, SigType, Binding, SpendAuth, Randomizer, Signature};
|
||||||
|
|
||||||
/// A refinement type indicating that the inner `[u8; 32]` represents an
|
/// A refinement type indicating that the inner `[u8; 32]` represents an
|
||||||
/// encoding of a RedJubJub secret key.
|
/// encoding of a RedJubJub secret key.
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
pub struct SecretKeyBytes(pub [u8; 32]);
|
pub struct SecretKeyBytes<T: SigType> {
|
||||||
|
bytes: [u8; 32],
|
||||||
|
_marker: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
impl From<[u8; 32]> for SecretKeyBytes {
|
impl<T: SigType> From<[u8; 32]> for SecretKeyBytes<T> {
|
||||||
fn from(raw: [u8; 32]) -> SecretKeyBytes {
|
fn from(bytes: [u8; 32]) -> SecretKeyBytes<T> {
|
||||||
SecretKeyBytes(raw)
|
SecretKeyBytes{ bytes, _marker: PhantomData }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SecretKeyBytes> for [u8; 32] {
|
impl<T: SigType> From<SecretKeyBytes<T>> for [u8; 32] {
|
||||||
fn from(refined: SecretKeyBytes) -> [u8; 32] {
|
fn from(refined: SecretKeyBytes<T>) -> [u8; 32] {
|
||||||
refined.0
|
refined.bytes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A RedJubJub secret key.
|
/// A RedJubJub secret key.
|
||||||
// XXX PartialEq, Eq?
|
// XXX PartialEq, Eq?
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct SecretKey {
|
pub struct SecretKey<T: SigType> {
|
||||||
// fields
|
// fields
|
||||||
|
_marker: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SecretKey> for SecretKeyBytes {
|
impl<T: SigType> From<SecretKey<T>> for SecretKeyBytes<T> {
|
||||||
fn from(pk: SecretKey) -> SecretKeyBytes {
|
fn from(pk: SecretKey<T>) -> SecretKeyBytes<T> {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX could this be a From impl?
|
// XXX could this be a From impl?
|
||||||
impl TryFrom<SecretKeyBytes> for SecretKey {
|
impl<T: SigType> TryFrom<SecretKeyBytes<T>> for SecretKey<T> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn try_from(bytes: SecretKeyBytes) -> Result<Self, Self::Error> {
|
fn try_from(bytes: SecretKeyBytes<T>) -> Result<Self, Self::Error> {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a SecretKey> for PublicKey {
|
impl<'a, T: SigType> From<&'a SecretKey<T>> for PublicKey<T> {
|
||||||
fn from(sk: &'a SecretKey) -> PublicKey {
|
fn from(sk: &'a SecretKey<T>) -> PublicKey<T> {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SecretKey {
|
impl<T: SigType> SecretKey<T> {
|
||||||
/// Randomize this public key with the given `randomizer`.
|
/// Randomize this public key with the given `randomizer`.
|
||||||
pub fn randomize(&self, randomizer: Randomizer) -> PublicKey {
|
pub fn randomize(&self, randomizer: Randomizer) -> PublicKey<T> {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/// Sign the given `msg` with this `SecretKey`.
|
|
||||||
// Similar to signature::Signer but without boxed errors.
|
impl SecretKey<Binding> {
|
||||||
pub fn sign(&self, msg: &[u8]) -> Signature {
|
/// Create a Zcash `BindingSig` 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!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,42 +1,53 @@
|
||||||
use std::{convert, fmt};
|
use std::{marker::PhantomData, convert, fmt};
|
||||||
|
|
||||||
|
use crate::SigType;
|
||||||
|
|
||||||
/// A RedJubJub signature.
|
/// A RedJubJub signature.
|
||||||
pub struct Signature(pub [u8; 64]);
|
pub struct Signature<T: SigType> {
|
||||||
|
bytes: [u8; 64],
|
||||||
|
_marker: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
impl From<[u8; 64]> for Signature {
|
impl<T: SigType> From<[u8; 64]> for Signature<T> {
|
||||||
fn from(bytes: [u8; 64]) -> Signature {
|
fn from(bytes: [u8; 64]) -> Signature<T> {
|
||||||
Signature(bytes)
|
Signature {
|
||||||
|
bytes, _marker: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Signature> for [u8; 64] {
|
impl<T: SigType> From<Signature<T>> for [u8; 64] {
|
||||||
fn from(s: Signature) -> [u8; 64] {
|
fn from(s: Signature<T>) -> [u8; 64] {
|
||||||
s.0
|
s.bytes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// These impls all only exist because of array length restrictions.
|
// These impls all only exist because of array length restrictions.
|
||||||
|
|
||||||
impl fmt::Debug for Signature {
|
// XXX print the type variable
|
||||||
|
impl<T: SigType> fmt::Debug for Signature<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_tuple("Signature").field(&self.0[..]).finish()
|
//f.debug_tuple("Signature").field(&self.0[..]).finish()
|
||||||
|
f.debug_tuple("Signature").finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Copy for Signature {}
|
impl<T: SigType> Copy for Signature<T> {}
|
||||||
|
|
||||||
impl Clone for Signature {
|
impl<T: SigType> Clone for Signature<T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
let mut bytes = [0; 64];
|
let mut bytes = [0; 64];
|
||||||
bytes[..].copy_from_slice(&self.0[..]);
|
bytes[..].copy_from_slice(&self.bytes[..]);
|
||||||
Self(bytes)
|
Signature {
|
||||||
|
bytes, _marker: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Signature {
|
impl<T: SigType> PartialEq for Signature<T> {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.0[..] == other.0[..]
|
self.bytes[..] == other.bytes[..]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eq for Signature {}
|
impl<T: SigType> Eq for Signature<T> {}
|
||||||
|
|
Loading…
Reference in New Issue