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 ENCRYPTION_DOMAIN: Field<CanaryV0> = Field::<CanaryV0>::new_domain_separator("AleoSymmetricEncryption0");
46 static ref GRAPH_KEY_DOMAIN: Field<CanaryV0> = Field::<CanaryV0>::new_domain_separator("AleoGraphKey0");
48 static ref SERIAL_NUMBER_DOMAIN: Field<CanaryV0> = Field::<CanaryV0>::new_domain_separator("AleoSerialNumber0");
50
51 pub static ref CANARY_BHP_256: BHP256<CanaryV0> = BHP256::<CanaryV0>::setup("AleoBHP256").expect("Failed to setup BHP256");
53 pub static ref CANARY_BHP_512: BHP512<CanaryV0> = BHP512::<CanaryV0>::setup("AleoBHP512").expect("Failed to setup BHP512");
55 pub static ref CANARY_BHP_768: BHP768<CanaryV0> = BHP768::<CanaryV0>::setup("AleoBHP768").expect("Failed to setup BHP768");
57 pub static ref CANARY_BHP_1024: BHP1024<CanaryV0> = BHP1024::<CanaryV0>::setup("AleoBHP1024").expect("Failed to setup BHP1024");
59
60 pub static ref CANARY_PEDERSEN_64: Pedersen64<CanaryV0> = Pedersen64::<CanaryV0>::setup("AleoPedersen64");
62 pub static ref CANARY_PEDERSEN_128: Pedersen128<CanaryV0> = Pedersen128::<CanaryV0>::setup("AleoPedersen128");
64
65 pub static ref CANARY_POSEIDON_2: Poseidon2<CanaryV0> = Poseidon2::<CanaryV0>::setup("AleoPoseidon2").expect("Failed to setup Poseidon2");
67 pub static ref CANARY_POSEIDON_4: Poseidon4<CanaryV0> = Poseidon4::<CanaryV0>::setup("AleoPoseidon4").expect("Failed to setup Poseidon4");
69 pub static ref CANARY_POSEIDON_8: Poseidon8<CanaryV0> = Poseidon8::<CanaryV0>::setup("AleoPoseidon8").expect("Failed to setup Poseidon8");
71
72 pub static ref CANARY_CREDITS_PROVING_KEYS: IndexMap<String, Arc<VarunaProvingKey<Console>>> = {
73 let mut map = IndexMap::new();
74 snarkvm_parameters::insert_canary_credit_keys!(map, VarunaProvingKey<Console>, Prover);
75 map
76 };
77 pub static ref CANARY_CREDITS_VERIFYING_KEYS: IndexMap<String, Arc<VarunaVerifyingKey<Console>>> = {
78 let mut map = IndexMap::new();
79 snarkvm_parameters::insert_canary_credit_keys!(map, VarunaVerifyingKey<Console>, Verifier);
80 map
81 };
82}
83
84#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
85pub struct CanaryV0;
86
87impl CanaryV0 {
88 fn new_bases(message: &str) -> Vec<Group<Self>> {
90 let (base, _, _) = Blake2Xs::hash_to_curve::<<Self as Environment>::Affine>(message);
92
93 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 CanaryV0 {
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 const EDWARDS_A: Self::Field = Console::EDWARDS_A;
114 const EDWARDS_D: Self::Field = Console::EDWARDS_D;
116 const MONTGOMERY_A: Self::Field = Console::MONTGOMERY_A;
118 const MONTGOMERY_B: Self::Field = Console::MONTGOMERY_B;
120}
121
122impl Network for CanaryV0 {
123 type BlockHash = AleoID<Field<Self>, { hrp2!("ab") }>;
125 type RatificationID = AleoID<Field<Self>, { hrp2!("ar") }>;
127 type StateRoot = AleoID<Field<Self>, { hrp2!("sr") }>;
129 type TransactionID = AleoID<Field<Self>, { hrp2!(TRANSACTION_PREFIX) }>;
131 type TransitionID = AleoID<Field<Self>, { hrp2!("au") }>;
133 type TransmissionChecksum = u128;
135
136 #[cfg(not(any(test, feature = "test", feature = "test_consensus_heights")))]
139 const CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); 7] = [
140 (ConsensusVersion::V1, 0),
141 (ConsensusVersion::V2, 2_900_000),
142 (ConsensusVersion::V3, 4_560_000),
143 (ConsensusVersion::V4, 5_730_000),
144 (ConsensusVersion::V5, 5_780_000),
145 (ConsensusVersion::V6, 6_240_000),
146 (ConsensusVersion::V7, 6_895_000),
147 ];
148 #[cfg(any(test, feature = "test", feature = "test_consensus_heights"))]
151 const CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); 7] = [
152 (ConsensusVersion::V1, 0),
153 (ConsensusVersion::V2, 10),
154 (ConsensusVersion::V3, 11),
155 (ConsensusVersion::V4, 12),
156 (ConsensusVersion::V5, 13),
157 (ConsensusVersion::V6, 14),
158 (ConsensusVersion::V7, 15),
159 ];
160 const EDITION: u16 = 0;
162 #[cfg(not(feature = "test_targets"))]
164 const GENESIS_COINBASE_TARGET: u64 = (1u64 << 29).saturating_sub(1);
165 #[cfg(feature = "test_targets")]
166 const GENESIS_COINBASE_TARGET: u64 = (1u64 << 5).saturating_sub(1);
167 #[cfg(not(feature = "test_targets"))]
169 const GENESIS_PROOF_TARGET: u64 = 1u64 << 27;
170 #[cfg(feature = "test_targets")]
171 const GENESIS_PROOF_TARGET: u64 = 1u64 << 3;
172 const GENESIS_TIMESTAMP: i64 = 1715776496 ;
174 const ID: u16 = 2;
176 const INCLUSION_FUNCTION_NAME: &'static str = MainnetV0::INCLUSION_FUNCTION_NAME;
178 #[cfg(not(any(test, feature = "test", feature = "test_consensus_heights")))]
180 const MAX_CERTIFICATES: [(ConsensusVersion, u16); 4] = [
181 (ConsensusVersion::V1, 100),
182 (ConsensusVersion::V3, 100),
183 (ConsensusVersion::V5, 100),
184 (ConsensusVersion::V6, 100),
185 ];
186 #[cfg(any(test, feature = "test", feature = "test_consensus_heights"))]
188 const MAX_CERTIFICATES: [(ConsensusVersion, u16); 4] = [
189 (ConsensusVersion::V1, 25),
190 (ConsensusVersion::V3, 25),
191 (ConsensusVersion::V5, 25),
192 (ConsensusVersion::V6, 25),
193 ];
194 const NAME: &'static str = "Aleo Canary (v0)";
196
197 fn genesis_bytes() -> &'static [u8] {
199 snarkvm_parameters::canary::GenesisBytes::load_bytes()
200 }
201
202 fn restrictions_list_as_str() -> &'static str {
204 snarkvm_parameters::canary::RESTRICTIONS_LIST
205 }
206
207 fn get_credits_proving_key(function_name: String) -> Result<&'static Arc<VarunaProvingKey<Self>>> {
209 CANARY_CREDITS_PROVING_KEYS
210 .get(&function_name)
211 .ok_or_else(|| anyhow!("Proving key for credits.aleo/{function_name}' not found"))
212 }
213
214 fn get_credits_verifying_key(function_name: String) -> Result<&'static Arc<VarunaVerifyingKey<Self>>> {
216 CANARY_CREDITS_VERIFYING_KEYS
217 .get(&function_name)
218 .ok_or_else(|| anyhow!("Verifying key for credits.aleo/{function_name}' not found"))
219 }
220
221 fn inclusion_proving_key() -> &'static Arc<VarunaProvingKey<Self>> {
223 static INSTANCE: OnceCell<Arc<VarunaProvingKey<Console>>> = OnceCell::new();
224 INSTANCE.get_or_init(|| {
225 Arc::new(
227 CircuitProvingKey::from_bytes_le(&snarkvm_parameters::canary::INCLUSION_PROVING_KEY[1..])
228 .expect("Failed to load inclusion proving key."),
229 )
230 })
231 }
232
233 fn inclusion_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>> {
235 static INSTANCE: OnceCell<Arc<VarunaVerifyingKey<Console>>> = OnceCell::new();
236 INSTANCE.get_or_init(|| {
237 Arc::new(
239 CircuitVerifyingKey::from_bytes_le(&snarkvm_parameters::canary::INCLUSION_VERIFYING_KEY[1..])
240 .expect("Failed to load inclusion verifying key."),
241 )
242 })
243 }
244
245 fn g_powers() -> &'static Vec<Group<Self>> {
247 &GENERATOR_G
248 }
249
250 fn g_scalar_multiply(scalar: &Scalar<Self>) -> Group<Self> {
252 GENERATOR_G
253 .iter()
254 .zip_eq(&scalar.to_bits_le())
255 .filter_map(|(base, bit)| match bit {
256 true => Some(base),
257 false => None,
258 })
259 .sum()
260 }
261
262 fn varuna_universal_prover() -> &'static UniversalProver<Self::PairingCurve> {
264 MainnetV0::varuna_universal_prover()
265 }
266
267 fn varuna_universal_verifier() -> &'static UniversalVerifier<Self::PairingCurve> {
269 MainnetV0::varuna_universal_verifier()
270 }
271
272 fn varuna_fs_parameters() -> &'static FiatShamirParameters<Self> {
274 &VARUNA_FS_PARAMETERS
275 }
276
277 fn encryption_domain() -> Field<Self> {
279 *ENCRYPTION_DOMAIN
280 }
281
282 fn graph_key_domain() -> Field<Self> {
284 *GRAPH_KEY_DOMAIN
285 }
286
287 fn serial_number_domain() -> Field<Self> {
289 *SERIAL_NUMBER_DOMAIN
290 }
291
292 fn commit_bhp256(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
294 CANARY_BHP_256.commit(input, randomizer)
295 }
296
297 fn commit_bhp512(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
299 CANARY_BHP_512.commit(input, randomizer)
300 }
301
302 fn commit_bhp768(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
304 CANARY_BHP_768.commit(input, randomizer)
305 }
306
307 fn commit_bhp1024(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
309 CANARY_BHP_1024.commit(input, randomizer)
310 }
311
312 fn commit_ped64(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
314 CANARY_PEDERSEN_64.commit(input, randomizer)
315 }
316
317 fn commit_ped128(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
319 CANARY_PEDERSEN_128.commit(input, randomizer)
320 }
321
322 fn commit_to_group_bhp256(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
324 CANARY_BHP_256.commit_uncompressed(input, randomizer)
325 }
326
327 fn commit_to_group_bhp512(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
329 CANARY_BHP_512.commit_uncompressed(input, randomizer)
330 }
331
332 fn commit_to_group_bhp768(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
334 CANARY_BHP_768.commit_uncompressed(input, randomizer)
335 }
336
337 fn commit_to_group_bhp1024(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
339 CANARY_BHP_1024.commit_uncompressed(input, randomizer)
340 }
341
342 fn commit_to_group_ped64(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
344 CANARY_PEDERSEN_64.commit_uncompressed(input, randomizer)
345 }
346
347 fn commit_to_group_ped128(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
349 CANARY_PEDERSEN_128.commit_uncompressed(input, randomizer)
350 }
351
352 fn hash_bhp256(input: &[bool]) -> Result<Field<Self>> {
354 CANARY_BHP_256.hash(input)
355 }
356
357 fn hash_bhp512(input: &[bool]) -> Result<Field<Self>> {
359 CANARY_BHP_512.hash(input)
360 }
361
362 fn hash_bhp768(input: &[bool]) -> Result<Field<Self>> {
364 CANARY_BHP_768.hash(input)
365 }
366
367 fn hash_bhp1024(input: &[bool]) -> Result<Field<Self>> {
369 CANARY_BHP_1024.hash(input)
370 }
371
372 fn hash_keccak256(input: &[bool]) -> Result<Vec<bool>> {
374 Keccak256::default().hash(input)
375 }
376
377 fn hash_keccak384(input: &[bool]) -> Result<Vec<bool>> {
379 Keccak384::default().hash(input)
380 }
381
382 fn hash_keccak512(input: &[bool]) -> Result<Vec<bool>> {
384 Keccak512::default().hash(input)
385 }
386
387 fn hash_ped64(input: &[bool]) -> Result<Field<Self>> {
389 CANARY_PEDERSEN_64.hash(input)
390 }
391
392 fn hash_ped128(input: &[bool]) -> Result<Field<Self>> {
394 CANARY_PEDERSEN_128.hash(input)
395 }
396
397 fn hash_psd2(input: &[Field<Self>]) -> Result<Field<Self>> {
399 CANARY_POSEIDON_2.hash(input)
400 }
401
402 fn hash_psd4(input: &[Field<Self>]) -> Result<Field<Self>> {
404 CANARY_POSEIDON_4.hash(input)
405 }
406
407 fn hash_psd8(input: &[Field<Self>]) -> Result<Field<Self>> {
409 CANARY_POSEIDON_8.hash(input)
410 }
411
412 fn hash_sha3_256(input: &[bool]) -> Result<Vec<bool>> {
414 Sha3_256::default().hash(input)
415 }
416
417 fn hash_sha3_384(input: &[bool]) -> Result<Vec<bool>> {
419 Sha3_384::default().hash(input)
420 }
421
422 fn hash_sha3_512(input: &[bool]) -> Result<Vec<bool>> {
424 Sha3_512::default().hash(input)
425 }
426
427 fn hash_many_psd2(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
429 CANARY_POSEIDON_2.hash_many(input, num_outputs)
430 }
431
432 fn hash_many_psd4(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
434 CANARY_POSEIDON_4.hash_many(input, num_outputs)
435 }
436
437 fn hash_many_psd8(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
439 CANARY_POSEIDON_8.hash_many(input, num_outputs)
440 }
441
442 fn hash_to_group_bhp256(input: &[bool]) -> Result<Group<Self>> {
444 CANARY_BHP_256.hash_uncompressed(input)
445 }
446
447 fn hash_to_group_bhp512(input: &[bool]) -> Result<Group<Self>> {
449 CANARY_BHP_512.hash_uncompressed(input)
450 }
451
452 fn hash_to_group_bhp768(input: &[bool]) -> Result<Group<Self>> {
454 CANARY_BHP_768.hash_uncompressed(input)
455 }
456
457 fn hash_to_group_bhp1024(input: &[bool]) -> Result<Group<Self>> {
459 CANARY_BHP_1024.hash_uncompressed(input)
460 }
461
462 fn hash_to_group_ped64(input: &[bool]) -> Result<Group<Self>> {
464 CANARY_PEDERSEN_64.hash_uncompressed(input)
465 }
466
467 fn hash_to_group_ped128(input: &[bool]) -> Result<Group<Self>> {
469 CANARY_PEDERSEN_128.hash_uncompressed(input)
470 }
471
472 fn hash_to_group_psd2(input: &[Field<Self>]) -> Result<Group<Self>> {
474 CANARY_POSEIDON_2.hash_to_group(input)
475 }
476
477 fn hash_to_group_psd4(input: &[Field<Self>]) -> Result<Group<Self>> {
479 CANARY_POSEIDON_4.hash_to_group(input)
480 }
481
482 fn hash_to_group_psd8(input: &[Field<Self>]) -> Result<Group<Self>> {
484 CANARY_POSEIDON_8.hash_to_group(input)
485 }
486
487 fn hash_to_scalar_psd2(input: &[Field<Self>]) -> Result<Scalar<Self>> {
489 CANARY_POSEIDON_2.hash_to_scalar(input)
490 }
491
492 fn hash_to_scalar_psd4(input: &[Field<Self>]) -> Result<Scalar<Self>> {
494 CANARY_POSEIDON_4.hash_to_scalar(input)
495 }
496
497 fn hash_to_scalar_psd8(input: &[Field<Self>]) -> Result<Scalar<Self>> {
499 CANARY_POSEIDON_8.hash_to_scalar(input)
500 }
501
502 fn merkle_tree_bhp<const DEPTH: u8>(leaves: &[Vec<bool>]) -> Result<BHPMerkleTree<Self, DEPTH>> {
504 MerkleTree::new(&*CANARY_BHP_1024, &*CANARY_BHP_512, leaves)
505 }
506
507 fn merkle_tree_psd<const DEPTH: u8>(leaves: &[Vec<Field<Self>>]) -> Result<PoseidonMerkleTree<Self, DEPTH>> {
509 MerkleTree::new(&*CANARY_POSEIDON_4, &*CANARY_POSEIDON_2, leaves)
510 }
511
512 fn verify_merkle_path_bhp<const DEPTH: u8>(
514 path: &MerklePath<Self, DEPTH>,
515 root: &Field<Self>,
516 leaf: &Vec<bool>,
517 ) -> bool {
518 path.verify(&*CANARY_BHP_1024, &*CANARY_BHP_512, root, leaf)
519 }
520
521 fn verify_merkle_path_psd<const DEPTH: u8>(
523 path: &MerklePath<Self, DEPTH>,
524 root: &Field<Self>,
525 leaf: &Vec<Field<Self>>,
526 ) -> bool {
527 path.verify(&*CANARY_POSEIDON_4, &*CANARY_POSEIDON_2, root, leaf)
528 }
529}
530
531#[cfg(test)]
532mod tests {
533 use super::*;
534
535 type CurrentNetwork = CanaryV0;
536
537 #[test]
538 fn test_g_scalar_multiply() {
539 let scalar = Scalar::rand(&mut TestRng::default());
541 let group = CurrentNetwork::g_scalar_multiply(&scalar);
542 assert_eq!(group, CurrentNetwork::g_powers()[0] * scalar);
543 }
544}