use std::{convert::TryFrom, marker::PhantomData}; use crate::{Binding, Error, Randomizer, SigType, Signature, SpendAuth}; /// A refinement type for `[u8; 32]` indicating that the bytes represent /// an encoding of a RedJubJub public key. /// /// This is useful for representing a compressed public key; the /// [`PublicKey`] type in this library holds other decompressed state /// used in signature verification. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct PublicKeyBytes { pub(crate) bytes: [u8; 32], pub(crate) _marker: PhantomData, } impl From<[u8; 32]> for PublicKeyBytes { fn from(bytes: [u8; 32]) -> PublicKeyBytes { PublicKeyBytes { bytes, _marker: PhantomData, } } } impl From> for [u8; 32] { fn from(refined: PublicKeyBytes) -> [u8; 32] { refined.bytes } } /// A RedJubJub public key. #[derive(Copy, Clone, Debug)] pub struct PublicKey { // XXX-jubjub: this should just be Point pub(crate) point: jubjub::ExtendedPoint, pub(crate) bytes: PublicKeyBytes, } impl From> for PublicKeyBytes { fn from(pk: PublicKey) -> PublicKeyBytes { pk.bytes } } impl TryFrom> for PublicKey { type Error = Error; fn try_from(bytes: PublicKeyBytes) -> Result { // XXX-jubjub: this should not use CtOption // XXX-jubjub: this takes ownership of bytes, while Fr doesn't. let maybe_point = jubjub::AffinePoint::from_bytes(bytes.bytes); if maybe_point.is_some().into() { Ok(PublicKey { point: maybe_point.unwrap().into(), bytes, }) } else { Err(Error::MalformedPublicKey) } } } impl PublicKey { /// Randomize this public key with the given `randomizer`. pub fn randomize(&self, randomizer: Randomizer) -> PublicKey { unimplemented!(); } } impl PublicKey { /// 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) -> Result<(), Error> { // this lets us specialize the basepoint parameter, could call a verify_inner unimplemented!(); } } impl PublicKey { /// 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) -> Result<(), Error> { // this lets us specialize the basepoint parameter, could call a verify_inner unimplemented!(); } }