Skip to main content

snarkvm_console_network/
canary_v0.rs

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