use std::{convert::TryFrom, marker::PhantomData}; use crate::{Binding, Error, Randomizer, SigType, Signature, SpendAuth}; /// A refinement type indicating that the inner `[u8; 32]` represents an /// encoding of a RedJubJub public key. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct PublicKeyBytes { bytes: [u8; 32], _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. // XXX PartialEq, Eq? #[derive(Copy, Clone, Debug)] pub struct PublicKey { // XXX-jubjub: this should just be Point pub(crate) point: jubjub::ExtendedPoint, // XXX should this just store a PublicKeyBytes? pub(crate) bytes: [u8; 32], pub(crate) _marker: PhantomData, } impl From> for PublicKeyBytes { fn from(pk: PublicKey) -> PublicKeyBytes { let PublicKey { bytes, _marker, .. } = pk; PublicKeyBytes { bytes, _marker } } } 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: bytes.bytes, _marker: PhantomData, }) } 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!(); } }