Fix Orchard implementation, refactor, and add more test vectors (#2445)

* Support incomplete Pallas addition, all the way down

* Check Orchard key derivation against test vectors (currently not passing)

* Fix up Orchard keys, notes, nullifiers, address, and their tests

* Fix Incoming Viewing Key generation

* Move around test vectors, impl From<SpendingKey> for FullViewingKey

* Add orchard test vectors module

* Pull in and use the Sinsemilla test vectors

* Test Pallas group hashes for Orchard with test vectors

* Move Orchard Arbitrary implementations to arbitrary.rs

* Improvements from code review

* Derive Eq instead of implementing it for SpendAuthorizingKey

* Dedupe Orchard NoteCommitment::extract_x; fix documentation

* Update zebra-chain/src/orchard/note.rs

Co-authored-by: Deirdre Connolly <deirdre@zfnd.org>

Co-authored-by: Conrado P. L. Gouvea <conradoplg@gmail.com>
Co-authored-by: teor <teor@riseup.net>
Co-authored-by: Conrado Gouvea <conrado@zfnd.org>
This commit is contained in:
Deirdre Connolly 2021-07-16 03:52:35 -10:00 committed by GitHub
parent 049c92374e
commit 8a4add55f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 1726 additions and 344 deletions

View File

@ -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::<Network>(),
any::<keys::Diversifier>(),
any::<keys::TransmissionKey>(),
)
.prop_map(|(network, diversifier, transmission_key)| Self {
network,
diversifier,
transmission_key,
})
.boxed()
}
type Strategy = BoxedStrategy<Self>;
}
#[cfg(test)]
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,
};

View File

@ -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<Self>;
}
impl Arbitrary for keys::TransmissionKey {
type Parameters = ();
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
(any::<keys::SpendingKey>())
.prop_map(|spending_key| {
let full_viewing_key = keys::FullViewingKey::from(spending_key);
let diversifier_key = keys::DiversifierKey::from(full_viewing_key);
let diversifier = Diversifier::from(diversifier_key);
let incoming_viewing_key = keys::IncomingViewingKey::from(full_viewing_key);
Self::from((incoming_viewing_key, diversifier))
})
.boxed()
}
type Strategy = BoxedStrategy<Self>;
}
impl Arbitrary for Address {
type Parameters = ();
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
(any::<keys::Diversifier>(), any::<keys::TransmissionKey>())
.prop_map(|(diversifier, transmission_key)| Self {
diversifier,
transmission_key,
})
.boxed()
}
type Strategy = BoxedStrategy<Self>;
}

View File

@ -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<T>(
csprng: &mut T,
diversifier: Diversifier,
transmission_key: TransmissionKey,
value: Amount<NonNegative>,
rho: note::Rho,
psi: note::Psi,
) -> Option<(CommitmentRandomness, Self)>
where
T: RngCore + CryptoRng,
{
pub fn new(note: Note) -> Option<Self> {
// s as in the argument name for WindowedPedersenCommit_r(s)
let mut s: BitVec<Lsb0, u8> = BitVec::new();
@ -138,17 +124,15 @@ impl NoteCommitment {
// The `TryFrom<Diversifier>` 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(
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<Coordinates<pallas::Affine>> = 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())
}
}

View File

