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