From 8a4add55f19a21033064c1315581a65bb33b9905 Mon Sep 17 00:00:00 2001 From: Deirdre Connolly Date: Fri, 16 Jul 2021 03:52:35 -1000 Subject: [PATCH] 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 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 Co-authored-by: Conrado P. L. Gouvea Co-authored-by: teor Co-authored-by: Conrado Gouvea --- zebra-chain/src/orchard/address.rs | 39 +- zebra-chain/src/orchard/arbitrary.rs | 41 +- zebra-chain/src/orchard/commitment.rs | 65 +- zebra-chain/src/orchard/keys.rs | 401 +++++----- zebra-chain/src/orchard/keys/tests.rs | 76 +- zebra-chain/src/orchard/note.rs | 85 +- zebra-chain/src/orchard/note/nullifiers.rs | 16 +- zebra-chain/src/orchard/sinsemilla.rs | 48 ++ zebra-chain/src/orchard/tests.rs | 2 +- zebra-chain/src/orchard/tests/tree.rs | 10 +- zebra-chain/src/orchard/tests/vectors.rs | 9 + .../src/orchard/tests/vectors/group_hash.rs | 225 ++++++ .../orchard/tests/vectors/key_components.rs | 737 ++++++++++++++++++ .../src/orchard/tests/vectors/sinsemilla.rs | 316 ++++++++ .../{test_vectors.rs => vectors/tree.rs} | 0 15 files changed, 1726 insertions(+), 344 deletions(-) create mode 100644 zebra-chain/src/orchard/tests/vectors.rs create mode 100644 zebra-chain/src/orchard/tests/vectors/group_hash.rs create mode 100644 zebra-chain/src/orchard/tests/vectors/key_components.rs create mode 100644 zebra-chain/src/orchard/tests/vectors/sinsemilla.rs rename zebra-chain/src/orchard/tests/{test_vectors.rs => vectors/tree.rs} (100%) diff --git a/zebra-chain/src/orchard/address.rs b/zebra-chain/src/orchard/address.rs index 4f0dafc8..24cef75f 100644 --- a/zebra-chain/src/orchard/address.rs +++ b/zebra-chain/src/orchard/address.rs @@ -2,14 +2,9 @@ use std::fmt; -#[cfg(test)] -use proptest::prelude::*; - -use crate::parameters::Network; - use super::keys; -/// A Orchard _shielded payment address_. +/// A raw **Orchard** _shielded payment address_. /// /// Also known as a _diversified payment address_ for Orchard, as /// 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 #[derive(Clone, Copy, Eq, PartialEq)] pub struct Address { - network: Network, - diversifier: keys::Diversifier, - transmission_key: keys::TransmissionKey, + pub(crate) diversifier: keys::Diversifier, + pub(crate) transmission_key: keys::TransmissionKey, } impl fmt::Debug for Address { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("OrchardAddress") - .field("network", &self.network) .field("diversifier", &self.diversifier) .field("transmission_key", &self.transmission_key) .finish() } } -#[cfg(test)] -impl Arbitrary for Address { - type Parameters = (); - - fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { - ( - any::(), - any::(), - any::(), - ) - .prop_map(|(network, diversifier, transmission_key)| Self { - network, - diversifier, - transmission_key, - }) - .boxed() - } - - type Strategy = BoxedStrategy; -} - #[cfg(test)] mod tests { use rand_core::OsRng; + use crate::parameters::Network; + use super::*; #[test] @@ -68,7 +42,7 @@ mod tests { 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. 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 _orchard_shielded_address = Address { - network, diversifier, transmission_key, }; diff --git a/zebra-chain/src/orchard/arbitrary.rs b/zebra-chain/src/orchard/arbitrary.rs index 5d3ae697..5bb60e3d 100644 --- a/zebra-chain/src/orchard/arbitrary.rs +++ b/zebra-chain/src/orchard/arbitrary.rs @@ -4,7 +4,10 @@ use proptest::{arbitrary::any, array, collection::vec, prelude::*}; 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::{ convert::{TryFrom, TryInto}, @@ -125,3 +128,39 @@ impl Arbitrary for tree::Root { type Strategy = BoxedStrategy; } + +impl Arbitrary for keys::TransmissionKey { + type Parameters = (); + + fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { + (any::()) + .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; +} + +impl Arbitrary for Address { + type Parameters = (); + + fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { + (any::(), any::()) + .prop_map(|(diversifier, transmission_key)| Self { + diversifier, + transmission_key, + }) + .boxed() + } + + type Strategy = BoxedStrategy; +} diff --git a/zebra-chain/src/orchard/commitment.rs b/zebra-chain/src/orchard/commitment.rs index 14cc9bff..303bd819 100644 --- a/zebra-chain/src/orchard/commitment.rs +++ b/zebra-chain/src/orchard/commitment.rs @@ -12,15 +12,15 @@ use lazy_static::lazy_static; use rand_core::{CryptoRng, RngCore}; use crate::{ - amount::{Amount, NonNegative}, + amount::Amount, serialization::{ serde_helpers, ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize, }, }; use super::{ - keys::{prf_expand, Diversifier, TransmissionKey}, - note::{self, SeedRandomness}, + keys::prf_expand, + note::{Note, Psi, SeedRandomness}, sinsemilla::*, }; @@ -105,11 +105,7 @@ impl TryFrom<[u8; 32]> for NoteCommitment { } impl NoteCommitment { - /// Generate a new _NoteCommitment_ and the randomness used to create it. - /// - /// 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. + /// Generate a new _NoteCommitment_. /// /// Unlike in Sapling, the definition of an Orchard _note_ includes the ρ /// 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 #[allow(non_snake_case)] - pub fn new( - csprng: &mut T, - diversifier: Diversifier, - transmission_key: TransmissionKey, - value: Amount, - rho: note::Rho, - psi: note::Psi, - ) -> Option<(CommitmentRandomness, Self)> - where - T: RngCore + CryptoRng, - { + pub fn new(note: Note) -> Option { // s as in the argument name for WindowedPedersenCommit_r(s) let mut s: BitVec = BitVec::new(); @@ -138,17 +124,15 @@ impl NoteCommitment { // The `TryFrom` impls for the `pallas::*Point`s handles // calling `DiversifyHash` implicitly. - let g_d_bytes: [u8; 32]; - if let Ok(g_d) = pallas::Affine::try_from(diversifier) { - g_d_bytes = g_d.to_bytes(); - } else { - return None; - } + // _diversified base_ + let g_d_bytes = pallas::Affine::try_from(note.address.diversifier) + .ok()? + .to_bytes(); - let pk_d_bytes: [u8; 32] = transmission_key.into(); - let v_bytes = value.to_bytes(); - let rho_bytes: [u8; 32] = rho.into(); - let psi_bytes: [u8; 32] = psi.into(); + let pk_d_bytes: [u8; 32] = note.address.transmission_key.into(); + let v_bytes = note.value.to_bytes(); + let rho_bytes: [u8; 32] = note.rho.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(ψ) s.extend(g_d_bytes); @@ -157,28 +141,17 @@ impl NoteCommitment { s.extend(rho_bytes); s.extend(psi_bytes); - let rcm = CommitmentRandomness(generate_trapdoor(csprng)); + let rcm = CommitmentRandomness::from(note.rseed); - Some(( - rcm, - NoteCommitment::from( - sinsemilla_commit(rcm.0, b"z.cash:Orchard-NoteCommit", &s) - .expect("valid orchard note commitment, not ⊥ "), - ), + Some(NoteCommitment::from( + sinsemilla_commit(rcm.0, b"z.cash:Orchard-NoteCommit", &s) + .expect("valid orchard note commitment, not ⊥ "), )) } - /// Hash Extractor for Pallas - /// - /// https://zips.z.cash/protocol/nu5.pdf#concreteextractorpallas + /// Extract the x coordinate of the note commitment. pub fn extract_x(&self) -> pallas::Base { - let option: Option> = self.0.coordinates().into(); - - match option { - // If Some, it's not the identity. - Some(coordinates) => *coordinates.x(), - _ => pallas::Base::zero(), - } + extract_p(self.0.into()) } } diff --git a/zebra-chain/src/orchard/keys.rs b/zebra-chain/src/orchard/keys.rs index 864ed6df..48237a0b 100644 --- a/zebra-chain/src/orchard/keys.rs +++ b/zebra-chain/src/orchard/keys.rs @@ -9,8 +9,7 @@ mod tests; use std::{ convert::{From, Into, TryFrom, TryInto}, - fmt, - io::{self, Write}, + fmt, io, }; use aes::Aes256; @@ -213,7 +212,7 @@ impl SpendingKey { } /// 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 } } } @@ -225,7 +224,7 @@ impl SpendingKey { /// Description_ that spends notes, proving ownership of notes. /// /// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Eq)] pub struct SpendAuthorizingKey(pub(crate) pallas::Scalar); impl ConstantTimeEq for SpendAuthorizingKey { @@ -259,15 +258,21 @@ impl From for SpendAuthorizingKey { /// /// fn from(spending_key: SpendingKey) -> SpendAuthorizingKey { - let hash_bytes = prf_expand(spending_key.bytes, vec![&[6]]); - // 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 { fn eq(&self, other: &Self) -> bool { 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 /// §4.2.3][orchardkeycomponents]. /// -/// Used to validate Orchard _Spend Authorization Signatures_, proving ownership -/// of notes. -/// /// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents #[derive(Copy, Clone, Debug)] pub struct SpendValidatingKey(pub(crate) redpallas::VerificationKey); @@ -475,138 +477,14 @@ impl TryFrom<[u8; 32]> for IvkCommitRandomness { } } -/// Magic human-readable strings used to identify what networks Orchard incoming -/// viewing keys are associated with when encoded/decoded with bech32. -/// -/// -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 for IncomingViewingKey { - /// Commit^ivk_rivk(ak, nk) := - /// SinsemillaShortCommit_rcm (︁"z.cash:Orchard-CommitIvk", I2LEBSP_l(ak) || I2LEBSP_l(nk)︁) mod r_P - /// - /// - /// - #[allow(non_snake_case)] - fn from(fvk: FullViewingKey) -> Self { - let mut M: BitVec = 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. -/// -/// -mod fvk_hrp { - pub const MAINNET: &str = "zviewo"; - pub const TESTNET: &str = "zviewtestorchard"; -} - -/// Full Viewing Keys +/// _Full viewing keys_ /// /// Allows recognizing both incoming and outgoing notes without having /// 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”. -/// /// #[derive(Copy, Clone)] pub struct FullViewingKey { - network: Network, spend_validating_key: SpendValidatingKey, nullifier_deriving_key: NullifierDerivingKey, ivk_commit_randomness: IvkCommitRandomness, @@ -630,21 +508,6 @@ impl FullViewingKey { // let R = PRF^expand_K( [0x82] || I2LEOSP256(ak) || I2LEOSP256(nk) ) prf_expand(K, t) } - - /// Derive a full viewing key from a existing spending key and its network. - /// - /// - /// - 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 { @@ -653,12 +516,11 @@ impl ConstantTimeEq for FullViewingKey { /// /// # 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 /// secret component values. 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); } @@ -674,7 +536,6 @@ impl ConstantTimeEq for FullViewingKey { impl fmt::Debug for FullViewingKey { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("FullViewingKey") - .field("network", &self.network) .field("spend_validating_key", &self.spend_validating_key) .field("nullifier_deriving_key", &self.nullifier_deriving_key) .field("ivk_commit_randomness", &self.ivk_commit_randomness) @@ -683,19 +544,39 @@ impl fmt::Debug for FullViewingKey { } impl fmt::Display for FullViewingKey { + /// The _raw encoding_ of an **Orchard** _full viewing key_. + /// + /// 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)); - let _ = bytes.write_all(&<[u8; 32]>::from(self.nullifier_deriving_key)); - let _ = bytes.write_all(&<[u8; 32]>::from(self.ivk_commit_randomness)); +impl From for [u8; 96] { + fn from(fvk: FullViewingKey) -> [u8; 96] { + let mut bytes = [0u8; 96]; - let hrp = match self.network { - Network::Mainnet => fvk_hrp::MAINNET, - Network::Testnet => fvk_hrp::TESTNET, - }; + bytes[..32].copy_from_slice(&<[u8; 32]>::from(fvk.spend_validating_key)); + bytes[32..64].copy_from_slice(&<[u8; 32]>::from(fvk.nullifier_deriving_key)); + 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 for FullViewingKey { + /// Derive a _full viewing key_ from a existing _spending key_. + /// + /// + /// + 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_. + /// + /// + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(&hex::encode(<[u8; 64]>::from(*self))) + } +} + +impl Eq for IncomingViewingKey {} + +impl From 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 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 + /// + /// + /// + #[allow(non_snake_case)] + fn from(fvk: FullViewingKey) -> Self { + let mut M: BitVec = 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::::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::::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 /// §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 /// [ZIP-32]: https://zips.z.cash/zip-0032#orchard-diversifier-derivation -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub struct DiversifierKey([u8; 32]); 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]. /// -/// Combined with an `IncomingViewingKey`, produces a _diversified -/// payment address_. -/// /// [ps]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents #[derive(Copy, Clone, Eq, PartialEq)] #[cfg_attr( @@ -989,7 +969,7 @@ impl From<(IncomingViewingKey, Diversifier)> for TransmissionKey { fn from((ivk, d): (IncomingViewingKey, Diversifier)) -> Self { 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. +/// +/// +// 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. +/// +/// +/// +#[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 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. /// /// @@ -1050,7 +1085,7 @@ impl TryFrom<[u8; 32]> for EphemeralPublicKey { if possible_point.is_some().into() { Ok(Self(possible_point.unwrap())) } 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)) } } - -/// An _outgoing cipher key_ for Orchard note encryption/decryption. -/// -/// -#[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 diff --git a/zebra-chain/src/orchard/keys/tests.rs b/zebra-chain/src/orchard/keys/tests.rs index 56ce6251..6c2ca812 100644 --- a/zebra-chain/src/orchard/keys/tests.rs +++ b/zebra-chain/src/orchard/keys/tests.rs @@ -1,32 +1,52 @@ #![allow(clippy::module_inception)] -use super::*; -#[cfg(test)] +use super::*; +use crate::orchard::tests::vectors::KEY_COMPONENTS; + use proptest::prelude::*; -#[cfg(test)] -impl Arbitrary for TransmissionKey { - type Parameters = (); +#[test] +fn generate_keys_from_test_vectors() { + zebra_test::init(); - fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { - (any::()) - .prop_map(|spending_key| { - let full_viewing_key = FullViewingKey::from_spending_key(spending_key); + for test_vector in KEY_COMPONENTS.iter() { + let spending_key = SpendingKey::from_bytes(test_vector.sk, Network::Mainnet); - 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 incoming_viewing_key = IncomingViewingKey::from(full_viewing_key); + let spend_validating_key = SpendValidatingKey::from(spend_authorizing_key); + assert_eq!(<[u8; 32]>::from(spend_validating_key), test_vector.ak); - Self::from((incoming_viewing_key, diversifier)) - }) - .boxed() + let nullifier_deriving_key = NullifierDerivingKey::from(spending_key); + assert_eq!(nullifier_deriving_key, test_vector.nk); + + 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; } -#[cfg(test)] proptest! { #[test] @@ -35,46 +55,42 @@ proptest! { zebra_test::init(); // 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); // 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 let spend_validating_key = SpendValidatingKey::from(spend_authorizing_key); let nullifier_deriving_key = NullifierDerivingKey::from(spending_key); // 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); // 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 { - network: spending_key.network, spend_validating_key, nullifier_deriving_key, ivk_commit_randomness, }; // 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); // 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); // Test ConstantTimeEq, Eq, PartialEq - assert!(incoming_viewing_key == - IncomingViewingKey::from_bytes(incoming_viewing_key.scalar.into(), - incoming_viewing_key.network)); - + assert_eq!(incoming_viewing_key, incoming_viewing_key.clone()); let outgoing_viewing_key = OutgoingViewingKey::from(full_viewing_key); // 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 let diversifier = Diversifier::from(diversifier_key); diff --git a/zebra-chain/src/orchard/note.rs b/zebra-chain/src/orchard/note.rs index 7bcc0a89..32eb3362 100644 --- a/zebra-chain/src/orchard/note.rs +++ b/zebra-chain/src/orchard/note.rs @@ -7,16 +7,9 @@ use group::GroupEncoding; use halo2::{arithmetic::FieldExt, pasta::pallas}; use rand_core::{CryptoRng, RngCore}; -use crate::{ - amount::{Amount, NonNegative}, - transaction::Memo, -}; +use crate::amount::{Amount, NonNegative}; -use super::{ - commitment::CommitmentRandomness, - keys::{prf_expand, Diversifier, TransmissionKey}, - sinsemilla::extract_p, -}; +use super::{address::Address, keys::prf_expand, sinsemilla::extract_p}; #[cfg(any(test, feature = "proptest-impl"))] mod arbitrary; @@ -26,9 +19,21 @@ mod nullifiers; pub use ciphertexts::{EncryptedNote, WrappedNoteKey}; 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]); +impl SeedRandomness { + pub fn new(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_. /// /// When creating a new note from spending an old note, the new note's _rho_ is @@ -47,6 +52,12 @@ impl From for [u8; 32] { } } +impl From for Rho { + fn from(nf: Nullifier) -> Self { + Self(nf.0) + } +} + impl Rho { pub fn new(csprng: &mut T) -> Self where @@ -61,7 +72,7 @@ impl Rho { /// Additional randomness used in deriving the _nullifier_. /// -/// https://zips.z.cash/protocol/nu5.pdf#orchardsend +/// #[derive(Clone, Debug)] pub struct Psi(pub(crate) pallas::Base); @@ -74,7 +85,7 @@ impl From for [u8; 32] { impl From for Psi { /// rcm = ToScalar^Orchard((PRF^expand_rseed ([9])) /// - /// https://zips.z.cash/protocol/nu5.pdf#orchardsend + /// fn from(rseed: SeedRandomness) -> Self { Self(pallas::Base::from_bytes_wide(&prf_expand( rseed.0, @@ -83,25 +94,43 @@ impl From for Psi { } } -/// A Note represents that a value is spendable by the recipient who -/// holds the spending key corresponding to a given shielded payment -/// address. +/// A Note represents that a value is spendable by the recipient who holds the +/// spending key corresponding to a given shielded payment address. +/// +/// #[derive(Clone, Debug)] pub struct Note { - /// The _diversifer_ of the recipient’s _shielded payment address_. - pub diversifier: Diversifier, - /// The _diversified transmission key_ of the recipient’s shielded - /// payment address. - pub transmission_key: TransmissionKey, + /// The recipient's shielded payment address. + pub address: Address, /// An integer representing the value of the _note_ in zatoshi. pub value: Amount, - /// 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, - /// Additional randomness used in deriving the _nullifier_. - pub psi: Psi, - /// A random _commitment trapdoor_ used to produce the associated note - /// commitment. - pub rcm: CommitmentRandomness, - /// The note memo, after decryption. - pub memo: Memo, + /// 32 random bytes from which _rcm_, _psi_, and the _ephemeral private key_ + /// are derived. + pub rseed: SeedRandomness, +} + +impl Note { + /// Create an Orchard _note_, by choosing 32 uniformly random bytes for + /// rseed. + /// + /// + pub fn new( + csprng: &mut T, + address: Address, + value: Amount, + nf_old: Nullifier, + ) -> Self + where + T: RngCore + CryptoRng, + { + Self { + address, + value, + rho: nf_old.into(), + rseed: SeedRandomness::new(csprng), + } + } } diff --git a/zebra-chain/src/orchard/note/nullifiers.rs b/zebra-chain/src/orchard/note/nullifiers.rs index 6ccac05a..049e91a5 100644 --- a/zebra-chain/src/orchard/note/nullifiers.rs +++ b/zebra-chain/src/orchard/note/nullifiers.rs @@ -11,7 +11,10 @@ use halo2::{arithmetic::FieldExt, pasta::pallas}; use crate::serialization::{serde_helpers, SerializationError}; use super::super::{ - commitment::NoteCommitment, keys::NullifierDerivingKey, note::Note, sinsemilla::*, + commitment::NoteCommitment, + keys::NullifierDerivingKey, + note::{Note, Psi}, + sinsemilla::*, }; /// 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 #[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 { fn hash(&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)︀ /// - /// https://zips.z.cash/protocol/nu5.pdf#commitmentsandnullifiers + /// #[allow(non_snake_case)] + // TODO: tidy prf_nf, notes/rho/psi 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 psi: Psi = note.rseed.into(); + // impl Add for pallas::Base reduces by the modulus (q_P) // // [︀ (PRF^nfOrchard_nk(ρ) + ψ) mod q_P ]︀ K^Orchard + cm let scalar = - pallas::Scalar::from_bytes(&(prf_nf(nk.0, note.rho.0) + note.psi.0).to_bytes()) - .unwrap(); + pallas::Scalar::from_bytes(&(prf_nf(nk.0, note.rho.0) + psi.0).to_bytes()).unwrap(); // Basically a new-gen Pedersen hash? Nullifier(extract_p((K * scalar) + cm.0)) diff --git a/zebra-chain/src/orchard/sinsemilla.rs b/zebra-chain/src/orchard/sinsemilla.rs index 25f96ccc..0e11be08 100644 --- a/zebra-chain/src/orchard/sinsemilla.rs +++ b/zebra-chain/src/orchard/sinsemilla.rs @@ -201,6 +201,7 @@ pub fn sinsemilla_short_commit( mod tests { use super::*; + use crate::orchard::tests::vectors; fn x_from_str(s: &str) -> pallas::Base { use group::ff::PrimeField; @@ -234,4 +235,51 @@ mod tests { 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 = &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() + ); + } + } } diff --git a/zebra-chain/src/orchard/tests.rs b/zebra-chain/src/orchard/tests.rs index 2b8339b2..55d2d296 100644 --- a/zebra-chain/src/orchard/tests.rs +++ b/zebra-chain/src/orchard/tests.rs @@ -1,4 +1,4 @@ mod preallocate; mod prop; -mod test_vectors; mod tree; +pub(crate) mod vectors; diff --git a/zebra-chain/src/orchard/tests/tree.rs b/zebra-chain/src/orchard/tests/tree.rs index 0ecdb583..86e830bf 100644 --- a/zebra-chain/src/orchard/tests/tree.rs +++ b/zebra-chain/src/orchard/tests/tree.rs @@ -1,7 +1,7 @@ use halo2::arithmetic::FieldExt; use halo2::pasta::pallas; -use crate::orchard::tests::test_vectors; +use crate::orchard::tests::vectors; use crate::orchard::tree::*; #[test] @@ -12,7 +12,7 @@ fn empty_roots() { assert_eq!( EMPTY_ROOTS[i].to_bytes(), // 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(); - 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() { let cm_x = pallas::Base::from_bytes(cm_x_bytes).unwrap(); @@ -36,12 +36,12 @@ fn incremental_roots() { assert_eq!( hex::encode(incremental_tree.hash()), - hex::encode(test_vectors::ROOTS[i].anchor) + hex::encode(vectors::ROOTS[i].anchor) ); assert_eq!( hex::encode((NoteCommitmentTree::from(leaves.clone())).hash()), - hex::encode(test_vectors::ROOTS[i].anchor) + hex::encode(vectors::ROOTS[i].anchor) ); } } diff --git a/zebra-chain/src/orchard/tests/vectors.rs b/zebra-chain/src/orchard/tests/vectors.rs new file mode 100644 index 00000000..8d0576ed --- /dev/null +++ b/zebra-chain/src/orchard/tests/vectors.rs @@ -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}; diff --git a/zebra-chain/src/orchard/tests/vectors/group_hash.rs b/zebra-chain/src/orchard/tests/vectors/group_hash.rs new file mode 100644 index 00000000..c280cd1d --- /dev/null +++ b/zebra-chain/src/orchard/tests/vectors/group_hash.rs @@ -0,0 +1,225 @@ +use lazy_static::lazy_static; + +pub struct TestVector { + pub(crate) domain: Vec, + pub(crate) msg: Vec, + 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 + ], + }, + ]; +} diff --git a/zebra-chain/src/orchard/tests/vectors/key_components.rs b/zebra-chain/src/orchard/tests/vectors/key_components.rs new file mode 100644 index 00000000..95591679 --- /dev/null +++ b/zebra-chain/src/orchard/tests/vectors/key_components.rs @@ -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, + ], + }, +]; diff --git a/zebra-chain/src/orchard/tests/vectors/sinsemilla.rs b/zebra-chain/src/orchard/tests/vectors/sinsemilla.rs new file mode 100644 index 00000000..12e2eed4 --- /dev/null +++ b/zebra-chain/src/orchard/tests/vectors/sinsemilla.rs @@ -0,0 +1,316 @@ +use lazy_static::lazy_static; + +pub struct TestVector { + pub(crate) domain: Vec, + pub(crate) msg: Vec, + 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, + ], + }, + ]; +} diff --git a/zebra-chain/src/orchard/tests/test_vectors.rs b/zebra-chain/src/orchard/tests/vectors/tree.rs similarity index 100% rename from zebra-chain/src/orchard/tests/test_vectors.rs rename to zebra-chain/src/orchard/tests/vectors/tree.rs