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 pub static ref ENCRYPTION_DOMAIN: Field<MainnetV0> = Field::<MainnetV0>::new_domain_separator("AleoSymmetricEncryption0");
45 pub static ref GRAPH_KEY_DOMAIN: Field<MainnetV0> = Field::<MainnetV0>::new_domain_separator("AleoGraphKey0");
47 pub static ref SERIAL_NUMBER_DOMAIN: Field<MainnetV0> = Field::<MainnetV0>::new_domain_separator("AleoSerialNumber0");
49
50 pub static ref BHP_256: BHP256<MainnetV0> = BHP256::<MainnetV0>::setup("AleoBHP256").expect("Failed to setup BHP256");
52 pub static ref BHP_512: BHP512<MainnetV0> = BHP512::<MainnetV0>::setup("AleoBHP512").expect("Failed to setup BHP512");
54 pub static ref BHP_768: BHP768<MainnetV0> = BHP768::<MainnetV0>::setup("AleoBHP768").expect("Failed to setup BHP768");
56 pub static ref BHP_1024: BHP1024<MainnetV0> = BHP1024::<MainnetV0>::setup("AleoBHP1024").expect("Failed to setup BHP1024");
58
59 pub static ref PEDERSEN_64: Pedersen64<MainnetV0> = Pedersen64::<MainnetV0>::setup("AleoPedersen64");
61 pub static ref PEDERSEN_128: Pedersen128<MainnetV0> = Pedersen128::<MainnetV0>::setup("AleoPedersen128");
63
64 pub static ref POSEIDON_2: Poseidon2<MainnetV0> = Poseidon2::<MainnetV0>::setup("AleoPoseidon2").expect("Failed to setup Poseidon2");
66 pub static ref POSEIDON_4: Poseidon4<MainnetV0> = Poseidon4::<MainnetV0>::setup("AleoPoseidon4").expect("Failed to setup Poseidon4");
68 pub static ref POSEIDON_8: Poseidon8<MainnetV0> = Poseidon8::<MainnetV0>::setup("AleoPoseidon8").expect("Failed to setup Poseidon8");
70
71 pub static ref CREDITS_PROVING_KEYS: IndexMap<String, Arc<VarunaProvingKey<Console>>> = {
72 let mut map = IndexMap::new();
73 snarkvm_parameters::insert_credit_keys!(map, VarunaProvingKey<Console>, Prover);
74 map
75 };
76 pub static ref CREDITS_VERIFYING_KEYS: IndexMap<String, Arc<VarunaVerifyingKey<Console>>> = {
77 let mut map = IndexMap::new();
78 snarkvm_parameters::insert_credit_keys!(map, VarunaVerifyingKey<Console>, Verifier);
79 map
80 };
81}
82
83pub const TRANSACTION_PREFIX: &str = "at";
84
85#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
86pub struct MainnetV0;
87
88impl MainnetV0 {
89 fn new_bases(message: &str) -> Vec<Group<Self>> {
91 let (base, _, _) = Blake2Xs::hash_to_curve::<<Self as Environment>::Affine>(message);
93
94 let mut g = Group::<Self>::new(base);
96 let mut g_bases = Vec::with_capacity(Scalar::<Self>::size_in_bits());
97 for _ in 0..Scalar::<Self>::size_in_bits() {
98 g_bases.push(g);
99 g = g.double();
100 }
101 g_bases
102 }
103}
104
105impl Environment for MainnetV0 {
106 type Affine = <Console as Environment>::Affine;
107 type BigInteger = <Console as Environment>::BigInteger;
108 type Field = <Console as Environment>::Field;
109 type PairingCurve = <Console as Environment>::PairingCurve;
110 type Projective = <Console as Environment>::Projective;
111 type Scalar = <Console as Environment>::Scalar;
112
113 const EDWARDS_A: Self::Field = Console::EDWARDS_A;
115 const EDWARDS_D: Self::Field = Console::EDWARDS_D;
117 const MONTGOMERY_A: Self::Field = Console::MONTGOMERY_A;
119 const MONTGOMERY_B: Self::Field = Console::MONTGOMERY_B;
121}
122
123impl Network for MainnetV0 {
124 type BlockHash = AleoID<Field<Self>, { hrp2!("ab") }>;
126 type RatificationID = AleoID<Field<Self>, { hrp2!("ar") }>;
128 type StateRoot = AleoID<Field<Self>, { hrp2!("sr") }>;
130 type TransactionID = AleoID<Field<Self>, { hrp2!(TRANSACTION_PREFIX) }>;
132 type TransitionID = AleoID<Field<Self>, { hrp2!("au") }>;
134 type TransmissionChecksum = u128;
136
137 #[cfg(not(any(test, feature = "test")))]
140 const CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); 5] = [
141 (ConsensusVersion::V1, 0),
142 (ConsensusVersion::V2, 2_800_000),
143 (ConsensusVersion::V3, 4_900_000),
144 (ConsensusVersion::V4, 6_135_000),
145 (ConsensusVersion::V5, 7_060_000),
146 ];
147 #[cfg(any(test, feature = "test"))]
150 const CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); 5] = [
151 (ConsensusVersion::V1, 0),
152 (ConsensusVersion::V2, 10),
153 (ConsensusVersion::V3, 11),
154 (ConsensusVersion::V4, 12),
155 (ConsensusVersion::V5, 13),
156 ];
157 const EDITION: u16 = 0;
159 #[cfg(not(feature = "test"))]
161 const GENESIS_COINBASE_TARGET: u64 = (1u64 << 29).saturating_sub(1);
162 #[cfg(feature = "test")]
165 const GENESIS_COINBASE_TARGET: u64 = (1u64 << 5).saturating_sub(1);
166 #[cfg(not(feature = "test"))]
168 const GENESIS_PROOF_TARGET: u64 = 1u64 << 27;
169 #[cfg(feature = "test")]
172 const GENESIS_PROOF_TARGET: u64 = 1u64 << 3;
173 const GENESIS_TIMESTAMP: i64 = 1725462000 ;
175 const ID: u16 = 0;
177 const INCLUSION_FUNCTION_NAME: &'static str = snarkvm_parameters::mainnet::NETWORK_INCLUSION_FUNCTION_NAME;
179 #[cfg(not(any(test, feature = "test")))]
181 const MAX_CERTIFICATES: [(ConsensusVersion, u16); 3] =
182 [(ConsensusVersion::V1, 16), (ConsensusVersion::V3, 25), (ConsensusVersion::V5, 30)];
183 #[cfg(any(test, feature = "test"))]
185 const MAX_CERTIFICATES: [(ConsensusVersion, u16); 3] =
186 [(ConsensusVersion::V1, 100), (ConsensusVersion::V3, 100), (ConsensusVersion::V5, 100)];
187 const NAME: &'static str = "Aleo Mainnet (v0)";
189
190 fn genesis_bytes() -> &'static [u8] {
192 snarkvm_parameters::mainnet::GenesisBytes::load_bytes()
193 }
194
195 fn restrictions_list_as_str() -> &'static str {
197 snarkvm_parameters::mainnet::RESTRICTIONS_LIST
198 }
199
200 fn get_credits_proving_key(function_name: String) -> Result<&'static Arc<VarunaProvingKey<Self>>> {
202 CREDITS_PROVING_KEYS
203 .get(&function_name)
204 .ok_or_else(|| anyhow!("Proving key for credits.aleo/{function_name}' not found"))
205 }
206
207 fn get_credits_verifying_key(function_name: String) -> Result<&'static Arc<VarunaVerifyingKey<Self>>> {
209 CREDITS_VERIFYING_KEYS
210 .get(&function_name)
211 .ok_or_else(|| anyhow!("Verifying key for credits.aleo/{function_name}' not found"))
212 }
213
214 fn inclusion_proving_key() -> &'static Arc<VarunaProvingKey<Self>> {
216 static INSTANCE: OnceCell<Arc<VarunaProvingKey<Console>>> = OnceCell::new();
217 INSTANCE.get_or_init(|| {
218 Arc::new(
220 CircuitProvingKey::from_bytes_le(&snarkvm_parameters::mainnet::INCLUSION_PROVING_KEY[1..])
221 .expect("Failed to load inclusion proving key."),
222 )
223 })
224 }
225
226 fn inclusion_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>> {
228 static INSTANCE: OnceCell<Arc<VarunaVerifyingKey<Console>>> = OnceCell::new();
229 INSTANCE.get_or_init(|| {
230 Arc::new(
232 CircuitVerifyingKey::from_bytes_le(&snarkvm_parameters::mainnet::INCLUSION_VERIFYING_KEY[1..])
233 .expect("Failed to load inclusion verifying key."),
234 )
235 })
236 }
237
238 fn g_powers() -> &'static Vec<Group<Self>> {
240 &GENERATOR_G
241 }
242
243 fn g_scalar_multiply(scalar: &Scalar<Self>) -> Group<Self> {
245 GENERATOR_G
246 .iter()
247 .zip_eq(&scalar.to_bits_le())
248 .filter_map(|(base, bit)| match bit {
249 true => Some(base),
250 false => None,
251 })
252 .sum()
253 }
254
255 fn varuna_universal_prover() -> &'static UniversalProver<Self::PairingCurve> {
257 static INSTANCE: OnceCell<UniversalProver<<Console as Environment>::PairingCurve>> = OnceCell::new();
258 INSTANCE.get_or_init(|| {
259 snarkvm_algorithms::polycommit::kzg10::UniversalParams::load()
260 .expect("Failed to load universal SRS (KZG10).")
261 .to_universal_prover()
262 .expect("Failed to convert universal SRS (KZG10) to the prover.")
263 })
264 }
265
266 fn varuna_universal_verifier() -> &'static UniversalVerifier<Self::PairingCurve> {
268 static INSTANCE: OnceCell<UniversalVerifier<<Console as Environment>::PairingCurve>> = OnceCell::new();
269 INSTANCE.get_or_init(|| {
270 snarkvm_algorithms::polycommit::kzg10::UniversalParams::load()
271 .expect("Failed to load universal SRS (KZG10).")
272 .to_universal_verifier()
273 .expect("Failed to convert universal SRS (KZG10) to the verifier.")
274 })
275 }
276
277 fn varuna_fs_parameters() -> &'static FiatShamirParameters<Self> {
279 &VARUNA_FS_PARAMETERS
280 }
281
282 fn encryption_domain() -> Field<Self> {
284 *ENCRYPTION_DOMAIN
285 }
286
287 fn graph_key_domain() -> Field<Self> {
289 *GRAPH_KEY_DOMAIN
290 }
291
292 fn serial_number_domain() -> Field<Self> {
294 *SERIAL_NUMBER_DOMAIN
295 }
296
297 fn commit_bhp256(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
299 BHP_256.commit(input, randomizer)
300 }
301
302 fn commit_bhp512(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
304 BHP_512.commit(input, randomizer)
305 }
306
307 fn commit_bhp768(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
309 BHP_768.commit(input, randomizer)
310 }
311
312 fn commit_bhp1024(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
314 BHP_1024.commit(input, randomizer)
315 }
316
317 fn commit_ped64(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
319 PEDERSEN_64.commit(input, randomizer)
320 }
321
322 fn commit_ped128(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
324 PEDERSEN_128.commit(input, randomizer)
325 }
326
327 fn commit_to_group_bhp256(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
329 BHP_256.commit_uncompressed(input, randomizer)
330 }
331
332 fn commit_to_group_bhp512(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
334 BHP_512.commit_uncompressed(input, randomizer)
335 }
336
337 fn commit_to_group_bhp768(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
339 BHP_768.commit_uncompressed(input, randomizer)
340 }
341
342 fn commit_to_group_bhp1024(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
344 BHP_1024.commit_uncompressed(input, randomizer)
345 }
346
347 fn commit_to_group_ped64(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
349 PEDERSEN_64.commit_uncompressed(input, randomizer)
350 }
351
352 fn commit_to_group_ped128(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
354 PEDERSEN_128.commit_uncompressed(input, randomizer)
355 }
356
357 fn hash_bhp256(input: &[bool]) -> Result<Field<Self>> {
359 BHP_256.hash(input)
360 }
361
362 fn hash_bhp512(input: &[bool]) -> Result<Field<Self>> {
364 BHP_512.hash(input)
365 }
366
367 fn hash_bhp768(input: &[bool]) -> Result<Field<Self>> {
369 BHP_768.hash(input)
370 }
371
372 fn hash_bhp1024(input: &[bool]) -> Result<Field<Self>> {
374 BHP_1024.hash(input)
375 }
376
377 fn hash_keccak256(input: &[bool]) -> Result<Vec<bool>> {
379 Keccak256::default().hash(input)
380 }
381
382 fn hash_keccak384(input: &[bool]) -> Result<Vec<bool>> {
384 Keccak384::default().hash(input)
385 }
386
387 fn hash_keccak512(input: &[bool]) -> Result<Vec<bool>> {
389 Keccak512::default().hash(input)
390 }
391
392 fn hash_ped64(input: &[bool]) -> Result<Field<Self>> {
394 PEDERSEN_64.hash(input)
395 }
396
397 fn hash_ped128(input: &[bool]) -> Result<Field<Self>> {
399 PEDERSEN_128.hash(input)
400 }
401
402 fn hash_psd2(input: &[Field<Self>]) -> Result<Field<Self>> {
404 POSEIDON_2.hash(input)
405 }
406
407 fn hash_psd4(input: &[Field<Self>]) -> Result<Field<Self>> {
409 POSEIDON_4.hash(input)
410 }
411
412 fn hash_psd8(input: &[Field<Self>]) -> Result<Field<Self>> {
414 POSEIDON_8.hash(input)
415 }
416
417 fn hash_sha3_256(input: &[bool]) -> Result<Vec<bool>> {
419 Sha3_256::default().hash(input)
420 }
421
422 fn hash_sha3_384(input: &[bool]) -> Result<Vec<bool>> {
424 Sha3_384::default().hash(input)
425 }
426
427 fn hash_sha3_512(input: &[bool]) -> Result<Vec<bool>> {
429 Sha3_512::default().hash(input)
430 }
431
432 fn hash_many_psd2(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
434 POSEIDON_2.hash_many(input, num_outputs)
435 }
436
437 fn hash_many_psd4(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
439 POSEIDON_4.hash_many(input, num_outputs)
440 }
441
442 fn hash_many_psd8(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
444 POSEIDON_8.hash_many(input, num_outputs)
445 }
446
447 fn hash_to_group_bhp256(input: &[bool]) -> Result<Group<Self>> {
449 BHP_256.hash_uncompressed(input)
450 }
451
452 fn hash_to_group_bhp512(input: &[bool]) -> Result<Group<Self>> {
454 BHP_512.hash_uncompressed(input)
455 }
456
457 fn hash_to_group_bhp768(input: &[bool]) -> Result<Group<Self>> {
459 BHP_768.hash_uncompressed(input)
460 }
461
462 fn hash_to_group_bhp1024(input: &[bool]) -> Result<Group<Self>> {
464 BHP_1024.hash_uncompressed(input)
465 }
466
467 fn hash_to_group_ped64(input: &[bool]) -> Result<Group<Self>> {
469 PEDERSEN_64.hash_uncompressed(input)
470 }
471
472 fn hash_to_group_ped128(input: &[bool]) -> Result<Group<Self>> {
474 PEDERSEN_128.hash_uncompressed(input)
475 }
476
477 fn hash_to_group_psd2(input: &[Field<Self>]) -> Result<Group<Self>> {
479 POSEIDON_2.hash_to_group(input)
480 }
481
482 fn hash_to_group_psd4(input: &[Field<Self>]) -> Result<Group<Self>> {
484 POSEIDON_4.hash_to_group(input)
485 }
486
487 fn hash_to_group_psd8(input: &[Field<Self>]) -> Result<Group<Self>> {
489 POSEIDON_8.hash_to_group(input)
490 }
491
492 fn hash_to_scalar_psd2(input: &[Field<Self>]) -> Result<Scalar<Self>> {
494 POSEIDON_2.hash_to_scalar(input)
495 }
496
497 fn hash_to_scalar_psd4(input: &[Field<Self>]) -> Result<Scalar<Self>> {
499 POSEIDON_4.hash_to_scalar(input)
500 }
501
502 fn hash_to_scalar_psd8(input: &[Field<Self>]) -> Result<Scalar<Self>> {
504 POSEIDON_8.hash_to_scalar(input)
505 }
506
507 fn merkle_tree_bhp<const DEPTH: u8>(leaves: &[Vec<bool>]) -> Result<BHPMerkleTree<Self, DEPTH>> {
509 MerkleTree::new(&*BHP_1024, &*BHP_512, leaves)
510 }
511
512 fn merkle_tree_psd<const DEPTH: u8>(leaves: &[Vec<Field<Self>>]) -> Result<PoseidonMerkleTree<Self, DEPTH>> {
514 MerkleTree::new(&*POSEIDON_4, &*POSEIDON_2, leaves)
515 }
516
517 fn verify_merkle_path_bhp<const DEPTH: u8>(
519 path: &MerklePath<Self, DEPTH>,
520 root: &Field<Self>,
521 leaf: &Vec<bool>,
522 ) -> bool {
523 path.verify(&*BHP_1024, &*BHP_512, root, leaf)
524 }
525
526 fn verify_merkle_path_psd<const DEPTH: u8>(
528 path: &MerklePath<Self, DEPTH>,
529 root: &Field<Self>,
530 leaf: &Vec<Field<Self>>,
531 ) -> bool {
532 path.verify(&*POSEIDON_4, &*POSEIDON_2, root, leaf)
533 }
534}
535
536#[cfg(test)]
537mod tests {
538 use super::*;
539
540 type CurrentNetwork = MainnetV0;
541
542 #[test]
543 fn test_g_scalar_multiply() {
544 let scalar = Scalar::rand(&mut TestRng::default());
546 let group = CurrentNetwork::g_scalar_multiply(&scalar);
547 assert_eq!(group, CurrentNetwork::g_powers()[0] * scalar);
548 }
549}