Fix Orchard implementation, refactor, and add more test vectors (#2445)
* Support incomplete Pallas addition, all the way down * Check Orchard key derivation against test vectors (currently not passing) * Fix up Orchard keys, notes, nullifiers, address, and their tests * Fix Incoming Viewing Key generation * Move around test vectors, impl From<SpendingKey> for FullViewingKey * Add orchard test vectors module * Pull in and use the Sinsemilla test vectors * Test Pallas group hashes for Orchard with test vectors * Move Orchard Arbitrary implementations to arbitrary.rs * Improvements from code review * Derive Eq instead of implementing it for SpendAuthorizingKey * Dedupe Orchard NoteCommitment::extract_x; fix documentation * Update zebra-chain/src/orchard/note.rs Co-authored-by: Deirdre Connolly <deirdre@zfnd.org> Co-authored-by: Conrado P. L. Gouvea <conradoplg@gmail.com> Co-authored-by: teor <teor@riseup.net> Co-authored-by: Conrado Gouvea <conrado@zfnd.org>
This commit is contained in:
parent
049c92374e
commit
8a4add55f1
|
|
@ -2,14 +2,9 @@
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
use proptest::prelude::*;
|
|
||||||
|
|
||||||
use crate::parameters::Network;
|
|
||||||
|
|
||||||
use super::keys;
|
use super::keys;
|
||||||
|
|
||||||
/// A Orchard _shielded payment address_.
|
/// A raw **Orchard** _shielded payment address_.
|
||||||
///
|
///
|
||||||
/// Also known as a _diversified payment address_ for Orchard, as
|
/// Also known as a _diversified payment address_ for Orchard, as
|
||||||
/// defined in [§5.6.4.1 of the Zcash Specification][orchardpaymentaddrencoding].
|
/// defined in [§5.6.4.1 of the Zcash Specification][orchardpaymentaddrencoding].
|
||||||
|
|
@ -17,47 +12,26 @@ use super::keys;
|
||||||
/// [orchardpaymentaddrencoding]: https://zips.z.cash/protocol/nu5.pdf#orchardpaymentaddrencoding
|
/// [orchardpaymentaddrencoding]: https://zips.z.cash/protocol/nu5.pdf#orchardpaymentaddrencoding
|
||||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||||
pub struct Address {
|
pub struct Address {
|
||||||
network: Network,
|
pub(crate) diversifier: keys::Diversifier,
|
||||||
diversifier: keys::Diversifier,
|
pub(crate) transmission_key: keys::TransmissionKey,
|
||||||
transmission_key: keys::TransmissionKey,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Address {
|
impl fmt::Debug for Address {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_struct("OrchardAddress")
|
f.debug_struct("OrchardAddress")
|
||||||
.field("network", &self.network)
|
|
||||||
.field("diversifier", &self.diversifier)
|
.field("diversifier", &self.diversifier)
|
||||||
.field("transmission_key", &self.transmission_key)
|
.field("transmission_key", &self.transmission_key)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
impl Arbitrary for Address {
|
|
||||||
type Parameters = ();
|
|
||||||
|
|
||||||
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
|
|
||||||
(
|
|
||||||
any::<Network>(),
|
|
||||||
any::<keys::Diversifier>(),
|
|
||||||
any::<keys::TransmissionKey>(),
|
|
||||||
)
|
|
||||||
.prop_map(|(network, diversifier, transmission_key)| Self {
|
|
||||||
network,
|
|
||||||
diversifier,
|
|
||||||
transmission_key,
|
|
||||||
})
|
|
||||||
.boxed()
|
|
||||||
}
|
|
||||||
|
|
||||||
type Strategy = BoxedStrategy<Self>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use rand_core::OsRng;
|
use rand_core::OsRng;
|
||||||
|
|
||||||
|
use crate::parameters::Network;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -68,7 +42,7 @@ mod tests {
|
||||||
|
|
||||||
let spending_key = keys::SpendingKey::new(&mut OsRng, network);
|
let spending_key = keys::SpendingKey::new(&mut OsRng, network);
|
||||||
|
|
||||||
let full_viewing_key = keys::FullViewingKey::from_spending_key(spending_key);
|
let full_viewing_key = keys::FullViewingKey::from(spending_key);
|
||||||
|
|
||||||
// Default diversifier, where index = 0.
|
// Default diversifier, where index = 0.
|
||||||
let diversifier_key = keys::DiversifierKey::from(full_viewing_key);
|
let diversifier_key = keys::DiversifierKey::from(full_viewing_key);
|
||||||
|
|
@ -79,7 +53,6 @@ mod tests {
|
||||||
let transmission_key = keys::TransmissionKey::from((incoming_viewing_key, diversifier));
|
let transmission_key = keys::TransmissionKey::from((incoming_viewing_key, diversifier));
|
||||||
|
|
||||||
let _orchard_shielded_address = Address {
|
let _orchard_shielded_address = Address {
|
||||||
network,
|
|
||||||
diversifier,
|
diversifier,
|
||||||
transmission_key,
|
transmission_key,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,10 @@ use proptest::{arbitrary::any, array, collection::vec, prelude::*};
|
||||||
|
|
||||||
use crate::primitives::redpallas::{Signature, SpendAuth, VerificationKey, VerificationKeyBytes};
|
use crate::primitives::redpallas::{Signature, SpendAuth, VerificationKey, VerificationKeyBytes};
|
||||||
|
|
||||||
use super::{keys, note, tree, Action, AuthorizedAction, Flags, NoteCommitment, ValueCommitment};
|
use super::{
|
||||||
|
keys, note, tree, Action, Address, AuthorizedAction, Diversifier, Flags, NoteCommitment,
|
||||||
|
ValueCommitment,
|
||||||
|
};
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
convert::{TryFrom, TryInto},
|
convert::{TryFrom, TryInto},
|
||||||
|
|
@ -125,3 +128,39 @@ impl Arbitrary for tree::Root {
|
||||||
|
|
||||||
type Strategy = BoxedStrategy<Self>;
|
type Strategy = BoxedStrategy<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Arbitrary for keys::TransmissionKey {
|
||||||
|
type Parameters = ();
|
||||||
|
|
||||||
|
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
|
||||||
|
(any::<keys::SpendingKey>())
|
||||||
|
.prop_map(|spending_key| {
|
||||||
|
let full_viewing_key = keys::FullViewingKey::from(spending_key);
|
||||||
|
|
||||||
|
let diversifier_key = keys::DiversifierKey::from(full_viewing_key);
|
||||||
|
|
||||||
|
let diversifier = Diversifier::from(diversifier_key);
|
||||||
|
let incoming_viewing_key = keys::IncomingViewingKey::from(full_viewing_key);
|
||||||
|
|
||||||
|
Self::from((incoming_viewing_key, diversifier))
|
||||||
|
})
|
||||||
|
.boxed()
|
||||||
|
}
|
||||||
|
|
||||||
|
type Strategy = BoxedStrategy<Self>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Arbitrary for Address {
|
||||||
|
type Parameters = ();
|
||||||
|
|
||||||
|
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
|
||||||
|
(any::<keys::Diversifier>(), any::<keys::TransmissionKey>())
|
||||||
|
.prop_map(|(diversifier, transmission_key)| Self {
|
||||||
|
diversifier,
|
||||||
|
transmission_key,
|
||||||
|
})
|
||||||
|
.boxed()
|
||||||
|
}
|
||||||
|
|
||||||
|
type Strategy = BoxedStrategy<Self>;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,15 +12,15 @@ use lazy_static::lazy_static;
|
||||||
use rand_core::{CryptoRng, RngCore};
|
use rand_core::{CryptoRng, RngCore};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
amount::{Amount, NonNegative},
|
amount::Amount,
|
||||||
serialization::{
|
serialization::{
|
||||||
serde_helpers, ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize,
|
serde_helpers, ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
keys::{prf_expand, Diversifier, TransmissionKey},
|
keys::prf_expand,
|
||||||
note::{self, SeedRandomness},
|
note::{Note, Psi, SeedRandomness},
|
||||||
sinsemilla::*,
|
sinsemilla::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -105,11 +105,7 @@ impl TryFrom<[u8; 32]> for NoteCommitment {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NoteCommitment {
|
impl NoteCommitment {
|
||||||
/// Generate a new _NoteCommitment_ and the randomness used to create it.
|
/// Generate a new _NoteCommitment_.
|
||||||
///
|
|
||||||
/// We return the randomness because it is needed to construct a _Note_,
|
|
||||||
/// before it is encrypted as part of an output of an _Action_. This is a
|
|
||||||
/// higher level function that calls `NoteCommit^Orchard_rcm` internally.
|
|
||||||
///
|
///
|
||||||
/// Unlike in Sapling, the definition of an Orchard _note_ includes the ρ
|
/// Unlike in Sapling, the definition of an Orchard _note_ includes the ρ
|
||||||
/// field; the _note_'s position in the _note commitment tree_ does not need
|
/// field; the _note_'s position in the _note commitment tree_ does not need
|
||||||
|
|
@ -119,17 +115,7 @@ impl NoteCommitment {
|
||||||
///
|
///
|
||||||
/// https://zips.z.cash/protocol/nu5.pdf#concretewindowedcommit
|
/// https://zips.z.cash/protocol/nu5.pdf#concretewindowedcommit
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn new<T>(
|
pub fn new(note: Note) -> Option<Self> {
|
||||||
csprng: &mut T,
|
|
||||||
diversifier: Diversifier,
|
|
||||||
transmission_key: TransmissionKey,
|
|
||||||
value: Amount<NonNegative>,
|
|
||||||
rho: note::Rho,
|
|
||||||
psi: note::Psi,
|
|
||||||
) -> Option<(CommitmentRandomness, Self)>
|
|
||||||
where
|
|
||||||
T: RngCore + CryptoRng,
|
|
||||||
{
|
|
||||||
// s as in the argument name for WindowedPedersenCommit_r(s)
|
// s as in the argument name for WindowedPedersenCommit_r(s)
|
||||||
let mut s: BitVec<Lsb0, u8> = BitVec::new();
|
let mut s: BitVec<Lsb0, u8> = BitVec::new();
|
||||||
|
|
||||||
|
|
@ -138,17 +124,15 @@ impl NoteCommitment {
|
||||||
|
|
||||||
// The `TryFrom<Diversifier>` impls for the `pallas::*Point`s handles
|
// The `TryFrom<Diversifier>` impls for the `pallas::*Point`s handles
|
||||||
// calling `DiversifyHash` implicitly.
|
// calling `DiversifyHash` implicitly.
|
||||||
let g_d_bytes: [u8; 32];
|
// _diversified base_
|
||||||
if let Ok(g_d) = pallas::Affine::try_from(diversifier) {
|
let g_d_bytes = pallas::Affine::try_from(note.address.diversifier)
|
||||||
g_d_bytes = g_d.to_bytes();
|
.ok()?
|
||||||
} else {
|
.to_bytes();
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let pk_d_bytes: [u8; 32] = transmission_key.into();
|
let pk_d_bytes: [u8; 32] = note.address.transmission_key.into();
|
||||||
let v_bytes = value.to_bytes();
|
let v_bytes = note.value.to_bytes();
|
||||||
let rho_bytes: [u8; 32] = rho.into();
|
let rho_bytes: [u8; 32] = note.rho.into();
|
||||||
let psi_bytes: [u8; 32] = psi.into();
|
let psi_bytes: [u8; 32] = Psi::from(note.rseed).into();
|
||||||
|
|
||||||
// g*d || pk*d || I2LEBSP_64(v) || I2LEBSP_l^Orchard_Base(ρ) || I2LEBSP_l^Orchard_base(ψ)
|
// g*d || pk*d || I2LEBSP_64(v) || I2LEBSP_l^Orchard_Base(ρ) || I2LEBSP_l^Orchard_base(ψ)
|
||||||
s.extend(g_d_bytes);
|
s.extend(g_d_bytes);
|
||||||
|
|
@ -157,28 +141,17 @@ impl NoteCommitment {
|
||||||
s.extend(rho_bytes);
|
s.extend(rho_bytes);
|
||||||
s.extend(psi_bytes);
|
s.extend(psi_bytes);
|
||||||
|
|
||||||
let rcm = CommitmentRandomness(generate_trapdoor(csprng));
|
let rcm = CommitmentRandomness::from(note.rseed);
|
||||||
|
|
||||||
Some((
|
Some(NoteCommitment::from(
|
||||||
rcm,
|
sinsemilla_commit(rcm.0, b"z.cash:Orchard-NoteCommit", &s)
|
||||||
NoteCommitment::from(
|
.expect("valid orchard note commitment, not ⊥ "),
|
||||||
sinsemilla_commit(rcm.0, b"z.cash:Orchard-NoteCommit", &s)
|
|
||||||
.expect("valid orchard note commitment, not ⊥ "),
|
|
||||||
),
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hash Extractor for Pallas
|
/// Extract the x coordinate of the note commitment.
|
||||||
///
|
|
||||||
/// https://zips.z.cash/protocol/nu5.pdf#concreteextractorpallas
|
|
||||||
pub fn extract_x(&self) -> pallas::Base {
|
pub fn extract_x(&self) -> pallas::Base {
|
||||||
let option: Option<Coordinates<pallas::Affine>> = self.0.coordinates().into();
|
extract_p(self.0.into())
|
||||||
|
|
||||||
match option {
|
|
||||||
// If Some, it's not the identity.
|
|
||||||
Some(coordinates) => *coordinates.x(),
|
|
||||||
_ => pallas::Base::zero(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,7 @@ mod tests;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
convert::{From, Into, TryFrom, TryInto},
|
convert::{From, Into, TryFrom, TryInto},
|
||||||
fmt,
|
fmt, io,
|
||||||
io::{self, Write},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use aes::Aes256;
|
use aes::Aes256;
|
||||||
|
|
@ -213,7 +212,7 @@ impl SpendingKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate a `SpendingKey` from existing bytes.
|
/// Generate a `SpendingKey` from existing bytes.
|
||||||
fn from_bytes(bytes: [u8; 32], network: Network) -> Self {
|
pub fn from_bytes(bytes: [u8; 32], network: Network) -> Self {
|
||||||
Self { network, bytes }
|
Self { network, bytes }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -225,7 +224,7 @@ impl SpendingKey {
|
||||||
/// Description_ that spends notes, proving ownership of notes.
|
/// Description_ that spends notes, proving ownership of notes.
|
||||||
///
|
///
|
||||||
/// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents
|
/// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone, Eq)]
|
||||||
pub struct SpendAuthorizingKey(pub(crate) pallas::Scalar);
|
pub struct SpendAuthorizingKey(pub(crate) pallas::Scalar);
|
||||||
|
|
||||||
impl ConstantTimeEq for SpendAuthorizingKey {
|
impl ConstantTimeEq for SpendAuthorizingKey {
|
||||||
|
|
@ -259,15 +258,21 @@ impl From<SpendingKey> for SpendAuthorizingKey {
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents>
|
/// <https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents>
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#concreteprfs>
|
/// <https://zips.z.cash/protocol/nu5.pdf#concreteprfs>
|
||||||
fn from(spending_key: SpendingKey) -> SpendAuthorizingKey {
|
fn from(spending_key: SpendingKey) -> SpendAuthorizingKey {
|
||||||
let hash_bytes = prf_expand(spending_key.bytes, vec![&[6]]);
|
|
||||||
|
|
||||||
// Handles ToScalar^Orchard
|
// Handles ToScalar^Orchard
|
||||||
Self(pallas::Scalar::from_bytes_wide(&hash_bytes))
|
let ask = pallas::Scalar::from_bytes_wide(&prf_expand(spending_key.bytes, vec![&[6]]));
|
||||||
|
|
||||||
|
// let ak^P = SpendAuthSig^Orchard.DerivePublic(ask)...
|
||||||
|
let ak_bytes: [u8; 32] = SpendValidatingKey::from(SpendAuthorizingKey(ask)).into();
|
||||||
|
|
||||||
|
// if the last bit (that is, the 𝑦˜ bit) of repr_P (ak^P ) is 1:
|
||||||
|
// set ask ← −ask
|
||||||
|
match (ak_bytes[31] >> 7) == 0b0000_0001 {
|
||||||
|
true => Self(-ask),
|
||||||
|
false => Self(ask),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eq for SpendAuthorizingKey {}
|
|
||||||
|
|
||||||
impl PartialEq for SpendAuthorizingKey {
|
impl PartialEq for SpendAuthorizingKey {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.ct_eq(other).unwrap_u8() == 1u8
|
self.ct_eq(other).unwrap_u8() == 1u8
|
||||||
|
|
@ -283,9 +288,6 @@ impl PartialEq<[u8; 32]> for SpendAuthorizingKey {
|
||||||
/// A Spend validating key, as described in [protocol specification
|
/// A Spend validating key, as described in [protocol specification
|
||||||
/// §4.2.3][orchardkeycomponents].
|
/// §4.2.3][orchardkeycomponents].
|
||||||
///
|
///
|
||||||
/// Used to validate Orchard _Spend Authorization Signatures_, proving ownership
|
|
||||||
/// of notes.
|
|
||||||
///
|
|
||||||
/// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents
|
/// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct SpendValidatingKey(pub(crate) redpallas::VerificationKey<SpendAuth>);
|
pub struct SpendValidatingKey(pub(crate) redpallas::VerificationKey<SpendAuth>);
|
||||||
|
|
@ -475,138 +477,14 @@ impl TryFrom<[u8; 32]> for IvkCommitRandomness {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Magic human-readable strings used to identify what networks Orchard incoming
|
/// _Full viewing keys_
|
||||||
/// viewing keys are associated with when encoded/decoded with bech32.
|
|
||||||
///
|
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#orchardinviewingkeyencoding>
|
|
||||||
mod ivk_hrp {
|
|
||||||
pub const MAINNET: &str = "zivko";
|
|
||||||
pub const TESTNET: &str = "zivktestorchard";
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An incoming viewing key, as described in [protocol specification
|
|
||||||
/// §4.2.3][ps].
|
|
||||||
///
|
|
||||||
/// Used to decrypt incoming notes without spending them.
|
|
||||||
///
|
|
||||||
/// [ps]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct IncomingViewingKey {
|
|
||||||
network: Network,
|
|
||||||
scalar: pallas::Scalar,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IncomingViewingKey {
|
|
||||||
/// Generate an _IncomingViewingKey_ from existing bytes and a network variant.
|
|
||||||
fn from_bytes(bytes: [u8; 32], network: Network) -> Self {
|
|
||||||
Self {
|
|
||||||
network,
|
|
||||||
scalar: pallas::Scalar::from_bytes(&bytes).unwrap(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ConstantTimeEq for IncomingViewingKey {
|
|
||||||
/// Check whether two `IncomingViewingKey`s are equal, runtime independent
|
|
||||||
/// of the value of the secret.
|
|
||||||
///
|
|
||||||
/// # Note
|
|
||||||
///
|
|
||||||
/// This function short-circuits if the networks of the keys are different.
|
|
||||||
/// Otherwise, it should execute in time independent of the `bytes` value.
|
|
||||||
fn ct_eq(&self, other: &Self) -> Choice {
|
|
||||||
if self.network != other.network {
|
|
||||||
return Choice::from(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.scalar.to_bytes().ct_eq(&other.scalar.to_bytes())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for IncomingViewingKey {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
f.debug_tuple("IncomingViewingKey")
|
|
||||||
.field(&hex::encode(self.scalar.to_bytes()))
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for IncomingViewingKey {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
let hrp = match self.network {
|
|
||||||
Network::Mainnet => ivk_hrp::MAINNET,
|
|
||||||
Network::Testnet => ivk_hrp::TESTNET,
|
|
||||||
};
|
|
||||||
|
|
||||||
bech32::encode_to_fmt(f, hrp, &self.scalar.to_bytes().to_base32(), Variant::Bech32).unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Eq for IncomingViewingKey {}
|
|
||||||
|
|
||||||
impl From<FullViewingKey> for IncomingViewingKey {
|
|
||||||
/// Commit^ivk_rivk(ak, nk) :=
|
|
||||||
/// SinsemillaShortCommit_rcm (︁"z.cash:Orchard-CommitIvk", I2LEBSP_l(ak) || I2LEBSP_l(nk)︁) mod r_P
|
|
||||||
///
|
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents>
|
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#concreteprfs>
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
fn from(fvk: FullViewingKey) -> Self {
|
|
||||||
let mut M: BitVec<Lsb0, u8> = BitVec::new();
|
|
||||||
|
|
||||||
M.extend(<[u8; 32]>::from(fvk.spend_validating_key));
|
|
||||||
M.extend(<[u8; 32]>::from(fvk.nullifier_deriving_key));
|
|
||||||
|
|
||||||
// Commit^ivk_rivk
|
|
||||||
let commit_x = sinsemilla_short_commit(
|
|
||||||
fvk.ivk_commit_randomness.into(),
|
|
||||||
b"z.cash:Orchard-CommitIvk",
|
|
||||||
&M,
|
|
||||||
)
|
|
||||||
.expect("deriving orchard commit^ivk should not output ⊥ ");
|
|
||||||
|
|
||||||
Self {
|
|
||||||
network: fvk.network,
|
|
||||||
// mod r_P
|
|
||||||
scalar: pallas::Scalar::from_bytes(&commit_x.into()).unwrap(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq for IncomingViewingKey {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.ct_eq(other).unwrap_u8() == 1u8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq<[u8; 32]> for IncomingViewingKey {
|
|
||||||
fn eq(&self, other: &[u8; 32]) -> bool {
|
|
||||||
self.scalar.to_bytes().ct_eq(other).unwrap_u8() == 1u8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Magic human-readable strings used to identify what networks Orchard full
|
|
||||||
/// viewing keys are associated with when encoded/decoded with bech32.
|
|
||||||
///
|
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#orchardfullviewingkeyencoding>
|
|
||||||
mod fvk_hrp {
|
|
||||||
pub const MAINNET: &str = "zviewo";
|
|
||||||
pub const TESTNET: &str = "zviewtestorchard";
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Full Viewing Keys
|
|
||||||
///
|
///
|
||||||
/// Allows recognizing both incoming and outgoing notes without having
|
/// Allows recognizing both incoming and outgoing notes without having
|
||||||
/// spend authority.
|
/// spend authority.
|
||||||
///
|
///
|
||||||
/// For incoming viewing keys on the production network, the
|
|
||||||
/// Human-Readable Part is “zviewo”. For incoming viewing keys on the
|
|
||||||
/// test network, the Human-Readable Part is “zviewtestorchard”.
|
|
||||||
///
|
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#orchardfullviewingkeyencoding>
|
/// <https://zips.z.cash/protocol/nu5.pdf#orchardfullviewingkeyencoding>
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct FullViewingKey {
|
pub struct FullViewingKey {
|
||||||
network: Network,
|
|
||||||
spend_validating_key: SpendValidatingKey,
|
spend_validating_key: SpendValidatingKey,
|
||||||
nullifier_deriving_key: NullifierDerivingKey,
|
nullifier_deriving_key: NullifierDerivingKey,
|
||||||
ivk_commit_randomness: IvkCommitRandomness,
|
ivk_commit_randomness: IvkCommitRandomness,
|
||||||
|
|
@ -630,21 +508,6 @@ impl FullViewingKey {
|
||||||
// let R = PRF^expand_K( [0x82] || I2LEOSP256(ak) || I2LEOSP256(nk) )
|
// let R = PRF^expand_K( [0x82] || I2LEOSP256(ak) || I2LEOSP256(nk) )
|
||||||
prf_expand(K, t)
|
prf_expand(K, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Derive a full viewing key from a existing spending key and its network.
|
|
||||||
///
|
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#addressesandkeys>
|
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#orchardfullviewingkeyencoding>
|
|
||||||
pub fn from_spending_key(sk: SpendingKey) -> FullViewingKey {
|
|
||||||
let spend_authorizing_key = SpendAuthorizingKey::from(sk);
|
|
||||||
|
|
||||||
Self {
|
|
||||||
network: sk.network,
|
|
||||||
spend_validating_key: SpendValidatingKey::from(spend_authorizing_key),
|
|
||||||
nullifier_deriving_key: NullifierDerivingKey::from(sk),
|
|
||||||
ivk_commit_randomness: IvkCommitRandomness::from(sk),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConstantTimeEq for FullViewingKey {
|
impl ConstantTimeEq for FullViewingKey {
|
||||||
|
|
@ -653,12 +516,11 @@ impl ConstantTimeEq for FullViewingKey {
|
||||||
///
|
///
|
||||||
/// # Note
|
/// # Note
|
||||||
///
|
///
|
||||||
/// This function short-circuits if the networks or spend validating keys
|
/// This function short-circuits if the spend validating keys
|
||||||
/// are different. Otherwise, it should execute in time independent of the
|
/// are different. Otherwise, it should execute in time independent of the
|
||||||
/// secret component values.
|
/// secret component values.
|
||||||
fn ct_eq(&self, other: &Self) -> Choice {
|
fn ct_eq(&self, other: &Self) -> Choice {
|
||||||
if self.network != other.network || self.spend_validating_key != other.spend_validating_key
|
if self.spend_validating_key != other.spend_validating_key {
|
||||||
{
|
|
||||||
return Choice::from(0);
|
return Choice::from(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -674,7 +536,6 @@ impl ConstantTimeEq for FullViewingKey {
|
||||||
impl fmt::Debug for FullViewingKey {
|
impl fmt::Debug for FullViewingKey {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_struct("FullViewingKey")
|
f.debug_struct("FullViewingKey")
|
||||||
.field("network", &self.network)
|
|
||||||
.field("spend_validating_key", &self.spend_validating_key)
|
.field("spend_validating_key", &self.spend_validating_key)
|
||||||
.field("nullifier_deriving_key", &self.nullifier_deriving_key)
|
.field("nullifier_deriving_key", &self.nullifier_deriving_key)
|
||||||
.field("ivk_commit_randomness", &self.ivk_commit_randomness)
|
.field("ivk_commit_randomness", &self.ivk_commit_randomness)
|
||||||
|
|
@ -683,19 +544,39 @@ impl fmt::Debug for FullViewingKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for FullViewingKey {
|
impl fmt::Display for FullViewingKey {
|
||||||
|
/// The _raw encoding_ of an **Orchard** _full viewing key_.
|
||||||
|
///
|
||||||
|
/// <https://zips.z.cash/protocol/protocol.pdf#orchardfullviewingkeyencoding>
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let mut bytes = io::Cursor::new(Vec::new());
|
f.write_str(&hex::encode(<[u8; 96]>::from(*self)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let _ = bytes.write_all(&<[u8; 32]>::from(self.spend_validating_key));
|
impl From<FullViewingKey> for [u8; 96] {
|
||||||
let _ = bytes.write_all(&<[u8; 32]>::from(self.nullifier_deriving_key));
|
fn from(fvk: FullViewingKey) -> [u8; 96] {
|
||||||
let _ = bytes.write_all(&<[u8; 32]>::from(self.ivk_commit_randomness));
|
let mut bytes = [0u8; 96];
|
||||||
|
|
||||||
let hrp = match self.network {
|
bytes[..32].copy_from_slice(&<[u8; 32]>::from(fvk.spend_validating_key));
|
||||||
Network::Mainnet => fvk_hrp::MAINNET,
|
bytes[32..64].copy_from_slice(&<[u8; 32]>::from(fvk.nullifier_deriving_key));
|
||||||
Network::Testnet => fvk_hrp::TESTNET,
|
bytes[64..].copy_from_slice(&<[u8; 32]>::from(fvk.ivk_commit_randomness));
|
||||||
};
|
|
||||||
|
|
||||||
bech32::encode_to_fmt(f, hrp, bytes.get_ref().to_base32(), Variant::Bech32).unwrap()
|
bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SpendingKey> for FullViewingKey {
|
||||||
|
/// Derive a _full viewing key_ from a existing _spending key_.
|
||||||
|
///
|
||||||
|
/// <https://zips.z.cash/protocol/nu5.pdf#addressesandkeys>
|
||||||
|
/// <https://zips.z.cash/protocol/nu5.pdf#orchardfullviewingkeyencoding>
|
||||||
|
fn from(sk: SpendingKey) -> FullViewingKey {
|
||||||
|
let spend_authorizing_key = SpendAuthorizingKey::from(sk);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
spend_validating_key: SpendValidatingKey::from(spend_authorizing_key),
|
||||||
|
nullifier_deriving_key: NullifierDerivingKey::from(sk),
|
||||||
|
ivk_commit_randomness: IvkCommitRandomness::from(sk),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -705,6 +586,108 @@ impl PartialEq for FullViewingKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An _incoming viewing key_, as described in [protocol specification
|
||||||
|
/// §4.2.3][ps].
|
||||||
|
///
|
||||||
|
/// Used to decrypt incoming notes without spending them.
|
||||||
|
///
|
||||||
|
/// [ps]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct IncomingViewingKey {
|
||||||
|
dk: DiversifierKey,
|
||||||
|
// TODO: refine type
|
||||||
|
ivk: pallas::Scalar,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConstantTimeEq for IncomingViewingKey {
|
||||||
|
/// Check whether two `IncomingViewingKey`s are equal, runtime independent
|
||||||
|
/// of the value of the secret.
|
||||||
|
///
|
||||||
|
/// # Note
|
||||||
|
///
|
||||||
|
/// This function should execute in time independent of the `dk` and `ivk` values.
|
||||||
|
fn ct_eq(&self, other: &Self) -> Choice {
|
||||||
|
<[u8; 64]>::from(*self).ct_eq(&<[u8; 64]>::from(*other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for IncomingViewingKey {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.debug_struct("IncomingViewingKey")
|
||||||
|
.field("dk", &self.dk)
|
||||||
|
.field("ivk", &self.ivk)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for IncomingViewingKey {
|
||||||
|
/// The _raw encoding_ of an **Orchard** _incoming viewing key_.
|
||||||
|
///
|
||||||
|
/// <https://zips.z.cash/protocol/protocol.pdf#orchardfullviewingkeyencoding>
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.write_str(&hex::encode(<[u8; 64]>::from(*self)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for IncomingViewingKey {}
|
||||||
|
|
||||||
|
impl From<IncomingViewingKey> for [u8; 64] {
|
||||||
|
fn from(ivk: IncomingViewingKey) -> [u8; 64] {
|
||||||
|
let mut bytes = [0u8; 64];
|
||||||
|
|
||||||
|
bytes[..32].copy_from_slice(&<[u8; 32]>::from(ivk.dk));
|
||||||
|
bytes[32..].copy_from_slice(&<[u8; 32]>::from(ivk.ivk));
|
||||||
|
|
||||||
|
bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<FullViewingKey> for IncomingViewingKey {
|
||||||
|
/// Commit^ivk_rivk(ak, nk) :=
|
||||||
|
/// SinsemillaShortCommit_rcm(︁
|
||||||
|
/// "z.cash:Orchard-CommitIvk",
|
||||||
|
/// I2LEBSP_l^Orchard_base(ak) || I2LEBSP_l^Orchard_base(nk)︁
|
||||||
|
/// ) mod r_P
|
||||||
|
///
|
||||||
|
/// <https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents>
|
||||||
|
/// <https://zips.z.cash/protocol/nu5.pdf#concreteprfs>
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn from(fvk: FullViewingKey) -> Self {
|
||||||
|
let mut M: BitVec<Lsb0, u8> = BitVec::new();
|
||||||
|
|
||||||
|
// I2LEBSP_l^Orchard_base(ak)︁
|
||||||
|
let ak_bytes =
|
||||||
|
extract_p(pallas::Point::from_bytes(&fvk.spend_validating_key.into()).unwrap())
|
||||||
|
.to_bytes();
|
||||||
|
M.extend_from_bitslice(&BitArray::<Lsb0, _>::from(ak_bytes)[0..255]);
|
||||||
|
|
||||||
|
// I2LEBSP_l^Orchard_base(nk)︁
|
||||||
|
let nk_bytes: [u8; 32] = fvk.nullifier_deriving_key.into();
|
||||||
|
M.extend_from_bitslice(&BitArray::<Lsb0, _>::from(nk_bytes)[0..255]);
|
||||||
|
|
||||||
|
// Commit^ivk_rivk
|
||||||
|
// rivk needs to be 255 bits long
|
||||||
|
let commit_x = sinsemilla_short_commit(
|
||||||
|
fvk.ivk_commit_randomness.into(),
|
||||||
|
b"z.cash:Orchard-CommitIvk",
|
||||||
|
&M,
|
||||||
|
)
|
||||||
|
.expect("deriving orchard commit^ivk should not output ⊥ ");
|
||||||
|
|
||||||
|
Self {
|
||||||
|
dk: fvk.into(),
|
||||||
|
// mod r_P
|
||||||
|
ivk: pallas::Scalar::from_bytes(&commit_x.into()).unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for IncomingViewingKey {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.ct_eq(other).unwrap_u8() == 1u8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An outgoing viewing key, as described in [protocol specification
|
/// An outgoing viewing key, as described in [protocol specification
|
||||||
/// §4.2.3][ps].
|
/// §4.2.3][ps].
|
||||||
///
|
///
|
||||||
|
|
@ -785,7 +768,7 @@ impl PartialEq<[u8; 32]> for OutgoingViewingKey {
|
||||||
///
|
///
|
||||||
/// [4.2.3]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents
|
/// [4.2.3]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents
|
||||||
/// [ZIP-32]: https://zips.z.cash/zip-0032#orchard-diversifier-derivation
|
/// [ZIP-32]: https://zips.z.cash/zip-0032#orchard-diversifier-derivation
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct DiversifierKey([u8; 32]);
|
pub struct DiversifierKey([u8; 32]);
|
||||||
|
|
||||||
impl ConstantTimeEq for DiversifierKey {
|
impl ConstantTimeEq for DiversifierKey {
|
||||||
|
|
@ -841,9 +824,6 @@ impl PartialEq<[u8; 32]> for DiversifierKey {
|
||||||
|
|
||||||
/// A _diversifier_, as described in [protocol specification §4.2.3][ps].
|
/// A _diversifier_, as described in [protocol specification §4.2.3][ps].
|
||||||
///
|
///
|
||||||
/// Combined with an `IncomingViewingKey`, produces a _diversified
|
|
||||||
/// payment address_.
|
|
||||||
///
|
|
||||||
/// [ps]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents
|
/// [ps]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents
|
||||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
|
|
@ -989,7 +969,7 @@ impl From<(IncomingViewingKey, Diversifier)> for TransmissionKey {
|
||||||
fn from((ivk, d): (IncomingViewingKey, Diversifier)) -> Self {
|
fn from((ivk, d): (IncomingViewingKey, Diversifier)) -> Self {
|
||||||
let g_d = pallas::Point::from(d);
|
let g_d = pallas::Point::from(d);
|
||||||
|
|
||||||
Self(pallas::Affine::from(g_d * ivk.scalar))
|
Self(pallas::Affine::from(g_d * ivk.ivk))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -999,8 +979,63 @@ impl PartialEq<[u8; 32]> for TransmissionKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: implement EphemeralPrivateKey: #2192
|
/// An _outgoing cipher key_ for Orchard note encryption/decryption.
|
||||||
|
///
|
||||||
|
/// <https://zips.z.cash/protocol/nu5.pdf#saplingandorchardencrypt>
|
||||||
|
// TODO: derive `OutgoingCipherKey`: https://github.com/ZcashFoundation/zebra/issues/2041
|
||||||
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
|
pub struct OutgoingCipherKey([u8; 32]);
|
||||||
|
|
||||||
|
impl fmt::Debug for OutgoingCipherKey {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.debug_tuple("OutgoingCipherKey")
|
||||||
|
.field(&hex::encode(self.0))
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&OutgoingCipherKey> for [u8; 32] {
|
||||||
|
fn from(ock: &OutgoingCipherKey) -> [u8; 32] {
|
||||||
|
ock.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: implement PrivateKey: #2192
|
||||||
|
|
||||||
|
/// An ephemeral private key for Orchard key agreement.
|
||||||
|
///
|
||||||
|
/// <https://zips.z.cash/protocol/nu5.pdf#concreteorchardkeyagreement>
|
||||||
|
/// <https://zips.z.cash/protocol/nu5.pdf#saplingandorchardencrypt>
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub struct EphemeralPrivateKey(pub(crate) pallas::Scalar);
|
||||||
|
|
||||||
|
impl ConstantTimeEq for EphemeralPrivateKey {
|
||||||
|
/// Check whether two `EphemeralPrivateKey`s are equal, runtime independent
|
||||||
|
/// of the value of the secret.
|
||||||
|
fn ct_eq(&self, other: &Self) -> Choice {
|
||||||
|
self.0.to_bytes().ct_eq(&other.0.to_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for EphemeralPrivateKey {}
|
||||||
|
|
||||||
|
impl From<EphemeralPrivateKey> for [u8; 32] {
|
||||||
|
fn from(esk: EphemeralPrivateKey) -> Self {
|
||||||
|
esk.0.to_bytes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for EphemeralPrivateKey {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.ct_eq(other).unwrap_u8() == 1u8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq<[u8; 32]> for EphemeralPrivateKey {
|
||||||
|
fn eq(&self, other: &[u8; 32]) -> bool {
|
||||||
|
self.0.to_bytes().ct_eq(other).unwrap_u8() == 1u8
|
||||||
|
}
|
||||||
|
}
|
||||||
/// An ephemeral public key for Orchard key agreement.
|
/// An ephemeral public key for Orchard key agreement.
|
||||||
///
|
///
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#concreteorchardkeyagreement>
|
/// <https://zips.z.cash/protocol/nu5.pdf#concreteorchardkeyagreement>
|
||||||
|
|
@ -1050,7 +1085,7 @@ impl TryFrom<[u8; 32]> for EphemeralPublicKey {
|
||||||
if possible_point.is_some().into() {
|
if possible_point.is_some().into() {
|
||||||
Ok(Self(possible_point.unwrap()))
|
Ok(Self(possible_point.unwrap()))
|
||||||
} else {
|
} else {
|
||||||
Err("Invalid pallas::Affine value")
|
Err("Invalid pallas::Affine value for Orchard EphemeralPublicKey")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1067,25 +1102,3 @@ impl ZcashDeserialize for EphemeralPublicKey {
|
||||||
Self::try_from(reader.read_32_bytes()?).map_err(|e| SerializationError::Parse(e))
|
Self::try_from(reader.read_32_bytes()?).map_err(|e| SerializationError::Parse(e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An _outgoing cipher key_ for Orchard note encryption/decryption.
|
|
||||||
///
|
|
||||||
/// <https://zips.z.cash/protocol/nu5.pdf#saplingandorchardencrypt>
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
|
||||||
pub struct OutgoingCipherKey([u8; 32]);
|
|
||||||
|
|
||||||
impl fmt::Debug for OutgoingCipherKey {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
f.debug_tuple("OutgoingCipherKey")
|
|
||||||
.field(&hex::encode(self.0))
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&OutgoingCipherKey> for [u8; 32] {
|
|
||||||
fn from(ock: &OutgoingCipherKey) -> [u8; 32] {
|
|
||||||
ock.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: derive `OutgoingCipherKey`: https://github.com/ZcashFoundation/zebra/issues/2041
|
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,52 @@
|
||||||
#![allow(clippy::module_inception)]
|
#![allow(clippy::module_inception)]
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
use super::*;
|
||||||
|
use crate::orchard::tests::vectors::KEY_COMPONENTS;
|
||||||
|
|
||||||
use proptest::prelude::*;
|
use proptest::prelude::*;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[test]
|
||||||
impl Arbitrary for TransmissionKey {
|
fn generate_keys_from_test_vectors() {
|
||||||
type Parameters = ();
|
zebra_test::init();
|
||||||
|
|
||||||
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
|
for test_vector in KEY_COMPONENTS.iter() {
|
||||||
(any::<SpendingKey>())
|
let spending_key = SpendingKey::from_bytes(test_vector.sk, Network::Mainnet);
|
||||||
.prop_map(|spending_key| {
|
|
||||||
let full_viewing_key = FullViewingKey::from_spending_key(spending_key);
|
|
||||||
|
|
||||||
let diversifier_key = DiversifierKey::from(full_viewing_key);
|
let spend_authorizing_key = SpendAuthorizingKey::from(spending_key);
|
||||||
|
assert_eq!(spend_authorizing_key, test_vector.ask);
|
||||||
|
|
||||||
let diversifier = Diversifier::from(diversifier_key);
|
let spend_validating_key = SpendValidatingKey::from(spend_authorizing_key);
|
||||||
let incoming_viewing_key = IncomingViewingKey::from(full_viewing_key);
|
assert_eq!(<[u8; 32]>::from(spend_validating_key), test_vector.ak);
|
||||||
|
|
||||||
Self::from((incoming_viewing_key, diversifier))
|
let nullifier_deriving_key = NullifierDerivingKey::from(spending_key);
|
||||||
})
|
assert_eq!(nullifier_deriving_key, test_vector.nk);
|
||||||
.boxed()
|
|
||||||
|
let ivk_commit_randomness = IvkCommitRandomness::from(spending_key);
|
||||||
|
assert_eq!(ivk_commit_randomness, test_vector.rivk);
|
||||||
|
|
||||||
|
let full_viewing_key = FullViewingKey {
|
||||||
|
spend_validating_key,
|
||||||
|
nullifier_deriving_key,
|
||||||
|
ivk_commit_randomness,
|
||||||
|
};
|
||||||
|
|
||||||
|
let diversifier_key = DiversifierKey::from(full_viewing_key);
|
||||||
|
assert_eq!(diversifier_key, test_vector.dk);
|
||||||
|
|
||||||
|
let incoming_viewing_key = IncomingViewingKey::from(full_viewing_key);
|
||||||
|
assert_eq!(<[u8; 32]>::from(incoming_viewing_key.ivk), test_vector.ivk);
|
||||||
|
|
||||||
|
let outgoing_viewing_key = OutgoingViewingKey::from(full_viewing_key);
|
||||||
|
assert_eq!(outgoing_viewing_key, test_vector.ovk);
|
||||||
|
|
||||||
|
let diversifier = Diversifier::from(diversifier_key);
|
||||||
|
assert_eq!(diversifier, test_vector.default_d);
|
||||||
|
|
||||||
|
let transmission_key = TransmissionKey::from((incoming_viewing_key, diversifier));
|
||||||
|
assert_eq!(transmission_key, test_vector.default_pk_d);
|
||||||
}
|
}
|
||||||
|
|
||||||
type Strategy = BoxedStrategy<Self>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
proptest! {
|
proptest! {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -35,46 +55,42 @@ proptest! {
|
||||||
zebra_test::init();
|
zebra_test::init();
|
||||||
|
|
||||||
// Test ConstantTimeEq, Eq, PartialEq
|
// Test ConstantTimeEq, Eq, PartialEq
|
||||||
assert!(spending_key == SpendingKey::from_bytes(spending_key.bytes, spending_key.network));
|
assert_eq!(spending_key, SpendingKey::from_bytes(spending_key.bytes, spending_key.network));
|
||||||
|
|
||||||
let spend_authorizing_key = SpendAuthorizingKey::from(spending_key);
|
let spend_authorizing_key = SpendAuthorizingKey::from(spending_key);
|
||||||
// Test ConstantTimeEq, Eq, PartialEq
|
// Test ConstantTimeEq, Eq, PartialEq
|
||||||
assert!(spend_authorizing_key == <[u8; 32]>::from(spend_authorizing_key));
|
assert_eq!(spend_authorizing_key, spend_authorizing_key.clone());
|
||||||
|
|
||||||
// ConstantTimeEq not implemented as it's a public value
|
// ConstantTimeEq not implemented as it's a public value
|
||||||
let spend_validating_key = SpendValidatingKey::from(spend_authorizing_key);
|
let spend_validating_key = SpendValidatingKey::from(spend_authorizing_key);
|
||||||
|
|
||||||
let nullifier_deriving_key = NullifierDerivingKey::from(spending_key);
|
let nullifier_deriving_key = NullifierDerivingKey::from(spending_key);
|
||||||
// Test ConstantTimeEq, Eq, PartialEq
|
// Test ConstantTimeEq, Eq, PartialEq
|
||||||
assert!(nullifier_deriving_key == <[u8; 32]>::from(nullifier_deriving_key));
|
assert_eq!(nullifier_deriving_key, nullifier_deriving_key.clone());
|
||||||
|
|
||||||
let ivk_commit_randomness = IvkCommitRandomness::from(spending_key);
|
let ivk_commit_randomness = IvkCommitRandomness::from(spending_key);
|
||||||
// Test ConstantTimeEq, Eq, PartialEq
|
// Test ConstantTimeEq, Eq, PartialEq
|
||||||
assert!(ivk_commit_randomness == <[u8; 32]>::from(ivk_commit_randomness));
|
assert_eq!(ivk_commit_randomness, ivk_commit_randomness.clone());
|
||||||
|
|
||||||
let full_viewing_key = FullViewingKey {
|
let full_viewing_key = FullViewingKey {
|
||||||
network: spending_key.network,
|
|
||||||
spend_validating_key,
|
spend_validating_key,
|
||||||
nullifier_deriving_key,
|
nullifier_deriving_key,
|
||||||
ivk_commit_randomness,
|
ivk_commit_randomness,
|
||||||
};
|
};
|
||||||
// Test ConstantTimeEq, Eq, PartialEq
|
// Test ConstantTimeEq, Eq, PartialEq
|
||||||
assert!(full_viewing_key == full_viewing_key.clone());
|
assert_eq!(full_viewing_key, full_viewing_key.clone());
|
||||||
|
|
||||||
let diversifier_key = DiversifierKey::from(full_viewing_key);
|
let diversifier_key = DiversifierKey::from(full_viewing_key);
|
||||||
// Test ConstantTimeEq, Eq, PartialEq
|
// Test ConstantTimeEq, Eq, PartialEq
|
||||||
assert!(diversifier_key == <[u8; 32]>::from(diversifier_key));
|
assert_eq!(diversifier_key, diversifier_key.clone());
|
||||||
|
|
||||||
let incoming_viewing_key = IncomingViewingKey::from(full_viewing_key);
|
let incoming_viewing_key = IncomingViewingKey::from(full_viewing_key);
|
||||||
// Test ConstantTimeEq, Eq, PartialEq
|
// Test ConstantTimeEq, Eq, PartialEq
|
||||||
assert!(incoming_viewing_key ==
|
assert_eq!(incoming_viewing_key, incoming_viewing_key.clone());
|
||||||
IncomingViewingKey::from_bytes(incoming_viewing_key.scalar.into(),
|
|
||||||
incoming_viewing_key.network));
|
|
||||||
|
|
||||||
|
|
||||||
let outgoing_viewing_key = OutgoingViewingKey::from(full_viewing_key);
|
let outgoing_viewing_key = OutgoingViewingKey::from(full_viewing_key);
|
||||||
// Test ConstantTimeEq, Eq, PartialEq
|
// Test ConstantTimeEq, Eq, PartialEq
|
||||||
assert!(outgoing_viewing_key == <[u8; 32]>::from(outgoing_viewing_key));
|
assert_eq!(outgoing_viewing_key, outgoing_viewing_key.clone());
|
||||||
|
|
||||||
// ConstantTimeEq not implemented for Diversifier as it's a public value
|
// ConstantTimeEq not implemented for Diversifier as it's a public value
|
||||||
let diversifier = Diversifier::from(diversifier_key);
|
let diversifier = Diversifier::from(diversifier_key);
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,9 @@ use group::GroupEncoding;
|
||||||
use halo2::{arithmetic::FieldExt, pasta::pallas};
|
use halo2::{arithmetic::FieldExt, pasta::pallas};
|
||||||
use rand_core::{CryptoRng, RngCore};
|
use rand_core::{CryptoRng, RngCore};
|
||||||
|
|
||||||
use crate::{
|
use crate::amount::{Amount, NonNegative};
|
||||||
amount::{Amount, NonNegative},
|
|
||||||
transaction::Memo,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{
|
use super::{address::Address, keys::prf_expand, sinsemilla::extract_p};
|
||||||
commitment::CommitmentRandomness,
|
|
||||||
keys::{prf_expand, Diversifier, TransmissionKey},
|
|
||||||
sinsemilla::extract_p,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(any(test, feature = "proptest-impl"))]
|
#[cfg(any(test, feature = "proptest-impl"))]
|
||||||
mod arbitrary;
|
mod arbitrary;
|
||||||
|
|
@ -26,9 +19,21 @@ mod nullifiers;
|
||||||
pub use ciphertexts::{EncryptedNote, WrappedNoteKey};
|
pub use ciphertexts::{EncryptedNote, WrappedNoteKey};
|
||||||
pub use nullifiers::Nullifier;
|
pub use nullifiers::Nullifier;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
/// A random seed (rseed) used in the Orchard note creation.
|
||||||
pub struct SeedRandomness(pub(crate) [u8; 32]);
|
pub struct SeedRandomness(pub(crate) [u8; 32]);
|
||||||
|
|
||||||
|
impl SeedRandomness {
|
||||||
|
pub fn new<T>(csprng: &mut T) -> Self
|
||||||
|
where
|
||||||
|
T: RngCore + CryptoRng,
|
||||||
|
{
|
||||||
|
let mut bytes = [0u8; 32];
|
||||||
|
csprng.fill_bytes(&mut bytes);
|
||||||
|
Self(bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Used as input to PRF^nf as part of deriving the _nullifier_ of the _note_.
|
/// Used as input to PRF^nf as part of deriving the _nullifier_ of the _note_.
|
||||||
///
|
///
|
||||||
/// When creating a new note from spending an old note, the new note's _rho_ is
|
/// When creating a new note from spending an old note, the new note's _rho_ is
|
||||||
|
|
@ -47,6 +52,12 @@ impl From<Rho> for [u8; 32] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Nullifier> for Rho {
|
||||||
|
fn from(nf: Nullifier) -> Self {
|
||||||
|
Self(nf.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Rho {
|
impl Rho {
|
||||||
pub fn new<T>(csprng: &mut T) -> Self
|
pub fn new<T>(csprng: &mut T) -> Self
|
||||||
where
|
where
|
||||||
|
|
@ -61,7 +72,7 @@ impl Rho {
|
||||||
|
|
||||||
/// Additional randomness used in deriving the _nullifier_.
|
/// Additional randomness used in deriving the _nullifier_.
|
||||||
///
|
///
|
||||||
/// https://zips.z.cash/protocol/nu5.pdf#orchardsend
|
/// <https://zips.z.cash/protocol/nu5.pdf#orchardsend>
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Psi(pub(crate) pallas::Base);
|
pub struct Psi(pub(crate) pallas::Base);
|
||||||
|
|
||||||
|
|
@ -74,7 +85,7 @@ impl From<Psi> for [u8; 32] {
|
||||||
impl From<SeedRandomness> for Psi {
|
impl From<SeedRandomness> for Psi {
|
||||||
/// rcm = ToScalar^Orchard((PRF^expand_rseed ([9]))
|
/// rcm = ToScalar^Orchard((PRF^expand_rseed ([9]))
|
||||||
///
|
///
|
||||||
/// https://zips.z.cash/protocol/nu5.pdf#orchardsend
|
/// <https://zips.z.cash/protocol/nu5.pdf#orchardsend>
|
||||||
fn from(rseed: SeedRandomness) -> Self {
|
fn from(rseed: SeedRandomness) -> Self {
|
||||||
Self(pallas::Base::from_bytes_wide(&prf_expand(
|
Self(pallas::Base::from_bytes_wide(&prf_expand(
|
||||||
rseed.0,
|
rseed.0,
|
||||||
|
|
@ -83,25 +94,43 @@ impl From<SeedRandomness> for Psi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A Note represents that a value is spendable by the recipient who
|
/// A Note represents that a value is spendable by the recipient who holds the
|
||||||
/// holds the spending key corresponding to a given shielded payment
|
/// spending key corresponding to a given shielded payment address.
|
||||||
/// address.
|
///
|
||||||
|
/// <https://zips.z.cash/protocol/protocol.pdf#notes>
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Note {
|
pub struct Note {
|
||||||
/// The _diversifer_ of the recipient’s _shielded payment address_.
|
/// The recipient's shielded payment address.
|
||||||
pub diversifier: Diversifier,
|
pub address: Address,
|
||||||
/// The _diversified transmission key_ of the recipient’s shielded
|
|
||||||
/// payment address.
|
|
||||||
pub transmission_key: TransmissionKey,
|
|
||||||
/// An integer representing the value of the _note_ in zatoshi.
|
/// An integer representing the value of the _note_ in zatoshi.
|
||||||
pub value: Amount<NonNegative>,
|
pub value: Amount<NonNegative>,
|
||||||
/// Used as input to PRF^nf as part of deriving the _nullifier_ of the _note_.
|
/// Used as input to PRF^nfOrchard_nk as part of deriving the _nullifier_ of
|
||||||
|
/// the _note_.
|
||||||
pub rho: Rho,
|
pub rho: Rho,
|
||||||
/// Additional randomness used in deriving the _nullifier_.
|
/// 32 random bytes from which _rcm_, _psi_, and the _ephemeral private key_
|
||||||
pub psi: Psi,
|
/// are derived.
|
||||||
/// A random _commitment trapdoor_ used to produce the associated note
|
pub rseed: SeedRandomness,
|
||||||
/// commitment.
|
}
|
||||||
pub rcm: CommitmentRandomness,
|
|
||||||
/// The note memo, after decryption.
|
impl Note {
|
||||||
pub memo: Memo,
|
/// Create an Orchard _note_, by choosing 32 uniformly random bytes for
|
||||||
|
/// rseed.
|
||||||
|
///
|
||||||
|
/// <https://zips.z.cash/protocol/protocol.pdf#notes>
|
||||||
|
pub fn new<T>(
|
||||||
|
csprng: &mut T,
|
||||||
|
address: Address,
|
||||||
|
value: Amount<NonNegative>,
|
||||||
|
nf_old: Nullifier,
|
||||||
|
) -> Self
|
||||||
|
where
|
||||||
|
T: RngCore + CryptoRng,
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
address,
|
||||||
|
value,
|
||||||
|
rho: nf_old.into(),
|
||||||
|
rseed: SeedRandomness::new(csprng),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,10 @@ use halo2::{arithmetic::FieldExt, pasta::pallas};
|
||||||
use crate::serialization::{serde_helpers, SerializationError};
|
use crate::serialization::{serde_helpers, SerializationError};
|
||||||
|
|
||||||
use super::super::{
|
use super::super::{
|
||||||
commitment::NoteCommitment, keys::NullifierDerivingKey, note::Note, sinsemilla::*,
|
commitment::NoteCommitment,
|
||||||
|
keys::NullifierDerivingKey,
|
||||||
|
note::{Note, Psi},
|
||||||
|
sinsemilla::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A cryptographic permutation, defined in [poseidonhash].
|
/// A cryptographic permutation, defined in [poseidonhash].
|
||||||
|
|
@ -41,7 +44,7 @@ fn prf_nf(nk: pallas::Base, rho: pallas::Base) -> pallas::Base {
|
||||||
|
|
||||||
/// A Nullifier for Orchard transactions
|
/// A Nullifier for Orchard transactions
|
||||||
#[derive(Clone, Copy, Debug, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, Eq, Serialize, Deserialize)]
|
||||||
pub struct Nullifier(#[serde(with = "serde_helpers::Base")] pallas::Base);
|
pub struct Nullifier(#[serde(with = "serde_helpers::Base")] pub(crate) pallas::Base);
|
||||||
|
|
||||||
impl Hash for Nullifier {
|
impl Hash for Nullifier {
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
|
@ -79,18 +82,19 @@ impl From<(NullifierDerivingKey, Note, NoteCommitment)> for Nullifier {
|
||||||
///
|
///
|
||||||
/// DeriveNullifier_nk(ρ, ψ, cm) = Extract_P(︀ [︀ (PRF^nfOrchard_nk(ρ) + ψ) mod q_P ]︀ K^Orchard + cm)︀
|
/// DeriveNullifier_nk(ρ, ψ, cm) = Extract_P(︀ [︀ (PRF^nfOrchard_nk(ρ) + ψ) mod q_P ]︀ K^Orchard + cm)︀
|
||||||
///
|
///
|
||||||
/// https://zips.z.cash/protocol/nu5.pdf#commitmentsandnullifiers
|
/// <https://zips.z.cash/protocol/nu5.pdf#commitmentsandnullifiers>
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
|
// TODO: tidy prf_nf, notes/rho/psi
|
||||||
fn from((nk, note, cm): (NullifierDerivingKey, Note, NoteCommitment)) -> Self {
|
fn from((nk, note, cm): (NullifierDerivingKey, Note, NoteCommitment)) -> Self {
|
||||||
// https://zips.z.cash/protocol/nu5.pdf#commitmentsandnullifiers
|
|
||||||
let K = pallas_group_hash(b"z.cash:Orchard", b"K");
|
let K = pallas_group_hash(b"z.cash:Orchard", b"K");
|
||||||
|
|
||||||
|
let psi: Psi = note.rseed.into();
|
||||||
|
|
||||||
// impl Add for pallas::Base reduces by the modulus (q_P)
|
// impl Add for pallas::Base reduces by the modulus (q_P)
|
||||||
//
|
//
|
||||||
// [︀ (PRF^nfOrchard_nk(ρ) + ψ) mod q_P ]︀ K^Orchard + cm
|
// [︀ (PRF^nfOrchard_nk(ρ) + ψ) mod q_P ]︀ K^Orchard + cm
|
||||||
let scalar =
|
let scalar =
|
||||||
pallas::Scalar::from_bytes(&(prf_nf(nk.0, note.rho.0) + note.psi.0).to_bytes())
|
pallas::Scalar::from_bytes(&(prf_nf(nk.0, note.rho.0) + psi.0).to_bytes()).unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// Basically a new-gen Pedersen hash?
|
// Basically a new-gen Pedersen hash?
|
||||||
Nullifier(extract_p((K * scalar) + cm.0))
|
Nullifier(extract_p((K * scalar) + cm.0))
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,7 @@ pub fn sinsemilla_short_commit(
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::orchard::tests::vectors;
|
||||||
|
|
||||||
fn x_from_str(s: &str) -> pallas::Base {
|
fn x_from_str(s: &str) -> pallas::Base {
|
||||||
use group::ff::PrimeField;
|
use group::ff::PrimeField;
|
||||||
|
|
@ -234,4 +235,51 @@ mod tests {
|
||||||
test_vector
|
test_vector
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks Sinsemilla hashes to point and to bytes (aka the x-coordinate
|
||||||
|
// bytes of a point) with:
|
||||||
|
// - One of two domains.
|
||||||
|
// - Random message lengths between 0 and 255 bytes.
|
||||||
|
// - Random message bits.
|
||||||
|
#[test]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn hackworks_test_vectors() {
|
||||||
|
use group::GroupEncoding;
|
||||||
|
use halo2::arithmetic::FieldExt;
|
||||||
|
|
||||||
|
for tv in tests::vectors::SINSEMILLA.iter() {
|
||||||
|
let D = tv.domain.as_slice();
|
||||||
|
let M: &BitVec<Lsb0, u8> = &tv.msg.iter().collect();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
sinsemilla_hash_to_point(D, M).expect("should not fail per Theorem 5.4.4"),
|
||||||
|
pallas::Point::from_bytes(&tv.point).unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
sinsemilla_hash(D, M).expect("should not fail per Theorem 5.4.4"),
|
||||||
|
pallas::Base::from_bytes(&tv.hash).unwrap()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks Pallas group hashes with:
|
||||||
|
// - One of two domains.
|
||||||
|
// - Random message lengths between 0 and 255 bytes.
|
||||||
|
// - Random message contents.
|
||||||
|
#[test]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn hackworks_group_hash_test_vectors() {
|
||||||
|
use group::GroupEncoding;
|
||||||
|
|
||||||
|
for tv in tests::vectors::GROUP_HASHES.iter() {
|
||||||
|
let D = tv.domain.as_slice();
|
||||||
|
let M = tv.msg.as_slice();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
pallas_group_hash(D, M),
|
||||||
|
pallas::Point::from_bytes(&tv.point).unwrap()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
mod preallocate;
|
mod preallocate;
|
||||||
mod prop;
|
mod prop;
|
||||||
mod test_vectors;
|
|
||||||
mod tree;
|
mod tree;
|
||||||
|
pub(crate) mod vectors;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use halo2::arithmetic::FieldExt;
|
use halo2::arithmetic::FieldExt;
|
||||||
use halo2::pasta::pallas;
|
use halo2::pasta::pallas;
|
||||||
|
|
||||||
use crate::orchard::tests::test_vectors;
|
use crate::orchard::tests::vectors;
|
||||||
use crate::orchard::tree::*;
|
use crate::orchard::tree::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -12,7 +12,7 @@ fn empty_roots() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
EMPTY_ROOTS[i].to_bytes(),
|
EMPTY_ROOTS[i].to_bytes(),
|
||||||
// The test vector is in reversed order.
|
// The test vector is in reversed order.
|
||||||
test_vectors::EMPTY_ROOTS[MERKLE_DEPTH - i]
|
vectors::EMPTY_ROOTS[MERKLE_DEPTH - i]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -25,7 +25,7 @@ fn incremental_roots() {
|
||||||
|
|
||||||
let mut incremental_tree = NoteCommitmentTree::default();
|
let mut incremental_tree = NoteCommitmentTree::default();
|
||||||
|
|
||||||
for (i, commitment_set) in test_vectors::COMMITMENTS.iter().enumerate() {
|
for (i, commitment_set) in vectors::COMMITMENTS.iter().enumerate() {
|
||||||
for cm_x_bytes in commitment_set.iter() {
|
for cm_x_bytes in commitment_set.iter() {
|
||||||
let cm_x = pallas::Base::from_bytes(cm_x_bytes).unwrap();
|
let cm_x = pallas::Base::from_bytes(cm_x_bytes).unwrap();
|
||||||
|
|
||||||
|
|
@ -36,12 +36,12 @@ fn incremental_roots() {
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
hex::encode(incremental_tree.hash()),
|
hex::encode(incremental_tree.hash()),
|
||||||
hex::encode(test_vectors::ROOTS[i].anchor)
|
hex::encode(vectors::ROOTS[i].anchor)
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
hex::encode((NoteCommitmentTree::from(leaves.clone())).hash()),
|
hex::encode((NoteCommitmentTree::from(leaves.clone())).hash()),
|
||||||
hex::encode(test_vectors::ROOTS[i].anchor)
|
hex::encode(vectors::ROOTS[i].anchor)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
mod group_hash;
|
||||||
|
mod key_components;
|
||||||
|
mod sinsemilla;
|
||||||
|
mod tree;
|
||||||
|
|
||||||
|
pub use group_hash::GROUP_HASHES;
|
||||||
|
pub use key_components::KEY_COMPONENTS;
|
||||||
|
pub use sinsemilla::SINSEMILLA;
|
||||||
|
pub use tree::{COMMITMENTS, EMPTY_ROOTS, ROOTS};
|
||||||
|
|
@ -0,0 +1,225 @@
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
pub struct TestVector {
|
||||||
|
pub(crate) domain: Vec<u8>,
|
||||||
|
pub(crate) msg: Vec<u8>,
|
||||||
|
pub(crate) point: [u8; 32],
|
||||||
|
}
|
||||||
|
|
||||||
|
// From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/orchard_group_hash.py
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref GROUP_HASHES: [TestVector; 11] = [
|
||||||
|
TestVector {
|
||||||
|
domain: vec![0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74],
|
||||||
|
msg: vec![
|
||||||
|
0x54, 0x72, 0x61, 0x6e, 0x73, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x20, 0x6e,
|
||||||
|
0x6f, 0x77, 0x21
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0xd3, 0x6b, 0x0b, 0x64, 0x9b, 0x5c, 0x69, 0x36, 0x02, 0x7a, 0x18, 0x0f, 0x7d, 0x25,
|
||||||
|
0x40, 0x23, 0x95, 0x6f, 0xc2, 0x88, 0x3d, 0xdf, 0x23, 0xff, 0xc3, 0xc8, 0xfd, 0x1f,
|
||||||
|
0xa3, 0xcd, 0x18, 0x18
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![
|
||||||
|
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6c, 0x6f,
|
||||||
|
0x6e, 0x67, 0x65, 0x72
|
||||||
|
],
|
||||||
|
msg: vec![
|
||||||
|
0x8f, 0x73, 0x9a, 0x2d, 0x9e, 0x94, 0x5b, 0x0c, 0xe1, 0x52, 0xa8, 0x04, 0x9e, 0x29,
|
||||||
|
0x4c, 0x4d, 0x6e, 0x66, 0xb1, 0x64, 0x93, 0x9d, 0xaf, 0xfa, 0x2e, 0xf6, 0xee, 0x69,
|
||||||
|
0x21, 0x48, 0x1c, 0xdd, 0x86, 0xb3, 0xcc, 0x43, 0x18, 0xd9, 0x61, 0x4f, 0xc8, 0x20,
|
||||||
|
0x90, 0x5d, 0x04, 0x2b, 0xb1, 0xef, 0x9c, 0xa3, 0xf2, 0x49, 0x88, 0xc7, 0xb3, 0x53,
|
||||||
|
0x42, 0x01, 0xcf, 0xb1, 0xcd, 0x8d, 0xbf, 0x69, 0xb8, 0x25, 0x0c, 0x18, 0xef, 0x41,
|
||||||
|
0x29, 0x4c, 0xa9, 0x79, 0x93, 0xdb, 0x54, 0x6c, 0x1f, 0xe0, 0x1f, 0x7e, 0x9c, 0x8e,
|
||||||
|
0x36, 0xd6, 0xa5, 0xe2, 0x9d, 0x4e, 0x30, 0xa7, 0x35, 0x94, 0xbf, 0x50, 0x98, 0x42,
|
||||||
|
0x1c, 0x69, 0x37, 0x8a, 0xf1, 0xe4, 0x0f, 0x64, 0xe1, 0x25, 0x94, 0x6f, 0x62, 0xc2,
|
||||||
|
0xfa, 0x7b, 0x2f, 0xec, 0xbc, 0xb6, 0x4b, 0x69, 0x68, 0x91
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0xd3, 0x60, 0x3e, 0x4f, 0x26, 0x67, 0xe7, 0x7c, 0x77, 0x24, 0x8f, 0xd5, 0xbe, 0x8d,
|
||||||
|
0x80, 0x77, 0x23, 0xd7, 0x27, 0xe2, 0x2f, 0xc4, 0xa1, 0x1d, 0x1f, 0xf5, 0x57, 0xdd,
|
||||||
|
0x61, 0xdd, 0x4d, 0xb4
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74],
|
||||||
|
msg: vec![
|
||||||
|
0x81, 0xce, 0x3d, 0xc1, 0x66, 0xd5, 0x6a, 0x1d, 0x62, 0xf5, 0xa8, 0xd7, 0x55, 0x1d,
|
||||||
|
0xb5, 0xfd, 0x93, 0x13, 0xe8, 0xc7, 0x20, 0x3d, 0x99, 0x6a, 0xf7, 0xd4, 0x77, 0x08,
|
||||||
|
0x37, 0x56, 0xd5, 0x9a, 0xf8, 0x0d, 0x06, 0xa7, 0x45, 0xf4, 0x4a, 0xb0, 0x23, 0x75,
|
||||||
|
0x2c, 0xb5, 0xb4, 0x06, 0xed, 0x89, 0x85, 0xe1, 0x81, 0x30, 0xab, 0x33, 0x36, 0x26,
|
||||||
|
0x97, 0xb0, 0xe4, 0xe4, 0xc7, 0x63, 0xcc, 0xb8, 0xf6, 0x76, 0x49, 0x5c, 0x22, 0x2f,
|
||||||
|
0x7f, 0xba, 0x1e, 0x31, 0xde, 0xfa, 0x3d, 0x5a, 0x57, 0xef, 0xc2, 0xe1, 0xe9, 0xb0,
|
||||||
|
0x1a, 0x03, 0x55, 0x87, 0xd5, 0xfb, 0x1a, 0x38, 0xe0, 0x1d, 0x94, 0x90, 0x3d, 0x3c,
|
||||||
|
0x3e
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0xf6, 0x1d, 0x4d, 0xe9, 0x90, 0x7a, 0x65, 0x93, 0xd4, 0xc6, 0xb6, 0x42, 0x47, 0x5f,
|
||||||
|
0x51, 0xca, 0x28, 0x93, 0xfc, 0xcf, 0x9c, 0x48, 0xf5, 0x28, 0x2d, 0xf2, 0x5c, 0x9b,
|
||||||
|
0xb6, 0xda, 0xd9, 0x03
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74],
|
||||||
|
msg: vec![
|
||||||
|
0x36, 0x0c, 0x1d, 0x37, 0x10, 0xac, 0xd2, 0x0b, 0x18, 0x3e, 0x31, 0xd4, 0x9f, 0x25,
|
||||||
|
0xc9, 0xa1, 0x38, 0xf4, 0x9b, 0x1a, 0x53, 0x7e, 0xdc, 0xf0, 0x4b, 0xe3, 0x4a, 0x98,
|
||||||
|
0x51, 0xa7, 0xaf, 0x9d, 0xb6, 0x99, 0x0e, 0xd8, 0x3d, 0xd6, 0x4a, 0xf3, 0x59, 0x7c,
|
||||||
|
0x04, 0x32, 0x3e, 0xa5, 0x1b, 0x00, 0x52, 0xad, 0x80, 0x84, 0xa8, 0xb9, 0xda, 0x94,
|
||||||
|
0x8d, 0x32, 0x0d, 0xad, 0xd6, 0x4f, 0x54, 0x31, 0xe6, 0x1d, 0xdf, 0x65, 0x8d, 0x24,
|
||||||
|
0xae, 0x67, 0xc2, 0x2c, 0x8d, 0x13, 0x09, 0x13, 0x1f, 0xc0, 0x0f, 0xe7, 0xf2, 0x35,
|
||||||
|
0x73, 0x42, 0x76, 0xd3, 0x8d, 0x47, 0xf1, 0xe1, 0x91, 0xe0, 0x0c, 0x7a, 0x1d, 0x48,
|
||||||
|
0xaf, 0x04, 0x68, 0x27, 0x59, 0x1e, 0x97, 0x33, 0xa9, 0x7f, 0xa6, 0xb6, 0x79, 0xf3,
|
||||||
|
0xdc, 0x60, 0x1d, 0x00, 0x82, 0x85, 0xed, 0xcb, 0xda, 0xe6, 0x9c, 0xe8, 0xfc, 0x1b,
|
||||||
|
0xe4, 0xaa, 0xc0, 0x0f, 0xf2, 0x71, 0x1e, 0xbd, 0x93, 0x1d, 0xe5, 0x18, 0x85, 0x68,
|
||||||
|
0x78, 0xf7, 0x34, 0x76, 0xf2, 0x1a, 0x48, 0x2e, 0xc9, 0x37, 0x83, 0x65, 0xc8, 0xf7,
|
||||||
|
0x39, 0x3c, 0x94, 0xe2, 0x88, 0x53, 0x15, 0xeb, 0x46, 0x71, 0x09, 0x8b, 0x79, 0x53,
|
||||||
|
0x5e, 0x79, 0x0f, 0xe5, 0x3e, 0x29, 0xfe, 0xf2, 0xb3, 0x76, 0x66, 0x97, 0xac, 0x32,
|
||||||
|
0xb4, 0xf4, 0x73, 0xf4, 0x68, 0xa0, 0x08, 0xe7, 0x23, 0x89, 0xfc, 0x03, 0x88, 0x0d,
|
||||||
|
0x78, 0x0c, 0xb0, 0x7f, 0xcf, 0xaa, 0xbe, 0x3f, 0x1a, 0x84, 0xb2, 0x7d, 0xb5, 0x9a,
|
||||||
|
0x4a
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0xe9, 0xdc, 0xf5, 0xfd, 0x98, 0xcb, 0x6f, 0xd4, 0xfd, 0xc0, 0xf8, 0xf9, 0xdd, 0x46,
|
||||||
|
0x2d, 0x59, 0xe1, 0xde, 0x9c, 0x69, 0xc6, 0x04, 0x2d, 0x1a, 0xee, 0x40, 0xd1, 0xb5,
|
||||||
|
0xf8, 0x2e, 0xf9, 0x34
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![
|
||||||
|
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6c, 0x6f,
|
||||||
|
0x6e, 0x67, 0x65, 0x72
|
||||||
|
],
|
||||||
|
msg: vec![
|
||||||
|
0x88, 0x2d, 0x2b, 0x21, 0x03, 0x59, 0x65, 0x55, 0xed, 0x94, 0x94, 0xc6, 0xac, 0x89,
|
||||||
|
0x3c, 0x49, 0x72, 0x38, 0x33, 0xec, 0x89, 0x26, 0xc1, 0x03, 0x95, 0x86, 0xa7, 0xaf,
|
||||||
|
0xcf, 0x4a, 0x0d, 0x9c, 0x73, 0x1e, 0x98, 0x5d, 0x99, 0x58, 0x9c, 0x8b, 0xb8, 0x38,
|
||||||
|
0xe8, 0xaa, 0xf7, 0x45, 0x53, 0x3e, 0xd9, 0xe8, 0xae, 0x3a, 0x1c, 0xd0, 0x74, 0xa5,
|
||||||
|
0x1a, 0x20, 0xda, 0x8a, 0xba
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0xf3, 0x8c, 0xb5, 0xe1, 0x60, 0x7c, 0x71, 0x22, 0xce, 0xf7, 0x31, 0xc8, 0xe6, 0x18,
|
||||||
|
0x75, 0xb8, 0xc1, 0xf3, 0xe2, 0xec, 0x06, 0xc5, 0x9e, 0x9c, 0xca, 0xdb, 0xd3, 0xa2,
|
||||||
|
0xca, 0xe8, 0x68, 0x3f
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74],
|
||||||
|
msg: vec![
|
||||||
|
0xdb, 0xeb, 0xbc, 0x86, 0x2d, 0xed, 0x42, 0x43, 0x5e, 0x92, 0x47, 0x69, 0x30, 0xd0,
|
||||||
|
0x69, 0x89, 0x6c, 0xff, 0x30, 0xeb, 0x41, 0x4f, 0x72, 0x7b, 0x89, 0xe0, 0x01, 0xaf,
|
||||||
|
0xa2, 0xfb, 0x8d, 0xc3, 0x43, 0x6d, 0x75, 0xa4, 0xa6, 0xf2, 0x65, 0x72, 0x50, 0x4b,
|
||||||
|
0x19, 0x22, 0x32, 0xec, 0xb9, 0xf0, 0xc0, 0x24, 0x11, 0xe5, 0x25, 0x96, 0xbc, 0x5e,
|
||||||
|
0x90, 0x45, 0x7e, 0x74, 0x59, 0x39, 0xff, 0xed, 0xbd, 0x12, 0x86, 0x3c, 0xe7, 0x1a,
|
||||||
|
0x02, 0xaf, 0x11, 0x7d, 0x41, 0x7a, 0xdb, 0x3d, 0x15, 0xcc, 0x54, 0xdc, 0xb1, 0xfc,
|
||||||
|
0xe4, 0x67, 0x50, 0x0c, 0x6b, 0x8f, 0xb8, 0x6b, 0x12, 0xb5, 0x6d, 0xa9, 0xc3, 0x82,
|
||||||
|
0x85, 0x7d, 0xee, 0xcc, 0x40, 0xa9, 0x8d, 0x5f, 0x29, 0x35, 0x39, 0x5e, 0xe4, 0x76,
|
||||||
|
0x2d, 0xd2, 0x1a, 0xfd, 0xbb, 0x5d, 0x47, 0xfa, 0x9a, 0x6d, 0xd9, 0x84, 0xd5, 0x67,
|
||||||
|
0xdb, 0x28, 0x57, 0xb9, 0x27, 0xb7, 0xfa, 0xe2, 0xdb, 0x58, 0x71, 0x05, 0x41, 0x5d,
|
||||||
|
0x46, 0x42, 0x78, 0x9d, 0x38, 0xf5, 0x0b, 0x8d, 0xbc, 0xc1, 0x29, 0xca, 0xb3, 0xd1,
|
||||||
|
0x7d, 0x19, 0xf3, 0x35, 0x5b, 0xcf, 0x73, 0xce, 0xcb, 0x8c, 0xb8, 0xa5, 0xda, 0x01,
|
||||||
|
0x30, 0x71, 0x52, 0xf1, 0x39, 0x36, 0xa2, 0x70, 0x57, 0x26, 0x70, 0xdc, 0x82, 0xd3,
|
||||||
|
0x90, 0x26, 0xc6, 0xcb, 0x4c, 0xd4, 0xb0, 0xf7, 0xf5, 0xaa, 0x2a, 0x4f, 0x5a, 0x53,
|
||||||
|
0x41, 0xec, 0x5d, 0xd7, 0x15, 0x40, 0x6f, 0x2f, 0xdd, 0x2a, 0xfa, 0x73, 0x3f
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0x3d, 0xec, 0x03, 0x28, 0x60, 0xf1, 0xa8, 0x51, 0x51, 0x6a, 0xf3, 0x7b, 0x68, 0xac,
|
||||||
|
0xcc, 0xf3, 0x6e, 0x2a, 0x80, 0xbe, 0x13, 0xee, 0x36, 0x7e, 0xac, 0x1a, 0xac, 0x72,
|
||||||
|
0x5d, 0xbc, 0xf6, 0x85
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![
|
||||||
|
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6c, 0x6f,
|
||||||
|
0x6e, 0x67, 0x65, 0x72
|
||||||
|
],
|
||||||
|
msg: vec![
|
||||||
|
0x1c, 0x8c, 0x21, 0x86, 0x2a, 0x1b, 0xaf, 0xce, 0x26, 0x09, 0xd9, 0xee, 0xcf, 0xa1,
|
||||||
|
0x58, 0xcf, 0xb5, 0xcd, 0x79, 0xf8, 0x80, 0x08, 0xe3, 0x15, 0xdc, 0x7d, 0x83, 0x88,
|
||||||
|
0xe7, 0x6c, 0x17, 0x82, 0xfd, 0x27, 0x95, 0xd1, 0x8a, 0x76, 0x36, 0x24, 0xc2, 0x5f,
|
||||||
|
0xa9, 0x59, 0xcc, 0x97, 0x48, 0x9c, 0xe7, 0x57, 0x45, 0x82, 0x4b, 0x77, 0x86, 0x8c,
|
||||||
|
0x53, 0x23, 0x9c, 0xfb, 0xdf, 0x73, 0xca, 0xec, 0x65, 0x60, 0x40, 0x37, 0x31, 0x4f,
|
||||||
|
0xaa, 0xce, 0xb5, 0x62, 0x18, 0xc6, 0xbd, 0x30, 0xf8, 0x37, 0x4a, 0xc1, 0x33, 0x86,
|
||||||
|
0x79, 0x3f, 0x21, 0xa9, 0xfb, 0x80, 0xad, 0x03, 0xbc, 0x0c, 0xda, 0x4a, 0x44, 0x94,
|
||||||
|
0x6c, 0x00
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0xae, 0x52, 0x88, 0x72, 0xf0, 0x6c, 0xc1, 0x79, 0xa1, 0x54, 0xee, 0xc2, 0xdd, 0xf7,
|
||||||
|
0x4d, 0xcf, 0x5c, 0x49, 0xc4, 0x11, 0x5c, 0x6a, 0xb7, 0x4d, 0x7f, 0x31, 0x6e, 0x46,
|
||||||
|
0xb1, 0x64, 0x8e, 0x19
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![
|
||||||
|
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6c, 0x6f,
|
||||||
|
0x6e, 0x67, 0x65, 0x72
|
||||||
|
],
|
||||||
|
msg: vec![
|
||||||
|
0xa1, 0xdf, 0x0e, 0x5b, 0x87, 0xb5, 0xbe, 0xce, 0x47, 0x7a, 0x70, 0x96, 0x49, 0xe9,
|
||||||
|
0x50, 0x06, 0x05, 0x91, 0x39, 0x48, 0x12, 0x95, 0x1e, 0x1f, 0xe3, 0x89, 0x5b, 0x8c,
|
||||||
|
0xc3, 0xd1, 0x4d, 0x2c, 0xf6, 0x55, 0x6d, 0xf6, 0xed, 0x4b, 0x4d, 0xdd, 0x3d, 0x9a,
|
||||||
|
0x69, 0xf5, 0x33, 0x57, 0xd7, 0x76, 0x7f, 0x4f, 0x5c, 0xcb, 0xdb, 0xc5, 0x96, 0x63,
|
||||||
|
0x12, 0x77, 0xf8, 0xfe, 0xcd, 0x08, 0xcb, 0x05, 0x6b, 0x95, 0xe3, 0x02, 0x5b, 0x97,
|
||||||
|
0x92, 0xff, 0xf7, 0xf2, 0x44, 0xfc, 0x71, 0x62, 0x69, 0xb9, 0x26, 0xd6, 0x2e, 0x95,
|
||||||
|
0x96, 0xfa, 0x82, 0x5c, 0x6b, 0xf2, 0x1a, 0xff, 0x9e, 0x68, 0x62, 0x5a, 0x19, 0x24,
|
||||||
|
0x40, 0xea, 0x06, 0x82, 0x81, 0x23, 0xd9, 0x78, 0x84, 0x80, 0x6f, 0x15, 0xfa, 0x08,
|
||||||
|
0xda, 0x52, 0x75, 0x4a, 0x10, 0x95, 0xe3, 0xff, 0x1a, 0xbd, 0x5c, 0xe4, 0xfd, 0xdf,
|
||||||
|
0xcc, 0xfc, 0x3a, 0x61, 0x28, 0xae, 0xf7, 0x84, 0xa6, 0x46, 0x10, 0xa8, 0x9d, 0x1a,
|
||||||
|
0x70, 0x99, 0x21, 0x6d, 0x08, 0x14, 0xd3, 0xa2, 0xd4, 0x52, 0x43, 0x1c, 0x32, 0xd4,
|
||||||
|
0x11, 0xac, 0x1c, 0xce, 0x82, 0xad, 0x02, 0x29, 0x40, 0x7b, 0xbc, 0x48, 0x98, 0x56,
|
||||||
|
0x75, 0xe3, 0xf8, 0x74, 0xa4, 0x53, 0x3f, 0x1d, 0x63
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0xcc, 0x90, 0x4e, 0x5e, 0x31, 0x83, 0x4b, 0x4f, 0x85, 0xd6, 0xa6, 0x62, 0xc5, 0x4e,
|
||||||
|
0x7d, 0xaa, 0x8d, 0x3e, 0x34, 0xce, 0x22, 0x42, 0x8c, 0x3e, 0x8a, 0x53, 0xcc, 0x6e,
|
||||||
|
0xe8, 0x33, 0x87, 0xa9
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74],
|
||||||
|
msg: vec![
|
||||||
|
0xfa, 0x3e, 0x0f, 0x46, 0x0f, 0xe2, 0xf5, 0x7e, 0x34, 0xfb, 0xc7, 0x54, 0x23, 0xc3,
|
||||||
|
0x73, 0x7f, 0x5b, 0x2a, 0x06, 0x15, 0xf5, 0x72, 0x2d, 0xb0, 0x41, 0xa3, 0xef, 0x66,
|
||||||
|
0xfa, 0x48, 0x3a, 0xfd, 0x3c, 0x2e, 0x19, 0xe5, 0x94, 0x44, 0xa6, 0x4a, 0xdd, 0x6d,
|
||||||
|
0xf1, 0xd9, 0x63, 0xf5, 0xdd, 0x5b, 0x50, 0x10, 0xd3, 0xd0, 0x25, 0xf0, 0x28, 0x7c,
|
||||||
|
0x4c, 0xf1, 0x9c, 0x75, 0xf3, 0x3d, 0x51, 0xdd, 0xdd, 0xba, 0x5d, 0x65, 0x7b, 0x43,
|
||||||
|
0xee, 0x8d, 0xa6, 0x45, 0x44, 0x38, 0x14
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0xb0, 0x5e, 0xb0, 0xcc, 0x20, 0xef, 0x29, 0xfd, 0xb9, 0xf5, 0x8f, 0x6b, 0x55, 0x99,
|
||||||
|
0x11, 0x4d, 0x1b, 0xf8, 0x21, 0x49, 0x7a, 0xf7, 0xc1, 0x07, 0xea, 0x0b, 0xdf, 0xf9,
|
||||||
|
0x74, 0xf1, 0x7f, 0x3b
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74],
|
||||||
|
msg: vec![
|
||||||
|
0x29, 0xf3, 0xe9, 0xb4, 0xe5, 0x4c, 0x23, 0x6c, 0x29, 0xaf, 0x39, 0x23, 0x10, 0x17,
|
||||||
|
0x56, 0xd9, 0xfa, 0x4b, 0xd0, 0xf7, 0xd2, 0xdd, 0xaa, 0xcb, 0x6b, 0x0f, 0x86, 0xa2,
|
||||||
|
0x65, 0x8e, 0x0a, 0x07, 0xa0, 0x5a, 0xc5, 0xb9, 0x50, 0x05, 0x1c, 0xd2, 0x4c, 0x47,
|
||||||
|
0xa8, 0x8d, 0x13, 0xd6, 0x59, 0xba, 0x2a, 0x46, 0xca, 0x18, 0x30, 0x81, 0x6d, 0x09,
|
||||||
|
0xcd, 0x76, 0x46, 0xf7, 0x6f, 0x71, 0x6a, 0xbe, 0xc5, 0xde, 0x07, 0xfe, 0x9b, 0x52,
|
||||||
|
0x34, 0x10, 0x80, 0x6e, 0xa6, 0xf2, 0x88, 0xf8, 0x73, 0x6c, 0x23, 0x35, 0x7c, 0x85,
|
||||||
|
0xf4, 0x57, 0x91, 0xe1, 0x70, 0x80, 0x29, 0xd9, 0x82, 0x4d, 0x90, 0x70, 0x46, 0x07,
|
||||||
|
0xf3, 0x87, 0xa0, 0x3e, 0x49, 0xbf, 0x98, 0x36, 0x57, 0x44, 0x31, 0x34, 0x5a, 0x78,
|
||||||
|
0x77, 0xef, 0xaa
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0x52, 0x71, 0xbe, 0xd5, 0x91, 0x13, 0x39, 0xa7, 0xc6, 0x17, 0x97, 0xa9, 0x9e, 0x87,
|
||||||
|
0xc6, 0xb4, 0xcd, 0x85, 0xae, 0x10, 0xd0, 0xd4, 0xaa, 0x7e, 0x7a, 0xdb, 0x07, 0x49,
|
||||||
|
0x81, 0x63, 0x05, 0xae
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74],
|
||||||
|
msg: vec![0xe7, 0x30, 0x81, 0xef, 0x8d, 0x62, 0xcb, 0x78],
|
||||||
|
point: [
|
||||||
|
0xb6, 0x17, 0x44, 0xc0, 0xc7, 0x0d, 0x65, 0x4c, 0x02, 0x53, 0x70, 0x55, 0x7a, 0xac,
|
||||||
|
0x7f, 0xbe, 0x42, 0x1a, 0x49, 0x70, 0x77, 0x18, 0xba, 0x90, 0xff, 0x7d, 0x9e, 0xbd,
|
||||||
|
0xc5, 0x1d, 0x19, 0x19
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,737 @@
|
||||||
|
//! Test vectors for generating Orchard keys, addresses, notes, note
|
||||||
|
//! commitments, and nullifiers.
|
||||||
|
//!
|
||||||
|
//! Produced by https://github.com/zcash-hackworks/zcash-test-vectors/blob/ec5fe3abef5219d0f8c9edbc93bb4038f1729dfe/orchard_key_components.py
|
||||||
|
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
pub struct TestVector {
|
||||||
|
pub(crate) sk: [u8; 32],
|
||||||
|
pub(crate) ask: [u8; 32],
|
||||||
|
pub(crate) ak: [u8; 32],
|
||||||
|
pub(crate) nk: [u8; 32],
|
||||||
|
pub(crate) rivk: [u8; 32],
|
||||||
|
pub(crate) ivk: [u8; 32],
|
||||||
|
pub(crate) ovk: [u8; 32],
|
||||||
|
pub(crate) dk: [u8; 32],
|
||||||
|
pub(crate) default_d: [u8; 11],
|
||||||
|
pub(crate) default_pk_d: [u8; 32],
|
||||||
|
pub(crate) note_v: u64,
|
||||||
|
pub(crate) note_rho: [u8; 32],
|
||||||
|
pub(crate) note_rseed: [u8; 32],
|
||||||
|
pub(crate) note_cmx: [u8; 32],
|
||||||
|
pub(crate) note_nf: [u8; 32],
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const KEY_COMPONENTS: [TestVector; 10] = [
|
||||||
|
TestVector {
|
||||||
|
sk: [
|
||||||
|
0x5d, 0x7a, 0x8f, 0x73, 0x9a, 0x2d, 0x9e, 0x94, 0x5b, 0x0c, 0xe1, 0x52, 0xa8, 0x04,
|
||||||
|
0x9e, 0x29, 0x4c, 0x4d, 0x6e, 0x66, 0xb1, 0x64, 0x93, 0x9d, 0xaf, 0xfa, 0x2e, 0xf6,
|
||||||
|
0xee, 0x69, 0x21, 0x48,
|
||||||
|
],
|
||||||
|
ask: [
|
||||||
|
0x8e, 0xb8, 0xc4, 0x01, 0xc2, 0x87, 0xa6, 0xc1, 0x3a, 0x2c, 0x34, 0x5a, 0xd8, 0x21,
|
||||||
|
0x72, 0xd8, 0x6b, 0xe4, 0xa8, 0x85, 0x35, 0x25, 0xdb, 0x60, 0x2d, 0x14, 0xf6, 0x30,
|
||||||
|
0xf4, 0xe6, 0x1c, 0x17,
|
||||||
|
],
|
||||||
|
ak: [
|
||||||
|
0x74, 0x0b, 0xbe, 0x5d, 0x05, 0x80, 0xb2, 0xca, 0xd4, 0x30, 0x18, 0x0d, 0x02, 0xcc,
|
||||||
|
0x12, 0x8b, 0x9a, 0x14, 0x0d, 0x5e, 0x07, 0xc1, 0x51, 0x72, 0x1d, 0xc1, 0x6d, 0x25,
|
||||||
|
0xd4, 0xe2, 0x0f, 0x15,
|
||||||
|
],
|
||||||
|
nk: [
|
||||||
|
0x9f, 0x2f, 0x82, 0x67, 0x38, 0x94, 0x5a, 0xd0, 0x1f, 0x47, 0xf7, 0x0d, 0xb0, 0xc3,
|
||||||
|
0x67, 0xc2, 0x46, 0xc2, 0x0c, 0x61, 0xff, 0x55, 0x83, 0x94, 0x8c, 0x39, 0xde, 0xa9,
|
||||||
|
0x68, 0xfe, 0xfd, 0x1b,
|
||||||
|
],
|
||||||
|
rivk: [
|
||||||
|
0x02, 0x1c, 0xcf, 0x89, 0x60, 0x4f, 0x5f, 0x7c, 0xc6, 0xe0, 0x34, 0xb3, 0x2d, 0x33,
|
||||||
|
0x89, 0x08, 0xb8, 0x19, 0xfb, 0xe3, 0x25, 0xfe, 0xe6, 0x45, 0x8b, 0x56, 0xb4, 0xca,
|
||||||
|
0x71, 0xa7, 0xe4, 0x3d,
|
||||||
|
],
|
||||||
|
ivk: [
|
||||||
|
0x85, 0xc8, 0xb5, 0xcd, 0x1a, 0xc3, 0xec, 0x3a, 0xd7, 0x09, 0x21, 0x32, 0xf9, 0x7f,
|
||||||
|
0x01, 0x78, 0xb0, 0x75, 0xc8, 0x1a, 0x13, 0x9f, 0xd4, 0x60, 0xbb, 0xe0, 0xdf, 0xcd,
|
||||||
|
0x75, 0x51, 0x47, 0x24,
|
||||||
|
],
|
||||||
|
ovk: [
|
||||||
|
0xbc, 0xc7, 0x06, 0x5e, 0x59, 0x91, 0x0b, 0x35, 0x99, 0x3f, 0x59, 0x50, 0x5b, 0xe2,
|
||||||
|
0x09, 0xb1, 0x4b, 0xf0, 0x24, 0x88, 0x75, 0x0b, 0xbc, 0x8b, 0x1a, 0xcd, 0xcf, 0x10,
|
||||||
|
0x8c, 0x36, 0x20, 0x04,
|
||||||
|
],
|
||||||
|
dk: [
|
||||||
|
0x31, 0xd6, 0xa6, 0x85, 0xbe, 0x57, 0x0f, 0x9f, 0xaf, 0x3c, 0xa8, 0xb0, 0x52, 0xe8,
|
||||||
|
0x87, 0x84, 0x0b, 0x2c, 0x9f, 0x8d, 0x67, 0x22, 0x4c, 0xa8, 0x2a, 0xef, 0xb9, 0xe2,
|
||||||
|
0xee, 0x5b, 0xed, 0xaf,
|
||||||
|
],
|
||||||
|
default_d: [
|
||||||
|
0x8f, 0xf3, 0x38, 0x69, 0x71, 0xcb, 0x64, 0xb8, 0xe7, 0x78, 0x99,
|
||||||
|
],
|
||||||
|
default_pk_d: [
|
||||||
|
0x08, 0xdd, 0x8e, 0xbd, 0x7d, 0xe9, 0x2a, 0x68, 0xe5, 0x86, 0xa3, 0x4d, 0xb8, 0xfe,
|
||||||
|
0xa9, 0x99, 0xef, 0xd2, 0x01, 0x6f, 0xae, 0x76, 0x75, 0x0a, 0xfa, 0xe7, 0xee, 0x94,
|
||||||
|
0x16, 0x46, 0xbc, 0xb9,
|
||||||
|
],
|
||||||
|
note_v: 15643327852135767324,
|
||||||
|
note_rho: [
|
||||||
|
0x2c, 0xb5, 0xb4, 0x06, 0xed, 0x89, 0x85, 0xe1, 0x81, 0x30, 0xab, 0x33, 0x36, 0x26,
|
||||||
|
0x97, 0xb0, 0xe4, 0xe4, 0xc7, 0x63, 0xcc, 0xb8, 0xf6, 0x76, 0x49, 0x5c, 0x22, 0x2f,
|
||||||
|
0x7f, 0xba, 0x1e, 0x31,
|
||||||
|
],
|
||||||
|
note_rseed: [
|
||||||
|
0xde, 0xfa, 0x3d, 0x5a, 0x57, 0xef, 0xc2, 0xe1, 0xe9, 0xb0, 0x1a, 0x03, 0x55, 0x87,
|
||||||
|
0xd5, 0xfb, 0x1a, 0x38, 0xe0, 0x1d, 0x94, 0x90, 0x3d, 0x3c, 0x3e, 0x0a, 0xd3, 0x36,
|
||||||
|
0x0c, 0x1d, 0x37, 0x10,
|
||||||
|
],
|
||||||
|
note_cmx: [
|
||||||
|
0x45, 0x02, 0xe3, 0x39, 0x90, 0x1e, 0x39, 0x77, 0x17, 0x83, 0x91, 0x67, 0xcb, 0xb4,
|
||||||
|
0x03, 0x7e, 0x0e, 0xcf, 0x68, 0x13, 0xb5, 0x1c, 0x81, 0xfe, 0x08, 0x5a, 0x7b, 0x78,
|
||||||
|
0x2f, 0x12, 0x42, 0x28,
|
||||||
|
],
|
||||||
|
note_nf: [
|
||||||
|
0xe0, 0xc4, 0xb2, 0x6b, 0xe5, 0x77, 0x85, 0x67, 0xbf, 0xa6, 0xf7, 0x7f, 0xe4, 0x5a,
|
||||||
|
0xaf, 0x73, 0xab, 0x5b, 0x64, 0x6f, 0x3e, 0x7a, 0x48, 0xf0, 0x7e, 0x08, 0xd2, 0xc7,
|
||||||
|
0x38, 0xe2, 0x1b, 0x14,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
sk: [
|
||||||
|
0xac, 0xd2, 0x0b, 0x18, 0x3e, 0x31, 0xd4, 0x9f, 0x25, 0xc9, 0xa1, 0x38, 0xf4, 0x9b,
|
||||||
|
0x1a, 0x53, 0x7e, 0xdc, 0xf0, 0x4b, 0xe3, 0x4a, 0x98, 0x51, 0xa7, 0xaf, 0x9d, 0xb6,
|
||||||
|
0x99, 0x0e, 0xd8, 0x3d,
|
||||||
|
],
|
||||||
|
ask: [
|
||||||
|
0x41, 0xd4, 0x7c, 0xc9, 0x63, 0x13, 0xb4, 0x82, 0x1d, 0xfc, 0x12, 0x96, 0x51, 0xc3,
|
||||||
|
0x13, 0x7f, 0x44, 0xd9, 0xca, 0xd1, 0x6b, 0x3d, 0xc0, 0x81, 0x33, 0xc3, 0xd2, 0xdf,
|
||||||
|
0x0d, 0x0c, 0x53, 0x20,
|
||||||
|
],
|
||||||
|
ak: [
|
||||||
|
0x6d, 0xe1, 0x34, 0x98, 0x30, 0xd6, 0x6d, 0x7b, 0x97, 0xfe, 0x23, 0x1f, 0xc7, 0xb0,
|
||||||
|
0x2a, 0xd6, 0x43, 0x23, 0x62, 0x9c, 0xfe, 0xd1, 0xe3, 0xaa, 0x24, 0xef, 0x05, 0x2f,
|
||||||
|
0x56, 0xe4, 0x00, 0x2a,
|
||||||
|
],
|
||||||
|
nk: [
|
||||||
|
0xa8, 0xb7, 0x3d, 0x97, 0x9b, 0x6e, 0xaa, 0xda, 0x89, 0x24, 0xbc, 0xbd, 0xc6, 0x3a,
|
||||||
|
0x9e, 0xf4, 0xe8, 0x73, 0x46, 0xf2, 0x30, 0xab, 0xa6, 0xbb, 0xe1, 0xe2, 0xb4, 0x3c,
|
||||||
|
0x5b, 0xea, 0x6b, 0x22,
|
||||||
|
],
|
||||||
|
rivk: [
|
||||||
|
0xda, 0xcb, 0x2f, 0x2a, 0x9c, 0xed, 0x36, 0x31, 0x71, 0x82, 0x1a, 0xaf, 0x5d, 0x8c,
|
||||||
|
0xd9, 0x02, 0xbc, 0x5e, 0x3a, 0x5a, 0x41, 0xfb, 0x51, 0xae, 0x61, 0xa9, 0xf0, 0x2d,
|
||||||
|
0xc8, 0x9d, 0x1d, 0x12,
|
||||||
|
],
|
||||||
|
ivk: [
|
||||||
|
0x56, 0x3a, 0x6d, 0xb6, 0x0c, 0x74, 0xc2, 0xdb, 0x08, 0x49, 0x2c, 0xba, 0xe3, 0xbb,
|
||||||
|
0x08, 0x3f, 0x1a, 0xea, 0xbf, 0xfb, 0xcf, 0x42, 0x55, 0x1d, 0x0a, 0xc6, 0x4f, 0x26,
|
||||||
|
0x90, 0x53, 0x67, 0x11,
|
||||||
|
],
|
||||||
|
ovk: [
|
||||||
|
0x71, 0xcd, 0x30, 0x64, 0x0f, 0xdb, 0x63, 0xf8, 0xd1, 0x30, 0x50, 0x29, 0xe9, 0x40,
|
||||||
|
0xe5, 0x3f, 0xd5, 0xec, 0x04, 0xa8, 0xcc, 0xad, 0x41, 0x95, 0x78, 0xc2, 0x42, 0xfe,
|
||||||
|
0xc0, 0x5b, 0x9a, 0xf7,
|
||||||
|
],
|
||||||
|
dk: [
|
||||||
|
0x9d, 0x9b, 0xd4, 0x45, 0x25, 0xe7, 0xae, 0x06, 0xb0, 0x3a, 0xe6, 0xd4, 0xae, 0xcd,
|
||||||
|
0xe6, 0xae, 0x09, 0x27, 0xa7, 0xc6, 0x67, 0xd5, 0xd9, 0xf8, 0x17, 0x6b, 0x54, 0x46,
|
||||||
|
0x95, 0xdf, 0xec, 0x11,
|
||||||
|
],
|
||||||
|
default_d: [
|
||||||
|
0x78, 0x07, 0xca, 0x65, 0x08, 0x58, 0x81, 0x4d, 0x50, 0x22, 0xa8,
|
||||||
|
],
|
||||||
|
default_pk_d: [
|
||||||
|
0x3d, 0x3d, 0xe4, 0xd5, 0x2c, 0x77, 0xfd, 0x0b, 0x63, 0x0a, 0x40, 0xdc, 0x38, 0x21,
|
||||||
|
0x24, 0x87, 0xb2, 0xff, 0x6e, 0xee, 0xf5, 0x6d, 0x8c, 0x6a, 0x61, 0x63, 0xe8, 0x54,
|
||||||
|
0xaf, 0xf0, 0x41, 0x89,
|
||||||
|
],
|
||||||
|
note_v: 4481649511318637270,
|
||||||
|
note_rho: [
|
||||||
|
0xa5, 0x1b, 0x00, 0x52, 0xad, 0x80, 0x84, 0xa8, 0xb9, 0xda, 0x94, 0x8d, 0x32, 0x0d,
|
||||||
|
0xad, 0xd6, 0x4f, 0x54, 0x31, 0xe6, 0x1d, 0xdf, 0x65, 0x8d, 0x24, 0xae, 0x67, 0xc2,
|
||||||
|
0x2c, 0x8d, 0x13, 0x09,
|
||||||
|
],
|
||||||
|
note_rseed: [
|
||||||
|
0x13, 0x1f, 0xc0, 0x0f, 0xe7, 0xf2, 0x35, 0x73, 0x42, 0x76, 0xd3, 0x8d, 0x47, 0xf1,
|
||||||
|
0xe1, 0x91, 0xe0, 0x0c, 0x7a, 0x1d, 0x48, 0xaf, 0x04, 0x68, 0x27, 0x59, 0x1e, 0x97,
|
||||||
|
0x33, 0xa9, 0x7f, 0xa6,
|
||||||
|
],
|
||||||
|
note_cmx: [
|
||||||
|
0xc7, 0xad, 0x79, 0x4c, 0x56, 0x3e, 0x32, 0xca, 0xd4, 0x7d, 0x47, 0xdc, 0xda, 0x78,
|
||||||
|
0x84, 0x69, 0x28, 0x48, 0xdc, 0xe2, 0x9b, 0xa4, 0xfe, 0xbd, 0x93, 0x20, 0x2b, 0x73,
|
||||||
|
0x05, 0xf9, 0x03, 0x00,
|
||||||
|
],
|
||||||
|
note_nf: [
|
||||||
|
0x1e, 0xbf, 0xac, 0x2d, 0x34, 0x2f, 0xf7, 0xc2, 0xe5, 0xf8, 0xef, 0xe2, 0xe9, 0xde,
|
||||||
|
0x37, 0xdd, 0x3b, 0x82, 0x84, 0x27, 0x03, 0x8e, 0x55, 0x32, 0x30, 0x34, 0xdd, 0xb0,
|
||||||
|
0xa6, 0x63, 0x4a, 0x12,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
sk: [
|
||||||
|
0xb6, 0x79, 0xf3, 0xdc, 0x60, 0x1d, 0x00, 0x82, 0x85, 0xed, 0xcb, 0xda, 0xe6, 0x9c,
|
||||||
|
0xe8, 0xfc, 0x1b, 0xe4, 0xaa, 0xc0, 0x0f, 0xf2, 0x71, 0x1e, 0xbd, 0x93, 0x1d, 0xe5,
|
||||||
|
0x18, 0x85, 0x68, 0x78,
|
||||||
|
],
|
||||||
|
ask: [
|
||||||
|
0xce, 0x8b, 0x65, 0xa7, 0x23, 0x65, 0x11, 0xb2, 0xea, 0xf1, 0x9f, 0x72, 0xa3, 0xd6,
|
||||||
|
0xdb, 0x7d, 0x06, 0x2b, 0x66, 0xf5, 0x16, 0x30, 0x7d, 0x19, 0x87, 0x06, 0xe5, 0xf6,
|
||||||
|
0x92, 0x8e, 0x16, 0x15,
|
||||||
|
],
|
||||||
|
ak: [
|
||||||
|
0xef, 0xa5, 0xf1, 0xde, 0xbe, 0xea, 0xd0, 0x94, 0x0a, 0x61, 0x9c, 0xe0, 0x01, 0x7b,
|
||||||
|
0xed, 0xb4, 0x26, 0x65, 0x7b, 0x2d, 0x07, 0x40, 0x66, 0x64, 0xd8, 0x95, 0x31, 0x2e,
|
||||||
|
0xa1, 0xc3, 0xb3, 0x34,
|
||||||
|
],
|
||||||
|
nk: [
|
||||||
|
0x04, 0x51, 0x4e, 0xa0, 0x48, 0xb9, 0x43, 0x63, 0xde, 0xa7, 0xcb, 0x3b, 0xe8, 0xd6,
|
||||||
|
0x25, 0x82, 0xac, 0x52, 0x92, 0x2e, 0x08, 0x65, 0xf6, 0x62, 0x74, 0x3b, 0x05, 0xea,
|
||||||
|
0xe8, 0x71, 0x5f, 0x17,
|
||||||
|
],
|
||||||
|
rivk: [
|
||||||
|
0x2a, 0x32, 0x8f, 0x99, 0x4f, 0x6e, 0x5a, 0xd2, 0x9c, 0xa8, 0x11, 0xed, 0x34, 0x49,
|
||||||
|
0x68, 0xea, 0x2c, 0xfc, 0x3f, 0xd2, 0x31, 0x03, 0x0e, 0x37, 0xbb, 0xd5, 0x6d, 0xb4,
|
||||||
|
0x26, 0x40, 0x23, 0x1c,
|
||||||
|
],
|
||||||
|
ivk: [
|
||||||
|
0x60, 0x9e, 0xcb, 0xc3, 0xd8, 0xce, 0xe3, 0xbe, 0x2b, 0x2a, 0x23, 0x62, 0x95, 0x1f,
|
||||||
|
0x58, 0xb7, 0x44, 0x82, 0xad, 0xfa, 0xee, 0xe1, 0xc4, 0x0f, 0x94, 0x03, 0x04, 0x40,
|
||||||
|
0xf5, 0x58, 0xaa, 0x30,
|
||||||
|
],
|
||||||
|
ovk: [
|
||||||
|
0xdf, 0xd3, 0x0f, 0x62, 0xaa, 0x31, 0x9c, 0x6f, 0x53, 0xe2, 0x4c, 0x1f, 0x48, 0xc1,
|
||||||
|
0xde, 0x96, 0x1b, 0x90, 0x01, 0xcb, 0x98, 0x8b, 0x80, 0xb3, 0xed, 0xa2, 0x44, 0xfc,
|
||||||
|
0xfe, 0xb2, 0x5f, 0x83,
|
||||||
|
],
|
||||||
|
dk: [
|
||||||
|
0x23, 0x6b, 0xc3, 0xf3, 0xd0, 0x2f, 0x96, 0x02, 0x80, 0xee, 0xde, 0xde, 0x10, 0x8d,
|
||||||
|
0x36, 0x85, 0x04, 0x9f, 0x23, 0x9a, 0xa6, 0x7c, 0x48, 0x55, 0x8f, 0x7c, 0x01, 0xd3,
|
||||||
|
0xfd, 0x46, 0x9e, 0xcd,
|
||||||
|
],
|
||||||
|
default_d: [
|
||||||
|
0x64, 0x24, 0xf7, 0x1a, 0x3a, 0xd1, 0x97, 0x42, 0x64, 0x98, 0xf4,
|
||||||
|
],
|
||||||
|
default_pk_d: [
|
||||||
|
0xec, 0xcb, 0x6a, 0x57, 0x80, 0x20, 0x42, 0x37, 0x98, 0x72, 0x32, 0xbc, 0x09, 0x8f,
|
||||||
|
0x89, 0xac, 0xc4, 0x75, 0xc3, 0xf7, 0x4b, 0xd6, 0x9e, 0x2f, 0x35, 0xd4, 0x47, 0x36,
|
||||||
|
0xf4, 0x8f, 0x3c, 0x14,
|
||||||
|
],
|
||||||
|
note_v: 14496603531126387959,
|
||||||
|
note_rho: [
|
||||||
|
0x32, 0xb4, 0xf4, 0x73, 0xf4, 0x68, 0xa0, 0x08, 0xe7, 0x23, 0x89, 0xfc, 0x03, 0x88,
|
||||||
|
0x0d, 0x78, 0x0c, 0xb0, 0x7f, 0xcf, 0xaa, 0xbe, 0x3f, 0x1a, 0x84, 0xb2, 0x7d, 0xb5,
|
||||||
|
0x9a, 0x4a, 0x15, 0x3d,
|
||||||
|
],
|
||||||
|
note_rseed: [
|
||||||
|
0x88, 0x2d, 0x2b, 0x21, 0x03, 0x59, 0x65, 0x55, 0xed, 0x94, 0x94, 0xc6, 0xac, 0x89,
|
||||||
|
0x3c, 0x49, 0x72, 0x38, 0x33, 0xec, 0x89, 0x26, 0xc1, 0x03, 0x95, 0x86, 0xa7, 0xaf,
|
||||||
|
0xcf, 0x4a, 0x0d, 0x9c,
|
||||||
|
],
|
||||||
|
note_cmx: [
|
||||||
|
0x03, 0xce, 0x20, 0xce, 0xa1, 0x94, 0xb7, 0x55, 0x9a, 0x8a, 0x90, 0x47, 0x1d, 0x28,
|
||||||
|
0xa3, 0xc0, 0x53, 0xc3, 0x72, 0x0a, 0xd4, 0x9f, 0x40, 0xd2, 0x7c, 0x2d, 0xcc, 0xe3,
|
||||||
|
0x35, 0x00, 0x56, 0x16,
|
||||||
|
],
|
||||||
|
note_nf: [
|
||||||
|
0x69, 0xf4, 0x1f, 0xfa, 0xc4, 0xc0, 0x40, 0x50, 0xa6, 0x68, 0xcf, 0x94, 0x1a, 0xce,
|
||||||
|
0x51, 0xde, 0x7e, 0x0f, 0xaa, 0x38, 0x68, 0xe4, 0x9a, 0x33, 0x45, 0x4d, 0x96, 0x10,
|
||||||
|
0x09, 0x20, 0x0d, 0x34,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
sk: [
|
||||||
|
0x73, 0x1e, 0x98, 0x5d, 0x99, 0x58, 0x9c, 0x8b, 0xb8, 0x38, 0xe8, 0xaa, 0xf7, 0x45,
|
||||||
|
0x53, 0x3e, 0xd9, 0xe8, 0xae, 0x3a, 0x1c, 0xd0, 0x74, 0xa5, 0x1a, 0x20, 0xda, 0x8a,
|
||||||
|
0xba, 0x18, 0xd1, 0xdb,
|
||||||
|
],
|
||||||
|
ask: [
|
||||||
|
0x42, 0x6a, 0x78, 0x44, 0xf3, 0x05, 0xb9, 0xd4, 0xe0, 0x7e, 0xa5, 0x2a, 0x39, 0x00,
|
||||||
|
0x1c, 0x9b, 0x33, 0x6c, 0xfc, 0x0d, 0x6f, 0xa1, 0x5e, 0xf3, 0xd1, 0x1c, 0x3d, 0x7b,
|
||||||
|
0x74, 0xf0, 0x8c, 0x2d,
|
||||||
|
],
|
||||||
|
ak: [
|
||||||
|
0xb1, 0xe0, 0xac, 0xbc, 0x69, 0xbf, 0x37, 0x7b, 0x85, 0xab, 0xf0, 0xf5, 0xa1, 0x0b,
|
||||||
|
0xe7, 0x2c, 0x3b, 0x64, 0x00, 0x06, 0xff, 0x08, 0x50, 0x52, 0x80, 0xe4, 0xf0, 0x0f,
|
||||||
|
0xad, 0xf7, 0x63, 0x28,
|
||||||
|
],
|
||||||
|
nk: [
|
||||||
|
0xcf, 0x36, 0xad, 0x6a, 0x06, 0x6c, 0xd2, 0x13, 0xe1, 0xd7, 0x67, 0xab, 0x07, 0x1d,
|
||||||
|
0xc1, 0x16, 0x78, 0x85, 0xc4, 0x16, 0x8b, 0xc2, 0xe2, 0x17, 0x54, 0x48, 0x56, 0x3a,
|
||||||
|
0xd1, 0x3f, 0x33, 0x3d,
|
||||||
|
],
|
||||||
|
rivk: [
|
||||||
|
0xc4, 0x1b, 0xba, 0xd3, 0x51, 0x05, 0xa8, 0x03, 0x14, 0xb7, 0x96, 0x24, 0xb6, 0x75,
|
||||||
|
0x24, 0x12, 0x20, 0xb3, 0x31, 0xf1, 0x25, 0x92, 0x61, 0x7b, 0xdb, 0x70, 0x5b, 0xfc,
|
||||||
|
0xce, 0x72, 0xae, 0x38,
|
||||||
|
],
|
||||||
|
ivk: [
|
||||||
|
0xf7, 0x9f, 0xe8, 0x02, 0xe4, 0xd2, 0x43, 0x07, 0xa6, 0xaa, 0xf8, 0x5d, 0x19, 0xf5,
|
||||||
|
0xe0, 0x83, 0x37, 0x40, 0xba, 0xe5, 0x98, 0xdc, 0x7c, 0x88, 0x0a, 0xc6, 0x09, 0x63,
|
||||||
|
0x1d, 0xe1, 0x58, 0x19,
|
||||||
|
],
|
||||||
|
ovk: [
|
||||||
|
0xf9, 0x63, 0x66, 0xbc, 0x6e, 0xab, 0xd2, 0x32, 0x54, 0x9e, 0xbb, 0x43, 0xb4, 0xed,
|
||||||
|
0x6f, 0xd8, 0x1d, 0x33, 0x03, 0x73, 0xc5, 0xb5, 0x66, 0x90, 0x4e, 0x9a, 0xf1, 0x1a,
|
||||||
|
0x6b, 0xab, 0x8d, 0x77,
|
||||||
|
],
|
||||||
|
dk: [
|
||||||
|
0x80, 0x3e, 0x34, 0x85, 0x73, 0x02, 0x2b, 0xf8, 0x93, 0x2f, 0x23, 0xee, 0x7a, 0x32,
|
||||||
|
0x5e, 0xa2, 0x83, 0x87, 0x9c, 0x65, 0x24, 0x12, 0xb8, 0x60, 0x6b, 0xe3, 0x19, 0x8c,
|
||||||
|
0x4b, 0x78, 0x2c, 0x47,
|
||||||
|
],
|
||||||
|
default_d: [
|
||||||
|
0xdb, 0x8c, 0x30, 0x55, 0x24, 0xbc, 0x0d, 0xea, 0xa8, 0x5d, 0x97,
|
||||||
|
],
|
||||||
|
default_pk_d: [
|
||||||
|
0x04, 0xea, 0x8c, 0x13, 0x20, 0xff, 0xbb, 0xad, 0xfe, 0x96, 0xf0, 0xc6, 0xff, 0x16,
|
||||||
|
0xb6, 0x07, 0x11, 0x1b, 0x55, 0x83, 0xbf, 0xb6, 0xf1, 0xea, 0x45, 0x27, 0x5e, 0xf2,
|
||||||
|
0xaa, 0x2d, 0x87, 0x9b,
|
||||||
|
],
|
||||||
|
note_v: 6792346249443327211,
|
||||||
|
note_rho: [
|
||||||
|
0x4b, 0x19, 0x22, 0x32, 0xec, 0xb9, 0xf0, 0xc0, 0x24, 0x11, 0xe5, 0x25, 0x96, 0xbc,
|
||||||
|
0x5e, 0x90, 0x45, 0x7e, 0x74, 0x59, 0x39, 0xff, 0xed, 0xbd, 0x12, 0x86, 0x3c, 0xe7,
|
||||||
|
0x1a, 0x02, 0xaf, 0x11,
|
||||||
|
],
|
||||||
|
note_rseed: [
|
||||||
|
0x7d, 0x41, 0x7a, 0xdb, 0x3d, 0x15, 0xcc, 0x54, 0xdc, 0xb1, 0xfc, 0xe4, 0x67, 0x50,
|
||||||
|
0x0c, 0x6b, 0x8f, 0xb8, 0x6b, 0x12, 0xb5, 0x6d, 0xa9, 0xc3, 0x82, 0x85, 0x7d, 0xee,
|
||||||
|
0xcc, 0x40, 0xa9, 0x8d,
|
||||||
|
],
|
||||||
|
note_cmx: [
|
||||||
|
0xa9, 0xb1, 0x1b, 0xaf, 0x30, 0x34, 0xb6, 0x5c, 0x64, 0x24, 0x84, 0x1b, 0xfe, 0x02,
|
||||||
|
0x3f, 0x8e, 0xda, 0x13, 0x13, 0xc3, 0x0a, 0xa2, 0x7d, 0xe9, 0x2e, 0x21, 0xa1, 0x08,
|
||||||
|
0x31, 0x6e, 0x82, 0x19,
|
||||||
|
],
|
||||||
|
note_nf: [
|
||||||
|
0xf0, 0x0f, 0x19, 0x5b, 0xe1, 0xd7, 0x9b, 0x42, 0x75, 0xc8, 0xe3, 0xbc, 0xfd, 0x4d,
|
||||||
|
0xbf, 0x00, 0xa8, 0x07, 0x88, 0xd6, 0xc2, 0x28, 0x6a, 0x40, 0x4c, 0x67, 0x3c, 0x91,
|
||||||
|
0xec, 0xf5, 0x13, 0x16,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
sk: [
|
||||||
|
0x5f, 0x29, 0x35, 0x39, 0x5e, 0xe4, 0x76, 0x2d, 0xd2, 0x1a, 0xfd, 0xbb, 0x5d, 0x47,
|
||||||
|
0xfa, 0x9a, 0x6d, 0xd9, 0x84, 0xd5, 0x67, 0xdb, 0x28, 0x57, 0xb9, 0x27, 0xb7, 0xfa,
|
||||||
|
0xe2, 0xdb, 0x58, 0x71,
|
||||||
|
],
|
||||||
|
ask: [
|
||||||
|
0x11, 0x80, 0x73, 0x28, 0x51, 0x64, 0xe6, 0x55, 0x73, 0x58, 0xfb, 0xc4, 0x1a, 0x81,
|
||||||
|
0x35, 0xcb, 0x06, 0x2f, 0x86, 0x76, 0xcb, 0x61, 0xf9, 0xaa, 0x52, 0xd1, 0x9a, 0x09,
|
||||||
|
0xfa, 0xc5, 0x58, 0x02,
|
||||||
|
],
|
||||||
|
ak: [
|
||||||
|
0x0d, 0x26, 0x2d, 0xe3, 0x60, 0x94, 0x33, 0xfe, 0x5b, 0x7c, 0x86, 0x2b, 0xc4, 0x8e,
|
||||||
|
0xf5, 0x6d, 0x83, 0x20, 0x09, 0xf7, 0x24, 0x2e, 0x1f, 0x7c, 0x77, 0x0a, 0x12, 0x24,
|
||||||
|
0x1d, 0xfa, 0x28, 0x07,
|
||||||
|
],
|
||||||
|
nk: [
|
||||||
|
0x51, 0xba, 0xf3, 0x33, 0xcf, 0xf1, 0xf2, 0xd0, 0xc7, 0xe3, 0xcf, 0xf4, 0xd3, 0x01,
|
||||||
|
0x29, 0x9d, 0xc1, 0xef, 0xe9, 0x83, 0x00, 0x31, 0x4a, 0x54, 0x19, 0x38, 0x02, 0x9b,
|
||||||
|
0x45, 0xcc, 0x15, 0x21,
|
||||||
|
],
|
||||||
|
rivk: [
|
||||||
|
0x22, 0x8f, 0xeb, 0x79, 0x21, 0x98, 0x73, 0xc7, 0xa7, 0x60, 0x6e, 0x52, 0x97, 0x3c,
|
||||||
|
0x85, 0xf4, 0x60, 0x46, 0x5a, 0x60, 0x59, 0x08, 0x39, 0x19, 0xed, 0x73, 0xeb, 0x80,
|
||||||
|
0x5c, 0x11, 0x83, 0x01,
|
||||||
|
],
|
||||||
|
ivk: [
|
||||||
|
0x76, 0xf4, 0x9c, 0xf8, 0xa3, 0x19, 0x21, 0x85, 0x61, 0x6a, 0x9a, 0x0d, 0xa0, 0xc7,
|
||||||
|
0x6e, 0xc2, 0xc2, 0x75, 0x61, 0x59, 0xbc, 0xe1, 0x86, 0xa1, 0x86, 0x2b, 0x6e, 0x6e,
|
||||||
|
0x59, 0x44, 0x2d, 0x11,
|
||||||
|
],
|
||||||
|
ovk: [
|
||||||
|
0xeb, 0x72, 0xb6, 0xc3, 0x1e, 0x83, 0x7f, 0xd8, 0x37, 0xaa, 0xcb, 0x61, 0xfa, 0xba,
|
||||||
|
0xce, 0x75, 0xa1, 0x9d, 0xd9, 0xdd, 0x5b, 0x4b, 0x3a, 0x3e, 0xe7, 0x23, 0xc1, 0x4d,
|
||||||
|
0xa7, 0x7b, 0x4b, 0xe8,
|
||||||
|
],
|
||||||
|
dk: [
|
||||||
|
0xee, 0x19, 0xf8, 0xdd, 0xd9, 0xda, 0x06, 0x34, 0x24, 0x51, 0x43, 0xc4, 0xb4, 0x3a,
|
||||||
|
0xfc, 0x7d, 0x78, 0xc5, 0x49, 0xc8, 0x20, 0x54, 0xa9, 0xd8, 0x40, 0x07, 0xb5, 0x62,
|
||||||
|
0x17, 0xdb, 0xfd, 0xd6,
|
||||||
|
],
|
||||||
|
default_d: [
|
||||||
|
0xaa, 0xe3, 0x6e, 0x09, 0x4d, 0xe0, 0x7b, 0xc1, 0x6f, 0x89, 0x8e,
|
||||||
|
],
|
||||||
|
default_pk_d: [
|
||||||
|
0xb6, 0x53, 0x3d, 0xcb, 0xff, 0xf0, 0xf6, 0xc1, 0xce, 0xef, 0xa8, 0x47, 0x99, 0xbd,
|
||||||
|
0xa3, 0xde, 0x73, 0x34, 0x32, 0x6c, 0xcd, 0x65, 0xf7, 0xce, 0x92, 0xff, 0x3d, 0x9e,
|
||||||
|
0x6e, 0x1f, 0x14, 0x0b,
|
||||||
|
],
|
||||||
|
note_v: 4079549063511228677,
|
||||||
|
note_rho: [
|
||||||
|
0x26, 0x70, 0xdc, 0x82, 0xd3, 0x90, 0x26, 0xc6, 0xcb, 0x4c, 0xd4, 0xb0, 0xf7, 0xf5,
|
||||||
|
0xaa, 0x2a, 0x4f, 0x5a, 0x53, 0x41, 0xec, 0x5d, 0xd7, 0x15, 0x40, 0x6f, 0x2f, 0xdd,
|
||||||
|
0x2a, 0xfa, 0x73, 0x3f,
|
||||||
|
],
|
||||||
|
note_rseed: [
|
||||||
|
0x5f, 0x64, 0x1c, 0x8c, 0x21, 0x86, 0x2a, 0x1b, 0xaf, 0xce, 0x26, 0x09, 0xd9, 0xee,
|
||||||
|
0xcf, 0xa1, 0x58, 0xcf, 0xb5, 0xcd, 0x79, 0xf8, 0x80, 0x08, 0xe3, 0x15, 0xdc, 0x7d,
|
||||||
|
0x83, 0x88, 0xe7, 0x6c,
|
||||||
|
],
|
||||||
|
note_cmx: [
|
||||||
|
0x0f, 0xfb, 0xca, 0x1d, 0x59, 0x21, 0xfa, 0x0a, 0x8c, 0x51, 0x16, 0xae, 0x13, 0x7e,
|
||||||
|
0x37, 0xf2, 0xc1, 0x18, 0xd5, 0x21, 0x25, 0x62, 0x8d, 0x8a, 0x3f, 0x41, 0x2c, 0xe0,
|
||||||
|
0xe6, 0x53, 0x0e, 0x04,
|
||||||
|
],
|
||||||
|
note_nf: [
|
||||||
|
0xf5, 0x1f, 0x2d, 0x6b, 0x9f, 0x72, 0xeb, 0x69, 0x52, 0x6c, 0x9b, 0xed, 0x7a, 0xa8,
|
||||||
|
0xf7, 0x5d, 0x28, 0x19, 0xcb, 0xdc, 0x23, 0xe4, 0xc5, 0xd4, 0x37, 0x89, 0xf1, 0xaf,
|
||||||
|
0x07, 0x42, 0xa7, 0x02,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
sk: [
|
||||||
|
0x17, 0x82, 0xfd, 0x27, 0x95, 0xd1, 0x8a, 0x76, 0x36, 0x24, 0xc2, 0x5f, 0xa9, 0x59,
|
||||||
|
0xcc, 0x97, 0x48, 0x9c, 0xe7, 0x57, 0x45, 0x82, 0x4b, 0x77, 0x86, 0x8c, 0x53, 0x23,
|
||||||
|
0x9c, 0xfb, 0xdf, 0x73,
|
||||||
|
],
|
||||||
|
ask: [
|
||||||
|
0xf6, 0xef, 0x32, 0x8d, 0x24, 0x76, 0x1d, 0x6d, 0x3c, 0xcd, 0x25, 0xd4, 0x71, 0x96,
|
||||||
|
0xe8, 0x10, 0x9c, 0x03, 0x8f, 0xe1, 0x7c, 0x59, 0xa7, 0xf0, 0x5b, 0x98, 0xd6, 0x6b,
|
||||||
|
0xeb, 0xc6, 0x41, 0x24,
|
||||||
|
],
|
||||||
|
ak: [
|
||||||
|
0xd1, 0x17, 0x87, 0xca, 0x58, 0x2f, 0x94, 0x8e, 0x45, 0x07, 0x18, 0xb3, 0x69, 0x98,
|
||||||
|
0xdf, 0x28, 0xbb, 0x0f, 0x10, 0x21, 0xea, 0x84, 0x3f, 0x86, 0x7f, 0x8a, 0x17, 0x0f,
|
||||||
|
0x5c, 0x33, 0x90, 0x1f,
|
||||||
|
],
|
||||||
|
nk: [
|
||||||
|
0x9e, 0x99, 0x7d, 0x9d, 0x26, 0x97, 0x87, 0x26, 0x8e, 0x09, 0x2a, 0x7c, 0x85, 0x41,
|
||||||
|
0x7d, 0xa5, 0x30, 0xea, 0x42, 0xfa, 0xc6, 0x68, 0xa7, 0x49, 0xaf, 0x55, 0xdf, 0xb7,
|
||||||
|
0x1c, 0xdb, 0xbe, 0x09,
|
||||||
|
],
|
||||||
|
rivk: [
|
||||||
|
0x13, 0x6c, 0x6f, 0xe2, 0xe2, 0xb7, 0x9c, 0x51, 0x56, 0xdb, 0x50, 0x47, 0xd8, 0xd5,
|
||||||
|
0xe7, 0x95, 0xdf, 0xc0, 0xbd, 0xc0, 0x88, 0x08, 0x53, 0xa4, 0x4a, 0xdb, 0x73, 0x92,
|
||||||
|
0xc0, 0x2f, 0x94, 0x1b,
|
||||||
|
],
|
||||||
|
ivk: [
|
||||||
|
0x02, 0x8b, 0x64, 0x05, 0x64, 0xb2, 0x49, 0x05, 0xde, 0x92, 0x92, 0xba, 0x5b, 0x98,
|
||||||
|
0x10, 0xad, 0xdd, 0x86, 0xbe, 0xd0, 0xfb, 0x3b, 0x2d, 0x6b, 0x37, 0xf2, 0x6d, 0xd2,
|
||||||
|
0x38, 0xa7, 0xdb, 0x13,
|
||||||
|
],
|
||||||
|
ovk: [
|
||||||
|
0x98, 0xd6, 0xa4, 0xbf, 0x68, 0x01, 0xd8, 0xba, 0x0d, 0x0b, 0x67, 0xea, 0x7b, 0x80,
|
||||||
|
0x52, 0x07, 0xab, 0xc0, 0x34, 0x8f, 0xc5, 0x62, 0x00, 0x5a, 0x59, 0xa2, 0x7a, 0x8a,
|
||||||
|
0x46, 0xfa, 0x6a, 0xdd,
|
||||||
|
],
|
||||||
|
dk: [
|
||||||
|
0xd0, 0xba, 0xef, 0x60, 0x12, 0xd3, 0x08, 0xef, 0xbb, 0x76, 0x9a, 0x99, 0xcc, 0xa2,
|
||||||
|
0x92, 0x8c, 0xed, 0xe8, 0xdb, 0x27, 0x76, 0x45, 0xa7, 0x77, 0xea, 0xf1, 0x72, 0x2c,
|
||||||
|
0xd0, 0x84, 0x50, 0xb3,
|
||||||
|
],
|
||||||
|
default_d: [
|
||||||
|
0xcc, 0x7c, 0xe7, 0x34, 0xb0, 0x75, 0xa0, 0x1b, 0x92, 0xaa, 0xca,
|
||||||
|
],
|
||||||
|
default_pk_d: [
|
||||||
|
0x3d, 0xa5, 0x27, 0x3a, 0x56, 0x67, 0xc7, 0x66, 0xb8, 0x23, 0x12, 0x06, 0x18, 0x0f,
|
||||||
|
0x15, 0x8a, 0xc0, 0x2a, 0xf3, 0xf0, 0x6e, 0xcc, 0xa6, 0xec, 0x7c, 0x38, 0xc7, 0x5d,
|
||||||
|
0x33, 0x60, 0x03, 0x20,
|
||||||
|
],
|
||||||
|
note_v: 5706402952489856202,
|
||||||
|
note_rho: [
|
||||||
|
0xa1, 0xdf, 0x0e, 0x5b, 0x87, 0xb5, 0xbe, 0xce, 0x47, 0x7a, 0x70, 0x96, 0x49, 0xe9,
|
||||||
|
0x50, 0x06, 0x05, 0x91, 0x39, 0x48, 0x12, 0x95, 0x1e, 0x1f, 0xe3, 0x89, 0x5b, 0x8c,
|
||||||
|
0xc3, 0xd1, 0x4d, 0x2c,
|
||||||
|
],
|
||||||
|
note_rseed: [
|
||||||
|
0xf6, 0x55, 0x6d, 0xf6, 0xed, 0x4b, 0x4d, 0xdd, 0x3d, 0x9a, 0x69, 0xf5, 0x33, 0x57,
|
||||||
|
0xd7, 0x76, 0x7f, 0x4f, 0x5c, 0xcb, 0xdb, 0xc5, 0x96, 0x63, 0x12, 0x77, 0xf8, 0xfe,
|
||||||
|
0xcd, 0x08, 0xcb, 0x05,
|
||||||
|
],
|
||||||
|
note_cmx: [
|
||||||
|
0x63, 0xce, 0xe3, 0x7e, 0x3c, 0x7b, 0x4e, 0x6c, 0xc9, 0x39, 0xa2, 0xe6, 0x3a, 0xda,
|
||||||
|
0x74, 0xf8, 0x5e, 0xa4, 0x8b, 0xa0, 0x7a, 0x4f, 0x92, 0xcc, 0xbd, 0x34, 0xfa, 0xa4,
|
||||||
|
0x2d, 0xfd, 0x49, 0x16,
|
||||||
|
],
|
||||||
|
note_nf: [
|
||||||
|
0xbd, 0x93, 0xac, 0xda, 0x9a, 0xc3, 0x38, 0xca, 0x8e, 0x2e, 0x72, 0xc7, 0x25, 0x06,
|
||||||
|
0x17, 0x9d, 0xe4, 0x7f, 0x36, 0x56, 0x4a, 0x45, 0x22, 0x26, 0x54, 0xb7, 0x81, 0x0d,
|
||||||
|
0x2a, 0xe4, 0x00, 0x10,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
sk: [
|
||||||
|
0x6b, 0x95, 0xe3, 0x02, 0x5b, 0x97, 0x92, 0xff, 0xf7, 0xf2, 0x44, 0xfc, 0x71, 0x62,
|
||||||
|
0x69, 0xb9, 0x26, 0xd6, 0x2e, 0x95, 0x96, 0xfa, 0x82, 0x5c, 0x6b, 0xf2, 0x1a, 0xff,
|
||||||
|
0x9e, 0x68, 0x62, 0x5a,
|
||||||
|
],
|
||||||
|
ask: [
|
||||||
|
0x75, 0x7d, 0x15, 0x8d, 0x07, 0x35, 0x6b, 0x3b, 0xc2, 0xc9, 0xe5, 0x1c, 0x55, 0x8a,
|
||||||
|
0x9b, 0x31, 0x6b, 0xdd, 0xbc, 0x36, 0x0b, 0x8b, 0xeb, 0x6e, 0x2a, 0xe3, 0xb0, 0x61,
|
||||||
|
0x8f, 0x06, 0x2d, 0x2e,
|
||||||
|
],
|
||||||
|
ak: [
|
||||||
|
0x44, 0x9a, 0x90, 0xd2, 0xe8, 0xd1, 0xa0, 0x37, 0x64, 0x2a, 0x97, 0x09, 0x6c, 0x91,
|
||||||
|
0x65, 0x43, 0x46, 0x2a, 0x13, 0x7f, 0xfe, 0xa3, 0x7b, 0xaf, 0x41, 0xef, 0x28, 0x6b,
|
||||||
|
0xb7, 0x32, 0xbe, 0x2c,
|
||||||
|
],
|
||||||
|
nk: [
|
||||||
|
0xfd, 0x31, 0x64, 0xc6, 0x32, 0xbe, 0xc9, 0x4c, 0xe9, 0xfb, 0x2f, 0x30, 0x22, 0x63,
|
||||||
|
0xb8, 0x84, 0xab, 0xb9, 0xc1, 0x0e, 0x55, 0xe4, 0x48, 0x64, 0x7f, 0x67, 0x98, 0x49,
|
||||||
|
0x5c, 0x9d, 0x08, 0x3f,
|
||||||
|
],
|
||||||
|
rivk: [
|
||||||
|
0xc0, 0xb3, 0x6b, 0x56, 0x07, 0x0f, 0xff, 0x2f, 0xdf, 0x38, 0xeb, 0xa1, 0x1a, 0x74,
|
||||||
|
0x24, 0x95, 0x71, 0x95, 0x01, 0x4c, 0xba, 0x43, 0xa5, 0x6b, 0xd1, 0xb1, 0x65, 0x8e,
|
||||||
|
0x66, 0xa3, 0x9d, 0x00,
|
||||||
|
],
|
||||||
|
ivk: [
|
||||||
|
0x97, 0x6a, 0x87, 0x88, 0x19, 0x1b, 0x87, 0xe4, 0xc1, 0x3f, 0x2c, 0x6d, 0x23, 0xb4,
|
||||||
|
0xf3, 0x59, 0x5e, 0x02, 0x28, 0xe2, 0x45, 0xe9, 0x6e, 0xef, 0x1d, 0x24, 0xb2, 0x93,
|
||||||
|
0x29, 0x6a, 0x19, 0x1c,
|
||||||
|
],
|
||||||
|
ovk: [
|
||||||
|
0x1e, 0xd0, 0xed, 0xa5, 0xa4, 0x08, 0x61, 0x31, 0x26, 0x1a, 0x2e, 0xd4, 0x42, 0x92,
|
||||||
|
0x61, 0xe4, 0x27, 0x6a, 0x26, 0xd4, 0x28, 0x59, 0xfa, 0xbd, 0xa3, 0x1a, 0xa9, 0x67,
|
||||||
|
0x09, 0x87, 0x43, 0x71,
|
||||||
|
],
|
||||||
|
dk: [
|
||||||
|
0x5e, 0x5b, 0x60, 0xc0, 0x5b, 0x53, 0xd0, 0xbc, 0xd2, 0xda, 0x46, 0xa1, 0x31, 0x29,
|
||||||
|
0x12, 0x51, 0x5c, 0xc7, 0xcf, 0x2d, 0x97, 0x4c, 0x11, 0x7c, 0x8d, 0xde, 0xa9, 0xfa,
|
||||||
|
0xb6, 0x20, 0xc6, 0x68,
|
||||||
|
],
|
||||||
|
default_d: [
|
||||||
|
0x99, 0xaf, 0x6b, 0xf3, 0xf4, 0x75, 0xbd, 0xe8, 0x89, 0xaa, 0xca,
|
||||||
|
],
|
||||||
|
default_pk_d: [
|
||||||
|
0xac, 0xdc, 0xd3, 0x48, 0xca, 0x45, 0xee, 0x58, 0x32, 0x78, 0x30, 0x38, 0x46, 0xca,
|
||||||
|
0x07, 0x84, 0x59, 0xd5, 0xbe, 0x5c, 0x5d, 0xcf, 0x34, 0x7e, 0x3b, 0x9a, 0x34, 0xcb,
|
||||||
|
0xa1, 0x24, 0xb4, 0xa3,
|
||||||
|
],
|
||||||
|
note_v: 2558469029534639129,
|
||||||
|
note_rho: [
|
||||||
|
0x72, 0x2d, 0xb0, 0x41, 0xa3, 0xef, 0x66, 0xfa, 0x48, 0x3a, 0xfd, 0x3c, 0x2e, 0x19,
|
||||||
|
0xe5, 0x94, 0x44, 0xa6, 0x4a, 0xdd, 0x6d, 0xf1, 0xd9, 0x63, 0xf5, 0xdd, 0x5b, 0x50,
|
||||||
|
0x10, 0xd3, 0xd0, 0x25,
|
||||||
|
],
|
||||||
|
note_rseed: [
|
||||||
|
0xf0, 0x28, 0x7c, 0x4c, 0xf1, 0x9c, 0x75, 0xf3, 0x3d, 0x51, 0xdd, 0xdd, 0xba, 0x5d,
|
||||||
|
0x65, 0x7b, 0x43, 0xee, 0x8d, 0xa6, 0x45, 0x44, 0x38, 0x14, 0xcc, 0x73, 0x29, 0xf3,
|
||||||
|
0xe9, 0xb4, 0xe5, 0x4c,
|
||||||
|
],
|
||||||
|
note_cmx: [
|
||||||
|
0x1e, 0x61, 0x9e, 0x46, 0xbb, 0x62, 0xb6, 0x1d, 0x4e, 0x1c, 0xf3, 0x62, 0x2e, 0xa7,
|
||||||
|
0x0a, 0x90, 0x8d, 0xe7, 0xf0, 0x76, 0xec, 0xf8, 0x7f, 0x54, 0x1e, 0x0b, 0x7b, 0x48,
|
||||||
|
0xad, 0x4a, 0x26, 0x01,
|
||||||
|
],
|
||||||
|
note_nf: [
|
||||||
|
0x86, 0x23, 0xbf, 0xe6, 0xa5, 0xf9, 0x99, 0x09, 0x3c, 0x6b, 0xc0, 0x85, 0xf3, 0x70,
|
||||||
|
0x28, 0xf1, 0x8e, 0xa4, 0xc1, 0xcd, 0xf9, 0xbb, 0xf5, 0xba, 0x09, 0xa4, 0x30, 0x2e,
|
||||||
|
0x9c, 0xfe, 0xde, 0x0f,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
sk: [
|
||||||
|
0x23, 0x6c, 0x29, 0xaf, 0x39, 0x23, 0x10, 0x17, 0x56, 0xd9, 0xfa, 0x4b, 0xd0, 0xf7,
|
||||||
|
0xd2, 0xdd, 0xaa, 0xcb, 0x6b, 0x0f, 0x86, 0xa2, 0x65, 0x8e, 0x0a, 0x07, 0xa0, 0x5a,
|
||||||
|
0xc5, 0xb9, 0x50, 0x05,
|
||||||
|
],
|
||||||
|
ask: [
|
||||||
|
0xb4, 0xde, 0xd9, 0x0d, 0x62, 0x11, 0x7f, 0x18, 0xf3, 0xdd, 0x5f, 0xdb, 0x22, 0x23,
|
||||||
|
0x8a, 0x35, 0xca, 0x37, 0xc4, 0x0f, 0xee, 0xc8, 0x45, 0xce, 0x5f, 0xc2, 0x7f, 0xe8,
|
||||||
|
0xbc, 0xa5, 0xef, 0x0f,
|
||||||
|
],
|
||||||
|
ak: [
|
||||||
|
0x4e, 0xfd, 0x5a, 0x2e, 0xf1, 0xff, 0xa9, 0x9a, 0x0f, 0xf6, 0x2b, 0x76, 0x7d, 0x44,
|
||||||
|
0xb3, 0x65, 0x1f, 0xfa, 0x1c, 0x69, 0x69, 0x15, 0xac, 0x00, 0xa2, 0x5e, 0xa3, 0xac,
|
||||||
|
0x7d, 0xff, 0x99, 0x01,
|
||||||
|
],
|
||||||
|
nk: [
|
||||||
|
0x02, 0xab, 0x99, 0x5c, 0xe9, 0x8f, 0x63, 0x02, 0x5f, 0xb6, 0x24, 0x28, 0xa0, 0xfb,
|
||||||
|
0xf5, 0x2f, 0x25, 0x22, 0xe6, 0xa2, 0x72, 0x61, 0x07, 0x8a, 0x9f, 0x4d, 0x6a, 0x36,
|
||||||
|
0xa1, 0xc0, 0x5d, 0x39,
|
||||||
|
],
|
||||||
|
rivk: [
|
||||||
|
0xd9, 0x84, 0x0d, 0x0b, 0xd8, 0x95, 0x20, 0xab, 0xbc, 0xa7, 0xf1, 0x0b, 0xe6, 0xeb,
|
||||||
|
0xa3, 0x66, 0xf8, 0x6e, 0xc3, 0xb7, 0x8d, 0xbd, 0xf1, 0xeb, 0xfe, 0x20, 0xd9, 0x95,
|
||||||
|
0x12, 0xaf, 0x15, 0x15,
|
||||||
|
],
|
||||||
|
ivk: [
|
||||||
|
0x58, 0xf5, 0xbb, 0x5c, 0x32, 0x31, 0x15, 0x25, 0x29, 0x42, 0x3b, 0x67, 0xfa, 0x43,
|
||||||
|
0x28, 0x79, 0x11, 0x26, 0x35, 0xcd, 0xa0, 0xda, 0x2e, 0xc2, 0x41, 0x9c, 0x6f, 0xe9,
|
||||||
|
0x1e, 0xa4, 0x8d, 0x24,
|
||||||
|
],
|
||||||
|
ovk: [
|
||||||
|
0x78, 0xf5, 0xd3, 0x48, 0x67, 0x2e, 0x8d, 0x20, 0x9c, 0x41, 0xb7, 0x83, 0xf8, 0xca,
|
||||||
|
0x14, 0xa7, 0x7b, 0x3e, 0xa3, 0xe6, 0x00, 0x4c, 0xa4, 0xe0, 0xc2, 0x5a, 0xa4, 0x45,
|
||||||
|
0x63, 0x98, 0x1d, 0xcb,
|
||||||
|
],
|
||||||
|
dk: [
|
||||||
|
0x5d, 0x7f, 0xe3, 0x96, 0xbb, 0xfd, 0x22, 0x67, 0xac, 0xa7, 0x11, 0xab, 0x5b, 0x3e,
|
||||||
|
0x1f, 0x02, 0x4f, 0x49, 0x11, 0xf3, 0xa1, 0x81, 0x73, 0x2f, 0x13, 0x22, 0xa1, 0x59,
|
||||||
|
0x2f, 0x9e, 0x0e, 0xbe,
|
||||||
|
],
|
||||||
|
default_d: [
|
||||||
|
0x2f, 0xbe, 0x4b, 0x4b, 0x1e, 0xdf, 0xf3, 0x31, 0x23, 0xce, 0x65,
|
||||||
|
],
|
||||||
|
default_pk_d: [
|
||||||
|
0xeb, 0x2c, 0x6f, 0xee, 0x34, 0x1e, 0xad, 0xe0, 0x7d, 0x74, 0x87, 0x99, 0x7a, 0xa7,
|
||||||
|
0x23, 0x69, 0x7d, 0x05, 0xe6, 0x29, 0x60, 0xdf, 0x37, 0x9c, 0x9e, 0x4a, 0x8d, 0x47,
|
||||||
|
0x6d, 0xfa, 0xc5, 0xbf,
|
||||||
|
],
|
||||||
|
note_v: 15425828902564319772,
|
||||||
|
note_rho: [
|
||||||
|
0x73, 0x6c, 0x23, 0x35, 0x7c, 0x85, 0xf4, 0x57, 0x91, 0xe1, 0x70, 0x80, 0x29, 0xd9,
|
||||||
|
0x82, 0x4d, 0x90, 0x70, 0x46, 0x07, 0xf3, 0x87, 0xa0, 0x3e, 0x49, 0xbf, 0x98, 0x36,
|
||||||
|
0x57, 0x44, 0x31, 0x34,
|
||||||
|
],
|
||||||
|
note_rseed: [
|
||||||
|
0x5a, 0x78, 0x77, 0xef, 0xaa, 0x8a, 0x08, 0xe7, 0x30, 0x81, 0xef, 0x8d, 0x62, 0xcb,
|
||||||
|
0x78, 0x0a, 0xb6, 0x88, 0x3a, 0x50, 0xa0, 0xd4, 0x70, 0x19, 0x0d, 0xfb, 0xa1, 0x0a,
|
||||||
|
0x85, 0x7f, 0x82, 0x84,
|
||||||
|
],
|
||||||
|
note_cmx: [
|
||||||
|
0xc8, 0x52, 0x8f, 0x72, 0x2c, 0xd3, 0xe4, 0x7d, 0xc9, 0x9e, 0x1e, 0x38, 0x80, 0x56,
|
||||||
|
0x37, 0x08, 0x15, 0xa9, 0xd0, 0x37, 0x97, 0x3d, 0x85, 0xca, 0xc7, 0xea, 0x38, 0xb5,
|
||||||
|
0xa7, 0x16, 0xfa, 0x3b,
|
||||||
|
],
|
||||||
|
note_nf: [
|
||||||
|
0x1c, 0xea, 0x44, 0xb3, 0x4e, 0x9d, 0x25, 0xbe, 0x11, 0x4b, 0x21, 0xed, 0xd4, 0x0c,
|
||||||
|
0x2c, 0x39, 0x8e, 0x71, 0xe3, 0x3e, 0x01, 0xdd, 0x79, 0xde, 0x81, 0x37, 0x87, 0x74,
|
||||||
|
0xff, 0xac, 0x93, 0x02,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
sk: [
|
||||||
|
0x2d, 0x38, 0x25, 0xb3, 0xd6, 0xda, 0x05, 0x73, 0xd3, 0x16, 0xeb, 0x16, 0x0d, 0xc0,
|
||||||
|
0xb7, 0x16, 0xc4, 0x8f, 0xbd, 0x46, 0x7f, 0x75, 0xb7, 0x80, 0x14, 0x9a, 0xe8, 0x80,
|
||||||
|
0x8f, 0x4e, 0x68, 0xf5,
|
||||||
|
],
|
||||||
|
ask: [
|
||||||
|
0x2d, 0x6e, 0x97, 0x3e, 0x17, 0x54, 0xd4, 0x17, 0x87, 0x93, 0x4c, 0x34, 0x55, 0x8c,
|
||||||
|
0xfe, 0x99, 0x38, 0x44, 0x19, 0x99, 0x72, 0xd9, 0xa6, 0x34, 0x8b, 0x7a, 0x3d, 0xad,
|
||||||
|
0xfc, 0xb6, 0x77, 0x2a,
|
||||||
|
],
|
||||||
|
ak: [
|
||||||
|
0x76, 0x21, 0x59, 0xa4, 0x14, 0xf5, 0x74, 0xb5, 0x39, 0x75, 0x0f, 0x22, 0xc8, 0x86,
|
||||||
|
0x3b, 0x02, 0xd2, 0x5c, 0xc1, 0x0c, 0x90, 0x71, 0xfc, 0x02, 0x19, 0xe9, 0x7f, 0x93,
|
||||||
|
0x92, 0xd0, 0x67, 0x0c,
|
||||||
|
],
|
||||||
|
nk: [
|
||||||
|
0x25, 0x91, 0xed, 0xf7, 0xef, 0x4c, 0xf2, 0x18, 0x4c, 0x34, 0xbe, 0x93, 0xfc, 0xf6,
|
||||||
|
0x12, 0x91, 0x50, 0x42, 0xf1, 0x5a, 0xb5, 0x08, 0x4b, 0x14, 0xe1, 0x66, 0x79, 0x5b,
|
||||||
|
0x09, 0xce, 0xa1, 0x33,
|
||||||
|
],
|
||||||
|
rivk: [
|
||||||
|
0x75, 0x8f, 0xb2, 0x50, 0xdd, 0x29, 0x50, 0xe5, 0xd2, 0xb2, 0xee, 0xd7, 0xff, 0xcf,
|
||||||
|
0x94, 0xae, 0x67, 0xcd, 0xe1, 0x25, 0xb9, 0x5b, 0x47, 0x9e, 0x23, 0x77, 0x81, 0x3a,
|
||||||
|
0x85, 0xa0, 0x3d, 0x2f,
|
||||||
|
],
|
||||||
|
ivk: [
|
||||||
|
0x6e, 0xa4, 0x36, 0x3c, 0xb2, 0xdf, 0x62, 0xb1, 0x0d, 0xa1, 0x30, 0x8a, 0x0b, 0x96,
|
||||||
|
0x79, 0xbd, 0x0f, 0x74, 0x95, 0xff, 0xe7, 0xd4, 0xe2, 0x61, 0x8f, 0x54, 0xdf, 0x9b,
|
||||||
|
0x67, 0x0c, 0x33, 0x16,
|
||||||
|
],
|
||||||
|
ovk: [
|
||||||
|
0xa6, 0x3c, 0xbc, 0xd3, 0x1b, 0xa1, 0x36, 0xd8, 0x3b, 0x8f, 0x1e, 0x88, 0xef, 0xb6,
|
||||||
|
0x00, 0x55, 0xef, 0x6f, 0x98, 0x25, 0x2d, 0xdb, 0xd7, 0x5f, 0x62, 0x5f, 0x44, 0xdc,
|
||||||
|
0xb6, 0x63, 0x2c, 0x72,
|
||||||
|
],
|
||||||
|
dk: [
|
||||||
|
0x02, 0xf0, 0x74, 0x08, 0xf3, 0x3e, 0x87, 0x12, 0xe4, 0xc9, 0xec, 0x42, 0xde, 0x56,
|
||||||
|
0x04, 0x20, 0x01, 0x09, 0x86, 0x17, 0x24, 0xd3, 0x3e, 0xb6, 0x36, 0x8b, 0x70, 0xf6,
|
||||||
|
0x5e, 0x0a, 0x16, 0x21,
|
||||||
|
],
|
||||||
|
default_d: [
|
||||||
|
0x08, 0xdf, 0x1d, 0x4b, 0x45, 0xc6, 0x73, 0xa4, 0x59, 0xff, 0x58,
|
||||||
|
],
|
||||||
|
default_pk_d: [
|
||||||
|
0x26, 0x8c, 0xc2, 0x4b, 0x38, 0xa6, 0x28, 0x80, 0xb6, 0xee, 0x3c, 0xbc, 0xb8, 0x5a,
|
||||||
|
0x71, 0x2f, 0xa6, 0x86, 0xcf, 0xfc, 0xa6, 0xdb, 0x2f, 0xee, 0xc5, 0xf3, 0xc3, 0x56,
|
||||||
|
0x6f, 0x84, 0x21, 0x8f,
|
||||||
|
],
|
||||||
|
note_v: 12606128263924155660,
|
||||||
|
note_rho: [
|
||||||
|
0x12, 0xf6, 0xb0, 0x2f, 0xe8, 0x06, 0xb9, 0x45, 0x69, 0xcd, 0x40, 0x59, 0xf3, 0x96,
|
||||||
|
0xbf, 0x29, 0xb9, 0x9d, 0x0a, 0x40, 0xe5, 0xe1, 0x71, 0x1c, 0xa9, 0x44, 0xf7, 0x2d,
|
||||||
|
0x43, 0x6a, 0x10, 0x2f,
|
||||||
|
],
|
||||||
|
note_rseed: [
|
||||||
|
0xca, 0x4b, 0x97, 0x69, 0x3d, 0xa0, 0xb0, 0x86, 0xfe, 0x9d, 0x2e, 0x71, 0x62, 0x47,
|
||||||
|
0x0d, 0x02, 0xe0, 0xf0, 0x5d, 0x4b, 0xec, 0x95, 0x12, 0xbf, 0xb3, 0xf3, 0x83, 0x27,
|
||||||
|
0x29, 0x6e, 0xfa, 0xa7,
|
||||||
|
],
|
||||||
|
note_cmx: [
|
||||||
|
0x6a, 0x11, 0x95, 0xaa, 0x05, 0x36, 0xf6, 0x0e, 0xcf, 0xae, 0xcb, 0xdf, 0x53, 0x74,
|
||||||
|
0xe4, 0x94, 0xea, 0x07, 0x2a, 0x2b, 0x86, 0x7b, 0x5f, 0x69, 0x43, 0x40, 0xc9, 0x6f,
|
||||||
|
0xc3, 0x70, 0xa9, 0x10,
|
||||||
|
],
|
||||||
|
note_nf: [
|
||||||
|
0xa2, 0x1c, 0x89, 0xa8, 0xdc, 0x99, 0x93, 0x92, 0xd4, 0x7a, 0x69, 0x1f, 0xf0, 0x14,
|
||||||
|
0xbb, 0xdc, 0x01, 0x00, 0x86, 0xa8, 0xb6, 0xb0, 0x3a, 0xc7, 0x5c, 0x55, 0x23, 0x89,
|
||||||
|
0x95, 0x42, 0x97, 0x3c,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
sk: [
|
||||||
|
0x43, 0x28, 0xb1, 0x18, 0xc2, 0x74, 0x02, 0xc7, 0x0c, 0x3a, 0x90, 0xb4, 0x9a, 0xd4,
|
||||||
|
0xbb, 0xc6, 0x8e, 0x37, 0xc0, 0xaa, 0x7d, 0x9b, 0x3f, 0xe1, 0x77, 0x99, 0xd7, 0x3b,
|
||||||
|
0x84, 0x1e, 0x75, 0x17,
|
||||||
|
],
|
||||||
|
ask: [
|
||||||
|
0x28, 0xdc, 0x45, 0xf1, 0x15, 0x44, 0x42, 0x5c, 0x1b, 0xef, 0x86, 0x61, 0xda, 0x11,
|
||||||
|
0x15, 0x5f, 0xdb, 0xb7, 0xe3, 0xbc, 0xfc, 0x0f, 0x0d, 0x49, 0xe6, 0xf1, 0x31, 0xe7,
|
||||||
|
0xc0, 0x9d, 0x35, 0x2f,
|
||||||
|
],
|
||||||
|
ak: [
|
||||||
|
0x0d, 0x21, 0x1a, 0x90, 0x60, 0xfb, 0xaa, 0x66, 0x4e, 0x41, 0xa7, 0x34, 0xad, 0x1d,
|
||||||
|
0x8d, 0x4b, 0x02, 0x5f, 0x8c, 0xc1, 0x60, 0xe1, 0xf4, 0xe9, 0x5f, 0x0a, 0x85, 0x3e,
|
||||||
|
0xbc, 0x41, 0x6a, 0x2b,
|
||||||
|
],
|
||||||
|
nk: [
|
||||||
|
0x3e, 0x88, 0xf2, 0x07, 0x1f, 0xd9, 0xa2, 0xbb, 0x26, 0xcd, 0xa2, 0xea, 0x85, 0x6a,
|
||||||
|
0xa0, 0xfb, 0x3a, 0x80, 0xa8, 0x7d, 0x2f, 0xb6, 0x13, 0x6f, 0xab, 0x85, 0xe3, 0x6c,
|
||||||
|
0x5b, 0x38, 0xd8, 0x24,
|
||||||
|
],
|
||||||
|
rivk: [
|
||||||
|
0x2c, 0x37, 0x38, 0x82, 0xc4, 0x08, 0xcd, 0x5f, 0xd4, 0x82, 0xa0, 0xc9, 0x81, 0x6f,
|
||||||
|
0xc3, 0x22, 0x03, 0xa1, 0x0f, 0xbf, 0xce, 0x0e, 0x20, 0x0c, 0xcf, 0xd9, 0xee, 0x30,
|
||||||
|
0x7c, 0x5e, 0x12, 0x24,
|
||||||
|
],
|
||||||
|
ivk: [
|
||||||
|
0xbb, 0x9e, 0x20, 0xb2, 0x99, 0x1c, 0x99, 0x6d, 0xa2, 0x1e, 0x3e, 0xcd, 0x39, 0xfb,
|
||||||
|
0x7b, 0x3a, 0xa2, 0xba, 0xbc, 0x6b, 0xde, 0x18, 0x6f, 0x7d, 0xd8, 0xa8, 0x75, 0xd1,
|
||||||
|
0x0c, 0x51, 0xa4, 0x30,
|
||||||
|
],
|
||||||
|
ovk: [
|
||||||
|
0x93, 0x21, 0x83, 0x8a, 0x2d, 0xb7, 0xf1, 0x68, 0xf0, 0xce, 0x77, 0xc4, 0x5b, 0x21,
|
||||||
|
0x1f, 0xfb, 0xb9, 0xb3, 0x65, 0xe8, 0x5e, 0x67, 0x31, 0xd9, 0x09, 0x70, 0x05, 0x53,
|
||||||
|
0xde, 0x49, 0x2b, 0x28,
|
||||||
|
],
|
||||||
|
dk: [
|
||||||
|
0x3d, 0xf5, 0x83, 0x36, 0x1b, 0x33, 0x38, 0xbb, 0x68, 0x15, 0xf8, 0x58, 0x72, 0xe3,
|
||||||
|
0x9f, 0x04, 0xdf, 0x50, 0x08, 0x52, 0x48, 0x84, 0xaf, 0x0f, 0x8c, 0x55, 0x97, 0x16,
|
||||||
|
0xfc, 0xb1, 0x49, 0x58,
|
||||||
|
],
|
||||||
|
default_d: [
|
||||||
|
0x4c, 0x40, 0x64, 0xc4, 0x7a, 0x5c, 0xa6, 0xe7, 0x5d, 0x46, 0x44,
|
||||||
|
],
|
||||||
|
default_pk_d: [
|
||||||
|
0xf5, 0x17, 0x17, 0x4b, 0xe2, 0x58, 0x92, 0x32, 0x78, 0xcf, 0x45, 0x89, 0x08, 0xc0,
|
||||||
|
0x73, 0x56, 0x49, 0xf1, 0x89, 0x9d, 0xb9, 0x9c, 0x3b, 0xa9, 0x00, 0x3f, 0x4b, 0xa3,
|
||||||
|
0x0a, 0xb0, 0xd2, 0x10,
|
||||||
|
],
|
||||||
|
note_v: 625536973899669523,
|
||||||
|
note_rho: [
|
||||||
|
0x03, 0xfd, 0x69, 0x44, 0x2e, 0xb7, 0x68, 0x1e, 0xc2, 0xa0, 0x56, 0x00, 0x05, 0x4e,
|
||||||
|
0x92, 0xee, 0xd5, 0x55, 0x02, 0x8f, 0x21, 0xb6, 0xa1, 0x55, 0x26, 0x8a, 0x2d, 0xd6,
|
||||||
|
0x64, 0x0a, 0x69, 0x30,
|
||||||
|
],
|
||||||
|
note_rseed: [
|
||||||
|
0x1a, 0x52, 0xa3, 0x8d, 0x4d, 0x9f, 0x9f, 0x95, 0x7a, 0xe3, 0x5a, 0xf7, 0x16, 0x71,
|
||||||
|
0x18, 0x14, 0x1c, 0xe4, 0xc9, 0xbe, 0x0a, 0x6a, 0x49, 0x2f, 0xe7, 0x9f, 0x15, 0x81,
|
||||||
|
0xa1, 0x55, 0xfa, 0x3a,
|
||||||
|
],
|
||||||
|
note_cmx: [
|
||||||
|
0xf7, 0x0e, 0xbf, 0x0f, 0x5e, 0xe5, 0xda, 0x6c, 0x6c, 0xde, 0xff, 0x8f, 0xec, 0x2f,
|
||||||
|
0x8e, 0xed, 0x65, 0xc8, 0x8e, 0x67, 0x55, 0xda, 0xf1, 0x14, 0xd5, 0x54, 0xaf, 0x19,
|
||||||
|
0x67, 0xa7, 0xf4, 0x0a,
|
||||||
|
],
|
||||||
|
note_nf: [
|
||||||
|
0xef, 0x12, 0xc1, 0x5e, 0xe4, 0xb7, 0x26, 0x32, 0xb6, 0x1f, 0x16, 0x52, 0x6b, 0x6f,
|
||||||
|
0xbc, 0x84, 0xba, 0xb8, 0x49, 0x5d, 0xcb, 0xd1, 0x7b, 0x74, 0x05, 0xb7, 0x6c, 0x69,
|
||||||
|
0xdd, 0x9f, 0x1d, 0x29,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,316 @@
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
pub struct TestVector {
|
||||||
|
pub(crate) domain: Vec<u8>,
|
||||||
|
pub(crate) msg: Vec<bool>,
|
||||||
|
pub(crate) point: [u8; 32],
|
||||||
|
pub(crate) hash: [u8; 32],
|
||||||
|
}
|
||||||
|
|
||||||
|
// From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/orchard_sinsemilla.py
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref SINSEMILLA: [TestVector; 11] = [
|
||||||
|
TestVector {
|
||||||
|
domain: vec![
|
||||||
|
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
|
||||||
|
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61,
|
||||||
|
],
|
||||||
|
msg: vec![
|
||||||
|
false, false, false, true, false, true, true, false, true, false, true, false,
|
||||||
|
false, true, true, false, false, false, true, true, false, true, true, false,
|
||||||
|
false, false, true, true, false, true, true, false, true, true, true, true, false,
|
||||||
|
true, true, false,
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0x98, 0x54, 0xaa, 0x38, 0x43, 0x63, 0xb5, 0x70, 0x8e, 0x06, 0xb4, 0x19, 0xb6, 0x43,
|
||||||
|
0x58, 0x68, 0x39, 0x65, 0x3f, 0xba, 0x5a, 0x78, 0x2d, 0x2d, 0xb1, 0x4c, 0xed, 0x13,
|
||||||
|
0xc1, 0x9a, 0x83, 0xab,
|
||||||
|
],
|
||||||
|
hash: [
|
||||||
|
0x98, 0x54, 0xaa, 0x38, 0x43, 0x63, 0xb5, 0x70, 0x8e, 0x06, 0xb4, 0x19, 0xb6, 0x43,
|
||||||
|
0x58, 0x68, 0x39, 0x65, 0x3f, 0xba, 0x5a, 0x78, 0x2d, 0x2d, 0xb1, 0x4c, 0xed, 0x13,
|
||||||
|
0xc1, 0x9a, 0x83, 0x2b,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![
|
||||||
|
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
|
||||||
|
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61, 0x2d, 0x6c, 0x6f, 0x6e, 0x67, 0x65,
|
||||||
|
0x72,
|
||||||
|
],
|
||||||
|
msg: vec![
|
||||||
|
true, true, false, true, false, false, true, false, true, false, false, false,
|
||||||
|
false, true, false, true, false, false, true, false, true, true, true, false,
|
||||||
|
false, false, false, true, true, false, false, true, false, true, false, true,
|
||||||
|
false, true, true, true, false, false, false, true, false, true, true, true, false,
|
||||||
|
true, false, true, false, true, true, true, false, true, true, true, true, true,
|
||||||
|
true, true, false, true, false, false, true, true, true, false, true, true, true,
|
||||||
|
true, false, false, true, false, true, false, false, false, false, false, true,
|
||||||
|
false, true, false, false, true, true, false, true, false, false, false, false,
|
||||||
|
true, true, false, true, false, true, false, true, true, false, true, false, false,
|
||||||
|
false, true, true, false, false, false, true, true, false, true,
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0xed, 0x5b, 0x98, 0x8e, 0x4e, 0x98, 0x17, 0x1f, 0x61, 0x8f, 0xee, 0xb1, 0x23, 0xe5,
|
||||||
|
0xcd, 0x0d, 0xc2, 0xd3, 0x67, 0x11, 0xc5, 0x06, 0xd5, 0xbe, 0x11, 0x5c, 0xfe, 0x38,
|
||||||
|
0x8f, 0x03, 0xc4, 0x80,
|
||||||
|
],
|
||||||
|
hash: [
|
||||||
|
0xed, 0x5b, 0x98, 0x8e, 0x4e, 0x98, 0x17, 0x1f, 0x61, 0x8f, 0xee, 0xb1, 0x23, 0xe5,
|
||||||
|
0xcd, 0x0d, 0xc2, 0xd3, 0x67, 0x11, 0xc5, 0x06, 0xd5, 0xbe, 0x11, 0x5c, 0xfe, 0x38,
|
||||||
|
0x8f, 0x03, 0xc4, 0x00,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![
|
||||||
|
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
|
||||||
|
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61,
|
||||||
|
],
|
||||||
|
msg: vec![
|
||||||
|
true, false, true, true, false, true, false, true, false, true, false, true, true,
|
||||||
|
true, true, true, true, true, false, true, false, true, true, false, true, false,
|
||||||
|
true, false, true, false, true, false, false, true, false, true, true, false,
|
||||||
|
false, false, true, true, false, true, false, false, true, true, true, true, true,
|
||||||
|
false, true, true, false, false, true, false, false, false, true, true, false,
|
||||||
|
false, false, false, true, false, false, true, true, false, false, true, false,
|
||||||
|
false, true, false, true, true, false, true, true, false, false, true, true, true,
|
||||||
|
true, true, false, false, false, true, false, false, true, false, false,
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0xd9, 0x5e, 0xe5, 0x8f, 0xbd, 0xaa, 0x6f, 0x3d, 0xe5, 0xe4, 0xfd, 0x7a, 0xfc, 0x35,
|
||||||
|
0xfa, 0x9d, 0xcf, 0xe8, 0x2a, 0xd1, 0x93, 0x06, 0xb0, 0x7e, 0x6c, 0xda, 0x0c, 0x30,
|
||||||
|
0xe5, 0x98, 0x34, 0x07,
|
||||||
|
],
|
||||||
|
hash: [
|
||||||
|
0xd9, 0x5e, 0xe5, 0x8f, 0xbd, 0xaa, 0x6f, 0x3d, 0xe5, 0xe4, 0xfd, 0x7a, 0xfc, 0x35,
|
||||||
|
0xfa, 0x9d, 0xcf, 0xe8, 0x2a, 0xd1, 0x93, 0x06, 0xb0, 0x7e, 0x6c, 0xda, 0x0c, 0x30,
|
||||||
|
0xe5, 0x98, 0x34, 0x07,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![
|
||||||
|
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
|
||||||
|
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61,
|
||||||
|
],
|
||||||
|
msg: vec![
|
||||||
|
false, false, true, true, false, false, false, true, false, false, true, false,
|
||||||
|
true, true, true, true, false, false, true, false, true, false, false, false, true,
|
||||||
|
true, false, false, true, true, true, true, false, true, false, false, true, false,
|
||||||
|
false, true, true, false, false, false, false, true, true, false, false, true,
|
||||||
|
false, false, false, true, false, false, true, false, true, true, false, true,
|
||||||
|
false, true, false, true, true, true, true, false, false, true, false, false, true,
|
||||||
|
true, true, true, true, false, true, true, false, true, true, false, false, true,
|
||||||
|
true, true, true, true, true, false, false, false, true, false, true, false, false,
|
||||||
|
true, true, false, true, true, true, true, false, false, true, true, false, false,
|
||||||
|
true, false, false, true, true, true, false, false, false, false, false, true,
|
||||||
|
false, false, false, true, false, true, false, true, true, true, true, false, true,
|
||||||
|
false, false, true, false, false, false, false, false, false, true, true, true,
|
||||||
|
true, false, true, true, false, false, false, false, true, true, true, false, true,
|
||||||
|
true, true, true, true, false, true, true, true, false, true, false, false, true,
|
||||||
|
false, false, true, false, false, false, false, true, false, false, false, false,
|
||||||
|
true, true, true, false, true, false, true, false, false, false, true, true, false,
|
||||||
|
false, true, false, false, false, true, true, false, false,
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0x6a, 0x92, 0x4b, 0x41, 0x39, 0x84, 0x29, 0x91, 0x0a, 0x78, 0x83, 0x2b, 0x61, 0x19,
|
||||||
|
0x2a, 0x0b, 0x67, 0x40, 0xd6, 0x27, 0x77, 0xeb, 0x71, 0x54, 0x50, 0x32, 0xeb, 0x6c,
|
||||||
|
0xe9, 0x3e, 0xc9, 0xb8,
|
||||||
|
],
|
||||||
|
hash: [
|
||||||
|
0x6a, 0x92, 0x4b, 0x41, 0x39, 0x84, 0x29, 0x91, 0x0a, 0x78, 0x83, 0x2b, 0x61, 0x19,
|
||||||
|
0x2a, 0x0b, 0x67, 0x40, 0xd6, 0x27, 0x77, 0xeb, 0x71, 0x54, 0x50, 0x32, 0xeb, 0x6c,
|
||||||
|
0xe9, 0x3e, 0xc9, 0x38,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![
|
||||||
|
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
|
||||||
|
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61, 0x2d, 0x6c, 0x6f, 0x6e, 0x67, 0x65,
|
||||||
|
0x72,
|
||||||
|
],
|
||||||
|
msg: vec![
|
||||||
|
false, true, true, true, true, true, true, true, true, false, false, false, false,
|
||||||
|
true, false, true, false, false, true, false, true, false, true, true, true, false,
|
||||||
|
true, true, true, false, true, false, true, false, false, true, true, false, false,
|
||||||
|
true, false, false, false, false, true, true, true, false, true, false, false,
|
||||||
|
false, false, false, false, true, false, false, false, false, false,
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0xdc, 0x5f, 0xf0, 0x5b, 0x6f, 0x18, 0xb0, 0x76, 0xb6, 0x12, 0x82, 0x37, 0xa7, 0x59,
|
||||||
|
0xed, 0xc7, 0xc8, 0x77, 0x8c, 0x70, 0x22, 0x2c, 0x79, 0xb7, 0x34, 0x03, 0x7b, 0x69,
|
||||||
|
0x39, 0x3a, 0xbf, 0xbe,
|
||||||
|
],
|
||||||
|
hash: [
|
||||||
|
0xdc, 0x5f, 0xf0, 0x5b, 0x6f, 0x18, 0xb0, 0x76, 0xb6, 0x12, 0x82, 0x37, 0xa7, 0x59,
|
||||||
|
0xed, 0xc7, 0xc8, 0x77, 0x8c, 0x70, 0x22, 0x2c, 0x79, 0xb7, 0x34, 0x03, 0x7b, 0x69,
|
||||||
|
0x39, 0x3a, 0xbf, 0x3e,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![
|
||||||
|
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
|
||||||
|
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61,
|
||||||
|
],
|
||||||
|
msg: vec![
|
||||||
|
true, true, false, false, true, true, false, true, false, false, true, true, false,
|
||||||
|
false, true, true, false, true, false, true, true, true, false, true, true, false,
|
||||||
|
true, true, false, true, true, true, true, true, true, false, false, false, true,
|
||||||
|
false, false, true, true, false, false, false, true, false, false, false, true,
|
||||||
|
true, true, false, false, false, false, true, false, false, true, true, true, true,
|
||||||
|
true, false, false, false, true, false, false, true, true, true, true, false, true,
|
||||||
|
true, true, false, false, false, true, false, false, true, false, false, true,
|
||||||
|
true, false, true, false, true, true, true, true, false, true, true, false, false,
|
||||||
|
false, true, true, true, true, true, true, false, false, false, true, false, false,
|
||||||
|
true, true, true, true, false, false, true, true, false, true, true, true, false,
|
||||||
|
true, true, true, true, false, false, true, false, true, true, true, true, false,
|
||||||
|
false, false, true, false, true, true, true, false, true, true, false, true, true,
|
||||||
|
true, true, true, true, true, true, true, false, true, false, false, true, false,
|
||||||
|
true, false, true, false, true, true, false, false, false, true, false, false,
|
||||||
|
false, false, true, false, false, false, true, false, false, false, true, true,
|
||||||
|
false, false, true, false, true, true, false, true, true, true, false, true, true,
|
||||||
|
true, false, false, true, true,
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0xc7, 0x6c, 0x8d, 0x7c, 0x43, 0x55, 0x04, 0x1b, 0xd7, 0xa7, 0xc9, 0x9b, 0x54, 0x86,
|
||||||
|
0x44, 0x19, 0x6f, 0x41, 0x94, 0x56, 0x20, 0x75, 0x37, 0xc2, 0x82, 0x85, 0x8a, 0x9b,
|
||||||
|
0x19, 0x2d, 0x07, 0xbb,
|
||||||
|
],
|
||||||
|
hash: [
|
||||||
|
0xc7, 0x6c, 0x8d, 0x7c, 0x43, 0x55, 0x04, 0x1b, 0xd7, 0xa7, 0xc9, 0x9b, 0x54, 0x86,
|
||||||
|
0x44, 0x19, 0x6f, 0x41, 0x94, 0x56, 0x20, 0x75, 0x37, 0xc2, 0x82, 0x85, 0x8a, 0x9b,
|
||||||
|
0x19, 0x2d, 0x07, 0x3b,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![
|
||||||
|
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
|
||||||
|
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61, 0x2d, 0x6c, 0x6f, 0x6e, 0x67, 0x65,
|
||||||
|
0x72,
|
||||||
|
],
|
||||||
|
msg: vec![
|
||||||
|
false, false, true, false, false, true, true, false, false, true, true, false,
|
||||||
|
true, true, false, true, true, true, true, false, false, false, true, true, false,
|
||||||
|
true, true, false, true, false, true, false, true, true, true, true, false, false,
|
||||||
|
false, false, false, true, true, true, false, true, false, false, true, true, true,
|
||||||
|
false, true, true, false, false, true, true, false, true, true, true, false, false,
|
||||||
|
true, false, false, true, true, true, false, false, true, false, false, false,
|
||||||
|
true, false, false, true, false, true, true, false, true, true, true, true, true,
|
||||||
|
false, true, true, false, false, false, false, false, false, false, false,
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0x1a, 0xe8, 0x25, 0xeb, 0x42, 0xd7, 0x4e, 0x1b, 0xca, 0x7e, 0xe8, 0xa1, 0xf8, 0xf3,
|
||||||
|
0xde, 0xd8, 0x01, 0xff, 0xcd, 0x1f, 0x22, 0xba, 0x75, 0xc3, 0x4b, 0xd6, 0xe0, 0x6a,
|
||||||
|
0x2c, 0x7c, 0x5a, 0xa0,
|
||||||
|
],
|
||||||
|
hash: [
|
||||||
|
0x1a, 0xe8, 0x25, 0xeb, 0x42, 0xd7, 0x4e, 0x1b, 0xca, 0x7e, 0xe8, 0xa1, 0xf8, 0xf3,
|
||||||
|
0xde, 0xd8, 0x01, 0xff, 0xcd, 0x1f, 0x22, 0xba, 0x75, 0xc3, 0x4b, 0xd6, 0xe0, 0x6a,
|
||||||
|
0x2c, 0x7c, 0x5a, 0x20,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![
|
||||||
|
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
|
||||||
|
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61, 0x2d, 0x6c, 0x6f, 0x6e, 0x67, 0x65,
|
||||||
|
0x72,
|
||||||
|
],
|
||||||
|
msg: vec![
|
||||||
|
true, true, false, true, true, true, false, false, true, false, false, false, true,
|
||||||
|
true, false, false, true, true, true, false, false, true, false, true, true, true,
|
||||||
|
true, false, true, true, true, false, false, true, true, false, true, true, true,
|
||||||
|
true, true, false, true, true, true, true, true, false, true, true, false, true,
|
||||||
|
true, true, false, true, false, true, false, false, true, false, true, true, true,
|
||||||
|
true, true, false, true, true, false, true, true, false, false, false, true, false,
|
||||||
|
true, true, false, false, false, true, false, false, false, false, true, false,
|
||||||
|
false, true, false, false, false, false, true, false, false, false, false, false,
|
||||||
|
true, true, true, false, false, false, true, true, false, false, false, false,
|
||||||
|
true, false, false, true, true, true, false, true, false, false, true, true, false,
|
||||||
|
false, false, true, false, false, true, false, false, false, false, false, true,
|
||||||
|
false, false, true, true, true, false, false, true, false, false, false, true,
|
||||||
|
false, false, false, true, false, false, false, false, true, false, true, false,
|
||||||
|
true, false, false, false, false, true, true, false, false, false, true, true,
|
||||||
|
true, true,
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0x38, 0xcf, 0xa6, 0x00, 0xaf, 0xd8, 0x67, 0x0e, 0x1f, 0x9a, 0x79, 0xcb, 0x22, 0x42,
|
||||||
|
0x5f, 0xa9, 0x50, 0xcc, 0x4d, 0x3a, 0x3f, 0x5a, 0xfe, 0x39, 0x76, 0xd7, 0x1b, 0xb1,
|
||||||
|
0x11, 0x46, 0x0c, 0x2b,
|
||||||
|
],
|
||||||
|
hash: [
|
||||||
|
0x38, 0xcf, 0xa6, 0x00, 0xaf, 0xd8, 0x67, 0x0e, 0x1f, 0x9a, 0x79, 0xcb, 0x22, 0x42,
|
||||||
|
0x5f, 0xa9, 0x50, 0xcc, 0x4d, 0x3a, 0x3f, 0x5a, 0xfe, 0x39, 0x76, 0xd7, 0x1b, 0xb1,
|
||||||
|
0x11, 0x46, 0x0c, 0x2b,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![
|
||||||
|
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
|
||||||
|
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61,
|
||||||
|
],
|
||||||
|
msg: vec![
|
||||||
|
false, false, true, false, true, false, true, false, false, true, true, false,
|
||||||
|
true, true, true, true, true, false, false, true, true, false, true, false, true,
|
||||||
|
true, true, false, false, false, false, true, false, false, true, true, false,
|
||||||
|
false, false, false, true, true, true, true, true, true, true, true, false, false,
|
||||||
|
true, false, true, false, false, false, false, true, false, true, true, true, true,
|
||||||
|
true, true, false, true, true, true, true, false, true, false, true, false, false,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0x82, 0x6f, 0xcb, 0xed, 0xfc, 0x83, 0xb9, 0xfa, 0xa5, 0x71, 0x1a, 0xab, 0x59, 0xbf,
|
||||||
|
0xc9, 0x1b, 0xd4, 0x45, 0x58, 0x14, 0x67, 0x72, 0x5d, 0xde, 0x94, 0x1d, 0x58, 0xe6,
|
||||||
|
0x26, 0x56, 0x66, 0x15,
|
||||||
|
],
|
||||||
|
hash: [
|
||||||
|
0x82, 0x6f, 0xcb, 0xed, 0xfc, 0x83, 0xb9, 0xfa, 0xa5, 0x71, 0x1a, 0xab, 0x59, 0xbf,
|
||||||
|
0xc9, 0x1b, 0xd4, 0x45, 0x58, 0x14, 0x67, 0x72, 0x5d, 0xde, 0x94, 0x1d, 0x58, 0xe6,
|
||||||
|
0x26, 0x56, 0x66, 0x15,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![
|
||||||
|
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
|
||||||
|
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61,
|
||||||
|
],
|
||||||
|
msg: vec![
|
||||||
|
true, true, true, false, true, false, true, false, true, true, true, true, false,
|
||||||
|
true, false, true, false, true, false, true, false, true, false, true, true, true,
|
||||||
|
false, false, true, false, false, true, false, false, true, true, false, true,
|
||||||
|
false, false, false, true, false, true, true, false, true, false, false, false,
|
||||||
|
false, false, false, true, true, true, true, false, false, true, true, true, false,
|
||||||
|
false, true, false, true, false, true, false, false, false, false, false, false,
|
||||||
|
false, false, false, true, false, true, true, false, true, false, true, true, true,
|
||||||
|
false, false, true, true, false, true, false, false, false, true, true, true,
|
||||||
|
false, false, true, true, false, false, true, false, true, false, false, false,
|
||||||
|
true, true, false,
|
||||||
|
],
|
||||||
|
point: [
|
||||||
|
0x0b, 0xf0, 0x6c, 0xe8, 0x10, 0x05, 0xb8, 0x1a, 0x14, 0x80, 0x9f, 0xa6, 0xeb, 0xcb,
|
||||||
|
0x94, 0xe2, 0xb6, 0x37, 0x5f, 0x87, 0xce, 0x51, 0x95, 0x8c, 0x94, 0x98, 0xed, 0x1a,
|
||||||
|
0x31, 0x3c, 0x6a, 0x94,
|
||||||
|
],
|
||||||
|
hash: [
|
||||||
|
0x0b, 0xf0, 0x6c, 0xe8, 0x10, 0x05, 0xb8, 0x1a, 0x14, 0x80, 0x9f, 0xa6, 0xeb, 0xcb,
|
||||||
|
0x94, 0xe2, 0xb6, 0x37, 0x5f, 0x87, 0xce, 0x51, 0x95, 0x8c, 0x94, 0x98, 0xed, 0x1a,
|
||||||
|
0x31, 0x3c, 0x6a, 0x14,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TestVector {
|
||||||
|
domain: vec![
|
||||||
|
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
|
||||||
|
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61,
|
||||||
|
],
|
||||||
|
msg: vec![true, false, true, true, true, false, true, false],
|
||||||
|
point: [
|
||||||
|
0x80, 0x6a, 0xcc, 0x24, 0x7a, 0xc9, 0xba, 0x90, 0xd2, 0x5f, 0x58, 0x3d, 0xad, 0xb5,
|
||||||
|
0xe0, 0xee, 0x5c, 0x03, 0xe1, 0xab, 0x35, 0x70, 0xb3, 0x62, 0xb4, 0xbe, 0x5a, 0x8b,
|
||||||
|
0xce, 0xb6, 0x0b, 0x00,
|
||||||
|
],
|
||||||
|
hash: [
|
||||||
|
0x80, 0x6a, 0xcc, 0x24, 0x7a, 0xc9, 0xba, 0x90, 0xd2, 0x5f, 0x58, 0x3d, 0xad, 0xb5,
|
||||||
|
0xe0, 0xee, 0x5c, 0x03, 0xe1, 0xab, 0x35, 0x70, 0xb3, 0x62, 0xb4, 0xbe, 0x5a, 0x8b,
|
||||||
|
0xce, 0xb6, 0x0b, 0x00,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue