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<TestnetV0 >> = TestnetV0::new_bases("AleoAccountEncryptionAndSignatureScheme0");
40
41 static ref VARUNA_FS_PARAMETERS: FiatShamirParameters<TestnetV0> = FiatShamir::<TestnetV0>::sample_parameters();
43
44 static ref ENCRYPTION_DOMAIN: Field<TestnetV0> = Field::<TestnetV0>::new_domain_separator("AleoSymmetricEncryption0");
46 static ref GRAPH_KEY_DOMAIN: Field<TestnetV0> = Field::<TestnetV0>::new_domain_separator("AleoGraphKey0");
48 static ref SERIAL_NUMBER_DOMAIN: Field<TestnetV0> = Field::<TestnetV0>::new_domain_separator("AleoSerialNumber0");
50
51 pub static ref TESTNET_BHP_256: BHP256<TestnetV0> = BHP256::<TestnetV0>::setup("AleoBHP256").expect("Failed to setup BHP256");
53 pub static ref TESTNET_BHP_512: BHP512<TestnetV0> = BHP512::<TestnetV0>::setup("AleoBHP512").expect("Failed to setup BHP512");
55 pub static ref TESTNET_BHP_768: BHP768<TestnetV0> = BHP768::<TestnetV0>::setup("AleoBHP768").expect("Failed to setup BHP768");
57 pub static ref TESTNET_BHP_1024: BHP1024<TestnetV0> = BHP1024::<TestnetV0>::setup("AleoBHP1024").expect("Failed to setup BHP1024");
59
60 pub static ref TESTNET_PEDERSEN_64: Pedersen64<TestnetV0> = Pedersen64::<TestnetV0>::setup("AleoPedersen64");
62 pub static ref TESTNET_PEDERSEN_128: Pedersen128<TestnetV0> = Pedersen128::<TestnetV0>::setup("AleoPedersen128");
64
65 pub static ref TESTNET_POSEIDON_2: Poseidon2<TestnetV0> = Poseidon2::<TestnetV0>::setup("AleoPoseidon2").expect("Failed to setup Poseidon2");
67 pub static ref TESTNET_POSEIDON_4: Poseidon4<TestnetV0> = Poseidon4::<TestnetV0>::setup("AleoPoseidon4").expect("Failed to setup Poseidon4");
69 pub static ref TESTNET_POSEIDON_8: Poseidon8<TestnetV0> = Poseidon8::<TestnetV0>::setup("AleoPoseidon8").expect("Failed to setup Poseidon8");
71
72 pub static ref TESTNET_CREDITS_PROVING_KEYS: IndexMap<String, Arc<VarunaProvingKey<Console>>> = {
73 let mut map = IndexMap::new();
74 snarkvm_parameters::insert_testnet_credit_keys!(map, VarunaProvingKey<Console>, Prover);
75 map
76 };
77 pub static ref TESTNET_CREDITS_VERIFYING_KEYS: IndexMap<String, Arc<VarunaVerifyingKey<Console>>> = {
78 let mut map = IndexMap::new();
79 snarkvm_parameters::insert_testnet_credit_keys!(map, VarunaVerifyingKey<Console>, Verifier);
80 map
81 };
82}
83
84#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
85pub struct TestnetV0;
86
87impl TestnetV0 {
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 TestnetV0 {
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 TestnetV0 {
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")))]
139 const CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); 5] = [
140 (ConsensusVersion::V1, 0),
141 (ConsensusVersion::V2, 2_950_000),
142 (ConsensusVersion::V3, 4_800_000),
143 (ConsensusVersion::V4, 6_625_000),
144 (ConsensusVersion::V5, 6_765_000),
145 ];
146 #[cfg(any(test, feature = "test"))]
149 const CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); 5] = [
150 (ConsensusVersion::V1, 0),
151 (ConsensusVersion::V2, 10),
152 (ConsensusVersion::V3, 11),
153 (ConsensusVersion::V4, 12),
154 (ConsensusVersion::V5, 13),
155 ];
156 const EDITION: u16 = 0;
158 #[cfg(not(feature = "test_targets"))]
160 const GENESIS_COINBASE_TARGET: u64 = (1u64 << 29).saturating_sub(1);
161 #[cfg(feature = "test_targets")]
162 const GENESIS_COINBASE_TARGET: u64 = (1u64 << 5).saturating_sub(1);
163 #[cfg(not(feature = "test_targets"))]
165 const GENESIS_PROOF_TARGET: u64 = 1u64 << 27;
166 #[cfg(feature = "test_targets")]
167 const GENESIS_PROOF_TARGET: u64 = 1u64 << 3;
168 const GENESIS_TIMESTAMP: i64 = 1715776496 ;
170 const ID: u16 = 1;
172 const INCLUSION_FUNCTION_NAME: &'static str = MainnetV0::INCLUSION_FUNCTION_NAME;
174 #[cfg(not(any(test, feature = "test")))]
176 const MAX_CERTIFICATES: [(ConsensusVersion, u16); 3] =
177 [(ConsensusVersion::V1, 100), (ConsensusVersion::V3, 100), (ConsensusVersion::V5, 100)];
178 #[cfg(any(test, feature = "test"))]
180 const MAX_CERTIFICATES: [(ConsensusVersion, u16); 3] =
181 [(ConsensusVersion::V1, 25), (ConsensusVersion::V3, 25), (ConsensusVersion::V5, 25)];
182 const NAME: &'static str = "Aleo Testnet (v0)";
184
185 fn genesis_bytes() -> &'static [u8] {
187 snarkvm_parameters::testnet::GenesisBytes::load_bytes()
188 }
189
190 fn restrictions_list_as_str() -> &'static str {
192 snarkvm_parameters::testnet::RESTRICTIONS_LIST
193 }
194
195 fn get_credits_proving_key(function_name: String) -> Result<&'static Arc<VarunaProvingKey<Self>>> {
197 TESTNET_CREDITS_PROVING_KEYS
198 .get(&function_name)
199 .ok_or_else(|| anyhow!("Proving key for credits.aleo/{function_name}' not found"))
200 }
201
202 fn get_credits_verifying_key(function_name: String) -> Result<&'static Arc<VarunaVerifyingKey<Self>>> {
204 TESTNET_CREDITS_VERIFYING_KEYS
205 .get(&function_name)
206 .ok_or_else(|| anyhow!("Verifying key for credits.aleo/{function_name}' not found"))
207 }
208
209 fn inclusion_proving_key() -> &'static Arc<VarunaProvingKey<Self>> {
211 static INSTANCE: OnceCell<Arc<VarunaProvingKey<Console>>> = OnceCell::new();
212 INSTANCE.get_or_init(|| {
213 Arc::new(
215 CircuitProvingKey::from_bytes_le(&snarkvm_parameters::testnet::INCLUSION_PROVING_KEY[1..])
216 .expect("Failed to load inclusion proving key."),
217 )
218 })
219 }
220
221 fn inclusion_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>> {
223 static INSTANCE: OnceCell<Arc<VarunaVerifyingKey<Console>>> = OnceCell::new();
224 INSTANCE.get_or_init(|| {
225 Arc::new(
227 CircuitVerifyingKey::from_bytes_le(&snarkvm_parameters::testnet::INCLUSION_VERIFYING_KEY[1..])
228 .expect("Failed to load inclusion verifying key."),
229 )
230 })
231 }
232
233 fn g_powers() -> &'static Vec<Group<Self>> {
235 &GENERATOR_G
236 }
237
238 fn g_scalar_multiply(scalar: &Scalar<Self>) -> Group<Self> {
240 GENERATOR_G
241 .iter()
242 .zip_eq(&scalar.to_bits_le())
243 .filter_map(|(base, bit)| match bit {
244 true => Some(base),
245 false => None,
246 })
247 .sum()
248 }
249
250 fn varuna_universal_prover() -> &'static UniversalProver<Self::PairingCurve> {
252 MainnetV0::varuna_universal_prover()
253 }
254
255 fn varuna_universal_verifier() -> &'static UniversalVerifier<Self::PairingCurve> {
257 MainnetV0::varuna_universal_verifier()
258 }
259
260 fn varuna_fs_parameters() -> &'static FiatShamirParameters<Self> {
262 &VARUNA_FS_PARAMETERS
263 }
264
265 fn encryption_domain() -> Field<Self> {
267 *ENCRYPTION_DOMAIN
268 }
269
270 fn graph_key_domain() -> Field<Self> {
272 *GRAPH_KEY_DOMAIN
273 }
274
275 fn serial_number_domain() -> Field<Self> {
277 *SERIAL_NUMBER_DOMAIN
278 }
279
280 fn commit_bhp256(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
282 TESTNET_BHP_256.commit(input, randomizer)
283 }
284
285 fn commit_bhp512(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
287 TESTNET_BHP_512.commit(input, randomizer)
288 }
289
290 fn commit_bhp768(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
292 TESTNET_BHP_768.commit(input, randomizer)
293 }
294
295 fn commit_bhp1024(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
297 TESTNET_BHP_1024.commit(input, randomizer)
298 }
299
300 fn commit_ped64(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
302 TESTNET_PEDERSEN_64.commit(input, randomizer)
303 }
304
305 fn commit_ped128(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
307 TESTNET_PEDERSEN_128.commit(input, randomizer)
308 }
309
310 fn commit_to_group_bhp256(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
312 TESTNET_BHP_256.commit_uncompressed(input, randomizer)
313 }
314
315 fn commit_to_group_bhp512(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
317 TESTNET_BHP_512.commit_uncompressed(input, randomizer)
318 }
319
320 fn commit_to_group_bhp768(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
322 TESTNET_BHP_768.commit_uncompressed(input, randomizer)
323 }
324
325 fn commit_to_group_bhp1024(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
327 TESTNET_BHP_1024.commit_uncompressed(input, randomizer)
328 }
329
330 fn commit_to_group_ped64(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
332 TESTNET_PEDERSEN_64.commit_uncompressed(input, randomizer)
333 }
334
335 fn commit_to_group_ped128(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
337 TESTNET_PEDERSEN_128.commit_uncompressed(input, randomizer)
338 }
339
340 fn hash_bhp256(input: &[bool]) -> Result<Field<Self>> {
342 TESTNET_BHP_256.hash(input)
343 }
344
345 fn hash_bhp512(input: &[bool]) -> Result<Field<Self>> {
347 TESTNET_BHP_512.hash(input)
348 }
349
350 fn hash_bhp768(input: &[bool]) -> Result<Field<Self>> {
352 TESTNET_BHP_768.hash(input)
353 }
354
355 fn hash_bhp1024(input: &[bool]) -> Result<Field<Self>> {
357 TESTNET_BHP_1024.hash(input)
358 }
359
360 fn hash_keccak256(input: &[bool]) -> Result<Vec<bool>> {
362 Keccak256::default().hash(input)
363 }
364
365 fn hash_keccak384(input: &[bool]) -> Result<Vec<bool>> {
367 Keccak384::default().hash(input)
368 }
369
370 fn hash_keccak512(input: &[bool]) -> Result<Vec<bool>> {
372 Keccak512::default().hash(input)
373 }
374
375 fn hash_ped64(input: &[bool]) -> Result<Field<Self>> {
377 TESTNET_PEDERSEN_64.hash(input)
378 }
379
380 fn hash_ped128(input: &[bool]) -> Result<Field<Self>> {
382 TESTNET_PEDERSEN_128.hash(input)
383 }
384
385 fn hash_psd2(input: &[Field<Self>]) -> Result<Field<Self>> {
387 TESTNET_POSEIDON_2.hash(input)
388 }
389
390 fn hash_psd4(input: &[Field<Self>]) -> Result<Field<Self>> {
392 TESTNET_POSEIDON_4.hash(input)
393 }
394
395 fn hash_psd8(input: &[Field<Self>]) -> Result<Field<Self>> {
397 TESTNET_POSEIDON_8.hash(input)
398 }
399
400 fn hash_sha3_256(input: &[bool]) -> Result<Vec<bool>> {
402 Sha3_256::default().hash(input)
403 }
404
405 fn hash_sha3_384(input: &[bool]) -> Result<Vec<bool>> {
407 Sha3_384::default().hash(input)
408 }
409
410 fn hash_sha3_512(input: &[bool]) -> Result<Vec<bool>> {
412 Sha3_512::default().hash(input)
413 }
414
415 fn hash_many_psd2(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
417 TESTNET_POSEIDON_2.hash_many(input, num_outputs)
418 }
419
420 fn hash_many_psd4(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
422 TESTNET_POSEIDON_4.hash_many(input, num_outputs)
423 }
424
425 fn hash_many_psd8(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
427 TESTNET_POSEIDON_8.hash_many(input, num_outputs)
428 }
429
430 fn hash_to_group_bhp256(input: &[bool]) -> Result<Group<Self>> {
432 TESTNET_BHP_256.hash_uncompressed(input)
433 }
434
435 fn hash_to_group_bhp512(input: &[bool]) -> Result<Group<Self>> {
437 TESTNET_BHP_512.hash_uncompressed(input)
438 }
439
440 fn hash_to_group_bhp768(input: &[bool]) -> Result<Group<Self>> {
442 TESTNET_BHP_768.hash_uncompressed(input)
443 }
444
445 fn hash_to_group_bhp1024(input: &[bool]) -> Result<Group<Self>> {
447 TESTNET_BHP_1024.hash_uncompressed(input)
448 }
449
450 fn hash_to_group_ped64(input: &[bool]) -> Result<Group<Self>> {
452 TESTNET_PEDERSEN_64.hash_uncompressed(input)
453 }
454
455 fn hash_to_group_ped128(input: &[bool]) -> Result<Group<Self>> {
457 TESTNET_PEDERSEN_128.hash_uncompressed(input)
458 }
459
460 fn hash_to_group_psd2(input: &[Field<Self>]) -> Result<Group<Self>> {
462 TESTNET_POSEIDON_2.hash_to_group(input)
463 }
464
465 fn hash_to_group_psd4(input: &[Field<Self>]) -> Result<Group<Self>> {
467 TESTNET_POSEIDON_4.hash_to_group(input)
468 }
469
470 fn hash_to_group_psd8(input: &[Field<Self>]) -> Result<Group<Self>> {
472 TESTNET_POSEIDON_8.hash_to_group(input)
473 }
474
475 fn hash_to_scalar_psd2(input: &[Field<Self>]) -> Result<Scalar<Self>> {
477 TESTNET_POSEIDON_2.hash_to_scalar(input)
478 }
479
480 fn hash_to_scalar_psd4(input: &[Field<Self>]) -> Result<Scalar<Self>> {
482 TESTNET_POSEIDON_4.hash_to_scalar(input)
483 }
484
485 fn hash_to_scalar_psd8(input: &[Field<Self>]) -> Result<Scalar<Self>> {
487 TESTNET_POSEIDON_8.hash_to_scalar(input)
488 }
489
490 fn merkle_tree_bhp<const DEPTH: u8>(leaves: &[Vec<bool>]) -> Result<BHPMerkleTree<Self, DEPTH>> {
492 MerkleTree::new(&*TESTNET_BHP_1024, &*TESTNET_BHP_512, leaves)
493 }
494
495 fn merkle_tree_psd<const DEPTH: u8>(leaves: &[Vec<Field<Self>>]) -> Result<PoseidonMerkleTree<Self, DEPTH>> {
497 MerkleTree::new(&*TESTNET_POSEIDON_4, &*TESTNET_POSEIDON_2, leaves)
498 }
499
500 fn verify_merkle_path_bhp<const DEPTH: u8>(
502 path: &MerklePath<Self, DEPTH>,
503 root: &Field<Self>,
504 leaf: &Vec<bool>,
505 ) -> bool {
506 path.verify(&*TESTNET_BHP_1024, &*TESTNET_BHP_512, root, leaf)
507 }
508
509 fn verify_merkle_path_psd<const DEPTH: u8>(
511 path: &MerklePath<Self, DEPTH>,
512 root: &Field<Self>,
513 leaf: &Vec<Field<Self>>,
514 ) -> bool {
515 path.verify(&*TESTNET_POSEIDON_4, &*TESTNET_POSEIDON_2, root, leaf)
516 }
517}
518
519#[cfg(test)]
520mod tests {
521 use super::*;
522
523 type CurrentNetwork = TestnetV0;
524
525 #[test]
526 fn test_g_scalar_multiply() {
527 let scalar = Scalar::rand(&mut TestRng::default());
529 let group = CurrentNetwork::g_scalar_multiply(&scalar);
530 assert_eq!(group, CurrentNetwork::g_powers()[0] * scalar);
531 }
532}