mirror of https://github.com/zcash/orchard.git
AssetBase spec update (#44)
- Renamed AssetId to AssetBase - Changed the AssetBase implementation to support the zip update. - Updated visibility for various members of issuance.rs
This commit is contained in:
parent
cbf0a3a651
commit
43d5e77d38
|
@ -6,7 +6,7 @@ use criterion::{BenchmarkId, Criterion};
|
|||
#[cfg(unix)]
|
||||
use pprof::criterion::{Output, PProfProfiler};
|
||||
|
||||
use orchard::note::AssetId;
|
||||
use orchard::note::AssetBase;
|
||||
use orchard::{
|
||||
builder::Builder,
|
||||
bundle::Flags,
|
||||
|
@ -37,7 +37,7 @@ fn criterion_benchmark(c: &mut Criterion) {
|
|||
None,
|
||||
recipient,
|
||||
NoteValue::from_raw(10),
|
||||
AssetId::native(),
|
||||
AssetBase::native(),
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
|
|
@ -4,7 +4,7 @@ use orchard::{
|
|||
bundle::Flags,
|
||||
circuit::ProvingKey,
|
||||
keys::{FullViewingKey, PreparedIncomingViewingKey, Scope, SpendingKey},
|
||||
note::AssetId,
|
||||
note::AssetBase,
|
||||
note_encryption_v3::{CompactAction, OrchardDomainV3},
|
||||
value::NoteValue,
|
||||
Anchor, Bundle,
|
||||
|
@ -57,7 +57,7 @@ fn bench_note_decryption(c: &mut Criterion) {
|
|||
None,
|
||||
recipient,
|
||||
NoteValue::from_raw(10),
|
||||
AssetId::native(),
|
||||
AssetBase::native(),
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -66,7 +66,7 @@ fn bench_note_decryption(c: &mut Criterion) {
|
|||
None,
|
||||
recipient,
|
||||
NoteValue::from_raw(10),
|
||||
AssetId::native(),
|
||||
AssetBase::native(),
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
|
|
@ -126,7 +126,7 @@ pub(crate) mod testing {
|
|||
|
||||
use proptest::prelude::*;
|
||||
|
||||
use crate::note::asset_id::testing::arb_asset_id;
|
||||
use crate::note::asset_base::testing::arb_asset_id;
|
||||
use crate::{
|
||||
note::{
|
||||
commitment::ExtractedNoteCommitment, nullifier::testing::arb_nullifier,
|
||||
|
|
|
@ -9,7 +9,7 @@ use nonempty::NonEmpty;
|
|||
use pasta_curves::pallas;
|
||||
use rand::{prelude::SliceRandom, CryptoRng, RngCore};
|
||||
|
||||
use crate::note::AssetId;
|
||||
use crate::note::AssetBase;
|
||||
use crate::{
|
||||
action::Action,
|
||||
address::Address,
|
||||
|
@ -99,7 +99,7 @@ impl SpendInfo {
|
|||
/// Defined in [Zcash Protocol Spec § 4.8.3: Dummy Notes (Orchard)][orcharddummynotes].
|
||||
///
|
||||
/// [orcharddummynotes]: https://zips.z.cash/protocol/nu5.pdf#orcharddummynotes
|
||||
fn dummy(asset: AssetId, rng: &mut impl RngCore) -> Self {
|
||||
fn dummy(asset: AssetBase, rng: &mut impl RngCore) -> Self {
|
||||
let (sk, fvk, note) = Note::dummy(rng, None, asset);
|
||||
let merkle_path = MerklePath::dummy(rng);
|
||||
|
||||
|
@ -127,7 +127,7 @@ struct RecipientInfo {
|
|||
ovk: Option<OutgoingViewingKey>,
|
||||
recipient: Address,
|
||||
value: NoteValue,
|
||||
asset: AssetId,
|
||||
asset: AssetBase,
|
||||
memo: Option<[u8; 512]>,
|
||||
}
|
||||
|
||||
|
@ -135,7 +135,7 @@ impl RecipientInfo {
|
|||
/// Defined in [Zcash Protocol Spec § 4.8.3: Dummy Notes (Orchard)][orcharddummynotes].
|
||||
///
|
||||
/// [orcharddummynotes]: https://zips.z.cash/protocol/nu5.pdf#orcharddummynotes
|
||||
fn dummy(rng: &mut impl RngCore, asset: AssetId) -> Self {
|
||||
fn dummy(rng: &mut impl RngCore, asset: AssetBase) -> Self {
|
||||
let fvk: FullViewingKey = (&SpendingKey::random(rng)).into();
|
||||
let recipient = fvk.address_at(0u32, Scope::External);
|
||||
|
||||
|
@ -253,7 +253,7 @@ impl ActionInfo {
|
|||
pub struct Builder {
|
||||
spends: Vec<SpendInfo>,
|
||||
recipients: Vec<RecipientInfo>,
|
||||
burn: HashMap<AssetId, ValueSum>,
|
||||
burn: HashMap<AssetBase, ValueSum>,
|
||||
flags: Flags,
|
||||
anchor: Anchor,
|
||||
}
|
||||
|
@ -323,7 +323,7 @@ impl Builder {
|
|||
ovk: Option<OutgoingViewingKey>,
|
||||
recipient: Address,
|
||||
value: NoteValue,
|
||||
asset: AssetId,
|
||||
asset: AssetBase,
|
||||
memo: Option<[u8; 512]>,
|
||||
) -> Result<(), &'static str> {
|
||||
if !self.flags.outputs_enabled() {
|
||||
|
@ -342,7 +342,7 @@ impl Builder {
|
|||
}
|
||||
|
||||
/// Add an instruction to burn a given amount of a specific asset.
|
||||
pub fn add_burn(&mut self, asset: AssetId, value: NoteValue) -> Result<(), &'static str> {
|
||||
pub fn add_burn(&mut self, asset: AssetBase, value: NoteValue) -> Result<(), &'static str> {
|
||||
if asset.is_native().into() {
|
||||
return Err("Burning is only possible for non-native assets");
|
||||
}
|
||||
|
@ -481,7 +481,7 @@ fn partition_by_asset(
|
|||
spends: &[SpendInfo],
|
||||
recipients: &[RecipientInfo],
|
||||
rng: &mut impl RngCore,
|
||||
) -> HashMap<AssetId, (Vec<SpendInfo>, Vec<RecipientInfo>)> {
|
||||
) -> HashMap<AssetBase, (Vec<SpendInfo>, Vec<RecipientInfo>)> {
|
||||
let mut hm = HashMap::new();
|
||||
|
||||
for s in spends {
|
||||
|
@ -499,7 +499,7 @@ fn partition_by_asset(
|
|||
}
|
||||
|
||||
if hm.is_empty() {
|
||||
let dummy_spend = SpendInfo::dummy(AssetId::native(), rng);
|
||||
let dummy_spend = SpendInfo::dummy(AssetBase::native(), rng);
|
||||
hm.insert(dummy_spend.note.asset(), (vec![dummy_spend], vec![]));
|
||||
}
|
||||
|
||||
|
@ -770,7 +770,7 @@ pub mod testing {
|
|||
use proptest::collection::vec;
|
||||
use proptest::prelude::*;
|
||||
|
||||
use crate::note::AssetId;
|
||||
use crate::note::AssetBase;
|
||||
use crate::{
|
||||
address::testing::arb_address,
|
||||
bundle::{Authorized, Bundle, Flags},
|
||||
|
@ -798,7 +798,7 @@ pub mod testing {
|
|||
sk: SpendingKey,
|
||||
anchor: Anchor,
|
||||
notes: Vec<(Note, MerklePath)>,
|
||||
recipient_amounts: Vec<(Address, NoteValue, AssetId)>,
|
||||
recipient_amounts: Vec<(Address, NoteValue, AssetBase)>,
|
||||
}
|
||||
|
||||
impl<R: RngCore + CryptoRng> ArbitraryBundleInputs<R> {
|
||||
|
@ -852,7 +852,7 @@ pub mod testing {
|
|||
arb_address().prop_flat_map(move |a| {
|
||||
arb_positive_note_value(MAX_NOTE_VALUE / n_recipients as u64)
|
||||
.prop_map(move |v| {
|
||||
(a,v, AssetId::native())
|
||||
(a,v, AssetBase::native())
|
||||
})
|
||||
}),
|
||||
n_recipients as usize,
|
||||
|
@ -904,7 +904,7 @@ mod tests {
|
|||
use rand::rngs::OsRng;
|
||||
|
||||
use super::Builder;
|
||||
use crate::note::AssetId;
|
||||
use crate::note::AssetBase;
|
||||
use crate::{
|
||||
bundle::{Authorized, Bundle, Flags},
|
||||
circuit::ProvingKey,
|
||||
|
@ -933,7 +933,7 @@ mod tests {
|
|||
None,
|
||||
recipient,
|
||||
NoteValue::from_raw(5000),
|
||||
AssetId::native(),
|
||||
AssetBase::native(),
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
|
|
@ -12,7 +12,7 @@ use memuse::DynamicUsage;
|
|||
use nonempty::NonEmpty;
|
||||
use zcash_note_encryption::{try_note_decryption, try_output_recovery_with_ovk};
|
||||
|
||||
use crate::note::AssetId;
|
||||
use crate::note::AssetBase;
|
||||
use crate::{
|
||||
action::Action,
|
||||
address::Address,
|
||||
|
@ -142,7 +142,7 @@ pub struct Bundle<T: Authorization, V> {
|
|||
value_balance: V,
|
||||
/// Assets intended for burning
|
||||
/// TODO We need to add a consensus check to make sure that it is impossible to burn ZEC.
|
||||
burn: Vec<(AssetId, V)>,
|
||||
burn: Vec<(AssetBase, V)>,
|
||||
/// The root of the Orchard commitment tree that this bundle commits to.
|
||||
anchor: Anchor,
|
||||
/// The authorization for this bundle.
|
||||
|
@ -175,7 +175,7 @@ impl<T: Authorization, V> Bundle<T, V> {
|
|||
actions: NonEmpty<Action<T::SpendAuth>>,
|
||||
flags: Flags,
|
||||
value_balance: V,
|
||||
burn: Vec<(AssetId, V)>,
|
||||
burn: Vec<(AssetBase, V)>,
|
||||
anchor: Anchor,
|
||||
authorization: T,
|
||||
) -> Self {
|
||||
|
@ -232,7 +232,7 @@ impl<T: Authorization, V> Bundle<T, V> {
|
|||
.burn
|
||||
.into_iter()
|
||||
.map(|(asset, value)| Ok((asset, f(value)?)))
|
||||
.collect::<Result<Vec<(AssetId, V0)>, E>>()?,
|
||||
.collect::<Result<Vec<(AssetBase, V0)>, E>>()?,
|
||||
anchor: self.anchor,
|
||||
authorization: self.authorization,
|
||||
})
|
||||
|
@ -397,7 +397,7 @@ impl<T: Authorization, V: Copy + Into<i64>> Bundle<T, V> {
|
|||
- ValueCommitment::derive(
|
||||
ValueSum::from_raw(self.value_balance.into()),
|
||||
ValueCommitTrapdoor::zero(),
|
||||
AssetId::native(),
|
||||
AssetBase::native(),
|
||||
)
|
||||
- self
|
||||
.burn
|
||||
|
@ -527,8 +527,8 @@ pub mod testing {
|
|||
use super::{Action, Authorization, Authorized, Bundle, Flags};
|
||||
|
||||
pub use crate::action::testing::{arb_action, arb_unauthorized_action};
|
||||
use crate::note::asset_id::testing::arb_zsa_asset_id;
|
||||
use crate::note::AssetId;
|
||||
use crate::note::asset_base::testing::arb_zsa_asset_id;
|
||||
use crate::note::AssetBase;
|
||||
use crate::value::testing::arb_value_sum;
|
||||
|
||||
/// Marker for an unauthorized bundle with no proofs or signatures.
|
||||
|
@ -595,7 +595,7 @@ pub mod testing {
|
|||
(
|
||||
asset_id in arb_zsa_asset_id(),
|
||||
value in arb_value_sum()
|
||||
) -> (AssetId, ValueSum) {
|
||||
) -> (AssetBase, ValueSum) {
|
||||
(asset_id, value)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ use crate::{
|
|||
note::{
|
||||
commitment::{NoteCommitTrapdoor, NoteCommitment},
|
||||
nullifier::Nullifier,
|
||||
AssetId, ExtractedNoteCommitment, Note,
|
||||
AssetBase, ExtractedNoteCommitment, Note,
|
||||
},
|
||||
primitives::redpallas::{SpendAuth, VerificationKey},
|
||||
spec::NonIdentityPallasPoint,
|
||||
|
@ -109,7 +109,7 @@ pub struct Circuit {
|
|||
pub(crate) psi_old: Value<pallas::Base>,
|
||||
pub(crate) rcm_old: Value<NoteCommitTrapdoor>,
|
||||
pub(crate) cm_old: Value<NoteCommitment>,
|
||||
pub(crate) asset_old: Value<AssetId>,
|
||||
pub(crate) asset_old: Value<AssetBase>,
|
||||
pub(crate) alpha: Value<pallas::Scalar>,
|
||||
pub(crate) ak: Value<SpendValidatingKey>,
|
||||
pub(crate) nk: Value<NullifierDerivingKey>,
|
||||
|
@ -119,7 +119,7 @@ pub struct Circuit {
|
|||
pub(crate) v_new: Value<NoteValue>,
|
||||
pub(crate) psi_new: Value<pallas::Base>,
|
||||
pub(crate) rcm_new: Value<NoteCommitTrapdoor>,
|
||||
pub(crate) asset_new: Value<AssetId>,
|
||||
pub(crate) asset_new: Value<AssetBase>,
|
||||
pub(crate) rcv: Value<ValueCommitTrapdoor>,
|
||||
pub(crate) split_flag: Value<bool>,
|
||||
}
|
||||
|
@ -1034,7 +1034,7 @@ mod tests {
|
|||
|
||||
use super::{Circuit, Instance, Proof, ProvingKey, VerifyingKey, K};
|
||||
use crate::keys::{IssuanceAuthorizingKey, IssuanceValidatingKey, SpendingKey};
|
||||
use crate::note::AssetId;
|
||||
use crate::note::AssetBase;
|
||||
use crate::{
|
||||
keys::SpendValidatingKey,
|
||||
note::Note,
|
||||
|
@ -1043,7 +1043,7 @@ mod tests {
|
|||
};
|
||||
|
||||
fn generate_circuit_instance<R: RngCore>(mut rng: R) -> (Circuit, Instance) {
|
||||
let (_, fvk, spent_note) = Note::dummy(&mut rng, None, AssetId::native());
|
||||
let (_, fvk, spent_note) = Note::dummy(&mut rng, None, AssetBase::native());
|
||||
|
||||
let sender_address = spent_note.recipient();
|
||||
let nk = *fvk.nk();
|
||||
|
@ -1053,12 +1053,12 @@ mod tests {
|
|||
let alpha = pallas::Scalar::random(&mut rng);
|
||||
let rk = ak.randomize(&alpha);
|
||||
|
||||
let (_, _, output_note) = Note::dummy(&mut rng, Some(nf_old), AssetId::native());
|
||||
let (_, _, output_note) = Note::dummy(&mut rng, Some(nf_old), AssetBase::native());
|
||||
let cmx = output_note.commitment().into();
|
||||
|
||||
let value = spent_note.value() - output_note.value();
|
||||
let rcv = ValueCommitTrapdoor::random(&mut rng);
|
||||
let cv_net = ValueCommitment::derive(value, rcv, AssetId::native());
|
||||
let cv_net = ValueCommitment::derive(value, rcv, AssetBase::native());
|
||||
|
||||
let path = MerklePath::dummy(&mut rng);
|
||||
let anchor = path.root(spent_note.commitment().into());
|
||||
|
@ -1175,7 +1175,7 @@ mod tests {
|
|||
let isk = IssuanceAuthorizingKey::from(&sk);
|
||||
let ik = IssuanceValidatingKey::from(&isk);
|
||||
let asset_descr = "zsa_asset";
|
||||
AssetId::derive(&ik, asset_descr)
|
||||
AssetBase::derive(&ik, asset_descr)
|
||||
};
|
||||
circuit.asset_new = Value::known(random_asset_id);
|
||||
|
||||
|
|
|
@ -21,11 +21,11 @@ pub const ORCHARD_PERSONALIZATION: &str = "z.cash:Orchard";
|
|||
/// SWU hash-to-curve personalization for the value commitment generator
|
||||
pub const VALUE_COMMITMENT_PERSONALIZATION: &str = "z.cash:Orchard-cv";
|
||||
|
||||
/// SWU hash-to-curve personalization for the note type generator
|
||||
// pub const ASSET_ID_PERSONALIZATION: &str = "z.cash:Orchard-NoteType";
|
||||
/// SWU hash-to-curve personalization for the ZSA asset base generator
|
||||
pub const ZSA_ASSET_BASE_PERSONALIZATION: &str = "z.cash:OrchardZSA";
|
||||
|
||||
/// SWU hash-to-curve value for the value commitment generator
|
||||
pub const VALUE_COMMITMENT_V_BYTES: [u8; 1] = *b"v";
|
||||
pub const NATIVE_ASSET_BASE_V_BYTES: [u8; 1] = *b"v";
|
||||
|
||||
/// SWU hash-to-curve value for the value commitment generator
|
||||
pub const VALUE_COMMITMENT_R_BYTES: [u8; 1] = *b"r";
|
||||
|
|
101
src/issuance.rs
101
src/issuance.rs
|
@ -12,8 +12,10 @@ use crate::issuance::Error::{
|
|||
IssueBundleInvalidSignature, WrongAssetDescSize,
|
||||
};
|
||||
use crate::keys::{IssuanceAuthorizingKey, IssuanceValidatingKey};
|
||||
use crate::note::asset_id::is_asset_desc_of_valid_size;
|
||||
use crate::note::{AssetId, Nullifier};
|
||||
use crate::note::asset_base::is_asset_desc_of_valid_size;
|
||||
use crate::note::{AssetBase, Nullifier};
|
||||
use crate::primitives::redpallas::Signature;
|
||||
|
||||
use crate::value::NoteValue;
|
||||
use crate::{
|
||||
primitives::redpallas::{self, SpendAuth},
|
||||
|
@ -21,7 +23,7 @@ use crate::{
|
|||
};
|
||||
|
||||
/// A bundle of actions to be applied to the ledger.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct IssueBundle<T: IssueAuth> {
|
||||
/// The issuer key for the note being created.
|
||||
ik: IssuanceValidatingKey,
|
||||
|
@ -81,11 +83,11 @@ impl IssueAction {
|
|||
self.finalize
|
||||
}
|
||||
|
||||
/// Return the `AssetId` if the provided `ik` is used to derive the `asset_id` for **all** internal notes.
|
||||
/// Return the `AssetBase` if the provided `ik` is used to derive the `asset_id` for **all** internal notes.
|
||||
fn are_note_asset_ids_derived_correctly(
|
||||
&self,
|
||||
ik: &IssuanceValidatingKey,
|
||||
) -> Result<AssetId, Error> {
|
||||
) -> Result<AssetBase, Error> {
|
||||
match self
|
||||
.notes
|
||||
.iter()
|
||||
|
@ -97,7 +99,7 @@ impl IssueAction {
|
|||
.ok_or(IssueActionIncorrectNoteType)
|
||||
}) {
|
||||
Ok(asset) => asset // check that the asset was properly derived.
|
||||
.eq(&AssetId::derive(ik, &self.asset_desc))
|
||||
.eq(&AssetBase::derive(ik, &self.asset_desc))
|
||||
.then(|| asset)
|
||||
.ok_or(IssueBundleIkMismatchNoteType),
|
||||
Err(e) => Err(e),
|
||||
|
@ -106,20 +108,20 @@ impl IssueAction {
|
|||
}
|
||||
|
||||
/// Defines the authorization type of an Issue bundle.
|
||||
pub trait IssueAuth: fmt::Debug {}
|
||||
pub trait IssueAuth: fmt::Debug + Clone {}
|
||||
|
||||
/// Marker for an unauthorized bundle with no proofs or signatures.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Unauthorized;
|
||||
|
||||
/// Marker for an unauthorized bundle with injected sighash.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Prepared {
|
||||
sighash: [u8; 32],
|
||||
}
|
||||
|
||||
/// Marker for an authorized bundle.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Signed {
|
||||
signature: redpallas::Signature<SpendAuth>,
|
||||
}
|
||||
|
@ -129,6 +131,11 @@ impl Signed {
|
|||
pub fn signature(&self) -> &redpallas::Signature<SpendAuth> {
|
||||
&self.signature
|
||||
}
|
||||
|
||||
/// Constructs an `Signed` from its constituent parts.
|
||||
pub fn from_parts(signature: Signature<SpendAuth>) -> Self {
|
||||
Signed { signature }
|
||||
}
|
||||
}
|
||||
|
||||
impl IssueAuth for Unauthorized {}
|
||||
|
@ -163,11 +170,11 @@ impl<T: IssueAuth> IssueBundle<T> {
|
|||
}
|
||||
|
||||
/// Find an action by `asset` for a given `IssueBundle`.
|
||||
pub fn get_action_by_type(&self, asset: AssetId) -> Option<&IssueAction> {
|
||||
pub fn get_action_by_type(&self, asset: AssetBase) -> Option<&IssueAction> {
|
||||
let action = self
|
||||
.actions
|
||||
.iter()
|
||||
.find(|a| AssetId::derive(&self.ik, &a.asset_desc).eq(&asset));
|
||||
.find(|a| AssetBase::derive(&self.ik, &a.asset_desc).eq(&asset));
|
||||
action
|
||||
}
|
||||
|
||||
|
@ -176,6 +183,19 @@ impl<T: IssueAuth> IssueBundle<T> {
|
|||
pub fn commitment(&self) -> IssueBundleCommitment {
|
||||
IssueBundleCommitment(hash_issue_bundle_txid_data(self))
|
||||
}
|
||||
|
||||
/// Constructs an `IssueBundle` from its constituent parts.
|
||||
pub fn from_parts(
|
||||
ik: IssuanceValidatingKey,
|
||||
actions: Vec<IssueAction>,
|
||||
authorization: T,
|
||||
) -> Self {
|
||||
IssueBundle {
|
||||
ik,
|
||||
actions,
|
||||
authorization,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IssueBundle<Unauthorized> {
|
||||
|
@ -202,12 +222,12 @@ impl IssueBundle<Unauthorized> {
|
|||
value: NoteValue,
|
||||
finalize: bool,
|
||||
mut rng: impl RngCore,
|
||||
) -> Result<AssetId, Error> {
|
||||
) -> Result<AssetBase, Error> {
|
||||
if !is_asset_desc_of_valid_size(&asset_desc) {
|
||||
return Err(WrongAssetDescSize);
|
||||
}
|
||||
|
||||
let asset = AssetId::derive(&self.ik, &asset_desc);
|
||||
let asset = AssetBase::derive(&self.ik, &asset_desc);
|
||||
|
||||
let note = Note::new(
|
||||
recipient,
|
||||
|
@ -335,26 +355,26 @@ impl IssueBundle<Signed> {
|
|||
/// Validation for Orchard IssueBundles
|
||||
///
|
||||
/// A set of previously finalized asset types must be provided.
|
||||
/// In case of success, `finalized` will contain a set of the provided **and** the newly finalized `AssetId`s
|
||||
/// In case of success, `finalized` will contain a set of the provided **and** the newly finalized `AssetBase`s
|
||||
///
|
||||
/// The following checks are performed:
|
||||
/// * For the `IssueBundle`:
|
||||
/// * the Signature on top of the provided `sighash` verifies correctly.
|
||||
/// * For each `IssueAction`:
|
||||
/// * Asset description size is collect.
|
||||
/// * `AssetId` for the `IssueAction` has not been previously finalized.
|
||||
/// * `AssetBase` for the `IssueAction` has not been previously finalized.
|
||||
/// * For each `Note` inside an `IssueAction`:
|
||||
/// * All notes have the same, correct `AssetId`.
|
||||
/// * All notes have the same, correct `AssetBase`.
|
||||
pub fn verify_issue_bundle(
|
||||
bundle: &IssueBundle<Signed>,
|
||||
sighash: [u8; 32],
|
||||
finalized: &mut HashSet<AssetId>, // The finalization set.
|
||||
finalized: &mut HashSet<AssetBase>, // The finalization set.
|
||||
) -> Result<(), Error> {
|
||||
if let Err(e) = bundle.ik.verify(&sighash, &bundle.authorization.signature) {
|
||||
return Err(IssueBundleInvalidSignature(e));
|
||||
};
|
||||
|
||||
let s = &mut HashSet::<AssetId>::new();
|
||||
let s = &mut HashSet::<AssetBase>::new();
|
||||
|
||||
let newly_finalized = bundle
|
||||
.actions()
|
||||
|
@ -403,7 +423,7 @@ pub enum Error {
|
|||
/// Invalid signature.
|
||||
IssueBundleInvalidSignature(reddsa::Error),
|
||||
/// The provided `NoteType` has been previously finalized.
|
||||
IssueActionPreviouslyFinalizedNoteType(AssetId),
|
||||
IssueActionPreviouslyFinalizedNoteType(AssetBase),
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {}
|
||||
|
@ -454,7 +474,7 @@ mod tests {
|
|||
use crate::keys::{
|
||||
FullViewingKey, IssuanceAuthorizingKey, IssuanceValidatingKey, Scope, SpendingKey,
|
||||
};
|
||||
use crate::note::{AssetId, Nullifier};
|
||||
use crate::note::{AssetBase, Nullifier};
|
||||
use crate::value::NoteValue;
|
||||
use crate::{Address, Note};
|
||||
use nonempty::NonEmpty;
|
||||
|
@ -561,7 +581,7 @@ mod tests {
|
|||
|
||||
bundle
|
||||
.add_recipient(
|
||||
String::from("Precious NFT"),
|
||||
String::from("NFT"),
|
||||
recipient,
|
||||
NoteValue::from_raw(u64::MIN),
|
||||
false,
|
||||
|
@ -570,13 +590,13 @@ mod tests {
|
|||
.expect("Should properly add recipient");
|
||||
|
||||
bundle
|
||||
.finalize_action(String::from("Precious NFT"))
|
||||
.finalize_action(String::from("NFT"))
|
||||
.expect("Should finalize properly");
|
||||
|
||||
assert_eq!(
|
||||
bundle
|
||||
.add_recipient(
|
||||
String::from("Precious NFT"),
|
||||
String::from("NFT"),
|
||||
recipient,
|
||||
NoteValue::unsplittable(),
|
||||
false,
|
||||
|
@ -588,7 +608,7 @@ mod tests {
|
|||
|
||||
assert_eq!(
|
||||
bundle
|
||||
.finalize_action(String::from("Another precious NFT"))
|
||||
.finalize_action(String::from("Another NFT"))
|
||||
.unwrap_err(),
|
||||
IssueActionNotFound
|
||||
);
|
||||
|
@ -607,7 +627,7 @@ mod tests {
|
|||
|
||||
bundle
|
||||
.add_recipient(
|
||||
String::from("Another precious NFT"),
|
||||
String::from("Another NFT"),
|
||||
recipient,
|
||||
NoteValue::unsplittable(),
|
||||
true,
|
||||
|
@ -618,7 +638,7 @@ mod tests {
|
|||
assert_eq!(
|
||||
bundle
|
||||
.add_recipient(
|
||||
String::from("Another precious NFT"),
|
||||
String::from("Another NFT"),
|
||||
recipient,
|
||||
NoteValue::unsplittable(),
|
||||
true,
|
||||
|
@ -718,7 +738,7 @@ mod tests {
|
|||
let note = Note::new(
|
||||
recipient,
|
||||
NoteValue::from_raw(5),
|
||||
AssetId::derive(bundle.ik(), "Poisoned pill"),
|
||||
AssetBase::derive(bundle.ik(), "zsa_asset"),
|
||||
Nullifier::dummy(&mut rng),
|
||||
&mut rng,
|
||||
);
|
||||
|
@ -771,7 +791,7 @@ mod tests {
|
|||
|
||||
bundle
|
||||
.add_recipient(
|
||||
String::from("verify_with_finalize"),
|
||||
String::from("Verify with finalize"),
|
||||
recipient,
|
||||
NoteValue::from_raw(7),
|
||||
true,
|
||||
|
@ -785,9 +805,10 @@ mod tests {
|
|||
|
||||
let res = verify_issue_bundle(&signed, sighash, prev_finalized);
|
||||
assert!(res.is_ok());
|
||||
assert!(
|
||||
prev_finalized.contains(&AssetId::derive(&ik, &String::from("verify_with_finalize")))
|
||||
);
|
||||
assert!(prev_finalized.contains(&AssetBase::derive(
|
||||
&ik,
|
||||
&String::from("Verify with finalize")
|
||||
)));
|
||||
assert_eq!(prev_finalized.len(), 1);
|
||||
}
|
||||
|
||||
|
@ -810,7 +831,7 @@ mod tests {
|
|||
let signed = bundle.prepare(sighash).sign(rng, &isk).unwrap();
|
||||
let prev_finalized = &mut HashSet::new();
|
||||
|
||||
let final_type = AssetId::derive(&ik, &String::from("already final"));
|
||||
let final_type = AssetBase::derive(&ik, &String::from("already final"));
|
||||
|
||||
prev_finalized.insert(final_type);
|
||||
|
||||
|
@ -867,7 +888,7 @@ mod tests {
|
|||
|
||||
bundle
|
||||
.add_recipient(
|
||||
String::from("Good description"),
|
||||
String::from("Asset description"),
|
||||
recipient,
|
||||
NoteValue::from_raw(5),
|
||||
false,
|
||||
|
@ -896,7 +917,7 @@ mod tests {
|
|||
|
||||
bundle
|
||||
.add_recipient(
|
||||
String::from("Good description"),
|
||||
String::from("Asset description"),
|
||||
recipient,
|
||||
NoteValue::from_raw(5),
|
||||
false,
|
||||
|
@ -910,7 +931,7 @@ mod tests {
|
|||
let note = Note::new(
|
||||
recipient,
|
||||
NoteValue::from_raw(5),
|
||||
AssetId::derive(signed.ik(), "Poisoned pill"),
|
||||
AssetBase::derive(signed.ik(), "zsa_asset"),
|
||||
Nullifier::dummy(&mut rng),
|
||||
&mut rng,
|
||||
);
|
||||
|
@ -931,7 +952,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn issue_bundle_verify_fail_incorrect_ik() {
|
||||
let asset_description = "asset";
|
||||
let asset_description = "Asset";
|
||||
|
||||
let (mut rng, isk, ik, recipient, sighash) = setup_params();
|
||||
|
||||
|
@ -957,7 +978,7 @@ mod tests {
|
|||
let note = Note::new(
|
||||
recipient,
|
||||
NoteValue::from_raw(55),
|
||||
AssetId::derive(&incorrect_ik, asset_description),
|
||||
AssetBase::derive(&incorrect_ik, asset_description),
|
||||
Nullifier::dummy(&mut rng),
|
||||
&mut rng,
|
||||
);
|
||||
|
@ -985,7 +1006,7 @@ mod tests {
|
|||
|
||||
bundle
|
||||
.add_recipient(
|
||||
String::from("Good description"),
|
||||
String::from("Asset description"),
|
||||
recipient,
|
||||
NoteValue::from_raw(5),
|
||||
false,
|
||||
|
@ -1024,7 +1045,7 @@ mod tests {
|
|||
pub mod testing {
|
||||
use crate::issuance::{IssueAction, IssueBundle, Prepared, Signed, Unauthorized};
|
||||
use crate::keys::testing::{arb_issuance_authorizing_key, arb_issuance_validating_key};
|
||||
use crate::note::asset_id::testing::zsa_asset_id;
|
||||
use crate::note::asset_base::testing::zsa_asset_id;
|
||||
use crate::note::testing::arb_zsa_note;
|
||||
use proptest::collection::vec;
|
||||
use proptest::prelude::*;
|
||||
|
|
|
@ -271,7 +271,7 @@ impl Eq for IssuanceValidatingKey {}
|
|||
impl IssuanceValidatingKey {
|
||||
/// Converts this spend validating key to its serialized form,
|
||||
/// I2LEOSP_256(ik).
|
||||
pub(crate) fn to_bytes(&self) -> [u8; 32] {
|
||||
pub fn to_bytes(&self) -> [u8; 32] {
|
||||
// This is correct because the wrapped point must have ỹ = 0, and
|
||||
// so the point repr is the same as I2LEOSP of its x-coordinate.
|
||||
<[u8; 32]>::from(&self.0)
|
||||
|
@ -1127,7 +1127,7 @@ mod tests {
|
|||
testing::{arb_diversifier_index, arb_diversifier_key, arb_esk, arb_spending_key},
|
||||
*,
|
||||
};
|
||||
use crate::note::AssetId;
|
||||
use crate::note::AssetBase;
|
||||
use crate::{
|
||||
note::{ExtractedNoteCommitment, Nullifier, RandomSeed},
|
||||
value::NoteValue,
|
||||
|
@ -1219,7 +1219,7 @@ mod tests {
|
|||
let note = Note::from_parts(
|
||||
addr,
|
||||
NoteValue::from_raw(tv.note_v),
|
||||
AssetId::native(),
|
||||
AssetBase::native(),
|
||||
rho,
|
||||
RandomSeed::from_bytes(tv.note_rseed, &rho).unwrap(),
|
||||
)
|
||||
|
|
22
src/note.rs
22
src/note.rs
|
@ -19,8 +19,8 @@ pub use self::commitment::{ExtractedNoteCommitment, NoteCommitment};
|
|||
pub(crate) mod nullifier;
|
||||
pub use self::nullifier::Nullifier;
|
||||
|
||||
pub(crate) mod asset_id;
|
||||
pub use self::asset_id::AssetId;
|
||||
pub(crate) mod asset_base;
|
||||
pub use self::asset_base::AssetBase;
|
||||
|
||||
/// The ZIP 212 seed randomness for a note.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
|
@ -94,7 +94,7 @@ pub struct Note {
|
|||
/// The value of this note.
|
||||
value: NoteValue,
|
||||
/// The asset id of this note.
|
||||
asset: AssetId,
|
||||
asset: AssetBase,
|
||||
/// A unique creation ID for this note.
|
||||
///
|
||||
/// This is set to the nullifier of the note that was spent in the [`Action`] that
|
||||
|
@ -134,7 +134,7 @@ impl Note {
|
|||
pub fn from_parts(
|
||||
recipient: Address,
|
||||
value: NoteValue,
|
||||
asset: AssetId,
|
||||
asset: AssetBase,
|
||||
rho: Nullifier,
|
||||
rseed: RandomSeed,
|
||||
) -> CtOption<Self> {
|
||||
|
@ -156,7 +156,7 @@ impl Note {
|
|||
pub(crate) fn new(
|
||||
recipient: Address,
|
||||
value: NoteValue,
|
||||
asset: AssetId,
|
||||
asset: AssetBase,
|
||||
rho: Nullifier,
|
||||
mut rng: impl RngCore,
|
||||
) -> Self {
|
||||
|
@ -182,7 +182,7 @@ impl Note {
|
|||
pub(crate) fn dummy(
|
||||
rng: &mut impl RngCore,
|
||||
rho: Option<Nullifier>,
|
||||
asset: AssetId,
|
||||
asset: AssetBase,
|
||||
) -> (SpendingKey, FullViewingKey, Self) {
|
||||
let sk = SpendingKey::random(rng);
|
||||
let fvk: FullViewingKey = (&sk).into();
|
||||
|
@ -210,7 +210,7 @@ impl Note {
|
|||
}
|
||||
|
||||
/// Returns the note type of this note.
|
||||
pub fn asset(&self) -> AssetId {
|
||||
pub fn asset(&self) -> AssetBase {
|
||||
self.asset
|
||||
}
|
||||
|
||||
|
@ -301,8 +301,8 @@ impl fmt::Debug for TransmittedNoteCiphertext {
|
|||
pub mod testing {
|
||||
use proptest::prelude::*;
|
||||
|
||||
use crate::note::asset_id::testing::arb_asset_id;
|
||||
use crate::note::AssetId;
|
||||
use crate::note::asset_base::testing::arb_asset_id;
|
||||
use crate::note::AssetBase;
|
||||
use crate::value::testing::arb_note_value;
|
||||
use crate::{
|
||||
address::testing::arb_address, note::nullifier::testing::arb_nullifier, value::NoteValue,
|
||||
|
@ -346,7 +346,7 @@ pub mod testing {
|
|||
Note {
|
||||
recipient,
|
||||
value,
|
||||
asset: AssetId::native(),
|
||||
asset: AssetBase::native(),
|
||||
rho,
|
||||
rseed,
|
||||
}
|
||||
|
@ -355,7 +355,7 @@ pub mod testing {
|
|||
|
||||
prop_compose! {
|
||||
/// Generate an arbitrary zsa note
|
||||
pub fn arb_zsa_note(asset: AssetId)(
|
||||
pub fn arb_zsa_note(asset: AssetBase)(
|
||||
recipient in arb_address(),
|
||||
value in arb_note_value(),
|
||||
rho in arb_nullifier(),
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use blake2b_simd::{Hash as Blake2bHash, Params};
|
||||
use group::GroupEncoding;
|
||||
use halo2_proofs::arithmetic::CurveExt;
|
||||
use pasta_curves::pallas;
|
||||
|
@ -5,25 +6,38 @@ use std::hash::{Hash, Hasher};
|
|||
|
||||
use subtle::{Choice, ConstantTimeEq, CtOption};
|
||||
|
||||
use crate::constants::fixed_bases::{VALUE_COMMITMENT_PERSONALIZATION, VALUE_COMMITMENT_V_BYTES};
|
||||
use crate::constants::fixed_bases::{
|
||||
NATIVE_ASSET_BASE_V_BYTES, VALUE_COMMITMENT_PERSONALIZATION, ZSA_ASSET_BASE_PERSONALIZATION,
|
||||
};
|
||||
use crate::keys::IssuanceValidatingKey;
|
||||
|
||||
/// Note type identifier.
|
||||
#[derive(Clone, Copy, Debug, Eq)]
|
||||
pub struct AssetId(pallas::Point);
|
||||
pub struct AssetBase(pallas::Point);
|
||||
|
||||
pub const MAX_ASSET_DESCRIPTION_SIZE: usize = 512;
|
||||
|
||||
// the hasher used to derive the assetID
|
||||
fn asset_id_hasher(msg: Vec<u8>) -> pallas::Point {
|
||||
// TODO(zsa) replace personalization
|
||||
pallas::Point::hash_to_curve(VALUE_COMMITMENT_PERSONALIZATION)(&msg)
|
||||
/// Personalization for the ZSA asset digest generator
|
||||
pub const ZSA_ASSET_DIGEST_PERSONALIZATION: &[u8; 16] = b"ZSA-Asset-Digest";
|
||||
|
||||
/// AssetDigest for the ZSA asset
|
||||
///
|
||||
/// Defined in [Transfer and Burn of Zcash Shielded Assets][AssetDigest].
|
||||
///
|
||||
/// [assetdigest]: https://qed-it.github.io/zips/zip-0226.html#asset-identifiers
|
||||
pub fn asset_digest(asset_id: Vec<u8>) -> Blake2bHash {
|
||||
Params::new()
|
||||
.hash_length(64)
|
||||
.personal(ZSA_ASSET_DIGEST_PERSONALIZATION)
|
||||
.to_state()
|
||||
.update(&asset_id)
|
||||
.finalize()
|
||||
}
|
||||
|
||||
impl AssetId {
|
||||
impl AssetBase {
|
||||
/// Deserialize the asset_id from a byte array.
|
||||
pub fn from_bytes(bytes: &[u8; 32]) -> CtOption<Self> {
|
||||
pallas::Point::from_bytes(bytes).map(AssetId)
|
||||
pallas::Point::from_bytes(bytes).map(AssetBase)
|
||||
}
|
||||
|
||||
/// Serialize the asset_id to its canonical byte representation.
|
||||
|
@ -33,9 +47,9 @@ impl AssetId {
|
|||
|
||||
/// Note type derivation$.
|
||||
///
|
||||
/// Defined in [Transfer and Burn of Zcash Shielded Assets][notetypes].
|
||||
/// Defined in [Transfer and Burn of Zcash Shielded Assets][AssetBase].
|
||||
///
|
||||
/// [notetypes]: https://qed-it.github.io/zips/draft-ZIP-0226.html#asset-types
|
||||
/// [notetypes]: https://qed-it.github.io/zips/zip-0226.html#asset-identifiers
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
|
@ -44,16 +58,23 @@ impl AssetId {
|
|||
pub fn derive(ik: &IssuanceValidatingKey, asset_desc: &str) -> Self {
|
||||
assert!(is_asset_desc_of_valid_size(asset_desc));
|
||||
|
||||
let mut s = vec![];
|
||||
s.extend(ik.to_bytes());
|
||||
s.extend(asset_desc.as_bytes());
|
||||
// EncodeAssetId(ik, asset_desc) = version_byte || ik || asset_desc
|
||||
let version_byte = [0x00];
|
||||
let encode_asset_id = [&version_byte[..], &ik.to_bytes(), asset_desc.as_bytes()].concat();
|
||||
|
||||
AssetId(asset_id_hasher(s))
|
||||
let asset_digest = asset_digest(encode_asset_id);
|
||||
|
||||
// AssetBase = ZSAValueBase(AssetDigest)
|
||||
AssetBase(
|
||||
pallas::Point::hash_to_curve(ZSA_ASSET_BASE_PERSONALIZATION)(asset_digest.as_bytes()),
|
||||
)
|
||||
}
|
||||
|
||||
/// Note type for the "native" currency (zec), maintains backward compatibility with Orchard untyped notes.
|
||||
pub fn native() -> Self {
|
||||
AssetId(asset_id_hasher(VALUE_COMMITMENT_V_BYTES.to_vec()))
|
||||
AssetBase(pallas::Point::hash_to_curve(
|
||||
VALUE_COMMITMENT_PERSONALIZATION,
|
||||
)(&NATIVE_ASSET_BASE_V_BYTES[..]))
|
||||
}
|
||||
|
||||
/// The base point used in value commitments.
|
||||
|
@ -67,7 +88,7 @@ impl AssetId {
|
|||
}
|
||||
}
|
||||
|
||||
impl Hash for AssetId {
|
||||
impl Hash for AssetBase {
|
||||
fn hash<H: Hasher>(&self, h: &mut H) {
|
||||
h.write(&self.to_bytes());
|
||||
h.finish();
|
||||
|
@ -79,7 +100,7 @@ pub fn is_asset_desc_of_valid_size(asset_desc: &str) -> bool {
|
|||
!asset_desc.is_empty() && asset_desc.bytes().len() <= MAX_ASSET_DESCRIPTION_SIZE
|
||||
}
|
||||
|
||||
impl PartialEq for AssetId {
|
||||
impl PartialEq for AssetBase {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
bool::from(self.0.ct_eq(&other.0))
|
||||
}
|
||||
|
@ -89,7 +110,7 @@ impl PartialEq for AssetId {
|
|||
#[cfg(any(test, feature = "test-dependencies"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "test-dependencies")))]
|
||||
pub mod testing {
|
||||
use super::AssetId;
|
||||
use super::AssetBase;
|
||||
|
||||
use proptest::prelude::*;
|
||||
|
||||
|
@ -101,21 +122,21 @@ pub mod testing {
|
|||
is_native in prop::bool::ANY,
|
||||
sk in arb_spending_key(),
|
||||
str in "[A-Za-z]{255}",
|
||||
) -> AssetId {
|
||||
) -> AssetBase {
|
||||
if is_native {
|
||||
AssetId::native()
|
||||
AssetBase::native()
|
||||
} else {
|
||||
let isk = IssuanceAuthorizingKey::from(&sk);
|
||||
AssetId::derive(&IssuanceValidatingKey::from(&isk), &str)
|
||||
AssetBase::derive(&IssuanceValidatingKey::from(&isk), &str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prop_compose! {
|
||||
/// Generate the native note type
|
||||
pub fn native_asset_id()(_i in 0..10) -> AssetId {
|
||||
pub fn native_asset_id()(_i in 0..10) -> AssetBase {
|
||||
// TODO: remove _i
|
||||
AssetId::native()
|
||||
AssetBase::native()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,9 +145,9 @@ pub mod testing {
|
|||
pub fn arb_zsa_asset_id()(
|
||||
sk in arb_spending_key(),
|
||||
str in "[A-Za-z]{255}"
|
||||
) -> AssetId {
|
||||
) -> AssetBase {
|
||||
let isk = IssuanceAuthorizingKey::from(&sk);
|
||||
AssetId::derive(&IssuanceValidatingKey::from(&isk), &str)
|
||||
AssetBase::derive(&IssuanceValidatingKey::from(&isk), &str)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,25 +155,27 @@ pub mod testing {
|
|||
/// Generate an asset ID using a specific description
|
||||
pub fn zsa_asset_id(asset_desc: String)(
|
||||
sk in arb_spending_key(),
|
||||
) -> AssetId {
|
||||
) -> AssetBase {
|
||||
assert!(super::is_asset_desc_of_valid_size(&asset_desc));
|
||||
let isk = IssuanceAuthorizingKey::from(&sk);
|
||||
AssetId::derive(&IssuanceValidatingKey::from(&isk), &asset_desc)
|
||||
AssetBase::derive(&IssuanceValidatingKey::from(&isk), &asset_desc)
|
||||
}
|
||||
}
|
||||
|
||||
// the following test should fail until updated to use the new asset ID derivation
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_vectors() {
|
||||
let test_vectors = crate::test_vectors::asset_id::test_vectors();
|
||||
|
||||
for tv in test_vectors {
|
||||
let description = std::str::from_utf8(&tv.description).unwrap();
|
||||
|
||||
let calculated_asset_id = AssetId::derive(
|
||||
let calculated_asset_id = AssetBase::derive(
|
||||
&IssuanceValidatingKey::from_bytes(&tv.key).unwrap(),
|
||||
description,
|
||||
);
|
||||
let test_vector_asset_id = AssetId::from_bytes(&tv.asset_id).unwrap();
|
||||
let test_vector_asset_id = AssetBase::from_bytes(&tv.asset_id).unwrap();
|
||||
|
||||
assert_eq!(calculated_asset_id, test_vector_asset_id);
|
||||
}
|
|
@ -11,7 +11,7 @@ use crate::{
|
|||
fixed_bases::{NOTE_COMMITMENT_PERSONALIZATION, NOTE_ZSA_COMMITMENT_PERSONALIZATION},
|
||||
L_ORCHARD_BASE,
|
||||
},
|
||||
note::asset_id::AssetId,
|
||||
note::asset_base::AssetBase,
|
||||
spec::extract_p,
|
||||
value::NoteValue,
|
||||
};
|
||||
|
@ -45,7 +45,7 @@ impl NoteCommitment {
|
|||
g_d: [u8; 32],
|
||||
pk_d: [u8; 32],
|
||||
v: NoteValue,
|
||||
asset: AssetId,
|
||||
asset: AssetBase,
|
||||
rho: pallas::Base,
|
||||
psi: pallas::Base,
|
||||
rcm: NoteCommitTrapdoor,
|
||||
|
|
|
@ -8,7 +8,7 @@ use zcash_note_encryption::{
|
|||
AEAD_TAG_SIZE, MEMO_SIZE, OUT_PLAINTEXT_SIZE,
|
||||
};
|
||||
|
||||
use crate::note::AssetId;
|
||||
use crate::note::AssetBase;
|
||||
use crate::{
|
||||
action::Action,
|
||||
keys::{
|
||||
|
@ -163,7 +163,7 @@ where
|
|||
let note = Option::from(Note::from_parts(
|
||||
recipient,
|
||||
value,
|
||||
AssetId::native(), //V2 notes are always native.
|
||||
AssetBase::native(), //V2 notes are always native.
|
||||
domain.rho,
|
||||
rseed,
|
||||
))?;
|
||||
|
@ -474,7 +474,7 @@ mod tests {
|
|||
};
|
||||
|
||||
use super::{prf_ock_orchard, CompactAction, OrchardDomainV2, OrchardNoteEncryption};
|
||||
use crate::note::AssetId;
|
||||
use crate::note::AssetBase;
|
||||
use crate::{
|
||||
action::Action,
|
||||
keys::{
|
||||
|
@ -566,7 +566,7 @@ mod tests {
|
|||
assert_eq!(ock.as_ref(), tv.ock);
|
||||
|
||||
let recipient = Address::from_parts(d, pk_d);
|
||||
let note = Note::from_parts(recipient, value, AssetId::native(), rho, rseed).unwrap();
|
||||
let note = Note::from_parts(recipient, value, AssetBase::native(), rho, rseed).unwrap();
|
||||
assert_eq!(ExtractedNoteCommitment::from(note.commitment()), cmx);
|
||||
|
||||
let action = Action::from_parts(
|
||||
|
|
|
@ -8,7 +8,7 @@ use zcash_note_encryption::{
|
|||
AEAD_TAG_SIZE, MEMO_SIZE, OUT_PLAINTEXT_SIZE,
|
||||
};
|
||||
|
||||
use crate::note::AssetId;
|
||||
use crate::note::AssetBase;
|
||||
use crate::{
|
||||
action::Action,
|
||||
keys::{
|
||||
|
@ -109,14 +109,14 @@ where
|
|||
Some((note, recipient))
|
||||
}
|
||||
|
||||
fn parse_version_and_asset_type(plaintext: &CompactNotePlaintextBytes) -> Option<AssetId> {
|
||||
fn parse_version_and_asset_type(plaintext: &CompactNotePlaintextBytes) -> Option<AssetBase> {
|
||||
match plaintext {
|
||||
CompactNotePlaintextBytes::V2(x) if x[0] == 0x02 => Some(AssetId::native()),
|
||||
CompactNotePlaintextBytes::V2(x) if x[0] == 0x02 => Some(AssetBase::native()),
|
||||
CompactNotePlaintextBytes::V3(x) if x[0] == 0x03 => {
|
||||
let bytes = x[COMPACT_NOTE_SIZE_V2..COMPACT_NOTE_SIZE_V3]
|
||||
.try_into()
|
||||
.unwrap();
|
||||
AssetId::from_bytes(bytes).into()
|
||||
AssetBase::from_bytes(bytes).into()
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
|
@ -554,7 +554,7 @@ mod tests {
|
|||
};
|
||||
|
||||
use super::{prf_ock_orchard, CompactAction, OrchardDomain, OrchardNoteEncryption};
|
||||
use crate::note::AssetId;
|
||||
use crate::note::AssetBase;
|
||||
use crate::note_encryption::NoteCiphertextBytes;
|
||||
use crate::{
|
||||
action::Action,
|
||||
|
@ -646,8 +646,8 @@ mod tests {
|
|||
let recipient = Address::from_parts(d, pk_d);
|
||||
|
||||
let asset = match tv.asset {
|
||||
None => AssetId::native(),
|
||||
Some(type_bytes) => AssetId::from_bytes(&type_bytes).unwrap(),
|
||||
None => AssetBase::native(),
|
||||
Some(type_bytes) => AssetBase::from_bytes(&type_bytes).unwrap(),
|
||||
};
|
||||
|
||||
let note = Note::from_parts(recipient, value, asset, rho, rseed).unwrap();
|
||||
|
|
|
@ -8,7 +8,7 @@ use zcash_note_encryption::{
|
|||
AEAD_TAG_SIZE, MEMO_SIZE, OUT_PLAINTEXT_SIZE,
|
||||
};
|
||||
|
||||
use crate::note::AssetId;
|
||||
use crate::note::AssetBase;
|
||||
use crate::{
|
||||
action::Action,
|
||||
keys::{
|
||||
|
@ -161,12 +161,12 @@ where
|
|||
let recipient = Address::from_parts(diversifier, pk_d);
|
||||
|
||||
let asset = match note_version(plaintext.0.as_ref())? {
|
||||
0x02 => AssetId::native(),
|
||||
0x02 => AssetBase::native(),
|
||||
0x03 => {
|
||||
let bytes = plaintext.0[COMPACT_NOTE_SIZE_V2..COMPACT_NOTE_SIZE_V3]
|
||||
.try_into()
|
||||
.unwrap();
|
||||
AssetId::from_bytes(bytes).unwrap()
|
||||
AssetBase::from_bytes(bytes).unwrap()
|
||||
}
|
||||
_ => panic!("invalid note version"),
|
||||
};
|
||||
|
@ -483,7 +483,7 @@ mod tests {
|
|||
OutgoingViewingKey, PreparedIncomingViewingKey,
|
||||
},
|
||||
note::{
|
||||
testing::arb_note, AssetId, ExtractedNoteCommitment, Nullifier, RandomSeed,
|
||||
testing::arb_note, AssetBase, ExtractedNoteCommitment, Nullifier, RandomSeed,
|
||||
TransmittedNoteCiphertext,
|
||||
},
|
||||
primitives::redpallas,
|
||||
|
@ -565,7 +565,7 @@ mod tests {
|
|||
|
||||
let recipient = Address::from_parts(d, pk_d);
|
||||
|
||||
let asset = AssetId::from_bytes(&tv.asset).unwrap();
|
||||
let asset = AssetBase::from_bytes(&tv.asset).unwrap();
|
||||
|
||||
let note = Note::from_parts(recipient, value, asset, rho, rseed).unwrap();
|
||||
assert_eq!(ExtractedNoteCommitment::from(note.commitment()), cmx);
|
||||
|
|
16
src/value.rs
16
src/value.rs
|
@ -59,7 +59,7 @@ use crate::{
|
|||
};
|
||||
|
||||
use crate::builder::Error;
|
||||
use crate::note::AssetId;
|
||||
use crate::note::AssetBase;
|
||||
|
||||
/// Maximum note value.
|
||||
pub const MAX_NOTE_VALUE: u64 = u64::MAX;
|
||||
|
@ -345,7 +345,7 @@ impl ValueCommitment {
|
|||
///
|
||||
/// [concretehomomorphiccommit]: https://zips.z.cash/protocol/nu5.pdf#concretehomomorphiccommit
|
||||
#[allow(non_snake_case)]
|
||||
pub fn derive(value: ValueSum, rcv: ValueCommitTrapdoor, asset: AssetId) -> Self {
|
||||
pub fn derive(value: ValueSum, rcv: ValueCommitTrapdoor, asset: AssetBase) -> Self {
|
||||
let hasher = pallas::Point::hash_to_curve(VALUE_COMMITMENT_PERSONALIZATION);
|
||||
let R = hasher(&VALUE_COMMITMENT_R_BYTES);
|
||||
let abs_value = u64::try_from(value.0.abs()).expect("value must be in valid range");
|
||||
|
@ -461,9 +461,9 @@ pub mod testing {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::note::asset_id::testing::{arb_asset_id, native_asset_id};
|
||||
use crate::note::asset_base::testing::{arb_asset_id, native_asset_id};
|
||||
|
||||
use crate::note::AssetId;
|
||||
use crate::note::AssetBase;
|
||||
use proptest::prelude::*;
|
||||
|
||||
use super::{
|
||||
|
@ -473,10 +473,10 @@ mod tests {
|
|||
use crate::primitives::redpallas;
|
||||
|
||||
fn check_binding_signature(
|
||||
native_values: &[(ValueSum, ValueCommitTrapdoor, AssetId)],
|
||||
arb_values: &[(ValueSum, ValueCommitTrapdoor, AssetId)],
|
||||
native_values: &[(ValueSum, ValueCommitTrapdoor, AssetBase)],
|
||||
arb_values: &[(ValueSum, ValueCommitTrapdoor, AssetBase)],
|
||||
neg_trapdoors: &[ValueCommitTrapdoor],
|
||||
arb_values_to_burn: &[(ValueSum, ValueCommitTrapdoor, AssetId)],
|
||||
arb_values_to_burn: &[(ValueSum, ValueCommitTrapdoor, AssetBase)],
|
||||
) {
|
||||
// for each arb value, create a negative value with a different trapdoor
|
||||
let neg_arb_values: Vec<_> = arb_values
|
||||
|
@ -513,7 +513,7 @@ mod tests {
|
|||
- ValueCommitment::derive(
|
||||
native_value_balance,
|
||||
ValueCommitTrapdoor::zero(),
|
||||
AssetId::native(),
|
||||
AssetBase::native(),
|
||||
)
|
||||
- arb_values_to_burn
|
||||
.iter()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use incrementalmerkletree::{bridgetree::BridgeTree, Hashable, Tree};
|
||||
use orchard::note::AssetId;
|
||||
use orchard::note::AssetBase;
|
||||
use orchard::{
|
||||
builder::Builder,
|
||||
bundle::{Authorized, Flags},
|
||||
|
@ -68,7 +68,7 @@ fn bundle_chain() {
|
|||
None,
|
||||
recipient,
|
||||
NoteValue::from_raw(5000),
|
||||
AssetId::native(),
|
||||
AssetBase::native(),
|
||||
None
|
||||
),
|
||||
Ok(())
|
||||
|
@ -103,7 +103,7 @@ fn bundle_chain() {
|
|||
None,
|
||||
recipient,
|
||||
NoteValue::from_raw(5000),
|
||||
AssetId::native(),
|
||||
AssetBase::native(),
|
||||
None
|
||||
),
|
||||
Ok(())
|
||||
|
|
14
tests/zsa.rs
14
tests/zsa.rs
|
@ -6,7 +6,7 @@ use incrementalmerkletree::{Hashable, Tree};
|
|||
use orchard::bundle::Authorized;
|
||||
use orchard::issuance::{verify_issue_bundle, IssueBundle, Signed, Unauthorized};
|
||||
use orchard::keys::{IssuanceAuthorizingKey, IssuanceValidatingKey};
|
||||
use orchard::note::{AssetId, ExtractedNoteCommitment};
|
||||
use orchard::note::{AssetBase, ExtractedNoteCommitment};
|
||||
use orchard::note_encryption_v3::OrchardDomainV3;
|
||||
use orchard::tree::{MerkleHashOrchard, MerklePath};
|
||||
use orchard::{
|
||||
|
@ -189,7 +189,7 @@ fn create_native_note(keys: &Keychain) -> Note {
|
|||
None,
|
||||
keys.recipient,
|
||||
NoteValue::from_raw(100),
|
||||
AssetId::native(),
|
||||
AssetBase::native(),
|
||||
None
|
||||
),
|
||||
Ok(())
|
||||
|
@ -225,13 +225,13 @@ impl TestSpendInfo {
|
|||
|
||||
struct TestOutputInfo {
|
||||
value: NoteValue,
|
||||
asset: AssetId,
|
||||
asset: AssetBase,
|
||||
}
|
||||
|
||||
fn build_and_verify_bundle(
|
||||
spends: Vec<&TestSpendInfo>,
|
||||
outputs: Vec<TestOutputInfo>,
|
||||
assets_to_burn: Vec<(AssetId, NoteValue)>,
|
||||
assets_to_burn: Vec<(AssetBase, NoteValue)>,
|
||||
anchor: Anchor,
|
||||
expected_num_actions: usize,
|
||||
keys: &Keychain,
|
||||
|
@ -376,7 +376,7 @@ fn zsa_issue_and_transfer() {
|
|||
},
|
||||
TestOutputInfo {
|
||||
value: NoteValue::from_raw(100),
|
||||
asset: AssetId::native(),
|
||||
asset: AssetBase::native(),
|
||||
},
|
||||
],
|
||||
vec![],
|
||||
|
@ -396,7 +396,7 @@ fn zsa_issue_and_transfer() {
|
|||
},
|
||||
TestOutputInfo {
|
||||
value: native_spend.note.value(),
|
||||
asset: AssetId::native(),
|
||||
asset: AssetBase::native(),
|
||||
},
|
||||
],
|
||||
vec![],
|
||||
|
@ -493,7 +493,7 @@ fn zsa_issue_and_transfer() {
|
|||
let result = build_and_verify_bundle(
|
||||
vec![&native_spend],
|
||||
vec![],
|
||||
vec![(AssetId::native(), native_spend.note.value())],
|
||||
vec![(AssetBase::native(), native_spend.note.value())],
|
||||
native_anchor,
|
||||
2,
|
||||
&keys,
|
||||
|
|
Loading…
Reference in New Issue