Merge pull request #10 from ZcashFoundation/conversions
Add conversions for SecretKey -> PublicKey
This commit is contained in:
commit
09daa00fdf
|
@ -0,0 +1,15 @@
|
||||||
|
/// The byte-encoding of the basepoint for `SpendAuthSig`.
|
||||||
|
// Extracted ad-hoc from librustzcash
|
||||||
|
// XXX add tests for this value.
|
||||||
|
pub const SPENDAUTHSIG_BASEPOINT_BYTES: [u8; 32] = [
|
||||||
|
48, 181, 242, 170, 173, 50, 86, 48, 188, 221, 219, 206, 77, 103, 101, 109, 5, 253, 28, 194,
|
||||||
|
208, 55, 187, 83, 117, 182, 233, 109, 158, 1, 161, 215,
|
||||||
|
];
|
||||||
|
|
||||||
|
/// The byte-encoding of the basepoint for `BindingSig`.
|
||||||
|
// Extracted ad-hoc from librustzcash
|
||||||
|
// XXX add tests for this value.
|
||||||
|
pub const BINDINGSIG_BASEPOINT_BYTES: [u8; 32] = [
|
||||||
|
139, 106, 11, 56, 185, 250, 174, 60, 59, 128, 59, 71, 176, 241, 70, 173, 80, 171, 34, 30, 110,
|
||||||
|
42, 251, 230, 219, 222, 69, 203, 169, 211, 129, 237,
|
||||||
|
];
|
|
@ -3,7 +3,10 @@ use thiserror::Error;
|
||||||
/// An error related to RedJubJub signatures.
|
/// An error related to RedJubJub signatures.
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// This is a stub variant to check that thiserror derive works.
|
/// The encoding of a secret key was malformed.
|
||||||
#[error("Stub error-- remove this.")]
|
#[error("Malformed secret key encoding.")]
|
||||||
StubError,
|
MalformedSecretKey,
|
||||||
|
/// The encoding of a public key was malformed.
|
||||||
|
#[error("Malformed public key encoding.")]
|
||||||
|
MalformedPublicKey,
|
||||||
}
|
}
|
||||||
|
|
12
src/lib.rs
12
src/lib.rs
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
//! Docs require the `nightly` feature until RFC 1990 lands.
|
//! Docs require the `nightly` feature until RFC 1990 lands.
|
||||||
|
|
||||||
|
mod constants;
|
||||||
mod error;
|
mod error;
|
||||||
mod public_key;
|
mod public_key;
|
||||||
mod secret_key;
|
mod secret_key;
|
||||||
|
@ -12,6 +13,9 @@ mod signature;
|
||||||
/// 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;
|
||||||
|
|
||||||
|
/// A better name than Fr.
|
||||||
|
type Scalar = jubjub::Fr;
|
||||||
|
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
pub use public_key::{PublicKey, PublicKeyBytes};
|
pub use public_key::{PublicKey, PublicKeyBytes};
|
||||||
pub use secret_key::{SecretKey, SecretKeyBytes};
|
pub use secret_key::{SecretKey, SecretKeyBytes};
|
||||||
|
@ -44,11 +48,3 @@ mod private {
|
||||||
impl Sealed for Binding {}
|
impl Sealed for Binding {}
|
||||||
impl Sealed for SpendAuth {}
|
impl Sealed for SpendAuth {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
#[test]
|
|
||||||
fn it_works() {
|
|
||||||
assert_eq!(2 + 2, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{convert::TryFrom, marker::PhantomData};
|
use std::{convert::TryFrom, marker::PhantomData};
|
||||||
|
|
||||||
use crate::{Error, SigType, SpendAuth, Binding, Randomizer, Signature};
|
use crate::{Binding, Error, Randomizer, SigType, Signature, SpendAuth};
|
||||||
|
|
||||||
/// 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.
|
||||||
|
@ -12,7 +12,10 @@ pub struct PublicKeyBytes<T: SigType> {
|
||||||
|
|
||||||
impl<T: SigType> From<[u8; 32]> for PublicKeyBytes<T> {
|
impl<T: SigType> From<[u8; 32]> for PublicKeyBytes<T> {
|
||||||
fn from(bytes: [u8; 32]) -> PublicKeyBytes<T> {
|
fn from(bytes: [u8; 32]) -> PublicKeyBytes<T> {
|
||||||
PublicKeyBytes { bytes, _marker: PhantomData }
|
PublicKeyBytes {
|
||||||
|
bytes,
|
||||||
|
_marker: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,13 +29,17 @@ impl<T: SigType> From<PublicKeyBytes<T>> for [u8; 32] {
|
||||||
// XXX PartialEq, Eq?
|
// XXX PartialEq, Eq?
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct PublicKey<T: SigType> {
|
pub struct PublicKey<T: SigType> {
|
||||||
// fields
|
// XXX-jubjub: this should just be Point
|
||||||
_marker: PhantomData<T>,
|
pub(crate) point: jubjub::ExtendedPoint,
|
||||||
|
// XXX should this just store a PublicKeyBytes?
|
||||||
|
pub(crate) bytes: [u8; 32],
|
||||||
|
pub(crate) _marker: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: SigType> From<PublicKey<T>> for PublicKeyBytes<T> {
|
impl<T: SigType> From<PublicKey<T>> for PublicKeyBytes<T> {
|
||||||
fn from(pk: PublicKey<T>) -> PublicKeyBytes<T> {
|
fn from(pk: PublicKey<T>) -> PublicKeyBytes<T> {
|
||||||
unimplemented!();
|
let PublicKey { bytes, _marker, .. } = pk;
|
||||||
|
PublicKeyBytes { bytes, _marker }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +47,18 @@ impl<T: SigType> TryFrom<PublicKeyBytes<T>> for PublicKey<T> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn try_from(bytes: PublicKeyBytes<T>) -> Result<Self, Self::Error> {
|
fn try_from(bytes: PublicKeyBytes<T>) -> Result<Self, Self::Error> {
|
||||||
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{convert::TryFrom, marker::PhantomData};
|
use std::{convert::TryFrom, marker::PhantomData};
|
||||||
|
|
||||||
use crate::{Error, PublicKey, SigType, Binding, SpendAuth, Randomizer, Signature};
|
use crate::{Binding, Error, PublicKey, Randomizer, Scalar, SigType, Signature, SpendAuth};
|
||||||
|
|
||||||
/// 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.
|
||||||
|
@ -12,7 +12,10 @@ pub struct SecretKeyBytes<T: SigType> {
|
||||||
|
|
||||||
impl<T: SigType> From<[u8; 32]> for SecretKeyBytes<T> {
|
impl<T: SigType> From<[u8; 32]> for SecretKeyBytes<T> {
|
||||||
fn from(bytes: [u8; 32]) -> SecretKeyBytes<T> {
|
fn from(bytes: [u8; 32]) -> SecretKeyBytes<T> {
|
||||||
SecretKeyBytes{ bytes, _marker: PhantomData }
|
SecretKeyBytes {
|
||||||
|
bytes,
|
||||||
|
_marker: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,28 +29,72 @@ impl<T: SigType> From<SecretKeyBytes<T>> for [u8; 32] {
|
||||||
// XXX PartialEq, Eq?
|
// XXX PartialEq, Eq?
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct SecretKey<T: SigType> {
|
pub struct SecretKey<T: SigType> {
|
||||||
// fields
|
sk: Scalar,
|
||||||
_marker: PhantomData<T>,
|
_marker: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: SigType> From<SecretKey<T>> for SecretKeyBytes<T> {
|
impl<T: SigType> From<SecretKey<T>> for SecretKeyBytes<T> {
|
||||||
fn from(pk: SecretKey<T>) -> SecretKeyBytes<T> {
|
fn from(sk: SecretKey<T>) -> SecretKeyBytes<T> {
|
||||||
unimplemented!();
|
SecretKeyBytes {
|
||||||
|
bytes: sk.sk.to_bytes(),
|
||||||
|
_marker: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX could this be a From impl?
|
// 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<T: SigType> TryFrom<SecretKeyBytes<T>> for SecretKey<T> {
|
impl<T: SigType> TryFrom<SecretKeyBytes<T>> for SecretKey<T> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn try_from(bytes: SecretKeyBytes<T>) -> Result<Self, Self::Error> {
|
fn try_from(bytes: SecretKeyBytes<T>) -> Result<Self, Self::Error> {
|
||||||
unimplemented!();
|
// 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, T: SigType> From<&'a SecretKey<T>> for PublicKey<T> {
|
impl<'a> From<&'a SecretKey<SpendAuth>> for PublicKey<SpendAuth> {
|
||||||
fn from(sk: &'a SecretKey<T>) -> PublicKey<T> {
|
fn from(sk: &'a SecretKey<SpendAuth>) -> PublicKey<SpendAuth> {
|
||||||
unimplemented!();
|
// XXX-jubjub: this is pretty baroque
|
||||||
|
// XXX-jubjub: provide basepoint tables for generators
|
||||||
|
let basepoint: jubjub::ExtendedPoint =
|
||||||
|
jubjub::AffinePoint::from_bytes(crate::constants::SPENDAUTHSIG_BASEPOINT_BYTES)
|
||||||
|
.unwrap()
|
||||||
|
.into();
|
||||||
|
pk_from_sk_inner(sk, basepoint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a SecretKey<Binding>> for PublicKey<Binding> {
|
||||||
|
fn from(sk: &'a SecretKey<Binding>) -> PublicKey<Binding> {
|
||||||
|
let basepoint: jubjub::ExtendedPoint =
|
||||||
|
jubjub::AffinePoint::from_bytes(crate::constants::BINDINGSIG_BASEPOINT_BYTES)
|
||||||
|
.unwrap()
|
||||||
|
.into();
|
||||||
|
pk_from_sk_inner(sk, basepoint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pk_from_sk_inner<T: SigType>(
|
||||||
|
sk: &SecretKey<T>,
|
||||||
|
basepoint: jubjub::ExtendedPoint,
|
||||||
|
) -> PublicKey<T> {
|
||||||
|
let point = &basepoint * &sk.sk;
|
||||||
|
let bytes = jubjub::AffinePoint::from(&point).to_bytes();
|
||||||
|
PublicKey {
|
||||||
|
point,
|
||||||
|
bytes,
|
||||||
|
_marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{marker::PhantomData, convert, fmt};
|
use std::{convert, fmt, marker::PhantomData};
|
||||||
|
|
||||||
use crate::SigType;
|
use crate::SigType;
|
||||||
|
|
||||||
|
@ -11,7 +11,8 @@ pub struct Signature<T: SigType> {
|
||||||
impl<T: SigType> From<[u8; 64]> for Signature<T> {
|
impl<T: SigType> From<[u8; 64]> for Signature<T> {
|
||||||
fn from(bytes: [u8; 64]) -> Signature<T> {
|
fn from(bytes: [u8; 64]) -> Signature<T> {
|
||||||
Signature {
|
Signature {
|
||||||
bytes, _marker: PhantomData,
|
bytes,
|
||||||
|
_marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +40,8 @@ impl<T: SigType> Clone for Signature<T> {
|
||||||
let mut bytes = [0; 64];
|
let mut bytes = [0; 64];
|
||||||
bytes[..].copy_from_slice(&self.bytes[..]);
|
bytes[..].copy_from_slice(&self.bytes[..]);
|
||||||
Signature {
|
Signature {
|
||||||
bytes, _marker: PhantomData,
|
bytes,
|
||||||
|
_marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue