1use super::*;
17use snarkvm_console_algorithms::{
18 BHP256,
19 BHP512,
20 BHP768,
21 BHP1024,
22 Blake2Xs,
23 Keccak256,
24 Keccak384,
25 Keccak512,
26 Pedersen64,
27 Pedersen128,
28 Poseidon2,
29 Poseidon4,
30 Poseidon8,
31 Sha3_256,
32 Sha3_384,
33 Sha3_512,
34};
35
36lazy_static! {
37 pub static ref GENERATOR_G: Vec<Group<MainnetV0 >> = MainnetV0::new_bases("AleoAccountEncryptionAndSignatureScheme0");
39
40 pub static ref VARUNA_FS_PARAMETERS: FiatShamirParameters<MainnetV0> = FiatShamir::<MainnetV0>::sample_parameters();
42
43 static ref COMMITMENT_DOMAIN: Field<MainnetV0> = Field::<MainnetV0>::new_domain_separator("AleoCommitment0");
45 pub static ref ENCRYPTION_DOMAIN: Field<MainnetV0> = Field::<MainnetV0>::new_domain_separator("AleoSymmetricEncryption0");
47 pub static ref GRAPH_KEY_DOMAIN: Field<MainnetV0> = Field::<MainnetV0>::new_domain_separator("AleoGraphKey0");
49 pub static ref SERIAL_NUMBER_DOMAIN: Field<MainnetV0> = Field::<MainnetV0>::new_domain_separator("AleoSerialNumber0");
51
52 pub static ref BHP_256: BHP256<MainnetV0> = BHP256::<MainnetV0>::setup("AleoBHP256").expect("Failed to setup BHP256");
54 pub static ref BHP_512: BHP512<MainnetV0> = BHP512::<MainnetV0>::setup("AleoBHP512").expect("Failed to setup BHP512");
56 pub static ref BHP_768: BHP768<MainnetV0> = BHP768::<MainnetV0>::setup("AleoBHP768").expect("Failed to setup BHP768");
58 pub static ref BHP_1024: BHP1024<MainnetV0> = BHP1024::<MainnetV0>::setup("AleoBHP1024").expect("Failed to setup BHP1024");
60
61 pub static ref PEDERSEN_64: Pedersen64<MainnetV0> = Pedersen64::<MainnetV0>::setup("AleoPedersen64");
63 pub static ref PEDERSEN_128: Pedersen128<MainnetV0> = Pedersen128::<MainnetV0>::setup("AleoPedersen128");
65
66 pub static ref POSEIDON_2: Poseidon2<MainnetV0> = Poseidon2::<MainnetV0>::setup("AleoPoseidon2").expect("Failed to setup Poseidon2");
68 pub static ref POSEIDON_4: Poseidon4<MainnetV0> = Poseidon4::<MainnetV0>::setup("AleoPoseidon4").expect("Failed to setup Poseidon4");
70 pub static ref POSEIDON_8: Poseidon8<MainnetV0> = Poseidon8::<MainnetV0>::setup("AleoPoseidon8").expect("Failed to setup Poseidon8");
72
73 pub static ref CREDITS_V0_PROVING_KEYS: IndexMap<String, Arc<VarunaProvingKey<Console>>> = {
74 let mut map = IndexMap::new();
75 snarkvm_parameters::insert_credit_v0_keys!(map, VarunaProvingKey<Console>, Prover);
76 map
77 };
78 pub static ref CREDITS_V0_VERIFYING_KEYS: IndexMap<String, Arc<VarunaVerifyingKey<Console>>> = {
79 let mut map = IndexMap::new();
80 snarkvm_parameters::insert_credit_v0_keys!(map, VarunaVerifyingKey<Console>, Verifier);
81 map
82 };
83
84 pub static ref CREDITS_PROVING_KEYS: IndexMap<String, Arc<VarunaProvingKey<Console>>> = {
85 let mut map = IndexMap::new();
86 snarkvm_parameters::insert_credit_keys!(map, VarunaProvingKey<Console>, Prover);
87 map
88 };
89 pub static ref CREDITS_VERIFYING_KEYS: IndexMap<String, Arc<VarunaVerifyingKey<Console>>> = {
90 let mut map = IndexMap::new();
91 snarkvm_parameters::insert_credit_keys!(map, VarunaVerifyingKey<Console>, Verifier);
92 map
93 };
94}
95
96pub const TRANSACTION_PREFIX: &str = "at";
97
98#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
99pub struct MainnetV0;
100
101impl MainnetV0 {
102 fn new_bases(message: &str) -> Vec<Group<Self>> {
104 let (base, _, _) = Blake2Xs::hash_to_curve::<<Self as Environment>::Affine>(message);
106
107 let mut g = Group::<Self>::new(base);
109 let mut g_bases = Vec::with_capacity(Scalar::<Self>::size_in_bits());
110 for _ in 0..Scalar::<Self>::size_in_bits() {
111 g_bases.push(g);
112 g = g.double();
113 }
114 g_bases
115 }
116}
117
118impl Environment for MainnetV0 {
119 type Affine = <Console as Environment>::Affine;
120 type BigInteger = <Console as Environment>::BigInteger;
121 type Field = <Console as Environment>::Field;
122 type PairingCurve = <Console as Environment>::PairingCurve;
123 type Projective = <Console as Environment>::Projective;
124 type Scalar = <Console as Environment>::Scalar;
125
126 const EDWARDS_A: Self::Field = Console::EDWARDS_A;
128 const EDWARDS_D: Self::Field = Console::EDWARDS_D;
130 const MONTGOMERY_A: Self::Field = Console::MONTGOMERY_A;
132 const MONTGOMERY_B: Self::Field = Console::MONTGOMERY_B;
134}
135
136impl Network for MainnetV0 {
137 type BlockHash = AleoID<Field<Self>, { hrp2!("ab") }>;
139 type RatificationID = AleoID<Field<Self>, { hrp2!("ar") }>;
141 type StateRoot = AleoID<Field<Self>, { hrp2!("sr") }>;
143 type TransactionID = AleoID<Field<Self>, { hrp2!(TRANSACTION_PREFIX) }>;
145 type TransitionID = AleoID<Field<Self>, { hrp2!("au") }>;
147 type TransmissionChecksum = u128;
149
150 #[cfg(not(feature = "test"))]
152 const GENESIS_COINBASE_TARGET: u64 = (1u64 << 29).saturating_sub(1);
153 #[cfg(feature = "test")]
156 const GENESIS_COINBASE_TARGET: u64 = (1u64 << 5).saturating_sub(1);
157 #[cfg(not(feature = "test"))]
159 const GENESIS_PROOF_TARGET: u64 = 1u64 << 27;
160 #[cfg(feature = "test")]
163 const GENESIS_PROOF_TARGET: u64 = 1u64 << 3;
164 const GENESIS_TIMESTAMP: i64 = 1725462000 ;
166 const ID: u16 = 0;
168 const INCLUSION_FUNCTION_NAME: &'static str = snarkvm_parameters::mainnet::NETWORK_INCLUSION_FUNCTION_NAME;
170 #[cfg(not(any(test, feature = "test")))]
172 const MAX_CERTIFICATES: [(ConsensusVersion, u16); 5] = [
173 (ConsensusVersion::V1, 16),
174 (ConsensusVersion::V3, 25),
175 (ConsensusVersion::V5, 30),
176 (ConsensusVersion::V6, 35),
177 (ConsensusVersion::V9, 40),
178 ];
179 #[cfg(any(test, feature = "test"))]
181 const MAX_CERTIFICATES: [(ConsensusVersion, u16); 5] = [
182 (ConsensusVersion::V1, 100),
183 (ConsensusVersion::V3, 101),
184 (ConsensusVersion::V5, 102),
185 (ConsensusVersion::V6, 103),
186 (ConsensusVersion::V9, 104),
187 ];
188 const NAME: &'static str = "Aleo Mainnet (v0)";
190 const SHORT_NAME: &'static str = "mainnet";
192 const _CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS] =
196 MAINNET_V0_CONSENSUS_VERSION_HEIGHTS;
197
198 #[allow(non_snake_case)]
200 fn INCLUSION_UPGRADE_HEIGHT() -> Result<u32> {
201 Self::CONSENSUS_HEIGHT(ConsensusVersion::V8)
202 }
203
204 fn genesis_bytes() -> &'static [u8] {
206 snarkvm_parameters::mainnet::GenesisBytes::load_bytes()
207 }
208
209 fn restrictions_list_as_str() -> &'static str {
211 snarkvm_parameters::mainnet::RESTRICTIONS_LIST
212 }
213
214 fn get_credits_v0_proving_key(function_name: String) -> Result<&'static Arc<VarunaProvingKey<Self>>> {
216 CREDITS_V0_PROVING_KEYS
217 .get(&function_name)
218 .ok_or_else(|| anyhow!("Proving key (v0) for credits.aleo/{function_name}' not found"))
219 }
220
221 fn get_credits_v0_verifying_key(function_name: String) -> Result<&'static Arc<VarunaVerifyingKey<Self>>> {
223 CREDITS_V0_VERIFYING_KEYS
224 .get(&function_name)
225 .ok_or_else(|| anyhow!("Verifying key (v0) for credits_v0.aleo/{function_name}' not found"))
226 }
227
228 fn get_credits_proving_key(function_name: String) -> Result<&'static Arc<VarunaProvingKey<Self>>> {
230 CREDITS_PROVING_KEYS
231 .get(&function_name)
232 .ok_or_else(|| anyhow!("Proving key for credits.aleo/{function_name}' not found"))
233 }
234
235 fn get_credits_verifying_key(function_name: String) -> Result<&'static Arc<VarunaVerifyingKey<Self>>> {
237 CREDITS_VERIFYING_KEYS
238 .get(&function_name)
239 .ok_or_else(|| anyhow!("Verifying key for credits.aleo/{function_name}' not found"))
240 }
241
242 #[cfg(not(feature = "wasm"))]
243 fn inclusion_v0_proving_key() -> &'static Arc<VarunaProvingKey<Self>> {
245 static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
246 INSTANCE.get_or_init(|| {
247 Arc::new(
249 CircuitProvingKey::from_bytes_le(&snarkvm_parameters::mainnet::INCLUSION_V0_PROVING_KEY[1..])
250 .expect("Failed to load inclusion_v0 proving key."),
251 )
252 })
253 }
254
255 #[cfg(feature = "wasm")]
256 fn inclusion_v0_proving_key(inclusion_key_bytes: Option<Vec<u8>>) -> &'static Arc<VarunaProvingKey<Self>> {
258 static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
259 INSTANCE.get_or_init(|| {
260 inclusion_key_bytes
261 .map(|bytes| {
262 snarkvm_parameters::mainnet::InclusionV0Prover::verify_bytes(&bytes)
263 .expect("Bytes provided did not match expected inclusion checksum.");
264 Arc::new(
265 CircuitProvingKey::from_bytes_le(&bytes[1..]).expect("Failed to load inclusion proving key."),
266 )
267 })
268 .unwrap_or_else(|| {
269 Arc::new(
270 CircuitProvingKey::from_bytes_le(&snarkvm_parameters::mainnet::INCLUSION_V0_PROVING_KEY[1..])
271 .expect("Failed to load inclusion proving key."),
272 )
273 })
274 })
275 }
276
277 fn inclusion_v0_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>> {
279 static INSTANCE: OnceLock<Arc<VarunaVerifyingKey<Console>>> = OnceLock::new();
280 INSTANCE.get_or_init(|| {
281 Arc::new(
283 CircuitVerifyingKey::from_bytes_le(&snarkvm_parameters::mainnet::INCLUSION_V0_VERIFYING_KEY[1..])
284 .expect("Failed to load inclusion_v0 verifying key."),
285 )
286 })
287 }
288
289 #[cfg(not(feature = "wasm"))]
290 fn inclusion_proving_key() -> &'static Arc<VarunaProvingKey<Self>> {
292 static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
293 INSTANCE.get_or_init(|| {
294 Arc::new(
296 CircuitProvingKey::from_bytes_le(&snarkvm_parameters::mainnet::INCLUSION_PROVING_KEY[1..])
297 .expect("Failed to load inclusion proving key."),
298 )
299 })
300 }
301
302 #[cfg(feature = "wasm")]
303 fn inclusion_proving_key(inclusion_key_bytes: Option<Vec<u8>>) -> &'static Arc<VarunaProvingKey<Self>> {
305 static INSTANCE: OnceLock<Arc<VarunaProvingKey<Console>>> = OnceLock::new();
306 INSTANCE.get_or_init(|| {
307 inclusion_key_bytes
308 .map(|bytes| {
309 snarkvm_parameters::mainnet::InclusionProver::verify_bytes(&bytes)
310 .expect("Bytes provided did not match expected inclusion checksum.");
311 Arc::new(
312 CircuitProvingKey::from_bytes_le(&bytes[1..]).expect("Failed to load inclusion proving key."),
313 )
314 })
315 .unwrap_or_else(|| {
316 Arc::new(
317 CircuitProvingKey::from_bytes_le(&snarkvm_parameters::mainnet::INCLUSION_PROVING_KEY[1..])
318 .expect("Failed to load inclusion proving key."),
319 )
320 })
321 })
322 }
323
324 fn inclusion_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>> {
326 static INSTANCE: OnceLock<Arc<VarunaVerifyingKey<Console>>> = OnceLock::new();
327 INSTANCE.get_or_init(|| {
328 Arc::new(
330 CircuitVerifyingKey::from_bytes_le(&snarkvm_parameters::mainnet::INCLUSION_VERIFYING_KEY[1..])
331 .expect("Failed to load inclusion verifying key."),
332 )
333 })
334 }
335
336 fn g_powers() -> &'static Vec<Group<Self>> {
338 &GENERATOR_G
339 }
340
341 fn g_scalar_multiply(scalar: &Scalar<Self>) -> Group<Self> {
343 GENERATOR_G
344 .iter()
345 .zip_eq(&scalar.to_bits_le())
346 .filter_map(|(base, bit)| match bit {
347 true => Some(base),
348 false => None,
349 })
350 .sum()
351 }
352
353 fn varuna_universal_prover() -> &'static UniversalProver<Self::PairingCurve> {
355 static INSTANCE: OnceLock<UniversalProver<<Console as Environment>::PairingCurve>> = OnceLock::new();
356 INSTANCE.get_or_init(|| {
357 snarkvm_algorithms::polycommit::kzg10::UniversalParams::load()
358 .expect("Failed to load universal SRS (KZG10).")
359 .to_universal_prover()
360 .expect("Failed to convert universal SRS (KZG10) to the prover.")
361 })
362 }
363
364 fn varuna_universal_verifier() -> &'static UniversalVerifier<Self::PairingCurve> {
366 static INSTANCE: OnceLock<UniversalVerifier<<Console as Environment>::PairingCurve>> = OnceLock::new();
367 INSTANCE.get_or_init(|| {
368 snarkvm_algorithms::polycommit::kzg10::UniversalParams::load()
369 .expect("Failed to load universal SRS (KZG10).")
370 .to_universal_verifier()
371 .expect("Failed to convert universal SRS (KZG10) to the verifier.")
372 })
373 }
374
375 fn varuna_fs_parameters() -> &'static FiatShamirParameters<Self> {
377 &VARUNA_FS_PARAMETERS
378 }
379
380 fn commitment_domain() -> Field<Self> {
382 *COMMITMENT_DOMAIN
383 }
384
385 fn encryption_domain() -> Field<Self> {
387 *ENCRYPTION_DOMAIN
388 }
389
390 fn graph_key_domain() -> Field<Self> {
392 *GRAPH_KEY_DOMAIN
393 }
394
395 fn serial_number_domain() -> Field<Self> {
397 *SERIAL_NUMBER_DOMAIN
398 }
399
400 fn commit_bhp256(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
402 BHP_256.commit(input, randomizer)
403 }
404
405 fn commit_bhp512(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
407 BHP_512.commit(input, randomizer)
408 }
409
410 fn commit_bhp768(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
412 BHP_768.commit(input, randomizer)
413 }
414
415 fn commit_bhp1024(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
417 BHP_1024.commit(input, randomizer)
418 }
419
420 fn commit_ped64(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
422 PEDERSEN_64.commit(input, randomizer)
423 }
424
425 fn commit_ped128(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
427 PEDERSEN_128.commit(input, randomizer)
428 }
429
430 fn commit_to_group_bhp256(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
432 BHP_256.commit_uncompressed(input, randomizer)
433 }
434
435 fn commit_to_group_bhp512(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
437 BHP_512.commit_uncompressed(input, randomizer)
438 }
439
440 fn commit_to_group_bhp768(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
442 BHP_768.commit_uncompressed(input, randomizer)
443 }
444
445 fn commit_to_group_bhp1024(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
447 BHP_1024.commit_uncompressed(input, randomizer)
448 }
449
450 fn commit_to_group_ped64(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
452 PEDERSEN_64.commit_uncompressed(input, randomizer)
453 }
454
455 fn commit_to_group_ped128(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
457 PEDERSEN_128.commit_uncompressed(input, randomizer)
458 }
459
460 fn hash_bhp256(input: &[bool]) -> Result<Field<Self>> {
462 BHP_256.hash(input)
463 }
464
465 fn hash_bhp512(input: &[bool]) -> Result<Field<Self>> {
467 BHP_512.hash(input)
468 }
469
470 fn hash_bhp768(input: &[bool]) -> Result<Field<Self>> {
472 BHP_768.hash(input)
473 }
474
475 fn hash_bhp1024(input: &[bool]) -> Result<Field<Self>> {
477 BHP_1024.hash(input)
478 }
479
480 fn hash_keccak256(input: &[bool]) -> Result<Vec<bool>> {
482 Keccak256::default().hash(input)
483 }
484
485 fn hash_keccak384(input: &[bool]) -> Result<Vec<bool>> {
487 Keccak384::default().hash(input)
488 }
489
490 fn hash_keccak512(input: &[bool]) -> Result<Vec<bool>> {
492 Keccak512::default().hash(input)
493 }
494
495 fn hash_ped64(input: &[bool]) -> Result<Field<Self>> {
497 PEDERSEN_64.hash(input)
498 }
499
500 fn hash_ped128(input: &[bool]) -> Result<Field<Self>> {
502 PEDERSEN_128.hash(input)
503 }
504
505 fn hash_psd2(input: &[Field<Self>]) -> Result<Field<Self>> {
507 POSEIDON_2.hash(input)
508 }
509
510 fn hash_psd4(input: &[Field<Self>]) -> Result<Field<Self>> {
512 POSEIDON_4.hash(input)
513 }
514
515 fn hash_psd8(input: &[Field<Self>]) -> Result<Field<Self>> {
517 POSEIDON_8.hash(input)
518 }
519
520 fn hash_sha3_256(input: &[bool]) -> Result<Vec<bool>> {
522 Sha3_256::default().hash(input)
523 }
524
525 fn hash_sha3_384(input: &[bool]) -> Result<Vec<bool>> {
527 Sha3_384::default().hash(input)
528 }
529
530 fn hash_sha3_512(input: &[bool]) -> Result<Vec<bool>> {
532 Sha3_512::default().hash(input)
533 }
534
535 fn hash_many_psd2(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
537 POSEIDON_2.hash_many(input, num_outputs)
538 }
539
540 fn hash_many_psd4(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
542 POSEIDON_4.hash_many(input, num_outputs)
543 }
544
545 fn hash_many_psd8(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
547 POSEIDON_8.hash_many(input, num_outputs)
548 }
549
550 fn hash_to_group_bhp256(input: &[bool]) -> Result<Group<Self>> {
552 BHP_256.hash_uncompressed(input)
553 }
554
555 fn hash_to_group_bhp512(input: &[bool]) -> Result<Group<Self>> {
557 BHP_512.hash_uncompressed(input)
558 }
559
560 fn hash_to_group_bhp768(input: &[bool]) -> Result<Group<Self>> {
562 BHP_768.hash_uncompressed(input)
563 }
564
565 fn hash_to_group_bhp1024(input: &[bool]) -> Result<Group<Self>> {
567 BHP_1024.hash_uncompressed(input)
568 }
569
570 fn hash_to_group_ped64(input: &[bool]) -> Result<Group<Self>> {
572 PEDERSEN_64.hash_uncompressed(input)
573 }
574
575 fn hash_to_group_ped128(input: &[bool]) -> Result<Group<Self>> {
577 PEDERSEN_128.hash_uncompressed(input)
578 }
579
580 fn hash_to_group_psd2(input: &[Field<Self>]) -> Result<Group<Self>> {
582 POSEIDON_2.hash_to_group(input)
583 }
584
585 fn hash_to_group_psd4(input: &[Field<Self>]) -> Result<Group<Self>> {
587 POSEIDON_4.hash_to_group(input)
588 }
589
590 fn hash_to_group_psd8(input: &[Field<Self>]) -> Result<Group<Self>> {
592 POSEIDON_8.hash_to_group(input)
593 }
594
595 fn hash_to_scalar_psd2(input: &[Field<Self>]) -> Result<Scalar<Self>> {
597 POSEIDON_2.hash_to_scalar(input)
598 }
599
600 fn hash_to_scalar_psd4(input: &[Field<Self>]) -> Result<Scalar<Self>> {
602 POSEIDON_4.hash_to_scalar(input)
603 }
604
605 fn hash_to_scalar_psd8(input: &[Field<Self>]) -> Result<Scalar<Self>> {
607 POSEIDON_8.hash_to_scalar(input)
608 }
609
610 fn merkle_tree_bhp<const DEPTH: u8>(leaves: &[Vec<bool>]) -> Result<BHPMerkleTree<Self, DEPTH>> {
612 MerkleTree::new(&*BHP_1024, &*BHP_512, leaves)
613 }
614
615 fn merkle_tree_psd<const DEPTH: u8>(leaves: &[Vec<Field<Self>>]) -> Result<PoseidonMerkleTree<Self, DEPTH>> {
617 MerkleTree::new(&*POSEIDON_4, &*POSEIDON_2, leaves)
618 }
619
620 fn verify_merkle_path_bhp<const DEPTH: u8>(
622 path: &MerklePath<Self, DEPTH>,
623 root: &Field<Self>,
624 leaf: &Vec<bool>,
625 ) -> bool {
626 path.verify(&*BHP_1024, &*BHP_512, root, leaf)
627 }
628
629 fn verify_merkle_path_psd<const DEPTH: u8>(
631 path: &MerklePath<Self, DEPTH>,
632 root: &Field<Self>,
633 leaf: &Vec<Field<Self>>,
634 ) -> bool {
635 path.verify(&*POSEIDON_4, &*POSEIDON_2, root, leaf)
636 }
637}
638
639#[cfg(test)]
640mod tests {
641 use super::*;
642
643 type CurrentNetwork = MainnetV0;
644
645 #[test]
646 fn test_g_scalar_multiply() {
647 let scalar = Scalar::rand(&mut TestRng::default());
649 let group = CurrentNetwork::g_scalar_multiply(&scalar);
650 assert_eq!(group, CurrentNetwork::g_powers()[0] * scalar);
651 }
652}