Skip to main content

snarkvm_console_network/
mainnet_v0.rs

1// Copyright (c) 2019-2026 Provable Inc.
2// This file is part of the snarkVM library.
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7
8// http://www.apache.org/licenses/LICENSE-2.0
9
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use super::*;
17use snarkvm_console_algorithms::{
18    BHP256,
19    BHP512,
20    BHP768,
21    BHP1024,
22    Blake2Xs,
23    Keccak256,
24    Keccak384,
25    Keccak512,
26    Pedersen64,
27    Pedersen128,
28    Poseidon2,
29    Poseidon4,
30    Poseidon8,
31    Sha3_256,
32    Sha3_384,
33    Sha3_512,
34};
35
36lazy_static! {
37    /// The group bases for the Aleo signature and encryption schemes.
38    pub static ref GENERATOR_G: Vec<Group<MainnetV0 >> = MainnetV0::new_bases("AleoAccountEncryptionAndSignatureScheme0");
39
40    /// The Varuna sponge parameters.
41    pub static ref VARUNA_FS_PARAMETERS: FiatShamirParameters<MainnetV0> = FiatShamir::<MainnetV0>::sample_parameters();
42
43    /// The commitment domain as a constant field element.
44    static ref COMMITMENT_DOMAIN: Field<MainnetV0> = Field::<MainnetV0>::new_domain_separator("AleoCommitment0");
45    /// The encryption domain as a constant field element.
46    pub static ref ENCRYPTION_DOMAIN: Field<MainnetV0> = Field::<MainnetV0>::new_domain_separator("AleoSymmetricEncryption0");
47    /// The graph key domain as a constant field element.
48    pub static ref GRAPH_KEY_DOMAIN: Field<MainnetV0> = Field::<MainnetV0>::new_domain_separator("AleoGraphKey0");
49    /// The serial number domain as a constant field element.
50    pub static ref SERIAL_NUMBER_DOMAIN: Field<MainnetV0> = Field::<MainnetV0>::new_domain_separator("AleoSerialNumber0");
51
52    /// The BHP hash function, which can take an input of up to 256 bits.
53    pub static ref BHP_256: BHP256<MainnetV0> = BHP256::<MainnetV0>::setup("AleoBHP256").expect("Failed to setup BHP256");
54    /// The BHP hash function, which can take an input of up to 512 bits.
55    pub static ref BHP_512: BHP512<MainnetV0> = BHP512::<MainnetV0>::setup("AleoBHP512").expect("Failed to setup BHP512");
56    /// The BHP hash function, which can take an input of up to 768 bits.
57    pub static ref BHP_768: BHP768<MainnetV0> = BHP768::<MainnetV0>::setup("AleoBHP768").expect("Failed to setup BHP768");
58    /// The BHP hash function, which can take an input of up to 1024 bits.
59    pub static ref BHP_1024: BHP1024<MainnetV0> = BHP1024::<MainnetV0>::setup("AleoBHP1024").expect("Failed to setup BHP1024");
60
61    /// The Pedersen hash function, which can take an input of up to 64 bits.
62    pub static ref PEDERSEN_64: Pedersen64<MainnetV0> = Pedersen64::<MainnetV0>::setup("AleoPedersen64");
63    /// The Pedersen hash function, which can take an input of up to 128 bits.
64    pub static ref PEDERSEN_128: Pedersen128<MainnetV0> = Pedersen128::<MainnetV0>::setup("AleoPedersen128");
65
66    /// The Poseidon hash function, using a rate of 2.
67    pub static ref POSEIDON_2: Poseidon2<MainnetV0> = Poseidon2::<MainnetV0>::setup("AleoPoseidon2").expect("Failed to setup Poseidon2");
68    /// The Poseidon hash function, using a rate of 4.
69    pub static ref POSEIDON_4: Poseidon4<MainnetV0> = Poseidon4::<MainnetV0>::setup("AleoPoseidon4").expect("Failed to setup Poseidon4");
70    /// The Poseidon hash function, using a rate of 8.
71    pub static ref POSEIDON_8: Poseidon8<MainnetV0> = Poseidon8::<MainnetV0>::setup("AleoPoseidon8").expect("Failed to setup Poseidon8");
72
73    /// The Poseidon leaf hasher for dynamic records, using a rate of 8.
74    pub static ref DYNAMIC_RECORD_LEAF_HASHER: Poseidon8<MainnetV0> = Poseidon8::<MainnetV0>::setup("DynamicRecordLeafHasher").expect("Failed to setup DynamicRecordLeafHasher");
75    /// The Poseidon path hasher for dynamic records, using a rate of 2.
76    pub static ref DYNAMIC_RECORD_PATH_HASHER: Poseidon2<MainnetV0> = Poseidon2::<MainnetV0>::setup("DynamicRecordPathHasher").expect("Failed to setup DynamicRecordPathHasher");
77
78    pub static ref CREDITS_V0_PROVING_KEYS: IndexMap<String, Arc<VarunaProvingKey<Console>>> = {
79        let mut map = IndexMap::new();
80        snarkvm_parameters::insert_credit_v0_keys!(map, VarunaProvingKey<Console>, Prover);
81        map
82    };
83    pub static ref CREDITS_V0_VERIFYING_KEYS: IndexMap<String, Arc<VarunaVerifyingKey<Console>>> = {
84        let mut map = IndexMap::new();
85        snarkvm_parameters::insert_credit_v0_keys!(map, VarunaVerifyingKey<Console>, Verifier);
86        map
87    };
88
89    pub static ref CREDITS_PROVING_KEYS: IndexMap<String, Arc<VarunaProvingKey<Console>>> = {
90        let mut map = IndexMap::new();
91        snarkvm_parameters::insert_credit_keys!(map, VarunaProvingKey<Console>, Prover);
92        map
93    };
94    pub static ref CREDITS_VERIFYING_KEYS: IndexMap<String, Arc<VarunaVerifyingKey<Console>>> = {
95        let mut map = IndexMap::new();
96        snarkvm_parameters::insert_credit_keys!(map, VarunaVerifyingKey<Console>, Verifier);
97        map
98    };
99}
100
101pub const TRANSACTION_PREFIX: &str = "at";
102
103#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
104pub struct MainnetV0;
105
106impl MainnetV0 {
107    /// Initializes a new instance of group bases from a given input domain message.
108    fn new_bases(message: &str) -> Vec<Group<Self>> {
109        // Hash the given message to a point on the curve, to initialize the starting base.
110        let (base, _, _) = Blake2Xs::hash_to_curve::<<Self as Environment>::Affine>(message);
111
112        // Compute the bases up to the size of the scalar field (in bits).
113        let mut g = Group::<Self>::new(base);
114        let mut g_bases = Vec::with_capacity(Scalar::<Self>::size_in_bits());
115        for _ in 0..Scalar::<Self>::size_in_bits() {
116            g_bases.push(g);
117            g = g.double();
118        }
119        g_bases
120    }
121}
122
123impl Environment for MainnetV0 {
124    type Affine = <Console as Environment>::Affine;
125    type BigInteger = <Console as Environment>::BigInteger;
126    type Field = <Console as Environment>::Field;
127    type PairingCurve = <Console as Environment>::PairingCurve;
128    type Projective = <Console as Environment>::Projective;
129    type Scalar = <Console as Environment>::Scalar;
130
131    /// The coefficient `A` of the twisted Edwards curve.
132    const EDWARDS_A: Self::Field = Console::EDWARDS_A;
133    /// The coefficient `D` of the twisted Edwards curve.
134    const EDWARDS_D: Self::Field = Console::EDWARDS_D;
135    /// The coefficient `A` of the Montgomery curve.
136    const MONTGOMERY_A: Self::Field = Console::MONTGOMERY_A;
137    /// The coefficient `B` of the Montgomery curve.
138    const MONTGOMERY_B: Self::Field = Console::MONTGOMERY_B;
139}
140
141impl Network for MainnetV0 {
142    /// The block hash type.
143    type BlockHash = AleoID<Field<Self>, { hrp2!("ab") }>;
144    /// The ratification ID type.
145    type RatificationID = AleoID<Field<Self>, { hrp2!("ar") }>;
146    /// The state root type.
147    type StateRoot = AleoID<Field<Self>, { hrp2!("sr") }>;
148    /// The transaction ID type.
149    type TransactionID = AleoID<Field<Self>, { hrp2!(TRANSACTION_PREFIX) }>;
150    /// The transition ID type.
151    type TransitionID = AleoID<Field<Self>, { hrp2!("au") }>;
152    /// The transmission checksum type.
153    type TransmissionChecksum = u128;
154
155    /// The genesis block coinbase target.
156    #[cfg(not(feature = "test"))]
157    const GENESIS_COINBASE_TARGET: u64 = (1u64 << 29).saturating_sub(1);
158    /// The genesis block coinbase target.
159    /// This is deliberately set to a low value (32) for testing purposes only.
160    #[cfg(feature = "test")]
161    const GENESIS_COINBASE_TARGET: u64 = (1u64 << 5).saturating_sub(1);
162    /// The genesis block proof target.
163    #[cfg(not(feature = "test"))]
164    const GENESIS_PROOF_TARGET: u64 = 1u64 << 27;
165    /// The genesis block proof target.
166    /// This is deliberately set to a low value (8) for testing purposes only.
167    #[cfg(feature = "test")]
168    const GENESIS_PROOF_TARGET: u64 = 1u64 << 3;
169    /// The fixed timestamp of the genesis block.
170    const GENESIS_TIMESTAMP: i64 = 1725462000 /* 2024-09-04 11:00:00 UTC */;
171    /// The network ID.
172    const ID: u16 = 0;
173    /// The function name for the inclusion circuit.
174    const INCLUSION_FUNCTION_NAME: &'static str = snarkvm_parameters::mainnet::NETWORK_INCLUSION_FUNCTION_NAME;
175    /// A list of (consensus_version, size) pairs indicating the maximum number of certificates in a batch.
176    #[cfg(not(any(test, feature = "test")))]
177    const MAX_CERTIFICATES: [(ConsensusVersion, u16); 5] = [
178        (ConsensusVersion::V1, 16),
179        (ConsensusVersion::V3, 25),
180        (ConsensusVersion::V5, 30),
181        (ConsensusVersion::V6, 35),
182        (ConsensusVersion::V9, 40),
183    ];
184    /// A list of (consensus_version, size) pairs indicating the maximum number of certificates in a batch.
185    #[cfg(any(test, feature = "test"))]
186    const MAX_CERTIFICATES: [(ConsensusVersion, u16); 5] = [
187        (ConsensusVersion::V1, 100),
188        (ConsensusVersion::V3, 101),
189        (ConsensusVersion::V5, 102),
190        (ConsensusVersion::V6, 103),
191        (ConsensusVersion::V9, 104),
192    ];
193    /// The (long) network name.
194    const NAME: &'static str = "Aleo Mainnet (v0)";
195    /// The short network name.
196    const SHORT_NAME: &'static str = "mainnet";
197    /// A list of (consensus_version, block_height) pairs indicating when each consensus version takes effect.
198    /// Documentation for what is changed at each version can be found in `ConsensusVersion`.
199    /// Do not read this directly outside of tests, use `N::CONSENSUS_VERSION_HEIGHTS()` instead.
200    const _CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS] =
201        MAINNET_V0_CONSENSUS_VERSION_HEIGHTS;
202
203    /// Returns the block height where the the inclusion proof will be updated.
204    #[allow(non_snake_case)]
205    fn INCLUSION_UPGRADE_HEIGHT() -> Result<u32> {
206        Self::CONSENSUS_HEIGHT(ConsensusVersion::V8)
207    }
208
209    /// Returns the genesis block bytes.
210    fn genesis_bytes() -> &'static [u8] {
211        snarkvm_parameters::mainnet::GenesisBytes::load_bytes()
212    }
213
214    /// Returns the restrictions list as a JSON-compatible string.
215    fn restrictions_list_as_str() -> &'static str {
216        snarkvm_parameters::mainnet::RESTRICTIONS_LIST
217    }
218
219    /// Returns the proving key for the given function name in the v0 version of `credits.aleo`.
220    fn get_credits_v0_proving_key(function_name: String) -> Result<&'static Arc<VarunaProvingKey<Self>>> {
221        CREDITS_V0_PROVING_KEYS
222            .get(&function_name)
223            .ok_or_else(|| anyhow!("Proving key (v0) for credits.aleo/{function_name}' not found"))
224    }
225
226    /// Returns the verifying key for the given function name in the v0 version of `credits.aleo`.
227    fn get_credits_v0_verifying_key(function_name: String) -> Result<&'static Arc<VarunaVerifyingKey<Self>>> {
228        CREDITS_V0_VERIFYING_KEYS
229            .get(&function_name)
230            .ok_or_else(|| anyhow!("Verifying key (v0) for credits_v0.aleo/{function_name}' not found"))
231    }
232
233    /// Returns the proving key for the given function name in `credits.aleo`.
234    fn get_credits_proving_key(function_name: String) -> Result<&'static Arc<VarunaProvingKey<Self>>> {
235        CREDITS_PROVING_KEYS
236            .get(&function_name)
237            .ok_or_else(|| anyhow!("Proving key for credits.aleo/{function_name}' not found"))
238    }
239
240    /// Returns the verifying key for the given function name in `credits.aleo`.
241    fn get_credits_verifying_key(function_name: String) -> Result<&'static Arc<VarunaVerifyingKey<Self>>> {
242        CREDITS_VERIFYING_KEYS
243            .get(&function_name)
244            .ok_or_else(|| anyhow!("Verifying key for credits.aleo/{function_name}' not found"))
245    }
246
247    #[cfg(not(feature = "wasm"))]
248    /// Returns the `proving key` for the inclusion_v0 circuit.
249    fn inclusion_v0_proving_key() -> &'static Arc<VarunaProvingKey<Self>> {
250        static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
251        INSTANCE.get_or_init(|| {
252            // Skipping the first byte, which is the encoded version.
253            Arc::new(
254                CircuitProvingKey::from_bytes_le(&snarkvm_parameters::mainnet::INCLUSION_V0_PROVING_KEY[1..])
255                    .expect("Failed to load inclusion_v0 proving key."),
256            )
257        })
258    }
259
260    #[cfg(feature = "wasm")]
261    /// Returns the `proving key` for the inclusion_v0 circuit.
262    fn inclusion_v0_proving_key(inclusion_key_bytes: Option<Vec<u8>>) -> &'static Arc<VarunaProvingKey<Self>> {
263        static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
264        INSTANCE.get_or_init(|| {
265            inclusion_key_bytes
266                .map(|bytes| {
267                    snarkvm_parameters::mainnet::InclusionV0Prover::verify_bytes(&bytes)
268                        .expect("Bytes provided did not match expected inclusion checksum.");
269                    Arc::new(
270                        CircuitProvingKey::from_bytes_le(&bytes[1..]).expect("Failed to load inclusion proving key."),
271                    )
272                })
273                .unwrap_or_else(|| {
274                    Arc::new(
275                        CircuitProvingKey::from_bytes_le(&snarkvm_parameters::mainnet::INCLUSION_V0_PROVING_KEY[1..])
276                            .expect("Failed to load inclusion proving key."),
277                    )
278                })
279        })
280    }
281
282    /// Returns the `verifying key` for the inclusion_v0 circuit.
283    fn inclusion_v0_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>> {
284        static INSTANCE: OnceLock<Arc<VarunaVerifyingKey<Console>>> = OnceLock::new();
285        INSTANCE.get_or_init(|| {
286            // Skipping the first byte, which is the encoded version.
287            Arc::new(
288                CircuitVerifyingKey::from_bytes_le(&snarkvm_parameters::mainnet::INCLUSION_V0_VERIFYING_KEY[1..])
289                    .expect("Failed to load inclusion_v0 verifying key."),
290            )
291        })
292    }
293
294    #[cfg(not(feature = "wasm"))]
295    /// Returns the `proving key` for the inclusion circuit.
296    fn inclusion_proving_key() -> &'static Arc<VarunaProvingKey<Self>> {
297        static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
298        INSTANCE.get_or_init(|| {
299            // Skipping the first byte, which is the encoded version.
300            Arc::new(
301                CircuitProvingKey::from_bytes_le(&snarkvm_parameters::mainnet::INCLUSION_PROVING_KEY[1..])
302                    .expect("Failed to load inclusion proving key."),
303            )
304        })
305    }
306
307    #[cfg(feature = "wasm")]
308    /// Returns the `proving key` for the inclusion circuit.
309    fn inclusion_proving_key(inclusion_key_bytes: Option<Vec<u8>>) -> &'static Arc<VarunaProvingKey<Self>> {
310        static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
311        INSTANCE.get_or_init(|| {
312            inclusion_key_bytes
313                .map(|bytes| {
314                    snarkvm_parameters::mainnet::InclusionProver::verify_bytes(&bytes)
315                        .expect("Bytes provided did not match expected inclusion checksum.");
316                    Arc::new(
317                        CircuitProvingKey::from_bytes_le(&bytes[1..]).expect("Failed to load inclusion proving key."),
318                    )
319                })
320                .unwrap_or_else(|| {
321                    Arc::new(
322                        CircuitProvingKey::from_bytes_le(&snarkvm_parameters::mainnet::INCLUSION_PROVING_KEY[1..])
323                            .expect("Failed to load inclusion proving key."),
324                    )
325                })
326        })
327    }
328
329    /// Returns the `verifying key` for the inclusion circuit.
330    fn inclusion_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>> {
331        static INSTANCE: OnceLock<Arc<VarunaVerifyingKey<Console>>> = OnceLock::new();
332        INSTANCE.get_or_init(|| {
333            // Skipping the first byte, which is the encoded version.
334            Arc::new(
335                CircuitVerifyingKey::from_bytes_le(&snarkvm_parameters::mainnet::INCLUSION_VERIFYING_KEY[1..])
336                    .expect("Failed to load inclusion verifying key."),
337            )
338        })
339    }
340
341    #[cfg(not(feature = "wasm"))]
342    /// Returns the `proving key` for the credits.aleo credits record translation circuit.
343    fn translation_credits_proving_key() -> &'static Arc<VarunaProvingKey<Self>> {
344        static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
345        INSTANCE.get_or_init(|| {
346            // Skipping the first byte, which is the encoded version.
347            Arc::new(
348                CircuitProvingKey::from_bytes_le(&snarkvm_parameters::mainnet::TRANSLATION_CREDITS_PROVING_KEY[1..])
349                    .expect("Failed to load translation credits proving key."),
350            )
351        })
352    }
353
354    #[cfg(feature = "wasm")]
355    /// Returns the `proving key` for the translation credits circuit.
356    fn translation_credits_proving_key(
357        translation_credits_key_bytes: Option<Vec<u8>>,
358    ) -> &'static Arc<VarunaProvingKey<Self>> {
359        static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
360        INSTANCE.get_or_init(|| {
361            translation_credits_key_bytes
362                .map(|bytes| {
363                    snarkvm_parameters::mainnet::TranslationCreditsProver::verify_bytes(&bytes)
364                        .expect("Bytes provided did not match expected translation credits checksum.");
365                    Arc::new(
366                        CircuitProvingKey::from_bytes_le(&bytes[1..])
367                            .expect("Failed to load translation credits proving key."),
368                    )
369                })
370                .unwrap_or_else(|| {
371                    Arc::new(
372                        CircuitProvingKey::from_bytes_le(
373                            &snarkvm_parameters::mainnet::TRANSLATION_CREDITS_PROVING_KEY[1..],
374                        )
375                        .expect("Failed to load translation credits proving key."),
376                    )
377                })
378        })
379    }
380
381    /// Returns the `verifying key` for the translation circuit.
382    fn translation_credits_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>> {
383        static INSTANCE: OnceLock<Arc<VarunaVerifyingKey<Console>>> = OnceLock::new();
384        INSTANCE.get_or_init(|| {
385            Arc::new(
386                CircuitVerifyingKey::from_bytes_le(
387                    &snarkvm_parameters::mainnet::TRANSLATION_CREDITS_VERIFYING_KEY[1..],
388                )
389                .expect("Failed to load translation verifying key."),
390            )
391        })
392    }
393
394    /// Returns the powers of `G`.
395    fn g_powers() -> &'static Vec<Group<Self>> {
396        &GENERATOR_G
397    }
398
399    /// Returns the scalar multiplication on the generator `G`.
400    fn g_scalar_multiply(scalar: &Scalar<Self>) -> Group<Self> {
401        GENERATOR_G
402            .iter()
403            .zip_eq(&scalar.to_bits_le())
404            .filter_map(|(base, bit)| match bit {
405                true => Some(base),
406                false => None,
407            })
408            .sum()
409    }
410
411    /// Returns the Varuna universal prover.
412    fn varuna_universal_prover() -> &'static UniversalProver<Self::PairingCurve> {
413        static INSTANCE: OnceLock<UniversalProver<<Console as Environment>::PairingCurve>> = OnceLock::new();
414        INSTANCE.get_or_init(|| {
415            snarkvm_algorithms::polycommit::kzg10::UniversalParams::load()
416                .expect("Failed to load universal SRS (KZG10).")
417                .to_universal_prover()
418                .expect("Failed to convert universal SRS (KZG10) to the prover.")
419        })
420    }
421
422    /// Returns the Varuna universal verifier.
423    fn varuna_universal_verifier() -> &'static UniversalVerifier<Self::PairingCurve> {
424        static INSTANCE: OnceLock<UniversalVerifier<<Console as Environment>::PairingCurve>> = OnceLock::new();
425        INSTANCE.get_or_init(|| {
426            snarkvm_algorithms::polycommit::kzg10::UniversalParams::load()
427                .expect("Failed to load universal SRS (KZG10).")
428                .to_universal_verifier()
429                .expect("Failed to convert universal SRS (KZG10) to the verifier.")
430        })
431    }
432
433    /// Returns the sponge parameters used for the sponge in the Varuna SNARK.
434    fn varuna_fs_parameters() -> &'static FiatShamirParameters<Self> {
435        &VARUNA_FS_PARAMETERS
436    }
437
438    /// Returns the commitment domain as a constant field element.
439    fn commitment_domain() -> Field<Self> {
440        *COMMITMENT_DOMAIN
441    }
442
443    /// Returns the encryption domain as a constant field element.
444    fn encryption_domain() -> Field<Self> {
445        *ENCRYPTION_DOMAIN
446    }
447
448    /// Returns the graph key domain as a constant field element.
449    fn graph_key_domain() -> Field<Self> {
450        *GRAPH_KEY_DOMAIN
451    }
452
453    /// Returns the serial number domain as a constant field element.
454    fn serial_number_domain() -> Field<Self> {
455        *SERIAL_NUMBER_DOMAIN
456    }
457
458    /// Returns a BHP commitment with an input hasher of 256-bits and randomizer.
459    fn commit_bhp256(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
460        BHP_256.commit(input, randomizer)
461    }
462
463    /// Returns a BHP commitment with an input hasher of 512-bits and randomizer.
464    fn commit_bhp512(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
465        BHP_512.commit(input, randomizer)
466    }
467
468    /// Returns a BHP commitment with an input hasher of 768-bits and randomizer.
469    fn commit_bhp768(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
470        BHP_768.commit(input, randomizer)
471    }
472
473    /// Returns a BHP commitment with an input hasher of 1024-bits and randomizer.
474    fn commit_bhp1024(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
475        BHP_1024.commit(input, randomizer)
476    }
477
478    /// Returns a Pedersen commitment for the given (up to) 64-bit input and randomizer.
479    fn commit_ped64(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
480        PEDERSEN_64.commit(input, randomizer)
481    }
482
483    /// Returns a Pedersen commitment for the given (up to) 128-bit input and randomizer.
484    fn commit_ped128(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
485        PEDERSEN_128.commit(input, randomizer)
486    }
487
488    /// Returns a BHP commitment with an input hasher of 256-bits and randomizer.
489    fn commit_to_group_bhp256(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
490        BHP_256.commit_uncompressed(input, randomizer)
491    }
492
493    /// Returns a BHP commitment with an input hasher of 512-bits and randomizer.
494    fn commit_to_group_bhp512(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
495        BHP_512.commit_uncompressed(input, randomizer)
496    }
497
498    /// Returns a BHP commitment with an input hasher of 768-bits and randomizer.
499    fn commit_to_group_bhp768(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
500        BHP_768.commit_uncompressed(input, randomizer)
501    }
502
503    /// Returns a BHP commitment with an input hasher of 1024-bits and randomizer.
504    fn commit_to_group_bhp1024(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
505        BHP_1024.commit_uncompressed(input, randomizer)
506    }
507
508    /// Returns a Pedersen commitment for the given (up to) 64-bit input and randomizer.
509    fn commit_to_group_ped64(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
510        PEDERSEN_64.commit_uncompressed(input, randomizer)
511    }
512
513    /// Returns a Pedersen commitment for the given (up to) 128-bit input and randomizer.
514    fn commit_to_group_ped128(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
515        PEDERSEN_128.commit_uncompressed(input, randomizer)
516    }
517
518    /// Returns the BHP hash with an input hasher of 256-bits.
519    fn hash_bhp256(input: &[bool]) -> Result<Field<Self>> {
520        BHP_256.hash(input)
521    }
522
523    /// Returns the BHP hash with an input hasher of 512-bits.
524    fn hash_bhp512(input: &[bool]) -> Result<Field<Self>> {
525        BHP_512.hash(input)
526    }
527
528    /// Returns the BHP hash with an input hasher of 768-bits.
529    fn hash_bhp768(input: &[bool]) -> Result<Field<Self>> {
530        BHP_768.hash(input)
531    }
532
533    /// Returns the BHP hash with an input hasher of 1024-bits.
534    fn hash_bhp1024(input: &[bool]) -> Result<Field<Self>> {
535        BHP_1024.hash(input)
536    }
537
538    /// Returns the Keccak hash with a 256-bit output.
539    fn hash_keccak256(input: &[bool]) -> Result<Vec<bool>> {
540        Keccak256::default().hash(input)
541    }
542
543    /// Returns the Keccak hash with a 384-bit output.
544    fn hash_keccak384(input: &[bool]) -> Result<Vec<bool>> {
545        Keccak384::default().hash(input)
546    }
547
548    /// Returns the Keccak hash with a 512-bit output.
549    fn hash_keccak512(input: &[bool]) -> Result<Vec<bool>> {
550        Keccak512::default().hash(input)
551    }
552
553    /// Returns the Pedersen hash for a given (up to) 64-bit input.
554    fn hash_ped64(input: &[bool]) -> Result<Field<Self>> {
555        PEDERSEN_64.hash(input)
556    }
557
558    /// Returns the Pedersen hash for a given (up to) 128-bit input.
559    fn hash_ped128(input: &[bool]) -> Result<Field<Self>> {
560        PEDERSEN_128.hash(input)
561    }
562
563    /// Returns the Poseidon hash with an input rate of 2.
564    fn hash_psd2(input: &[Field<Self>]) -> Result<Field<Self>> {
565        POSEIDON_2.hash(input)
566    }
567
568    /// Returns the Poseidon hash with an input rate of 4.
569    fn hash_psd4(input: &[Field<Self>]) -> Result<Field<Self>> {
570        POSEIDON_4.hash(input)
571    }
572
573    /// Returns the Poseidon hash with an input rate of 8.
574    fn hash_psd8(input: &[Field<Self>]) -> Result<Field<Self>> {
575        POSEIDON_8.hash(input)
576    }
577
578    /// Returns the SHA-3 hash with a 256-bit output.
579    fn hash_sha3_256(input: &[bool]) -> Result<Vec<bool>> {
580        Sha3_256::default().hash(input)
581    }
582
583    /// Returns the SHA-3 hash with a 384-bit output.
584    fn hash_sha3_384(input: &[bool]) -> Result<Vec<bool>> {
585        Sha3_384::default().hash(input)
586    }
587
588    /// Returns the SHA-3 hash with a 512-bit output.
589    fn hash_sha3_512(input: &[bool]) -> Result<Vec<bool>> {
590        Sha3_512::default().hash(input)
591    }
592
593    /// Returns the extended Poseidon hash with an input rate of 2.
594    fn hash_many_psd2(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
595        POSEIDON_2.hash_many(input, num_outputs)
596    }
597
598    /// Returns the extended Poseidon hash with an input rate of 4.
599    fn hash_many_psd4(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
600        POSEIDON_4.hash_many(input, num_outputs)
601    }
602
603    /// Returns the extended Poseidon hash with an input rate of 8.
604    fn hash_many_psd8(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
605        POSEIDON_8.hash_many(input, num_outputs)
606    }
607
608    /// Returns the BHP hash with an input hasher of 256-bits.
609    fn hash_to_group_bhp256(input: &[bool]) -> Result<Group<Self>> {
610        BHP_256.hash_uncompressed(input)
611    }
612
613    /// Returns the BHP hash with an input hasher of 512-bits.
614    fn hash_to_group_bhp512(input: &[bool]) -> Result<Group<Self>> {
615        BHP_512.hash_uncompressed(input)
616    }
617
618    /// Returns the BHP hash with an input hasher of 768-bits.
619    fn hash_to_group_bhp768(input: &[bool]) -> Result<Group<Self>> {
620        BHP_768.hash_uncompressed(input)
621    }
622
623    /// Returns the BHP hash with an input hasher of 1024-bits.
624    fn hash_to_group_bhp1024(input: &[bool]) -> Result<Group<Self>> {
625        BHP_1024.hash_uncompressed(input)
626    }
627
628    /// Returns the Pedersen hash for a given (up to) 64-bit input.
629    fn hash_to_group_ped64(input: &[bool]) -> Result<Group<Self>> {
630        PEDERSEN_64.hash_uncompressed(input)
631    }
632
633    /// Returns the Pedersen hash for a given (up to) 128-bit input.
634    fn hash_to_group_ped128(input: &[bool]) -> Result<Group<Self>> {
635        PEDERSEN_128.hash_uncompressed(input)
636    }
637
638    /// Returns the Poseidon hash with an input rate of 2 on the affine curve.
639    fn hash_to_group_psd2(input: &[Field<Self>]) -> Result<Group<Self>> {
640        POSEIDON_2.hash_to_group(input)
641    }
642
643    /// Returns the Poseidon hash with an input rate of 4 on the affine curve.
644    fn hash_to_group_psd4(input: &[Field<Self>]) -> Result<Group<Self>> {
645        POSEIDON_4.hash_to_group(input)
646    }
647
648    /// Returns the Poseidon hash with an input rate of 8 on the affine curve.
649    fn hash_to_group_psd8(input: &[Field<Self>]) -> Result<Group<Self>> {
650        POSEIDON_8.hash_to_group(input)
651    }
652
653    /// Returns the Poseidon hash with an input rate of 2 on the scalar field.
654    fn hash_to_scalar_psd2(input: &[Field<Self>]) -> Result<Scalar<Self>> {
655        POSEIDON_2.hash_to_scalar(input)
656    }
657
658    /// Returns the Poseidon hash with an input rate of 4 on the scalar field.
659    fn hash_to_scalar_psd4(input: &[Field<Self>]) -> Result<Scalar<Self>> {
660        POSEIDON_4.hash_to_scalar(input)
661    }
662
663    /// Returns the Poseidon hash with an input rate of 8 on the scalar field.
664    fn hash_to_scalar_psd8(input: &[Field<Self>]) -> Result<Scalar<Self>> {
665        POSEIDON_8.hash_to_scalar(input)
666    }
667
668    /// Returns a Merkle tree with a BHP leaf hasher of 1024-bits and a BHP path hasher of 512-bits.
669    fn merkle_tree_bhp<const DEPTH: u8>(leaves: &[Vec<bool>]) -> Result<BHPMerkleTree<Self, DEPTH>> {
670        MerkleTree::new(&*BHP_1024, &*BHP_512, leaves)
671    }
672
673    /// Returns a Merkle tree with a Poseidon leaf hasher with input rate of 4 and a Poseidon path hasher with input rate of 2.
674    fn merkle_tree_psd<const DEPTH: u8>(leaves: &[Vec<Field<Self>>]) -> Result<PoseidonMerkleTree<Self, DEPTH>> {
675        MerkleTree::new(&*POSEIDON_4, &*POSEIDON_2, leaves)
676    }
677
678    /// Returns `true` if the given Merkle path is valid for the given root and leaf.
679    fn verify_merkle_path_bhp<const DEPTH: u8>(
680        path: &MerklePath<Self, DEPTH>,
681        root: &Field<Self>,
682        leaf: &Vec<bool>,
683    ) -> bool {
684        path.verify(&*BHP_1024, &*BHP_512, root, leaf)
685    }
686
687    /// Returns `true` if the given Merkle path is valid for the given root and leaf.
688    fn verify_merkle_path_psd<const DEPTH: u8>(
689        path: &MerklePath<Self, DEPTH>,
690        root: &Field<Self>,
691        leaf: &Vec<Field<Self>>,
692    ) -> bool {
693        path.verify(&*POSEIDON_4, &*POSEIDON_2, root, leaf)
694    }
695
696    /// Returns the Poseidon leaf hasher for dynamic records (rate 8).
697    fn dynamic_record_leaf_hasher() -> &'static Poseidon8<Self> {
698        &DYNAMIC_RECORD_LEAF_HASHER
699    }
700
701    /// Returns the Poseidon path hasher for dynamic records (rate 2).
702    fn dynamic_record_path_hasher() -> &'static Poseidon2<Self> {
703        &DYNAMIC_RECORD_PATH_HASHER
704    }
705}
706
707#[cfg(test)]
708mod tests {
709    use super::*;
710
711    type CurrentNetwork = MainnetV0;
712
713    #[test]
714    fn test_g_scalar_multiply() {
715        // Compute G^r.
716        let scalar = Scalar::rand(&mut TestRng::default());
717        let group = CurrentNetwork::g_scalar_multiply(&scalar);
718        assert_eq!(group, CurrentNetwork::g_powers()[0] * scalar);
719    }
720}