@ -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,14 +258,20 @@ impl From<SpendingKey> for SpendAuthorizingKey {
/// <https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents>
/// <https://zips.z.cash/protocol/nu5.pdf#concreteprfs>
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]]));
impl Eq for SpendAuthorizingKey {}
// 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 PartialEq for SpendAuthorizingKey {
fn eq(&self, other: &Self) -> bool {
@ -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<SpendAuth>);
@ -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.
///
/// <https://zips.z.cash/protocol/nu5.pdf#orchardinviewingkeyencoding>
mod ivk_hrp {
pub const MAINNET: &str = "zivko";
pub const TESTNET: &str = "zivktestorchard";
}
/// An incoming viewing key, as described in [protocol specification
/// §4.2.3][ps].
///
/// Used to decrypt incoming notes without spending them.
///
/// [ps]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents
#[derive(Copy, Clone)]
pub struct IncomingViewingKey {
network: Network,
scalar: pallas::Scalar,
}
impl IncomingViewingKey {
/// Generate an _IncomingViewingKey_ from existing bytes and a network variant.
fn from_bytes(bytes: [u8; 32], network: Network) -> Self {
Self {
network,
scalar: pallas::Scalar::from_bytes(&bytes).unwrap(),
}
}
}
impl ConstantTimeEq for IncomingViewingKey {
/// Check whether two `IncomingViewingKey`s are equal, runtime independent
/// of the value of the secret.
///
/// # Note
///
/// This function short-circuits if the networks of the keys are different.
/// Otherwise, it should execute in time independent of the `bytes` value.
fn ct_eq(&self, other: &Self) -> Choice {
if self.network != other.network {
return Choice::from(0);
}
self.scalar.to_bytes().ct_eq(&other.scalar.to_bytes())
}
}
impl fmt::Debug for IncomingViewingKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("IncomingViewingKey")
.field(&hex::encode(self.scalar.to_bytes()))
.finish()
}
}
impl fmt::Display for IncomingViewingKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let hrp = match self.network {
Network::Mainnet => ivk_hrp::MAINNET,
Network::Testnet => ivk_hrp::TESTNET,
};
bech32::encode_to_fmt(f, hrp, &self.scalar.to_bytes().to_base32(), Variant::Bech32).unwrap()
}
}
impl Eq for IncomingViewingKey {}
impl From<FullViewingKey> for IncomingViewingKey {
/// Commit^ivk_rivk(ak, nk) :=
/// SinsemillaShortCommit_rcm ("z.cash:Orchard-CommitIvk", I2LEBSP_l(ak) || I2LEBSP_l(nk)) mod r_P
///
/// <https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents>
/// <https://zips.z.cash/protocol/nu5.pdf#concreteprfs>
#[allow(non_snake_case)]
fn from(fvk: FullViewingKey) -> Self {
let mut M: BitVec<Lsb0, u8> = BitVec::new();
M.extend(<[u8; 32]>::from(fvk.spend_validating_key));
M.extend(<[u8; 32]>::from(fvk.nullifier_deriving_key));
// Commit^ivk_rivk
let commit_x = sinsemilla_short_commit(
fvk.ivk_commit_randomness.into(),
b"z.cash:Orchard-CommitIvk",
&M,
)
.expect("deriving orchard commit^ivk should not output ⊥ ");
Self {
network: fvk.network,
// mod r_P
scalar: pallas::Scalar::from_bytes(&commit_x.into()).unwrap(),
}
}
}
impl PartialEq for IncomingViewingKey {
fn eq(&self, other: &Self) -> bool {
self.ct_eq(other).unwrap_u8() == 1u8
}
}
impl PartialEq<[u8; 32]> for IncomingViewingKey {
fn eq(&self, other: &[u8; 32]) -> bool {
self.scalar.to_bytes().ct_eq(other).unwrap_u8() == 1u8
}
}
/// Magic human-readable strings used to identify what networks Orchard full
/// viewing keys are associated with when encoded/decoded with bech32.
///
/// <https://zips.z.cash/protocol/nu5.pdf#orchardfullviewingkeyencoding>
mod fvk_hrp {
pub const MAINNET: &str = "zviewo";
pub const TESTNET: &str = "zviewtestorchard";
}
/// Full Viewing Keys
/// _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”.
///
/// <https://zips.z.cash/protocol/nu5.pdf#orchardfullviewingkeyencoding>
#[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.
///
/// <https://zips.z.cash/protocol/nu5.pdf#addressesandkeys>
/// <https://zips.z.cash/protocol/nu5.pdf#orchardfullviewingkeyencoding>
pub fn from_spending_key(sk: SpendingKey) -> FullViewingKey {
let spend_authorizing_key = SpendAuthorizingKey::from(sk);
Self {
network: sk.network,
spend_validating_key: SpendValidatingKey::from(spend_authorizing_key),
nullifier_deriving_key: NullifierDerivingKey::from(sk),
ivk_commit_randomness: IvkCommitRandomness::from(sk),
}
}
}
impl ConstantTimeEq for FullViewingKey {
@ -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_.
///
/// <https://zips.z.cash/protocol/protocol.pdf#orchardfullviewingkeyencoding>
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<FullViewingKey> 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<SpendingKey> for FullViewingKey {
/// Derive a _full viewing key_ from a existing _spending key_.
///
/// <https://zips.z.cash/protocol/nu5.pdf#addressesandkeys>
/// <https://zips.z.cash/protocol/nu5.pdf#orchardfullviewingkeyencoding>
fn from(sk: SpendingKey) -> FullViewingKey {
let spend_authorizing_key = SpendAuthorizingKey::from(sk);
Self {
spend_validating_key: SpendValidatingKey::from(spend_authorizing_key),
nullifier_deriving_key: NullifierDerivingKey::from(sk),
ivk_commit_randomness: IvkCommitRandomness::from(sk),
}
}
}
@ -705,6 +586,108 @@ impl PartialEq for FullViewingKey {
}
}
/// An _incoming viewing key_, as described in [protocol specification
/// §4.2.3][ps].
///
/// Used to decrypt incoming notes without spending them.
///
/// [ps]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents
#[derive(Copy, Clone)]
pub struct IncomingViewingKey {
dk: DiversifierKey,
// TODO: refine type
ivk: pallas::Scalar,
}
impl ConstantTimeEq for IncomingViewingKey {
/// Check whether two `IncomingViewingKey`s are equal, runtime independent
/// of the value of the secret.
///
/// # Note
///
/// This function should execute in time independent of the `dk` and `ivk` values.
fn ct_eq(&self, other: &Self) -> Choice {
<[u8; 64]>::from(*self).ct_eq(&<[u8; 64]>::from(*other))
}
}
impl fmt::Debug for IncomingViewingKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("IncomingViewingKey")
.field("dk", &self.dk)
.field("ivk", &self.ivk)
.finish()
}
}
impl fmt::Display for IncomingViewingKey {
/// The _raw encoding_ of an **Orchard** _incoming viewing key_.
///
/// <https://zips.z.cash/protocol/protocol.pdf#orchardfullviewingkeyencoding>
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(&hex::encode(<[u8; 64]>::from(*self)))
}
}
impl Eq for IncomingViewingKey {}
impl From<IncomingViewingKey> for [u8; 64] {
fn from(ivk: IncomingViewingKey) -> [u8; 64] {
let mut bytes = [0u8; 64];
bytes[..32].copy_from_slice(&<[u8; 32]>::from(ivk.dk));
bytes[32..].copy_from_slice(&<[u8; 32]>::from(ivk.ivk));
bytes
}
}
impl From<FullViewingKey> for IncomingViewingKey {
/// Commit^ivk_rivk(ak, nk) :=
/// SinsemillaShortCommit_rcm(
/// "z.cash:Orchard-CommitIvk",
/// I2LEBSP_l^Orchard_base(ak) || I2LEBSP_l^Orchard_base(nk)
/// ) mod r_P
///
/// <https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents>
/// <https://zips.z.cash/protocol/nu5.pdf#concreteprfs>
#[allow(non_snake_case)]
fn from(fvk: FullViewingKey) -> Self {
let mut M: BitVec<Lsb0, u8> = BitVec::new();
// I2LEBSP_l^Orchard_base(ak)
let ak_bytes =
extract_p(pallas::Point::from_bytes(&fvk.spend_validating_key.into()).unwrap())
.to_bytes();
M.extend_from_bitslice(&BitArray::<Lsb0, _>::from(ak_bytes)[0..255]);
// I2LEBSP_l^Orchard_base(nk)
let nk_bytes: [u8; 32] = fvk.nullifier_deriving_key.into();
M.extend_from_bitslice(&BitArray::<Lsb0, _>::from(nk_bytes)[0..255]);
// Commit^ivk_rivk
// rivk needs to be 255 bits long
let commit_x = sinsemilla_short_commit(
fvk.ivk_commit_randomness.into(),
b"z.cash:Orchard-CommitIvk",
&M,
)
.expect("deriving orchard commit^ivk should not output ⊥ ");
Self {
dk: fvk.into(),
// mod r_P
ivk: pallas::Scalar::from_bytes(&commit_x.into()).unwrap(),
}
}
}
impl PartialEq for IncomingViewingKey {
fn eq(&self, other: &Self) -> bool {
self.ct_eq(other).unwrap_u8() == 1u8
}
}
/// An outgoing viewing key, as described in [protocol specification
/// §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.
///
/// <https://zips.z.cash/protocol/nu5.pdf#saplingandorchardencrypt>
// TODO: derive `OutgoingCipherKey`: https://github.com/ZcashFoundation/zebra/issues/2041
#[derive(Copy, Clone, PartialEq)]
pub struct OutgoingCipherKey([u8; 32]);
impl fmt::Debug for OutgoingCipherKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("OutgoingCipherKey")
.field(&hex::encode(self.0))
.finish()
}
}
impl From<&OutgoingCipherKey> for [u8; 32] {
fn from(ock: &OutgoingCipherKey) -> [u8; 32] {
ock.0
}
}
// TODO: implement PrivateKey: #2192
/// An ephemeral private key for Orchard key agreement.
///
/// <https://zips.z.cash/protocol/nu5.pdf#concreteorchardkeyagreement>
/// <https://zips.z.cash/protocol/nu5.pdf#saplingandorchardencrypt>
#[derive(Copy, Clone, Debug)]
pub struct EphemeralPrivateKey(pub(crate) pallas::Scalar);
impl ConstantTimeEq for EphemeralPrivateKey {
/// Check whether two `EphemeralPrivateKey`s are equal, runtime independent
/// of the value of the secret.
fn ct_eq(&self, other: &Self) -> Choice {
self.0.to_bytes().ct_eq(&other.0.to_bytes())
}
}
impl Eq for EphemeralPrivateKey {}
impl From<EphemeralPrivateKey> for [u8; 32] {
fn from(esk: EphemeralPrivateKey) -> Self {
esk.0.to_bytes()
}
}
impl PartialEq for EphemeralPrivateKey {
fn eq(&self, other: &Self) -> bool {
self.ct_eq(other).unwrap_u8() == 1u8
}
}
impl PartialEq<[u8; 32]> for EphemeralPrivateKey {
fn eq(&self, other: &[u8; 32]) -> bool {
self.0.to_bytes().ct_eq(other).unwrap_u8() == 1u8
}
}
/// An ephemeral public key for Orchard key agreement.
///
/// <https://zips.z.cash/protocol/nu5.pdf#concreteorchardkeyagreement>
@ -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.
///
/// <https://zips.z.cash/protocol/nu5.pdf#saplingandorchardencrypt>
#[derive(Copy, Clone, PartialEq)]
pub struct OutgoingCipherKey([u8; 32]);
impl fmt::Debug for OutgoingCipherKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("OutgoingCipherKey")
.field(&hex::encode(self.0))
.finish()
}
}
impl From<&OutgoingCipherKey> for [u8; 32] {
fn from(ock: &OutgoingCipherKey) -> [u8; 32] {
ock.0
}
}
// TODO: derive `OutgoingCipherKey`: https://github.com/ZcashFoundation/zebra/issues/2041

