1use 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    static ref GENERATOR_G: Vec<Group<CanaryV0 >> = CanaryV0::new_bases("AleoAccountEncryptionAndSignatureScheme0");
40
41    static ref VARUNA_FS_PARAMETERS: FiatShamirParameters<CanaryV0> = FiatShamir::<CanaryV0>::sample_parameters();
43
44    static ref COMMITMENT_DOMAIN: Field<CanaryV0> = Field::<CanaryV0>::new_domain_separator("AleoCommitment0");
46    static ref ENCRYPTION_DOMAIN: Field<CanaryV0> = Field::<CanaryV0>::new_domain_separator("AleoSymmetricEncryption0");
48    static ref GRAPH_KEY_DOMAIN: Field<CanaryV0> = Field::<CanaryV0>::new_domain_separator("AleoGraphKey0");
50    static ref SERIAL_NUMBER_DOMAIN: Field<CanaryV0> = Field::<CanaryV0>::new_domain_separator("AleoSerialNumber0");
52
53    pub static ref CANARY_BHP_256: BHP256<CanaryV0> = BHP256::<CanaryV0>::setup("AleoBHP256").expect("Failed to setup BHP256");
55    pub static ref CANARY_BHP_512: BHP512<CanaryV0> = BHP512::<CanaryV0>::setup("AleoBHP512").expect("Failed to setup BHP512");
57    pub static ref CANARY_BHP_768: BHP768<CanaryV0> = BHP768::<CanaryV0>::setup("AleoBHP768").expect("Failed to setup BHP768");
59    pub static ref CANARY_BHP_1024: BHP1024<CanaryV0> = BHP1024::<CanaryV0>::setup("AleoBHP1024").expect("Failed to setup BHP1024");
61
62    pub static ref CANARY_PEDERSEN_64: Pedersen64<CanaryV0> = Pedersen64::<CanaryV0>::setup("AleoPedersen64");
64    pub static ref CANARY_PEDERSEN_128: Pedersen128<CanaryV0> = Pedersen128::<CanaryV0>::setup("AleoPedersen128");
66
67    pub static ref CANARY_POSEIDON_2: Poseidon2<CanaryV0> = Poseidon2::<CanaryV0>::setup("AleoPoseidon2").expect("Failed to setup Poseidon2");
69    pub static ref CANARY_POSEIDON_4: Poseidon4<CanaryV0> = Poseidon4::<CanaryV0>::setup("AleoPoseidon4").expect("Failed to setup Poseidon4");
71    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    fn new_bases(message: &str) -> Vec<Group<Self>> {
103        let (base, _, _) = Blake2Xs::hash_to_curve::<<Self as Environment>::Affine>(message);
105
106        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    const EDWARDS_A: Self::Field = Console::EDWARDS_A;
127    const EDWARDS_D: Self::Field = Console::EDWARDS_D;
129    const MONTGOMERY_A: Self::Field = Console::MONTGOMERY_A;
131    const MONTGOMERY_B: Self::Field = Console::MONTGOMERY_B;
133}
134
135impl Network for CanaryV0 {
136    type BlockHash = AleoID<Field<Self>, { hrp2!("ab") }>;
138    type RatificationID = AleoID<Field<Self>, { hrp2!("ar") }>;
140    type StateRoot = AleoID<Field<Self>, { hrp2!("sr") }>;
142    type TransactionID = AleoID<Field<Self>, { hrp2!(TRANSACTION_PREFIX) }>;
144    type TransitionID = AleoID<Field<Self>, { hrp2!("au") }>;
146    type TransmissionChecksum = u128;
148
149    #[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    #[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    const GENESIS_TIMESTAMP: i64 = 1715776496 ;
161    const ID: u16 = 2;
163    const INCLUSION_FUNCTION_NAME: &'static str = snarkvm_parameters::canary::NETWORK_INCLUSION_FUNCTION_NAME;
165    #[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    #[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    const NAME: &'static str = "Aleo Canary (v0)";
185    const SHORT_NAME: &'static str = "canary";
187    const _CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS] =
191        CANARY_V0_CONSENSUS_VERSION_HEIGHTS;
192
193    #[allow(non_snake_case)]
195    fn INCLUSION_UPGRADE_HEIGHT() -> Result<u32> {
196        Self::CONSENSUS_HEIGHT(ConsensusVersion::V8)
197    }
198
199    fn genesis_bytes() -> &'static [u8] {
201        snarkvm_parameters::canary::GenesisBytes::load_bytes()
202    }
203
204    fn restrictions_list_as_str() -> &'static str {
206        snarkvm_parameters::canary::RESTRICTIONS_LIST
207    }
208
209    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    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    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    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    #[cfg(not(feature = "wasm"))]
238    fn inclusion_v0_proving_key() -> &'static Arc<VarunaProvingKey<Self>> {
240        static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
241        INSTANCE.get_or_init(|| {
242            Arc::new(
244                CircuitProvingKey::from_bytes_le(&snarkvm_parameters::canary::INCLUSION_V0_PROVING_KEY[1..])
245                    .expect("Failed to load inclusion_v0 proving key."),
246            )
247        })
248    }
249
250    #[cfg(feature = "wasm")]
251    fn inclusion_v0_proving_key(inclusion_key_bytes: Option<Vec<u8>>) -> &'static Arc<VarunaProvingKey<Self>> {
253        static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
254        INSTANCE.get_or_init(|| {
255            inclusion_key_bytes
256                .map(|bytes| {
257                    snarkvm_parameters::canary::InclusionV0Prover::verify_bytes(&bytes)
258                        .expect("Bytes provided did not match expected inclusion checksum.");
259                    Arc::new(
260                        CircuitProvingKey::from_bytes_le(&bytes[1..]).expect("Failed to load inclusion proving key."),
261                    )
262                })
263                .unwrap_or_else(|| {
264                    Arc::new(
265                        CircuitProvingKey::from_bytes_le(&snarkvm_parameters::canary::INCLUSION_V0_PROVING_KEY[1..])
266                            .expect("Failed to load inclusion proving key."),
267                    )
268                })
269        })
270    }
271
272    fn inclusion_v0_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>> {
274        static INSTANCE: OnceLock<Arc<VarunaVerifyingKey<Console>>> = OnceLock::new();
275        INSTANCE.get_or_init(|| {
276            Arc::new(
278                CircuitVerifyingKey::from_bytes_le(&snarkvm_parameters::canary::INCLUSION_V0_VERIFYING_KEY[1..])
279                    .expect("Failed to load inclusion_v0 verifying key."),
280            )
281        })
282    }
283
284    #[cfg(not(feature = "wasm"))]
285    fn inclusion_proving_key() -> &'static Arc<VarunaProvingKey<Self>> {
287        static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
288        INSTANCE.get_or_init(|| {
289            Arc::new(
291                CircuitProvingKey::from_bytes_le(&snarkvm_parameters::canary::INCLUSION_PROVING_KEY[1..])
292                    .expect("Failed to load inclusion proving key."),
293            )
294        })
295    }
296
297    #[cfg(feature = "wasm")]
298    fn inclusion_proving_key(inclusion_key_bytes: Option<Vec<u8>>) -> &'static Arc<VarunaProvingKey<Self>> {
300        static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
301        INSTANCE.get_or_init(|| {
302            inclusion_key_bytes
303                .map(|bytes| {
304                    snarkvm_parameters::canary::InclusionProver::verify_bytes(&bytes)
305                        .expect("Bytes provided did not match expected inclusion checksum.");
306                    Arc::new(
307                        CircuitProvingKey::from_bytes_le(&bytes[1..]).expect("Failed to load inclusion proving key."),
308                    )
309                })
310                .unwrap_or_else(|| {
311                    Arc::new(
312                        CircuitProvingKey::from_bytes_le(&snarkvm_parameters::canary::INCLUSION_PROVING_KEY[1..])
313                            .expect("Failed to load inclusion proving key."),
314                    )
315                })
316        })
317    }
318
319    fn inclusion_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>> {
321        static INSTANCE: OnceLock<Arc<VarunaVerifyingKey<Console>>> = OnceLock::new();
322        INSTANCE.get_or_init(|| {
323            Arc::new(
325                CircuitVerifyingKey::from_bytes_le(&snarkvm_parameters::canary::INCLUSION_VERIFYING_KEY[1..])
326                    .expect("Failed to load inclusion verifying key."),
327            )
328        })
329    }
330
331    fn g_powers() -> &'static Vec<Group<Self>> {
333        &GENERATOR_G
334    }
335
336    fn g_scalar_multiply(scalar: &Scalar<Self>) -> Group<Self> {
338        GENERATOR_G
339            .iter()
340            .zip_eq(&scalar.to_bits_le())
341            .filter_map(|(base, bit)| match bit {
342                true => Some(base),
343                false => None,
344            })
345            .sum()
346    }
347
348    fn varuna_universal_prover() -> &'static UniversalProver<Self::PairingCurve> {
350        MainnetV0::varuna_universal_prover()
351    }
352
353    fn varuna_universal_verifier() -> &'static UniversalVerifier<Self::PairingCurve> {
355        MainnetV0::varuna_universal_verifier()
356    }
357
358    fn varuna_fs_parameters() -> &'static FiatShamirParameters<Self> {
360        &VARUNA_FS_PARAMETERS
361    }
362
363    fn commitment_domain() -> Field<Self> {
365        *COMMITMENT_DOMAIN
366    }
367
368    fn encryption_domain() -> Field<Self> {
370        *ENCRYPTION_DOMAIN
371    }
372
373    fn graph_key_domain() -> Field<Self> {
375        *GRAPH_KEY_DOMAIN
376    }
377
378    fn serial_number_domain() -> Field<Self> {
380        *SERIAL_NUMBER_DOMAIN
381    }
382
383    fn commit_bhp256(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
385        CANARY_BHP_256.commit(input, randomizer)
386    }
387
388    fn commit_bhp512(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
390        CANARY_BHP_512.commit(input, randomizer)
391    }
392
393    fn commit_bhp768(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
395        CANARY_BHP_768.commit(input, randomizer)
396    }
397
398    fn commit_bhp1024(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
400        CANARY_BHP_1024.commit(input, randomizer)
401    }
402
403    fn commit_ped64(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
405        CANARY_PEDERSEN_64.commit(input, randomizer)
406    }
407
408    fn commit_ped128(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
410        CANARY_PEDERSEN_128.commit(input, randomizer)
411    }
412
413    fn commit_to_group_bhp256(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
415        CANARY_BHP_256.commit_uncompressed(input, randomizer)
416    }
417
418    fn commit_to_group_bhp512(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
420        CANARY_BHP_512.commit_uncompressed(input, randomizer)
421    }
422
423    fn commit_to_group_bhp768(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
425        CANARY_BHP_768.commit_uncompressed(input, randomizer)
426    }
427
428    fn commit_to_group_bhp1024(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
430        CANARY_BHP_1024.commit_uncompressed(input, randomizer)
431    }
432
433    fn commit_to_group_ped64(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
435        CANARY_PEDERSEN_64.commit_uncompressed(input, randomizer)
436    }
437
438    fn commit_to_group_ped128(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
440        CANARY_PEDERSEN_128.commit_uncompressed(input, randomizer)
441    }
442
443    fn hash_bhp256(input: &[bool]) -> Result<Field<Self>> {
445        CANARY_BHP_256.hash(input)
446    }
447
448    fn hash_bhp512(input: &[bool]) -> Result<Field<Self>> {
450        CANARY_BHP_512.hash(input)
451    }
452
453    fn hash_bhp768(input: &[bool]) -> Result<Field<Self>> {
455        CANARY_BHP_768.hash(input)
456    }
457
458    fn hash_bhp1024(input: &[bool]) -> Result<Field<Self>> {
460        CANARY_BHP_1024.hash(input)
461    }
462
463    fn hash_keccak256(input: &[bool]) -> Result<Vec<bool>> {
465        Keccak256::default().hash(input)
466    }
467
468    fn hash_keccak384(input: &[bool]) -> Result<Vec<bool>> {
470        Keccak384::default().hash(input)
471    }
472
473    fn hash_keccak512(input: &[bool]) -> Result<Vec<bool>> {
475        Keccak512::default().hash(input)
476    }
477
478    fn hash_ped64(input: &[bool]) -> Result<Field<Self>> {
480        CANARY_PEDERSEN_64.hash(input)
481    }
482
483    fn hash_ped128(input: &[bool]) -> Result<Field<Self>> {
485        CANARY_PEDERSEN_128.hash(input)
486    }
487
488    fn hash_psd2(input: &[Field<Self>]) -> Result<Field<Self>> {
490        CANARY_POSEIDON_2.hash(input)
491    }
492
493    fn hash_psd4(input: &[Field<Self>]) -> Result<Field<Self>> {
495        CANARY_POSEIDON_4.hash(input)
496    }
497
498    fn hash_psd8(input: &[Field<Self>]) -> Result<Field<Self>> {
500        CANARY_POSEIDON_8.hash(input)
501    }
502
503    fn hash_sha3_256(input: &[bool]) -> Result<Vec<bool>> {
505        Sha3_256::default().hash(input)
506    }
507
508    fn hash_sha3_384(input: &[bool]) -> Result<Vec<bool>> {
510        Sha3_384::default().hash(input)
511    }
512
513    fn hash_sha3_512(input: &[bool]) -> Result<Vec<bool>> {
515        Sha3_512::default().hash(input)
516    }
517
518    fn hash_many_psd2(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
520        CANARY_POSEIDON_2.hash_many(input, num_outputs)
521    }
522
523    fn hash_many_psd4(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
525        CANARY_POSEIDON_4.hash_many(input, num_outputs)
526    }
527
528    fn hash_many_psd8(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
530        CANARY_POSEIDON_8.hash_many(input, num_outputs)
531    }
532
533    fn hash_to_group_bhp256(input: &[bool]) -> Result<Group<Self>> {
535        CANARY_BHP_256.hash_uncompressed(input)
536    }
537
538    fn hash_to_group_bhp512(input: &[bool]) -> Result<Group<Self>> {
540        CANARY_BHP_512.hash_uncompressed(input)
541    }
542
543    fn hash_to_group_bhp768(input: &[bool]) -> Result<Group<Self>> {
545        CANARY_BHP_768.hash_uncompressed(input)
546    }
547
548    fn hash_to_group_bhp1024(input: &[bool]) -> Result<Group<Self>> {
550        CANARY_BHP_1024.hash_uncompressed(input)
551    }
552
553    fn hash_to_group_ped64(input: &[bool]) -> Result<Group<Self>> {
555        CANARY_PEDERSEN_64.hash_uncompressed(input)
556    }
557
558    fn hash_to_group_ped128(input: &[bool]) -> Result<Group<Self>> {
560        CANARY_PEDERSEN_128.hash_uncompressed(input)
561    }
562
563    fn hash_to_group_psd2(input: &[Field<Self>]) -> Result<Group<Self>> {
565        CANARY_POSEIDON_2.hash_to_group(input)
566    }
567
568    fn hash_to_group_psd4(input: &[Field<Self>]) -> Result<Group<Self>> {
570        CANARY_POSEIDON_4.hash_to_group(input)
571    }
572
573    fn hash_to_group_psd8(input: &[Field<Self>]) -> Result<Group<Self>> {
575        CANARY_POSEIDON_8.hash_to_group(input)
576    }
577
578    fn hash_to_scalar_psd2(input: &[Field<Self>]) -> Result<Scalar<Self>> {
580        CANARY_POSEIDON_2.hash_to_scalar(input)
581    }
582
583    fn hash_to_scalar_psd4(input: &[Field<Self>]) -> Result<Scalar<Self>> {
585        CANARY_POSEIDON_4.hash_to_scalar(input)
586    }
587
588    fn hash_to_scalar_psd8(input: &[Field<Self>]) -> Result<Scalar<Self>> {
590        CANARY_POSEIDON_8.hash_to_scalar(input)
591    }
592
593    fn merkle_tree_bhp<const DEPTH: u8>(leaves: &[Vec<bool>]) -> Result<BHPMerkleTree<Self, DEPTH>> {
595        MerkleTree::new(&*CANARY_BHP_1024, &*CANARY_BHP_512, leaves)
596    }
597
598    fn merkle_tree_psd<const DEPTH: u8>(leaves: &[Vec<Field<Self>>]) -> Result<PoseidonMerkleTree<Self, DEPTH>> {
600        MerkleTree::new(&*CANARY_POSEIDON_4, &*CANARY_POSEIDON_2, leaves)
601    }
602
603    fn verify_merkle_path_bhp<const DEPTH: u8>(
605        path: &MerklePath<Self, DEPTH>,
606        root: &Field<Self>,
607        leaf: &Vec<bool>,
608    ) -> bool {
609        path.verify(&*CANARY_BHP_1024, &*CANARY_BHP_512, root, leaf)
610    }
611
612    fn verify_merkle_path_psd<const DEPTH: u8>(
614        path: &MerklePath<Self, DEPTH>,
615        root: &Field<Self>,
616        leaf: &Vec<Field<Self>>,
617    ) -> bool {
618        path.verify(&*CANARY_POSEIDON_4, &*CANARY_POSEIDON_2, root, leaf)
619    }
620}
621
622#[cfg(test)]
623mod tests {
624    use super::*;
625
626    type CurrentNetwork = CanaryV0;
627
628    #[test]
629    fn test_g_scalar_multiply() {
630        let scalar = Scalar::rand(&mut TestRng::default());
632        let group = CurrentNetwork::g_scalar_multiply(&scalar);
633        assert_eq!(group, CurrentNetwork::g_powers()[0] * scalar);
634    }
635}