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