View File

@ -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::<SpendingKey>())
.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 spend_authorizing_key = SpendAuthorizingKey::from(spending_key);
assert_eq!(spend_authorizing_key, test_vector.ask);
let spend_validating_key = SpendValidatingKey::from(spend_authorizing_key);
assert_eq!(<[u8; 32]>::from(spend_validating_key), test_vector.ak);
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);
let incoming_viewing_key = IncomingViewingKey::from(full_viewing_key);
assert_eq!(diversifier, test_vector.default_d);
Self::from((incoming_viewing_key, diversifier))
})
.boxed()
let transmission_key = TransmissionKey::from((incoming_viewing_key, diversifier));
assert_eq!(transmission_key, test_vector.default_pk_d);
}
}
type Strategy = BoxedStrategy<Self>;
}
#[cfg(test)]
proptest! {
#[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);

View File

@ -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<T>(csprng: &mut T) -> Self
where
T: RngCore + CryptoRng,
{
let mut bytes = [0u8; 32];
csprng.fill_bytes(&mut bytes);
Self(bytes)
}
}
/// Used as input to PRF^nf as part of deriving the _nullifier_ of the _note_.
///
/// When creating a new note from spending an old note, the new note's _rho_ is
@ -47,6 +52,12 @@ impl From<Rho> for [u8; 32] {
}
}
impl From<Nullifier> for Rho {
fn from(nf: Nullifier) -> Self {
Self(nf.0)
}
}
impl Rho {
pub fn new<T>(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
/// <https://zips.z.cash/protocol/nu5.pdf#orchardsend>
#[derive(Clone, Debug)]
pub struct Psi(pub(crate) pallas::Base);
@ -74,7 +85,7 @@ impl From<Psi> for [u8; 32] {
impl From<SeedRandomness> for Psi {
/// rcm = ToScalar^Orchard((PRF^expand_rseed ([9]))
///
/// https://zips.z.cash/protocol/nu5.pdf#orchardsend
/// <https://zips.z.cash/protocol/nu5.pdf#orchardsend>
fn from(rseed: SeedRandomness) -> Self {
Self(pallas::Base::from_bytes_wide(&prf_expand(
rseed.0,
@ -83,25 +94,43 @@ impl From<SeedRandomness> 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.
///
/// <https://zips.z.cash/protocol/protocol.pdf#notes>
#[derive(Clone, Debug)]
pub struct Note {
/// The _diversifer_ of the recipients _shielded payment address_.
pub diversifier: Diversifier,
/// The _diversified transmission key_ of the recipients 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<NonNegative>,
/// Used as input to PRF^nf as part of deriving the _nullifier_ of the _note_.
/// Used as input to PRF^nfOrchard_nk as part of deriving the _nullifier_ of
/// the _note_.
pub rho: Rho,
/// 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.
///
/// <https://zips.z.cash/protocol/protocol.pdf#notes>
pub fn new<T>(
csprng: &mut T,
address: Address,
value: Amount<NonNegative>,
nf_old: Nullifier,
) -> Self
where
T: RngCore + CryptoRng,
{
Self {
address,
value,
rho: nf_old.into(),
rseed: SeedRandomness::new(csprng),
}
}
}

View File

@ -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<H: Hasher>(&self, state: &mut H) {
@ -79,18 +82,19 @@ impl From<(NullifierDerivingKey, Note, NoteCommitment)> for Nullifier {
///
/// DeriveNullifier_nk(ρ, ψ, cm) = Extract_P( [ (PRF^nfOrchard_nk(ρ) + ψ) mod q_P ] K^Orchard + cm)
///
/// https://zips.z.cash/protocol/nu5.pdf#commitmentsandnullifiers
/// <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))

View File

@ -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<Lsb0, u8> = &tv.msg.iter().collect();
assert_eq!(
sinsemilla_hash_to_point(D, M).expect("should not fail per Theorem 5.4.4"),
pallas::Point::from_bytes(&tv.point).unwrap()
);
assert_eq!(
sinsemilla_hash(D, M).expect("should not fail per Theorem 5.4.4"),
pallas::Base::from_bytes(&tv.hash).unwrap()
)
}
}
// Checks Pallas group hashes with:
// - One of two domains.
// - Random message lengths between 0 and 255 bytes.
// - Random message contents.
#[test]
#[allow(non_snake_case)]
fn hackworks_group_hash_test_vectors() {
use group::GroupEncoding;
for tv in tests::vectors::GROUP_HASHES.iter() {
let D = tv.domain.as_slice();
let M = tv.msg.as_slice();
assert_eq!(
pallas_group_hash(D, M),
pallas::Point::from_bytes(&tv.point).unwrap()
);
}
}
}

View File

@ -1,4 +1,4 @@
mod preallocate;
mod prop;
mod test_vectors;
mod tree;
pub(crate) mod vectors;

View File

@ -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)
);
}
}

View File

@ -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};

View File

@ -0,0 +1,225 @@
use lazy_static::lazy_static;
pub struct TestVector {
pub(crate) domain: Vec<u8>,
pub(crate) msg: Vec<u8>,
pub(crate) point: [u8; 32],
}
// From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/orchard_group_hash.py
lazy_static! {
pub static ref GROUP_HASHES: [TestVector; 11] = [
TestVector {
domain: vec![0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74],
msg: vec![
0x54, 0x72, 0x61, 0x6e, 0x73, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x20, 0x6e,
0x6f, 0x77, 0x21
],
point: [
0xd3, 0x6b, 0x0b, 0x64, 0x9b, 0x5c, 0x69, 0x36, 0x02, 0x7a, 0x18, 0x0f, 0x7d, 0x25,
0x40, 0x23, 0x95, 0x6f, 0xc2, 0x88, 0x3d, 0xdf, 0x23, 0xff, 0xc3, 0xc8, 0xfd, 0x1f,
0xa3, 0xcd, 0x18, 0x18
],
},
TestVector {
domain: vec![
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6c, 0x6f,
0x6e, 0x67, 0x65, 0x72
],
msg: vec![
0x8f, 0x73, 0x9a, 0x2d, 0x9e, 0x94, 0x5b, 0x0c, 0xe1, 0x52, 0xa8, 0x04, 0x9e, 0x29,
0x4c, 0x4d, 0x6e, 0x66, 0xb1, 0x64, 0x93, 0x9d, 0xaf, 0xfa, 0x2e, 0xf6, 0xee, 0x69,
0x21, 0x48, 0x1c, 0xdd, 0x86, 0xb3, 0xcc, 0x43, 0x18, 0xd9, 0x61, 0x4f, 0xc8, 0x20,
0x90, 0x5d, 0x04, 0x2b, 0xb1, 0xef, 0x9c, 0xa3, 0xf2, 0x49, 0x88, 0xc7, 0xb3, 0x53,
0x42, 0x01, 0xcf, 0xb1, 0xcd, 0x8d, 0xbf, 0x69, 0xb8, 0x25, 0x0c, 0x18, 0xef, 0x41,
0x29, 0x4c, 0xa9, 0x79, 0x93, 0xdb, 0x54, 0x6c, 0x1f, 0xe0, 0x1f, 0x7e, 0x9c, 0x8e,
0x36, 0xd6, 0xa5, 0xe2, 0x9d, 0x4e, 0x30, 0xa7, 0x35, 0x94, 0xbf, 0x50, 0x98, 0x42,
0x1c, 0x69, 0x37, 0x8a, 0xf1, 0xe4, 0x0f, 0x64, 0xe1, 0x25, 0x94, 0x6f, 0x62, 0xc2,
0xfa, 0x7b, 0x2f, 0xec, 0xbc, 0xb6, 0x4b, 0x69, 0x68, 0x91
],
point: [
0xd3, 0x60, 0x3e, 0x4f, 0x26, 0x67, 0xe7, 0x7c, 0x77, 0x24, 0x8f, 0xd5, 0xbe, 0x8d,
0x80, 0x77, 0x23, 0xd7, 0x27, 0xe2, 0x2f, 0xc4, 0xa1, 0x1d, 0x1f, 0xf5, 0x57, 0xdd,
0x61, 0xdd, 0x4d, 0xb4
],
},
TestVector {
domain: vec![0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74],
msg: vec![
0x81, 0xce, 0x3d, 0xc1, 0x66, 0xd5, 0x6a, 0x1d, 0x62, 0xf5, 0xa8, 0xd7, 0x55, 0x1d,
0xb5, 0xfd, 0x93, 0x13, 0xe8, 0xc7, 0x20, 0x3d, 0x99, 0x6a, 0xf7, 0xd4, 0x77, 0x08,
0x37, 0x56, 0xd5, 0x9a, 0xf8, 0x0d, 0x06, 0xa7, 0x45, 0xf4, 0x4a, 0xb0, 0x23, 0x75,
0x2c, 0xb5, 0xb4, 0x06, 0xed, 0x89, 0x85, 0xe1, 0x81, 0x30, 0xab, 0x33, 0x36, 0x26,
0x97, 0xb0, 0xe4, 0xe4, 0xc7, 0x63, 0xcc, 0xb8, 0xf6, 0x76, 0x49, 0x5c, 0x22, 0x2f,
0x7f, 0xba, 0x1e, 0x31, 0xde, 0xfa, 0x3d, 0x5a, 0x57, 0xef, 0xc2, 0xe1, 0xe9, 0xb0,
0x1a, 0x03, 0x55, 0x87, 0xd5, 0xfb, 0x1a, 0x38, 0xe0, 0x1d, 0x94, 0x90, 0x3d, 0x3c,
0x3e
],
point: [
0xf6, 0x1d, 0x4d, 0xe9, 0x90, 0x7a, 0x65, 0x93, 0xd4, 0xc6, 0xb6, 0x42, 0x47, 0x5f,
0x51, 0xca, 0x28, 0x93, 0xfc, 0xcf, 0x9c, 0x48, 0xf5, 0x28, 0x2d, 0xf2, 0x5c, 0x9b,
0xb6, 0xda, 0xd9, 0x03
],
},
TestVector {
domain: vec![0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74],
msg: vec![
0x36, 0x0c, 0x1d, 0x37, 0x10, 0xac, 0xd2, 0x0b, 0x18, 0x3e, 0x31, 0xd4, 0x9f, 0x25,
0xc9, 0xa1, 0x38, 0xf4, 0x9b, 0x1a, 0x53, 0x7e, 0xdc, 0xf0, 0x4b, 0xe3, 0x4a, 0x98,
0x51, 0xa7, 0xaf, 0x9d, 0xb6, 0x99, 0x0e, 0xd8, 0x3d, 0xd6, 0x4a, 0xf3, 0x59, 0x7c,
0x04, 0x32, 0x3e, 0xa5, 0x1b, 0x00, 0x52, 0xad, 0x80, 0x84, 0xa8, 0xb9, 0xda, 0x94,
0x8d, 0x32, 0x0d, 0xad, 0xd6, 0x4f, 0x54, 0x31, 0xe6, 0x1d, 0xdf, 0x65, 0x8d, 0x24,
0xae, 0x67, 0xc2, 0x2c, 0x8d, 0x13, 0x09, 0x13, 0x1f, 0xc0, 0x0f, 0xe7, 0xf2, 0x35,
0x73, 0x42, 0x76, 0xd3, 0x8d, 0x47, 0xf1, 0xe1, 0x91, 0xe0, 0x0c, 0x7a, 0x1d, 0x48,
0xaf, 0x04, 0x68, 0x27, 0x59, 0x1e, 0x97, 0x33, 0xa9, 0x7f, 0xa6, 0xb6, 0x79, 0xf3,
0xdc, 0x60, 0x1d, 0x00, 0x82, 0x85, 0xed, 0xcb, 0xda, 0xe6, 0x9c, 0xe8, 0xfc, 0x1b,
0xe4, 0xaa, 0xc0, 0x0f, 0xf2, 0x71, 0x1e, 0xbd, 0x93, 0x1d, 0xe5, 0x18, 0x85, 0x68,
0x78, 0xf7, 0x34, 0x76, 0xf2, 0x1a, 0x48, 0x2e, 0xc9, 0x37, 0x83, 0x65, 0xc8, 0xf7,
0x39, 0x3c, 0x94, 0xe2, 0x88, 0x53, 0x15, 0xeb, 0x46, 0x71, 0x09, 0x8b, 0x79, 0x53,
0x5e, 0x79, 0x0f, 0xe5, 0x3e, 0x29, 0xfe, 0xf2, 0xb3, 0x76, 0x66, 0x97, 0xac, 0x32,
0xb4, 0xf4, 0x73, 0xf4, 0x68, 0xa0, 0x08, 0xe7, 0x23, 0x89, 0xfc, 0x03, 0x88, 0x0d,
0x78, 0x0c, 0xb0, 0x7f, 0xcf, 0xaa, 0xbe, 0x3f, 0x1a, 0x84, 0xb2, 0x7d, 0xb5, 0x9a,
0x4a
],
point: [
0xe9, 0xdc, 0xf5, 0xfd, 0x98, 0xcb, 0x6f, 0xd4, 0xfd, 0xc0, 0xf8, 0xf9, 0xdd, 0x46,
0x2d, 0x59, 0xe1, 0xde, 0x9c, 0x69, 0xc6, 0x04, 0x2d, 0x1a, 0xee, 0x40, 0xd1, 0xb5,
0xf8, 0x2e, 0xf9, 0x34
],
},
TestVector {
domain: vec![
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6c, 0x6f,
0x6e, 0x67, 0x65, 0x72
],
msg: vec![
0x88, 0x2d, 0x2b, 0x21, 0x03, 0x59, 0x65, 0x55, 0xed, 0x94, 0x94, 0xc6, 0xac, 0x89,
0x3c, 0x49, 0x72, 0x38, 0x33, 0xec, 0x89, 0x26, 0xc1, 0x03, 0x95, 0x86, 0xa7, 0xaf,
0xcf, 0x4a, 0x0d, 0x9c, 0x73, 0x1e, 0x98, 0x5d, 0x99, 0x58, 0x9c, 0x8b, 0xb8, 0x38,
0xe8, 0xaa, 0xf7, 0x45, 0x53, 0x3e, 0xd9, 0xe8, 0xae, 0x3a, 0x1c, 0xd0, 0x74, 0xa5,
0x1a, 0x20, 0xda, 0x8a, 0xba
],
point: [
0xf3, 0x8c, 0xb5, 0xe1, 0x60, 0x7c, 0x71, 0x22, 0xce, 0xf7, 0x31, 0xc8, 0xe6, 0x18,
0x75, 0xb8, 0xc1, 0xf3, 0xe2, 0xec, 0x06, 0xc5, 0x9e, 0x9c, 0xca, 0xdb, 0xd3, 0xa2,
0xca, 0xe8, 0x68, 0x3f
],
},
TestVector {
domain: vec![0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74],
msg: vec![
0xdb, 0xeb, 0xbc, 0x86, 0x2d, 0xed, 0x42, 0x43, 0x5e, 0x92, 0x47, 0x69, 0x30, 0xd0,
0x69, 0x89, 0x6c, 0xff, 0x30, 0xeb, 0x41, 0x4f, 0x72, 0x7b, 0x89, 0xe0, 0x01, 0xaf,
0xa2, 0xfb, 0x8d, 0xc3, 0x43, 0x6d, 0x75, 0xa4, 0xa6, 0xf2, 0x65, 0x72, 0x50, 0x4b,
0x19, 0x22, 0x32, 0xec, 0xb9, 0xf0, 0xc0, 0x24, 0x11, 0xe5, 0x25, 0x96, 0xbc, 0x5e,
0x90, 0x45, 0x7e, 0x74, 0x59, 0x39, 0xff, 0xed, 0xbd, 0x12, 0x86, 0x3c, 0xe7, 0x1a,
0x02, 0xaf, 0x11, 0x7d, 0x41, 0x7a, 0xdb, 0x3d, 0x15, 0xcc, 0x54, 0xdc, 0xb1, 0xfc,
0xe4, 0x67, 0x50, 0x0c, 0x6b, 0x8f, 0xb8, 0x6b, 0x12, 0xb5, 0x6d, 0xa9, 0xc3, 0x82,
0x85, 0x7d, 0xee, 0xcc, 0x40, 0xa9, 0x8d, 0x5f, 0x29, 0x35, 0x39, 0x5e, 0xe4, 0x76,
0x2d, 0xd2, 0x1a, 0xfd, 0xbb, 0x5d, 0x47, 0xfa, 0x9a, 0x6d, 0xd9, 0x84, 0xd5, 0x67,
0xdb, 0x28, 0x57, 0xb9, 0x27, 0xb7, 0xfa, 0xe2, 0xdb, 0x58, 0x71, 0x05, 0x41, 0x5d,
0x46, 0x42, 0x78, 0x9d, 0x38, 0xf5, 0x0b, 0x8d, 0xbc, 0xc1, 0x29, 0xca, 0xb3, 0xd1,
0x7d, 0x19, 0xf3, 0x35, 0x5b, 0xcf, 0x73, 0xce, 0xcb, 0x8c, 0xb8, 0xa5, 0xda, 0x01,
0x30, 0x71, 0x52, 0xf1, 0x39, 0x36, 0xa2, 0x70, 0x57, 0x26, 0x70, 0xdc, 0x82, 0xd3,
0x90, 0x26, 0xc6, 0xcb, 0x4c, 0xd4, 0xb0, 0xf7, 0xf5, 0xaa, 0x2a, 0x4f, 0x5a, 0x53,
0x41, 0xec, 0x5d, 0xd7, 0x15, 0x40, 0x6f, 0x2f, 0xdd, 0x2a, 0xfa, 0x73, 0x3f
],
point: [
0x3d, 0xec, 0x03, 0x28, 0x60, 0xf1, 0xa8, 0x51, 0x51, 0x6a, 0xf3, 0x7b, 0x68, 0xac,
0xcc, 0xf3, 0x6e, 0x2a, 0x80, 0xbe, 0x13, 0xee, 0x36, 0x7e, 0xac, 0x1a, 0xac, 0x72,
0x5d, 0xbc, 0xf6, 0x85
],
},
TestVector {
domain: vec![
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6c, 0x6f,
0x6e, 0x67, 0x65, 0x72
],
msg: vec![
0x1c, 0x8c, 0x21, 0x86, 0x2a, 0x1b, 0xaf, 0xce, 0x26, 0x09, 0xd9, 0xee, 0xcf, 0xa1,
0x58, 0xcf, 0xb5, 0xcd, 0x79, 0xf8, 0x80, 0x08, 0xe3, 0x15, 0xdc, 0x7d, 0x83, 0x88,
0xe7, 0x6c, 0x17, 0x82, 0xfd, 0x27, 0x95, 0xd1, 0x8a, 0x76, 0x36, 0x24, 0xc2, 0x5f,
0xa9, 0x59, 0xcc, 0x97, 0x48, 0x9c, 0xe7, 0x57, 0x45, 0x82, 0x4b, 0x77, 0x86, 0x8c,
0x53, 0x23, 0x9c, 0xfb, 0xdf, 0x73, 0xca, 0xec, 0x65, 0x60, 0x40, 0x37, 0x31, 0x4f,
0xaa, 0xce, 0xb5, 0x62, 0x18, 0xc6, 0xbd, 0x30, 0xf8, 0x37, 0x4a, 0xc1, 0x33, 0x86,
0x79, 0x3f, 0x21, 0xa9, 0xfb, 0x80, 0xad, 0x03, 0xbc, 0x0c, 0xda, 0x4a, 0x44, 0x94,
0x6c, 0x00
],
point: [
0xae, 0x52, 0x88, 0x72, 0xf0, 0x6c, 0xc1, 0x79, 0xa1, 0x54, 0xee, 0xc2, 0xdd, 0xf7,
0x4d, 0xcf, 0x5c, 0x49, 0xc4, 0x11, 0x5c, 0x6a, 0xb7, 0x4d, 0x7f, 0x31, 0x6e, 0x46,
0xb1, 0x64, 0x8e, 0x19
],
},
TestVector {
domain: vec![
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6c, 0x6f,
0x6e, 0x67, 0x65, 0x72
],
msg: vec![
0xa1, 0xdf, 0x0e, 0x5b, 0x87, 0xb5, 0xbe, 0xce, 0x47, 0x7a, 0x70, 0x96, 0x49, 0xe9,
0x50, 0x06, 0x05, 0x91, 0x39, 0x48, 0x12, 0x95, 0x1e, 0x1f, 0xe3, 0x89, 0x5b, 0x8c,
0xc3, 0xd1, 0x4d, 0x2c, 0xf6, 0x55, 0x6d, 0xf6, 0xed, 0x4b, 0x4d, 0xdd, 0x3d, 0x9a,
0x69, 0xf5, 0x33, 0x57, 0xd7, 0x76, 0x7f, 0x4f, 0x5c, 0xcb, 0xdb, 0xc5, 0x96, 0x63,
0x12, 0x77, 0xf8, 0xfe, 0xcd, 0x08, 0xcb, 0x05, 0x6b, 0x95, 0xe3, 0x02, 0x5b, 0x97,
0x92, 0xff, 0xf7, 0xf2, 0x44, 0xfc, 0x71, 0x62, 0x69, 0xb9, 0x26, 0xd6, 0x2e, 0x95,
0x96, 0xfa, 0x82, 0x5c, 0x6b, 0xf2, 0x1a, 0xff, 0x9e, 0x68, 0x62, 0x5a, 0x19, 0x24,
0x40, 0xea, 0x06, 0x82, 0x81, 0x23, 0xd9, 0x78, 0x84, 0x80, 0x6f, 0x15, 0xfa, 0x08,
0xda, 0x52, 0x75, 0x4a, 0x10, 0x95, 0xe3, 0xff, 0x1a, 0xbd, 0x5c, 0xe4, 0xfd, 0xdf,
0xcc, 0xfc, 0x3a, 0x61, 0x28, 0xae, 0xf7, 0x84, 0xa6, 0x46, 0x10, 0xa8, 0x9d, 0x1a,
0x70, 0x99, 0x21, 0x6d, 0x08, 0x14, 0xd3, 0xa2, 0xd4, 0x52, 0x43, 0x1c, 0x32, 0xd4,
0x11, 0xac, 0x1c, 0xce, 0x82, 0xad, 0x02, 0x29, 0x40, 0x7b, 0xbc, 0x48, 0x98, 0x56,
0x75, 0xe3, 0xf8, 0x74, 0xa4, 0x53, 0x3f, 0x1d, 0x63
],
point: [
0xcc, 0x90, 0x4e, 0x5e, 0x31, 0x83, 0x4b, 0x4f, 0x85, 0xd6, 0xa6, 0x62, 0xc5, 0x4e,
0x7d, 0xaa, 0x8d, 0x3e, 0x34, 0xce, 0x22, 0x42, 0x8c, 0x3e, 0x8a, 0x53, 0xcc, 0x6e,
0xe8, 0x33, 0x87, 0xa9
],
},
TestVector {
domain: vec![0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74],
msg: vec![
0xfa, 0x3e, 0x0f, 0x46, 0x0f, 0xe2, 0xf5, 0x7e, 0x34, 0xfb, 0xc7, 0x54, 0x23, 0xc3,
0x73, 0x7f, 0x5b, 0x2a, 0x06, 0x15, 0xf5, 0x72, 0x2d, 0xb0, 0x41, 0xa3, 0xef, 0x66,
0xfa, 0x48, 0x3a, 0xfd, 0x3c, 0x2e, 0x19, 0xe5, 0x94, 0x44, 0xa6, 0x4a, 0xdd, 0x6d,
0xf1, 0xd9, 0x63, 0xf5, 0xdd, 0x5b, 0x50, 0x10, 0xd3, 0xd0, 0x25, 0xf0, 0x28, 0x7c,
0x4c, 0xf1, 0x9c, 0x75, 0xf3, 0x3d, 0x51, 0xdd, 0xdd, 0xba, 0x5d, 0x65, 0x7b, 0x43,
0xee, 0x8d, 0xa6, 0x45, 0x44, 0x38, 0x14
],
point: [
0xb0, 0x5e, 0xb0, 0xcc, 0x20, 0xef, 0x29, 0xfd, 0xb9, 0xf5, 0x8f, 0x6b, 0x55, 0x99,
0x11, 0x4d, 0x1b, 0xf8, 0x21, 0x49, 0x7a, 0xf7, 0xc1, 0x07, 0xea, 0x0b, 0xdf, 0xf9,
0x74, 0xf1, 0x7f, 0x3b
],
},
TestVector {
domain: vec![0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74],
msg: vec![
0x29, 0xf3, 0xe9, 0xb4, 0xe5, 0x4c, 0x23, 0x6c, 0x29, 0xaf, 0x39, 0x23, 0x10, 0x17,
0x56, 0xd9, 0xfa, 0x4b, 0xd0, 0xf7, 0xd2, 0xdd, 0xaa, 0xcb, 0x6b, 0x0f, 0x86, 0xa2,
0x65, 0x8e, 0x0a, 0x07, 0xa0, 0x5a, 0xc5, 0xb9, 0x50, 0x05, 0x1c, 0xd2, 0x4c, 0x47,
0xa8, 0x8d, 0x13, 0xd6, 0x59, 0xba, 0x2a, 0x46, 0xca, 0x18, 0x30, 0x81, 0x6d, 0x09,
0xcd, 0x76, 0x46, 0xf7, 0x6f, 0x71, 0x6a, 0xbe, 0xc5, 0xde, 0x07, 0xfe, 0x9b, 0x52,
0x34, 0x10, 0x80, 0x6e, 0xa6, 0xf2, 0x88, 0xf8, 0x73, 0x6c, 0x23, 0x35, 0x7c, 0x85,
0xf4, 0x57, 0x91, 0xe1, 0x70, 0x80, 0x29, 0xd9, 0x82, 0x4d, 0x90, 0x70, 0x46, 0x07,
0xf3, 0x87, 0xa0, 0x3e, 0x49, 0xbf, 0x98, 0x36, 0x57, 0x44, 0x31, 0x34, 0x5a, 0x78,
0x77, 0xef, 0xaa
],
point: [
0x52, 0x71, 0xbe, 0xd5, 0x91, 0x13, 0x39, 0xa7, 0xc6, 0x17, 0x97, 0xa9, 0x9e, 0x87,
0xc6, 0xb4, 0xcd, 0x85, 0xae, 0x10, 0xd0, 0xd4, 0xaa, 0x7e, 0x7a, 0xdb, 0x07, 0x49,
0x81, 0x63, 0x05, 0xae
],
},
TestVector {
domain: vec![0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74],
msg: vec![0xe7, 0x30, 0x81, 0xef, 0x8d, 0x62, 0xcb, 0x78],
point: [
0xb6, 0x17, 0x44, 0xc0, 0xc7, 0x0d, 0x65, 0x4c, 0x02, 0x53, 0x70, 0x55, 0x7a, 0xac,
0x7f, 0xbe, 0x42, 0x1a, 0x49, 0x70, 0x77, 0x18, 0xba, 0x90, 0xff, 0x7d, 0x9e, 0xbd,
0xc5, 0x1d, 0x19, 0x19
],
},
];
}

View File

@ -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,
],
},
];

