Skip to content

Commit e94d819

Browse files
committed
Feature-gate all code in ironfish-rust that requires Sapling parameters
This commit adds a new `transaction-proofs` Cargo feature (enabled by default) to the `ironfish-rust` crate. When this feature is disabled, all the structs and methods that create or verify zero-knowledge proofs are also disabled, hence making the Sapling parameters not needed. This way, developers have an option to use some of the `ironfish-rust` features (like transaction decryption) without having to deploy the Sapling parameters, which are several MBs in size. When `transaction-proofs` is disabled, all the transaction builder structs (like `ProposedTransaction`, `SpendBuilder, `OutputBuilder`, `MintBuilder`, ...) and related methods are unavailable, because those structs/methods all generate proofs. This commit also cleans up and reorganizes some code, in particular: * renamed the `ironfish::transaction::utils` module to `ironfish::transaction::verify`, because this module only contains methods for verification; * moved some of the transaction verification methods from `ironfish::transaction` to `ironfish::transaction::verify`; * moved `ProposedTransaction` to a dedicated submodule;
1 parent 29ed1d0 commit e94d819

File tree

11 files changed

+850
-771
lines changed

11 files changed

+850
-771
lines changed

ironfish-rust/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@ workspace = true
2424
workspace = true
2525

2626
[features]
27+
default = ["transaction-proofs"]
28+
2729
benchmark = []
2830
download-params = ["dep:reqwest"]
2931
note-encryption-stats = []
32+
transaction-proofs = []
3033

3134
[lib]
3235
name = "ironfish"

ironfish-rust/src/lib.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,35 @@ pub mod mining;
1414
pub mod nacl;
1515
pub mod note;
1616
pub mod rolling_filter;
17-
pub mod sapling_bls12;
1817
pub mod serializing;
1918
pub mod signal_catcher;
2019
pub mod transaction;
2120
pub mod util;
2221
pub mod witness;
2322
pub mod xchacha20poly1305;
2423

24+
#[cfg(any(test, feature = "benchmark"))]
25+
pub mod test_util;
26+
27+
#[cfg(feature = "transaction-proofs")]
28+
pub mod sapling_bls12;
29+
2530
pub use {
2631
ironfish_frost::frost,
2732
ironfish_frost::participant,
2833
keys::{IncomingViewKey, OutgoingViewKey, PublicAddress, SaplingKey, ViewKey},
2934
merkle_note::MerkleNote,
3035
merkle_note_hash::MerkleNoteHash,
3136
note::Note,
32-
transaction::{
33-
outputs::OutputDescription, spends::SpendDescription, ProposedTransaction, Transaction,
34-
},
37+
transaction::{outputs::OutputDescription, spends::SpendDescription, Transaction},
3538
};
3639

37-
#[cfg(any(test, feature = "benchmark"))]
38-
pub mod test_util;
39-
4040
#[cfg(feature = "benchmark")]
4141
pub use ironfish_zkp::primitives::ValueCommitment;
4242

43+
#[cfg(feature = "transaction-proofs")]
44+
pub use transaction::ProposedTransaction;
45+
4346
// The main entry-point to the sapling API. Construct this with loaded parameters, and then call
4447
// methods on it to do the actual work.
4548
//
@@ -57,6 +60,7 @@ pub struct Sapling {
5760
pub mint_verifying_key: groth16::PreparedVerifyingKey<Bls12>,
5861
}
5962

63+
#[cfg(feature = "transaction-proofs")]
6064
impl Sapling {
6165
/// Initialize a Sapling instance and prepare for proving. Load the parameters from files
6266
/// at a known location (`$OUT_DIR/sapling_params`).

ironfish-rust/src/merkle_note.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,29 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
44

5+
//! Implement a merkle note to store all the values that need to go into a merkle tree.
6+
//! A tree containing these values can serve as a snapshot of the entire chain.
7+
58
use crate::{
69
errors::IronfishError,
710
keys::EphemeralKeyPair,
8-
serializing::{read_point, read_point_unchecked},
9-
};
10-
11-
/// Implement a merkle note to store all the values that need to go into a merkle tree.
12-
/// A tree containing these values can serve as a snapshot of the entire chain.
13-
use super::{
1411
keys::{shared_secret, IncomingViewKey, OutgoingViewKey, PublicAddress},
1512
note::{Note, ENCRYPTED_NOTE_SIZE},
1613
serializing::{aead, read_scalar},
17-
witness::{WitnessNode, WitnessTrait},
14+
serializing::{read_point, read_point_unchecked},
1815
MerkleNoteHash,
1916
};
20-
2117
use blake2b_simd::Params as Blake2b;
2218
use blstrs::Scalar;
2319
use ff::PrimeField;
2420
use group::GroupEncoding;
2521
use ironfish_jubjub::{ExtendedPoint, SubgroupPoint};
2622
use ironfish_zkp::primitives::ValueCommitment;
27-
2823
use std::{convert::TryInto, io};
2924

25+
#[cfg(feature = "transaction-proofs")]
26+
use crate::witness::{WitnessNode, WitnessTrait};
27+
3028
pub const ENCRYPTED_SHARED_KEY_SIZE: usize = 64;
3129

3230
pub const NOTE_ENCRYPTION_KEY_SIZE: usize = ENCRYPTED_SHARED_KEY_SIZE + aead::MAC_SIZE;
@@ -108,6 +106,7 @@ impl MerkleNote {
108106

109107
/// Helper function to instantiate a MerkleNote with pre-set
110108
/// note_encryption_keys. Should only be used for miners fee transactions.
109+
#[cfg(feature = "transaction-proofs")]
111110
pub(crate) fn new_for_miners_fee(
112111
note: &Note,
113112
value_commitment: &ValueCommitment,
@@ -283,6 +282,7 @@ impl MerkleNote {
283282
}
284283
}
285284

285+
#[cfg(feature = "transaction-proofs")]
286286
pub(crate) fn sapling_auth_path(witness: &dyn WitnessTrait) -> Vec<Option<(Scalar, bool)>> {
287287
let mut auth_path = vec![];
288288
for element in &witness.get_auth_path() {
@@ -302,6 +302,7 @@ pub(crate) fn sapling_auth_path(witness: &dyn WitnessTrait) -> Vec<Option<(Scala
302302
/// on an assumption that the tree is complete and binary. And I didn't feel
303303
/// like making Witness a trait since it's otherwise very simple.
304304
/// So this hacky function gets to live here.
305+
#[cfg(feature = "transaction-proofs")]
305306
pub(crate) fn position(witness: &dyn WitnessTrait) -> u64 {
306307
let mut pos = 0;
307308
for (i, element) in witness.get_auth_path().iter().enumerate() {
@@ -460,9 +461,10 @@ mod test {
460461
);
461462
}
462463

463-
#[test]
464464
/// Test to confirm that creating a [`MerkleNote`] via new_for_miners_note()
465465
/// does use the hard-coded miners fee note encryption keys
466+
#[test]
467+
#[cfg(feature = "transaction-proofs")]
466468
fn test_new_miners_fee_key() {
467469
let receiver_key = SaplingKey::generate_key();
468470
let sender_key: SaplingKey = SaplingKey::generate_key();

ironfish-rust/src/transaction/mints.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
44

5-
use std::io;
6-
5+
use crate::{
6+
assets::asset::Asset,
7+
errors::{IronfishError, IronfishErrorKind},
8+
serializing::read_scalar,
9+
transaction::TransactionVersion,
10+
PublicAddress, SaplingKey,
11+
};
712
use blstrs::{Bls12, Scalar};
813
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
914
use ff::Field;
@@ -12,25 +17,19 @@ use ironfish_bellperson::groth16;
1217
use ironfish_jubjub::ExtendedPoint;
1318
use ironfish_zkp::{
1419
constants::SPENDING_KEY_GENERATOR,
15-
proofs::MintAsset,
1620
redjubjub::{self, Signature},
17-
ProofGenerationKey,
1821
};
1922
use rand::thread_rng;
23+
use std::io;
2024

21-
use crate::{
22-
assets::asset::Asset,
23-
errors::{IronfishError, IronfishErrorKind},
24-
sapling_bls12::SAPLING,
25-
serializing::read_scalar,
26-
transaction::TransactionVersion,
27-
PublicAddress, SaplingKey,
28-
};
29-
30-
use super::utils::verify_mint_proof;
25+
#[cfg(feature = "transaction-proofs")]
26+
use crate::{sapling_bls12::SAPLING, transaction::verify::verify_mint_proof};
27+
#[cfg(feature = "transaction-proofs")]
28+
use ironfish_zkp::{proofs::MintAsset, ProofGenerationKey};
3129

3230
/// Parameters used to build a circuit that verifies an asset can be minted with
3331
/// a given key
32+
#[cfg(feature = "transaction-proofs")]
3433
pub struct MintBuilder {
3534
/// Asset to be minted
3635
pub asset: Asset,
@@ -43,6 +42,7 @@ pub struct MintBuilder {
4342
pub transfer_ownership_to: Option<PublicAddress>,
4443
}
4544

45+
#[cfg(feature = "transaction-proofs")]
4646
impl MintBuilder {
4747
pub fn new(asset: Asset, value: u64) -> Self {
4848
Self {
@@ -362,25 +362,25 @@ impl MintDescription {
362362
}
363363

364364
#[cfg(test)]
365+
#[cfg(feature = "transaction-proofs")]
365366
mod test {
366-
use ff::Field;
367-
use ironfish_zkp::{constants::SPENDING_KEY_GENERATOR, redjubjub};
368-
use rand::{random, thread_rng};
369-
370367
use crate::{
371368
assets::asset::Asset,
372369
errors::IronfishErrorKind,
373370
transaction::{
374371
mints::{MintBuilder, MintDescription},
375-
utils::verify_mint_proof,
372+
verify::verify_mint_proof,
376373
TransactionVersion,
377374
},
378375
PublicAddress, SaplingKey,
379376
};
377+
use ff::Field;
378+
use ironfish_zkp::{constants::SPENDING_KEY_GENERATOR, redjubjub};
379+
use rand::{random, thread_rng};
380380

381-
#[test]
382381
/// Test that we can create a builder with a valid asset and proof
383382
/// generation key
383+
#[test]
384384
fn test_mint_builder() {
385385
let key = SaplingKey::generate_key();
386386
let creator = key.public_address();

0 commit comments

Comments
 (0)