snarkvm_console_network/
mainnet_v0.rs

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