View File

@ -0,0 +1,316 @@
use lazy_static::lazy_static;
pub struct TestVector {
pub(crate) domain: Vec<u8>,
pub(crate) msg: Vec<bool>,
pub(crate) point: [u8; 32],
pub(crate) hash: [u8; 32],
}
// From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/orchard_sinsemilla.py
lazy_static! {
pub static ref SINSEMILLA: [TestVector; 11] = [
TestVector {
domain: vec![
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61,
],
msg: vec![
false, false, false, true, false, true, true, false, true, false, true, false,
false, true, true, false, false, false, true, true, false, true, true, false,
false, false, true, true, false, true, true, false, true, true, true, true, false,
true, true, false,
],
point: [
0x98, 0x54, 0xaa, 0x38, 0x43, 0x63, 0xb5, 0x70, 0x8e, 0x06, 0xb4, 0x19, 0xb6, 0x43,
0x58, 0x68, 0x39, 0x65, 0x3f, 0xba, 0x5a, 0x78, 0x2d, 0x2d, 0xb1, 0x4c, 0xed, 0x13,
0xc1, 0x9a, 0x83, 0xab,
],
hash: [
0x98, 0x54, 0xaa, 0x38, 0x43, 0x63, 0xb5, 0x70, 0x8e, 0x06, 0xb4, 0x19, 0xb6, 0x43,
0x58, 0x68, 0x39, 0x65, 0x3f, 0xba, 0x5a, 0x78, 0x2d, 0x2d, 0xb1, 0x4c, 0xed, 0x13,
0xc1, 0x9a, 0x83, 0x2b,
],
},
TestVector {
domain: vec![
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61, 0x2d, 0x6c, 0x6f, 0x6e, 0x67, 0x65,
0x72,
],
msg: vec![
true, true, false, true, false, false, true, false, true, false, false, false,
false, true, false, true, false, false, true, false, true, true, true, false,
false, false, false, true, true, false, false, true, false, true, false, true,
false, true, true, true, false, false, false, true, false, true, true, true, false,
true, false, true, false, true, true, true, false, true, true, true, true, true,
true, true, false, true, false, false, true, true, true, false, true, true, true,
true, false, false, true, false, true, false, false, false, false, false, true,
false, true, false, false, true, true, false, true, false, false, false, false,
true, true, false, true, false, true, false, true, true, false, true, false, false,
false, true, true, false, false, false, true, true, false, true,
],
point: [
0xed, 0x5b, 0x98, 0x8e, 0x4e, 0x98, 0x17, 0x1f, 0x61, 0x8f, 0xee, 0xb1, 0x23, 0xe5,
0xcd, 0x0d, 0xc2, 0xd3, 0x67, 0x11, 0xc5, 0x06, 0xd5, 0xbe, 0x11, 0x5c, 0xfe, 0x38,
0x8f, 0x03, 0xc4, 0x80,
],
hash: [
0xed, 0x5b, 0x98, 0x8e, 0x4e, 0x98, 0x17, 0x1f, 0x61, 0x8f, 0xee, 0xb1, 0x23, 0xe5,
0xcd, 0x0d, 0xc2, 0xd3, 0x67, 0x11, 0xc5, 0x06, 0xd5, 0xbe, 0x11, 0x5c, 0xfe, 0x38,
0x8f, 0x03, 0xc4, 0x00,
],
},
TestVector {
domain: vec![
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61,
],
msg: vec![
true, false, true, true, false, true, false, true, false, true, false, true, true,
true, true, true, true, true, false, true, false, true, true, false, true, false,
true, false, true, false, true, false, false, true, false, true, true, false,
false, false, true, true, false, true, false, false, true, true, true, true, true,
false, true, true, false, false, true, false, false, false, true, true, false,
false, false, false, true, false, false, true, true, false, false, true, false,
false, true, false, true, true, false, true, true, false, false, true, true, true,
true, true, false, false, false, true, false, false, true, false, false,
],
point: [
0xd9, 0x5e, 0xe5, 0x8f, 0xbd, 0xaa, 0x6f, 0x3d, 0xe5, 0xe4, 0xfd, 0x7a, 0xfc, 0x35,
0xfa, 0x9d, 0xcf, 0xe8, 0x2a, 0xd1, 0x93, 0x06, 0xb0, 0x7e, 0x6c, 0xda, 0x0c, 0x30,
0xe5, 0x98, 0x34, 0x07,
],
hash: [
0xd9, 0x5e, 0xe5, 0x8f, 0xbd, 0xaa, 0x6f, 0x3d, 0xe5, 0xe4, 0xfd, 0x7a, 0xfc, 0x35,
0xfa, 0x9d, 0xcf, 0xe8, 0x2a, 0xd1, 0x93, 0x06, 0xb0, 0x7e, 0x6c, 0xda, 0x0c, 0x30,
0xe5, 0x98, 0x34, 0x07,
],
},
TestVector {
domain: vec![
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61,
],
msg: vec![
false, false, true, true, false, false, false, true, false, false, true, false,
true, true, true, true, false, false, true, false, true, false, false, false, true,
true, false, false, true, true, true, true, false, true, false, false, true, false,
false, true, true, false, false, false, false, true, true, false, false, true,
false, false, false, true, false, false, true, false, true, true, false, true,
false, true, false, true, true, true, true, false, false, true, false, false, true,
true, true, true, true, false, true, true, false, true, true, false, false, true,
true, true, true, true, true, false, false, false, true, false, true, false, false,
true, true, false, true, true, true, true, false, false, true, true, false, false,
true, false, false, true, true, true, false, false, false, false, false, true,
false, false, false, true, false, true, false, true, true, true, true, false, true,
false, false, true, false, false, false, false, false, false, true, true, true,
true, false, true, true, false, false, false, false, true, true, true, false, true,
true, true, true, true, false, true, true, true, false, true, false, false, true,
false, false, true, false, false, false, false, true, false, false, false, false,
true, true, true, false, true, false, true, false, false, false, true, true, false,
false, true, false, false, false, true, true, false, false,
],
point: [
0x6a, 0x92, 0x4b, 0x41, 0x39, 0x84, 0x29, 0x91, 0x0a, 0x78, 0x83, 0x2b, 0x61, 0x19,
0x2a, 0x0b, 0x67, 0x40, 0xd6, 0x27, 0x77, 0xeb, 0x71, 0x54, 0x50, 0x32, 0xeb, 0x6c,
0xe9, 0x3e, 0xc9, 0xb8,
],
hash: [
0x6a, 0x92, 0x4b, 0x41, 0x39, 0x84, 0x29, 0x91, 0x0a, 0x78, 0x83, 0x2b, 0x61, 0x19,
0x2a, 0x0b, 0x67, 0x40, 0xd6, 0x27, 0x77, 0xeb, 0x71, 0x54, 0x50, 0x32, 0xeb, 0x6c,
0xe9, 0x3e, 0xc9, 0x38,
],
},
TestVector {
domain: vec![
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61, 0x2d, 0x6c, 0x6f, 0x6e, 0x67, 0x65,
0x72,
],
msg: vec![
false, true, true, true, true, true, true, true, true, false, false, false, false,
true, false, true, false, false, true, false, true, false, true, true, true, false,
true, true, true, false, true, false, true, false, false, true, true, false, false,
true, false, false, false, false, true, true, true, false, true, false, false,
false, false, false, false, true, false, false, false, false, false,
],
point: [
0xdc, 0x5f, 0xf0, 0x5b, 0x6f, 0x18, 0xb0, 0x76, 0xb6, 0x12, 0x82, 0x37, 0xa7, 0x59,
0xed, 0xc7, 0xc8, 0x77, 0x8c, 0x70, 0x22, 0x2c, 0x79, 0xb7, 0x34, 0x03, 0x7b, 0x69,
0x39, 0x3a, 0xbf, 0xbe,
],
hash: [
0xdc, 0x5f, 0xf0, 0x5b, 0x6f, 0x18, 0xb0, 0x76, 0xb6, 0x12, 0x82, 0x37, 0xa7, 0x59,
0xed, 0xc7, 0xc8, 0x77, 0x8c, 0x70, 0x22, 0x2c, 0x79, 0xb7, 0x34, 0x03, 0x7b, 0x69,
0x39, 0x3a, 0xbf, 0x3e,
],
},
TestVector {
domain: vec![
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61,
],
msg: vec![
true, true, false, false, true, true, false, true, false, false, true, true, false,
false, true, true, false, true, false, true, true, true, false, true, true, false,
true, true, false, true, true, true, true, true, true, false, false, false, true,
false, false, true, true, false, false, false, true, false, false, false, true,
true, true, false, false, false, false, true, false, false, true, true, true, true,
true, false, false, false, true, false, false, true, true, true, true, false, true,
true, true, false, false, false, true, false, false, true, false, false, true,
true, false, true, false, true, true, true, true, false, true, true, false, false,
false, true, true, true, true, true, true, false, false, false, true, false, false,
true, true, true, true, false, false, true, true, false, true, true, true, false,
true, true, true, true, false, false, true, false, true, true, true, true, false,
false, false, true, false, true, true, true, false, true, true, false, true, true,
true, true, true, true, true, true, true, false, true, false, false, true, false,
true, false, true, false, true, true, false, false, false, true, false, false,
false, false, true, false, false, false, true, false, false, false, true, true,
false, false, true, false, true, true, false, true, true, true, false, true, true,
true, false, false, true, true,
],
point: [
0xc7, 0x6c, 0x8d, 0x7c, 0x43, 0x55, 0x04, 0x1b, 0xd7, 0xa7, 0xc9, 0x9b, 0x54, 0x86,
0x44, 0x19, 0x6f, 0x41, 0x94, 0x56, 0x20, 0x75, 0x37, 0xc2, 0x82, 0x85, 0x8a, 0x9b,
0x19, 0x2d, 0x07, 0xbb,
],
hash: [
0xc7, 0x6c, 0x8d, 0x7c, 0x43, 0x55, 0x04, 0x1b, 0xd7, 0xa7, 0xc9, 0x9b, 0x54, 0x86,
0x44, 0x19, 0x6f, 0x41, 0x94, 0x56, 0x20, 0x75, 0x37, 0xc2, 0x82, 0x85, 0x8a, 0x9b,
0x19, 0x2d, 0x07, 0x3b,
],
},
TestVector {
domain: vec![
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61, 0x2d, 0x6c, 0x6f, 0x6e, 0x67, 0x65,
0x72,
],
msg: vec![
false, false, true, false, false, true, true, false, false, true, true, false,
true, true, false, true, true, true, true, false, false, false, true, true, false,
true, true, false, true, false, true, false, true, true, true, true, false, false,
false, false, false, true, true, true, false, true, false, false, true, true, true,
false, true, true, false, false, true, true, false, true, true, true, false, false,
true, false, false, true, true, true, false, false, true, false, false, false,
true, false, false, true, false, true, true, false, true, true, true, true, true,
false, true, true, false, false, false, false, false, false, false, false,
],
point: [
0x1a, 0xe8, 0x25, 0xeb, 0x42, 0xd7, 0x4e, 0x1b, 0xca, 0x7e, 0xe8, 0xa1, 0xf8, 0xf3,
0xde, 0xd8, 0x01, 0xff, 0xcd, 0x1f, 0x22, 0xba, 0x75, 0xc3, 0x4b, 0xd6, 0xe0, 0x6a,
0x2c, 0x7c, 0x5a, 0xa0,
],
hash: [
0x1a, 0xe8, 0x25, 0xeb, 0x42, 0xd7, 0x4e, 0x1b, 0xca, 0x7e, 0xe8, 0xa1, 0xf8, 0xf3,
0xde, 0xd8, 0x01, 0xff, 0xcd, 0x1f, 0x22, 0xba, 0x75, 0xc3, 0x4b, 0xd6, 0xe0, 0x6a,
0x2c, 0x7c, 0x5a, 0x20,
],
},
TestVector {
domain: vec![
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61, 0x2d, 0x6c, 0x6f, 0x6e, 0x67, 0x65,
0x72,
],
msg: vec![
true, true, false, true, true, true, false, false, true, false, false, false, true,
true, false, false, true, true, true, false, false, true, false, true, true, true,
true, false, true, true, true, false, false, true, true, false, true, true, true,
true, true, false, true, true, true, true, true, false, true, true, false, true,
true, true, false, true, false, true, false, false, true, false, true, true, true,
true, true, false, true, true, false, true, true, false, false, false, true, false,
true, true, false, false, false, true, false, false, false, false, true, false,
false, true, false, false, false, false, true, false, false, false, false, false,
true, true, true, false, false, false, true, true, false, false, false, false,
true, false, false, true, true, true, false, true, false, false, true, true, false,
false, false, true, false, false, true, false, false, false, false, false, true,
false, false, true, true, true, false, false, true, false, false, false, true,
false, false, false, true, false, false, false, false, true, false, true, false,
true, false, false, false, false, true, true, false, false, false, true, true,
true, true,
],
point: [
0x38, 0xcf, 0xa6, 0x00, 0xaf, 0xd8, 0x67, 0x0e, 0x1f, 0x9a, 0x79, 0xcb, 0x22, 0x42,
0x5f, 0xa9, 0x50, 0xcc, 0x4d, 0x3a, 0x3f, 0x5a, 0xfe, 0x39, 0x76, 0xd7, 0x1b, 0xb1,
0x11, 0x46, 0x0c, 0x2b,
],
hash: [
0x38, 0xcf, 0xa6, 0x00, 0xaf, 0xd8, 0x67, 0x0e, 0x1f, 0x9a, 0x79, 0xcb, 0x22, 0x42,
0x5f, 0xa9, 0x50, 0xcc, 0x4d, 0x3a, 0x3f, 0x5a, 0xfe, 0x39, 0x76, 0xd7, 0x1b, 0xb1,
0x11, 0x46, 0x0c, 0x2b,
],
},
TestVector {
domain: vec![
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61,
],
msg: vec![
false, false, true, false, true, false, true, false, false, true, true, false,
true, true, true, true, true, false, false, true, true, false, true, false, true,
true, true, false, false, false, false, true, false, false, true, true, false,
false, false, false, true, true, true, true, true, true, true, true, false, false,
true, false, true, false, false, false, false, true, false, true, true, true, true,
true, true, false, true, true, true, true, false, true, false, true, false, false,
false,
],
point: [
0x82, 0x6f, 0xcb, 0xed, 0xfc, 0x83, 0xb9, 0xfa, 0xa5, 0x71, 0x1a, 0xab, 0x59, 0xbf,
0xc9, 0x1b, 0xd4, 0x45, 0x58, 0x14, 0x67, 0x72, 0x5d, 0xde, 0x94, 0x1d, 0x58, 0xe6,
0x26, 0x56, 0x66, 0x15,
],
hash: [
0x82, 0x6f, 0xcb, 0xed, 0xfc, 0x83, 0xb9, 0xfa, 0xa5, 0x71, 0x1a, 0xab, 0x59, 0xbf,
0xc9, 0x1b, 0xd4, 0x45, 0x58, 0x14, 0x67, 0x72, 0x5d, 0xde, 0x94, 0x1d, 0x58, 0xe6,
0x26, 0x56, 0x66, 0x15,
],
},
TestVector {
domain: vec![
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61,
],
msg: vec![
true, true, true, false, true, false, true, false, true, true, true, true, false,
true, false, true, false, true, false, true, false, true, false, true, true, true,
false, false, true, false, false, true, false, false, true, true, false, true,
false, false, false, true, false, true, true, false, true, false, false, false,
false, false, false, true, true, true, true, false, false, true, true, true, false,
false, true, false, true, false, true, false, false, false, false, false, false,
false, false, false, true, false, true, true, false, true, false, true, true, true,
false, false, true, true, false, true, false, false, false, true, true, true,
false, false, true, true, false, false, true, false, true, false, false, false,
true, true, false,
],
point: [
0x0b, 0xf0, 0x6c, 0xe8, 0x10, 0x05, 0xb8, 0x1a, 0x14, 0x80, 0x9f, 0xa6, 0xeb, 0xcb,
0x94, 0xe2, 0xb6, 0x37, 0x5f, 0x87, 0xce, 0x51, 0x95, 0x8c, 0x94, 0x98, 0xed, 0x1a,
0x31, 0x3c, 0x6a, 0x94,
],
hash: [
0x0b, 0xf0, 0x6c, 0xe8, 0x10, 0x05, 0xb8, 0x1a, 0x14, 0x80, 0x9f, 0xa6, 0xeb, 0xcb,
0x94, 0xe2, 0xb6, 0x37, 0x5f, 0x87, 0xce, 0x51, 0x95, 0x8c, 0x94, 0x98, 0xed, 0x1a,
0x31, 0x3c, 0x6a, 0x14,
],
},
TestVector {
domain: vec![
0x7a, 0x2e, 0x63, 0x61, 0x73, 0x68, 0x3a, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x69,
0x6e, 0x73, 0x65, 0x6d, 0x69, 0x6c, 0x6c, 0x61,
],
msg: vec![true, false, true, true, true, false, true, false],
point: [
0x80, 0x6a, 0xcc, 0x24, 0x7a, 0xc9, 0xba, 0x90, 0xd2, 0x5f, 0x58, 0x3d, 0xad, 0xb5,
0xe0, 0xee, 0x5c, 0x03, 0xe1, 0xab, 0x35, 0x70, 0xb3, 0x62, 0xb4, 0xbe, 0x5a, 0x8b,
0xce, 0xb6, 0x0b, 0x00,
],
hash: [
0x80, 0x6a, 0xcc, 0x24, 0x7a, 0xc9, 0xba, 0x90, 0xd2, 0x5f, 0x58, 0x3d, 0xad, 0xb5,
0xe0, 0xee, 0x5c, 0x03, 0xe1, 0xab, 0x35, 0x70, 0xb3, 0x62, 0xb4, 0xbe, 0x5a, 0x8b,
0xce, 0xb6, 0x0b, 0x00,
],
},
];
}