snarkvm_console_network/
testnet_v0.rs

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