Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Orchard-ZSA reference implementation #372

Draft
wants to merge 94 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
7f8a848
Circleci project setup (#1)
PaulLaux Mar 30, 2022
1328c62
issuer keys implementation (#5)
daniben31 Jun 14, 2022
e6b7762
Added NoteType to Notes (#2)
PaulLaux Jun 14, 2022
088abc6
ZSA note encryption in Orchard crate (#3)
naure Jul 20, 2022
1420f84
Zsa builder (#4)
PaulLaux Sep 19, 2022
0b2988a
Issuance (#12)
PaulLaux Sep 29, 2022
9b43497
E2E tests for issuance (#20)
alexeykoren Oct 20, 2022
985d0d2
disabled split notes (#22)
PaulLaux Oct 20, 2022
f3ebe7a
Review fixes (#23)
PaulLaux Oct 26, 2022
355b569
Review fixes2 (#24)
PaulLaux Oct 27, 2022
9405f80
verify_issue_bundle() cleanup (#25)
PaulLaux Oct 28, 2022
d8f3563
ZSA burn functionality (#35)
alexeykoren Dec 7, 2022
5a50fb8
Create dummy spend in empty builder by default (#36)
alexeykoren Dec 18, 2022
efbfc19
AssetID test vectors (#34)
alexeykoren Dec 20, 2022
babf1da
CI-Badge (#37)
PaulLaux Dec 21, 2022
4681cc2
Use different random nullifiers in dummy notes (#39)
alexeykoren Dec 23, 2022
cec48d7
V3 encryption (#38)
PaulLaux Jan 31, 2023
4e47677
Minimal API changes for Issuance in Client (#43)
alexeykoren Feb 9, 2023
cbf0a3a
Circuit: Split_flag handling (#42)
ConstanceBeguier Feb 14, 2023
43d5e77
AssetBase spec update (#44)
PaulLaux Mar 2, 2023
527e29a
Upgrade pprof version with a limited inferno version (#48)
ConstanceBeguier Mar 20, 2023
f0b7948
Making changes to the asset base derivation from the asset identifier…
vivek-arte Apr 18, 2023
563b4e5
Circuit: Update value_commit_orchard to take into account asset (#50)
ConstanceBeguier Apr 21, 2023
7d3b6df
Constant-time note commitment for ZEC and ZSA (#54)
ConstanceBeguier Apr 25, 2023
ea0fd59
Add tracking for supply info inside verify_issue_bundle (#55)
dmidem May 4, 2023
9a35108
Add getter method for Bundle.burn field (#58)
dmidem May 10, 2023
4e1c616
Merge branch 'main' into zsa1
ConstanceBeguier May 12, 2023
c77d96c
Merge branch main into zsa1 (#59)
ConstanceBeguier May 16, 2023
aeb9934
Circuit: Update note_commit to take into account asset (#56)
ConstanceBeguier May 23, 2023
b4f6281
Circuit: Use nf_old_pub to evaluate new note commitment (with rho_new…
ConstanceBeguier May 25, 2023
95fcf88
Circuit: Check pk_d_old = derived_pk_d_old only when split_flag = 0 (…
ConstanceBeguier May 29, 2023
8e71fff
Protect bundle burn from adding assets with zero amount (#60)
dmidem May 29, 2023
bedc732
Circuit: Add tests for orchard circuit (#63)
ConstanceBeguier Jun 1, 2023
32eee6e
Do not create split notes with native asset (#65)
ConstanceBeguier Jun 6, 2023
02fa582
Global padding for bundle (#67)
ConstanceBeguier Jun 6, 2023
9965a6d
Add serialization of finalize flag (#68)
ConstanceBeguier Jun 6, 2023
7ad2bac
Fix IssueBundle and IssueAction structures (#70)
ConstanceBeguier Jun 12, 2023
950b806
Updates to TXID Digest and Authorizing Data Commitment (#66)
vivek-arte Jun 13, 2023
8bc18f7
Merge branch main into zsa1
ConstanceBeguier Jun 13, 2023
5b003f8
Merge branch main into zsa1 (#72)
ConstanceBeguier Jun 13, 2023
f49be89
Update code to refer to the upgraded version of librustzcash and refl…
dmidem Jun 19, 2023
aa1d895
Fix issuance key derivation (#74)
ConstanceBeguier Jun 20, 2023
daf6269
Preventing Asset Base from being the identity point on the Pallas cur…
vivek-arte Jun 21, 2023
477f949
Update random nullifier for split notes and circuit (#76)
ConstanceBeguier Jun 23, 2023
d4ff716
Merge branch 'zsa1' into upgrade_librustzcash_for_orchard_v05_new
dmidem Jun 23, 2023
21d7273
Use tag instead of branch for zcash_note_encryption (librustzcash) re…
dmidem Jun 23, 2023
62d4ae7
Change tag name for zcash_note_encryption in root Cargo.toml
dmidem Jun 23, 2023
1a00c4a
Upgrade orchard to v0.5 and integrate corresponding librustzcash upgr…
dmidem Jun 23, 2023
ff2ac96
Circuit: Add constraints (#77)
ConstanceBeguier Jun 29, 2023
081513b
Circuit: Fix balance violation (#78)
ConstanceBeguier Jul 24, 2023
139ecca
Circuit: Add enable_zsa flag (#79)
ConstanceBeguier Aug 31, 2023
7937e5b
Enhance and cleanup ivk-to-bytes-visibility-downgrade branch (#81)
dmidem Oct 4, 2023
8b0560d
Circuit: optimized short range check on 4 and 5 bits (#86)
ConstanceBeguier Oct 16, 2023
2810365
Circuit: remove mutiplexer chip (#90)
ConstanceBeguier Oct 17, 2023
a680f41
Circuit: optimize ZEC/ZSA hash computations in note commitment (#87)
ConstanceBeguier Oct 18, 2023
7b943e1
Adopt Orchard ZSA for Zebra (introduce zcash_note_encryption_zsa alia…
dmidem Nov 1, 2023
f38d6b9
Rename `sk_iss` to `isk`, the `IssuanceKey` struct to `IssuanceAuthor…
vivek-arte Nov 7, 2023
0ee75f5
Circuit: move mux functionality into CondSwap chip (#94)
ConstanceBeguier Dec 18, 2023
344b647
Update zcash_note_encryption dependency reference (#95)
dmidem Dec 22, 2023
1a1f3e7
Changing the Issuance Authorization Signature to the BIP 340 Schnorr …
vivek-arte Jan 31, 2024
d8e2bc6
orchard release version 0.8.0
nuttycom Mar 25, 2024
c9a8f49
Merge branch 'zcash-0.8.0' into zsa1-with-zcash-0.8.0
dmidem Apr 15, 2024
f3d9459
Fix compilation errors after the merge (there're still several compli…
dmidem Apr 24, 2024
0f56f52
Fix compilation errors in tests
dmidem Apr 25, 2024
149827d
Fix cargo doc issues
dmidem Apr 25, 2024
c8c84aa
Fix Builder::bundle function to pass unit tests from tests folder cor…
dmidem Apr 29, 2024
ac371f0
Fix several comments, rename some flag constants
dmidem Apr 30, 2024
7969b9e
Fix flag names after renaming
dmidem Apr 30, 2024
47f7aae
Disable rustfmt for one line in keys.rs module to prevent removing do…
dmidem Apr 30, 2024
bb9e03b
Fix typo in constant name
dmidem Apr 30, 2024
dd956b8
Fix comments, rename DEFAULT_WITH(OUT)_ZSA to DEVAULT_VANILLA(ZSA)
dmidem May 1, 2024
123b609
1) Use Option instead of usize::MAX in builder::partition_by_asset fu…
dmidem May 2, 2024
ee89541
Refactor build function to remove `Copy + Into<i64>` constraints
dmidem May 7, 2024
73218b0
Remove extra comment
dmidem May 7, 2024
50c6310
Fix comments, indroduce and use MatadataIdx type in the builder
dmidem May 9, 2024
78c8efc
Update to upstream (zcash/main v0.8.0) (#103)
dmidem May 9, 2024
39b479e
OrchardZSA backward compatability 0.8.0 (#104)
dmidem Jul 16, 2024
6e6112c
Synchronize Orchard with updates from zcash_note_encryption for zcash…
dmidem Jul 31, 2024
07b3697
Update ShieldedOutput implementation to return reference from enc_cip…
dmidem Aug 14, 2024
3ba9e5b
Remove redundancy in vanilla/zsa circuits
ConstanceBeguier Sep 19, 2024
e2fb49d
Updating test vectors (#114)
vivek-arte Oct 8, 2024
dd69425
Remove ZSA dummy notes
ConstanceBeguier Oct 10, 2024
410037d
Changing the type of the asset description from String to Vec<u8> (#113)
vivek-arte Oct 14, 2024
a7c02d2
Provide compatibility with librustzcash/zcash_client_backend: derive …
dmidem Oct 15, 2024
25020f8
Exclude non-native assets from value_balance (#120)
alexeykoren Nov 13, 2024
8a2a8de
Simplify Unproven struct
ConstanceBeguier Nov 28, 2024
adc6995
Update SIGHASH according to OrchardDomain
ConstanceBeguier Dec 9, 2024
97cf5a3
Add Clone trait to auth-related structures (#125)
alexeykoren Dec 12, 2024
8b89888
Unify unique AssetBase concept in IssueAction
ConstanceBeguier Dec 16, 2024
fe15076
Add a reference note for each first issuance
ConstanceBeguier Dec 17, 2024
9eb97f0
Simplify bundle build function return type (#129)
ConstanceBeguier Dec 20, 2024
3d2515b
Fix some links and typo (#127)
ConstanceBeguier Dec 25, 2024
0d2f439
Install libfontconfig1-dev to fix CI build on updated Ubuntu runner (…
dmidem Jan 6, 2025
69f92a3
Update AssetSuply and SupplyInfo (new) (#133)
dmidem Jan 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix Builder::bundle function to pass unit tests from tests folder cor…
…rectly
  • Loading branch information
dmidem committed Apr 29, 2024
commit c8c84aa02f123c7e86295c10f005f41a2ec13876
194 changes: 95 additions & 99 deletions src/builder.rs
Original file line number Diff line number Diff line change
@@ -667,7 +667,10 @@ fn partition_by_asset(

if hm.is_empty() {
let dummy_spend = SpendInfo::dummy(AssetBase::native(), rng);
hm.insert(dummy_spend.note.asset(), (vec![(0, dummy_spend)], vec![]));
hm.insert(
dummy_spend.note.asset(),
(vec![(usize::MAX, dummy_spend)], vec![]),
);
}

hm
@@ -720,81 +723,86 @@ pub fn bundle<V: Copy + Into<i64> + TryFrom<i64>>(
return Err(BuildError::OutputsDisabled);
}

let num_actions = bundle_type
.num_actions(num_requested_spends, num_requested_outputs)
.map_err(|_| BuildError::BundleTypeNotSatisfiable)?;
// The number of actions to add to this bundle in order to contain at least MIN_ACTION actions.
let num_missing_actions = MIN_ACTIONS.saturating_sub(spends.len().max(outputs.len()));

// Pair up the spends and outputs, extending with dummy values as necessary.
// FIXME: cargo clippy suggests to avoid using collect for spends
// but the direct fix causes compilation error (bacause of rbg borrowing)
#[allow(clippy::needless_collect)]
let (pre_actions, bundle_meta) = {
let (mut indexed_spends, mut indexed_outputs): (Vec<_>, Vec<_>) =
partition_by_asset(&spends, &outputs, &mut rng)
.into_iter()
.flat_map(|(asset, (spends, outputs))| {
let first_spend = spends.first().map(|(_, s)| s.clone());

let indexed_spends = spends
.into_iter()
.chain(iter::repeat_with(|| {
(0, pad_spend(first_spend.as_ref(), asset, &mut rng))
}))
.take(num_actions)
.collect::<Vec<_>>();

let indexed_outputs = outputs
.into_iter()
.chain(iter::repeat_with(|| {
(0, OutputInfo::dummy(&mut rng, asset))
}))
.take(num_actions)
.collect::<Vec<_>>();

indexed_spends.into_iter().zip(indexed_outputs)
})
.unzip();

// Shuffle the spends and outputs, so that learning the position of a
// specific spent note or output note doesn't reveal anything on its own about
// the meaning of that note in the transaction context.
indexed_spends.shuffle(&mut rng);
indexed_outputs.shuffle(&mut rng);

let mut bundle_meta = BundleMetadata::new(num_requested_spends, num_requested_outputs);
let pre_actions = indexed_spends
.into_iter()
.zip(indexed_outputs.into_iter())
.enumerate()
.map(|(action_idx, ((spend_idx, spend), (out_idx, output)))| {
// Record the post-randomization spend location
if spend_idx < num_requested_spends {
bundle_meta.spend_indices[spend_idx] = action_idx;
}

// Record the post-randomization output location
if out_idx < num_requested_outputs {
bundle_meta.output_indices[out_idx] = action_idx;
}

ActionInfo::new(spend, output, &mut rng)
})
.collect::<Vec<_>>();

(pre_actions, bundle_meta)
};
let (pre_actions, bundle_meta, _) = partition_by_asset(&spends, &outputs, &mut rng)
.into_iter()
.fold(
(
Vec::new(),
BundleMetadata::new(num_requested_spends, num_requested_outputs),
// We might have to add dummy/split actions only for the first asset to reach MIN_ACTIONS.
num_missing_actions,
),
|(mut pre_actions, mut bundle_meta, num_missing_actions),
(asset, (spends, outputs))| {
let num_actions = spends.len().max(outputs.len()) + num_missing_actions;

let first_spend = spends.first().map(|(_, s)| s.clone());

let mut indexed_spends = spends
.into_iter()
.chain(iter::repeat_with(|| {
(usize::MAX, pad_spend(first_spend.as_ref(), asset, &mut rng))
}))
.take(num_actions)
.collect::<Vec<_>>();

let mut indexed_outputs = outputs
.into_iter()
.chain(iter::repeat_with(|| {
(usize::MAX, OutputInfo::dummy(&mut rng, asset))
}))
.take(num_actions)
.collect::<Vec<_>>();

// Shuffle the spends and outputs, so that learning the position of a
// specific spent note or output note doesn't reveal anything on its own about
// the meaning of that note in the transaction context.
indexed_spends.shuffle(&mut rng);
indexed_outputs.shuffle(&mut rng);

assert_eq!(indexed_spends.len(), indexed_outputs.len());

let pre_actions_len = pre_actions.len();

let new_actions = indexed_spends
.into_iter()
.zip(indexed_outputs.into_iter())
.enumerate()
.map(|(action_idx, ((spend_idx, spend), (out_idx, output)))| {
let action_idx = action_idx + pre_actions_len;

// Record the post-randomization spend location
if spend_idx < num_requested_spends {
bundle_meta.spend_indices[spend_idx] = action_idx;
}

// Record the post-randomization output location
if out_idx < num_requested_outputs {
bundle_meta.output_indices[out_idx] = action_idx;
}

ActionInfo::new(spend, output, &mut rng)
});

pre_actions.extend(new_actions);

(pre_actions, bundle_meta, 0)
},
);

// Determine the value balance for this bundle, ensuring it is valid.
let value_balance = pre_actions
let native_value_balance: V = pre_actions
.iter()
.filter(|action| action.spend.note.asset().is_native().into())
.fold(Some(ValueSum::zero()), |acc, action| {
acc? + action.value_sum()
})
.ok_or(OverflowError)?;

let result_value_balance: V = i64::try_from(value_balance)
.map_err(BuildError::ValueSum)
.and_then(|i| V::try_from(i).map_err(|_| BuildError::ValueSum(value::OverflowError)))?;
.ok_or(OverflowError)?
.into()?;

// Compute the transaction binding signing key.
let bsk = pre_actions
@@ -807,37 +815,25 @@ pub fn bundle<V: Copy + Into<i64> + TryFrom<i64>>(
let (actions, circuits): (Vec<_>, Vec<_>) =
pre_actions.into_iter().map(|a| a.build(&mut rng)).unzip();

let burn = burn
.into_iter()
.map(|(asset, value)| Ok((asset, value.into()?)))
.collect::<Result<_, BuildError>>()?;

let bundle = NonEmpty::from_vec(actions).map(|actions| {
(
Bundle::from_parts(
actions,
flags,
result_value_balance,
burn,
anchor,
InProgress {
proof: Unproven { circuits },
sigs: Unauthorized { bsk },
},
),
bundle_meta,
)
});

// Verify that bsk and bvk are consistent.
if let Some((bundle, _)) = &bundle {
assert_eq!(
redpallas::VerificationKey::from(&bundle.authorization().sigs.bsk),
bundle.binding_validating_key()
)
}

Ok(bundle)
let bundle = Bundle::from_parts(
NonEmpty::from_vec(actions).unwrap(),
flags,
native_value_balance,
burn.into_iter()
.map(|(asset, value)| Ok((asset, value.into()?)))
.collect::<Result<_, BuildError>>()?,
anchor,
InProgress {
proof: Unproven { circuits },
sigs: Unauthorized { bsk },
},
);

assert_eq!(
redpallas::VerificationKey::from(&bundle.authorization().sigs.bsk),
bundle.binding_validating_key()
);
Ok(Some((bundle, bundle_meta)))
}

/// Marker trait representing bundle signatures in the process of being created.