diff --git a/src/error.rs b/src/error.rs index a7c55d8..617773a 100644 --- a/src/error.rs +++ b/src/error.rs @@ -3,7 +3,10 @@ use thiserror::Error; /// An error related to RedJubJub signatures. #[derive(Error, Debug)] pub enum Error { - /// This is a stub variant to check that thiserror derive works. - #[error("Stub error-- remove this.")] - StubError, + /// The encoding of a secret key was malformed. + #[error("Malformed secret key encoding.")] + MalformedSecretKey, + /// The encoding of a public key was malformed. + #[error("Malformed public key encoding.")] + MalformedPublicKey, } diff --git a/src/lib.rs b/src/lib.rs index ef2ad7f..7ca40cf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,6 +13,9 @@ mod signature; /// An element of the JubJub scalar field used for randomization of public and secret keys. pub type Randomizer = jubjub::Fr; +/// A better name than Fr. +type Scalar = jubjub::Fr; + pub use error::Error; pub use public_key::{PublicKey, PublicKeyBytes}; pub use secret_key::{SecretKey, SecretKeyBytes}; diff --git a/src/public_key.rs b/src/public_key.rs index 978ee3a..a08bfba 100644 --- a/src/public_key.rs +++ b/src/public_key.rs @@ -29,13 +29,17 @@ impl From> for [u8; 32] { // XXX PartialEq, Eq? #[derive(Copy, Clone, Debug)] pub struct PublicKey { - // fields + // XXX-jubjub: this should just be Point + point: jubjub::ExtendedPoint, + // XXX should this just store a PublicKeyBytes? + bytes: [u8; 32], _marker: PhantomData, } impl From> for PublicKeyBytes { fn from(pk: PublicKey) -> PublicKeyBytes { - unimplemented!(); + let PublicKey { bytes, _marker, .. } = pk; + PublicKeyBytes { bytes, _marker } } } @@ -43,7 +47,18 @@ impl TryFrom> for PublicKey { type Error = Error; fn try_from(bytes: PublicKeyBytes) -> Result { - unimplemented!(); + // 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) + } } } diff --git a/src/secret_key.rs b/src/secret_key.rs index 90df0a2..d9a64dd 100644 --- a/src/secret_key.rs +++ b/src/secret_key.rs @@ -1,6 +1,6 @@ use std::{convert::TryFrom, marker::PhantomData}; -use crate::{Binding, Error, PublicKey, Randomizer, SigType, Signature, SpendAuth}; +use crate::{Binding, Error, PublicKey, Randomizer, Scalar, SigType, Signature, SpendAuth}; /// A refinement type indicating that the inner `[u8; 32]` represents an /// encoding of a RedJubJub secret key. @@ -29,27 +29,50 @@ impl From> for [u8; 32] { // XXX PartialEq, Eq? #[derive(Copy, Clone, Debug)] pub struct SecretKey { - // fields + sk: Scalar, _marker: PhantomData, } impl From> for SecretKeyBytes { - fn from(pk: SecretKey) -> SecretKeyBytes { - unimplemented!(); + fn from(sk: SecretKey) -> SecretKeyBytes { + SecretKeyBytes { + bytes: sk.sk.to_bytes(), + _marker: PhantomData, + } } } // XXX could this be a From impl? +// not unless there's an infallible conversion from bytes to scalars, +// which is not currently present in jubjub impl TryFrom> for SecretKey { type Error = Error; fn try_from(bytes: SecretKeyBytes) -> Result { + // XXX-jubjub: it does not make sense for this to be a CtOption... + // XXX-jubjub: this takes a borrow but point deser doesn't + let maybe_sk = Scalar::from_bytes(&bytes.bytes); + if maybe_sk.is_some().into() { + Ok(SecretKey { + sk: maybe_sk.unwrap(), + _marker: PhantomData, + }) + } else { + Err(Error::MalformedSecretKey) + } + } +} + +impl<'a> From<&'a SecretKey> for PublicKey { + fn from(sk: &'a SecretKey) -> PublicKey { + // XXX refactor jubjub API + //let basepoint: jubjub::ExtendedPoint = jubjub::AffinePoint::from_bytes(&crate::constants::SPENDAUTHSIG_BASEPOINT_BYTES).unwrap().into(); unimplemented!(); } } -impl<'a, T: SigType> From<&'a SecretKey> for PublicKey { - fn from(sk: &'a SecretKey) -> PublicKey { +impl<'a> From<&'a SecretKey> for PublicKey { + fn from(sk: &'a SecretKey) -> PublicKey { unimplemented!(); } }