use super::*;
use crate::TRANSACTION_PREFIX;
use snarkvm_console_algorithms::{
BHP256,
BHP512,
BHP768,
BHP1024,
Blake2Xs,
Keccak256,
Keccak384,
Keccak512,
Pedersen64,
Pedersen128,
Poseidon2,
Poseidon4,
Poseidon8,
Sha3_256,
Sha3_384,
Sha3_512,
};
lazy_static! {
static ref GENERATOR_G: Vec<Group<TestnetV0 >> = TestnetV0::new_bases("AleoAccountEncryptionAndSignatureScheme0");
static ref VARUNA_FS_PARAMETERS: FiatShamirParameters<TestnetV0> = FiatShamir::<TestnetV0>::sample_parameters();
static ref ENCRYPTION_DOMAIN: Field<TestnetV0> = Field::<TestnetV0>::new_domain_separator("AleoSymmetricEncryption0");
static ref GRAPH_KEY_DOMAIN: Field<TestnetV0> = Field::<TestnetV0>::new_domain_separator("AleoGraphKey0");
static ref SERIAL_NUMBER_DOMAIN: Field<TestnetV0> = Field::<TestnetV0>::new_domain_separator("AleoSerialNumber0");
pub static ref TESTNET_BHP_256: BHP256<TestnetV0> = BHP256::<TestnetV0>::setup("AleoBHP256").expect("Failed to setup BHP256");
pub static ref TESTNET_BHP_512: BHP512<TestnetV0> = BHP512::<TestnetV0>::setup("AleoBHP512").expect("Failed to setup BHP512");
pub static ref TESTNET_BHP_768: BHP768<TestnetV0> = BHP768::<TestnetV0>::setup("AleoBHP768").expect("Failed to setup BHP768");
pub static ref TESTNET_BHP_1024: BHP1024<TestnetV0> = BHP1024::<TestnetV0>::setup("AleoBHP1024").expect("Failed to setup BHP1024");
pub static ref TESTNET_PEDERSEN_64: Pedersen64<TestnetV0> = Pedersen64::<TestnetV0>::setup("AleoPedersen64");
pub static ref TESTNET_PEDERSEN_128: Pedersen128<TestnetV0> = Pedersen128::<TestnetV0>::setup("AleoPedersen128");
pub static ref TESTNET_POSEIDON_2: Poseidon2<TestnetV0> = Poseidon2::<TestnetV0>::setup("AleoPoseidon2").expect("Failed to setup Poseidon2");
pub static ref TESTNET_POSEIDON_4: Poseidon4<TestnetV0> = Poseidon4::<TestnetV0>::setup("AleoPoseidon4").expect("Failed to setup Poseidon4");
pub static ref TESTNET_POSEIDON_8: Poseidon8<TestnetV0> = Poseidon8::<TestnetV0>::setup("AleoPoseidon8").expect("Failed to setup Poseidon8");
pub static ref TESTNET_CREDITS_PROVING_KEYS: IndexMap<String, Arc<VarunaProvingKey<Console>>> = {
let mut map = IndexMap::new();
snarkvm_parameters::insert_testnet_credit_keys!(map, VarunaProvingKey<Console>, Prover);
map
};
pub static ref TESTNET_CREDITS_VERIFYING_KEYS: IndexMap<String, Arc<VarunaVerifyingKey<Console>>> = {
let mut map = IndexMap::new();
snarkvm_parameters::insert_testnet_credit_keys!(map, VarunaVerifyingKey<Console>, Verifier);
map
};
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct TestnetV0;
impl TestnetV0 {
fn new_bases(message: &str) -> Vec<Group<Self>> {
let (base, _, _) = Blake2Xs::hash_to_curve::<<Self as Environment>::Affine>(message);
let mut g = Group::<Self>::new(base);
let mut g_bases = Vec::with_capacity(Scalar::<Self>::size_in_bits());
for _ in 0..Scalar::<Self>::size_in_bits() {
g_bases.push(g);
g = g.double();
}
g_bases
}
}
impl Environment for TestnetV0 {
type Affine = <Console as Environment>::Affine;
type BigInteger = <Console as Environment>::BigInteger;
type Field = <Console as Environment>::Field;
type PairingCurve = <Console as Environment>::PairingCurve;
type Projective = <Console as Environment>::Projective;
type Scalar = <Console as Environment>::Scalar;
const EDWARDS_A: Self::Field = Console::EDWARDS_A;
const EDWARDS_D: Self::Field = Console::EDWARDS_D;
const MONTGOMERY_A: Self::Field = Console::MONTGOMERY_A;
const MONTGOMERY_B: Self::Field = Console::MONTGOMERY_B;
}
impl Network for TestnetV0 {
type BlockHash = AleoID<Field<Self>, { hrp2!("ab") }>;
type RatificationID = AleoID<Field<Self>, { hrp2!("ar") }>;
type StateRoot = AleoID<Field<Self>, { hrp2!("sr") }>;
type TransactionID = AleoID<Field<Self>, { hrp2!(TRANSACTION_PREFIX) }>;
type TransitionID = AleoID<Field<Self>, { hrp2!("au") }>;
type TransmissionChecksum = u128;
#[cfg(not(any(test, feature = "test")))]
const CONSENSUS_V2_HEIGHT: u32 = 2_950_000;
#[cfg(any(test, feature = "test"))]
const CONSENSUS_V2_HEIGHT: u32 = 10;
const EDITION: u16 = 0;
#[cfg(not(feature = "test_targets"))]
const GENESIS_COINBASE_TARGET: u64 = (1u64 << 29).saturating_sub(1);
#[cfg(feature = "test_targets")]
const GENESIS_COINBASE_TARGET: u64 = (1u64 << 5).saturating_sub(1);
#[cfg(not(feature = "test_targets"))]
const GENESIS_PROOF_TARGET: u64 = 1u64 << 27;
#[cfg(feature = "test_targets")]
const GENESIS_PROOF_TARGET: u64 = 1u64 << 3;
const GENESIS_TIMESTAMP: i64 = 1715776496 ;
const ID: u16 = 1;
const INCLUSION_FUNCTION_NAME: &'static str = MainnetV0::INCLUSION_FUNCTION_NAME;
const MAX_CERTIFICATES: u16 = 100;
const NAME: &'static str = "Aleo Testnet (v0)";
fn genesis_bytes() -> &'static [u8] {
snarkvm_parameters::testnet::GenesisBytes::load_bytes()
}
fn restrictions_list_as_str() -> &'static str {
snarkvm_parameters::testnet::RESTRICTIONS_LIST
}
fn get_credits_proving_key(function_name: String) -> Result<&'static Arc<VarunaProvingKey<Self>>> {
TESTNET_CREDITS_PROVING_KEYS
.get(&function_name)
.ok_or_else(|| anyhow!("Proving key for credits.aleo/{function_name}' not found"))
}
fn get_credits_verifying_key(function_name: String) -> Result<&'static Arc<VarunaVerifyingKey<Self>>> {
TESTNET_CREDITS_VERIFYING_KEYS
.get(&function_name)
.ok_or_else(|| anyhow!("Verifying key for credits.aleo/{function_name}' not found"))
}
fn inclusion_proving_key() -> &'static Arc<VarunaProvingKey<Self>> {
static INSTANCE: OnceCell<Arc<VarunaProvingKey<Console>>> = OnceCell::new();
INSTANCE.get_or_init(|| {
Arc::new(
CircuitProvingKey::from_bytes_le(&snarkvm_parameters::testnet::INCLUSION_PROVING_KEY[1..])
.expect("Failed to load inclusion proving key."),
)
})
}
fn inclusion_verifying_key() -> &'static Arc<VarunaVerifyingKey<Self>> {
static INSTANCE: OnceCell<Arc<VarunaVerifyingKey<Console>>> = OnceCell::new();
INSTANCE.get_or_init(|| {
Arc::new(
CircuitVerifyingKey::from_bytes_le(&snarkvm_parameters::testnet::INCLUSION_VERIFYING_KEY[1..])
.expect("Failed to load inclusion verifying key."),
)
})
}
fn g_powers() -> &'static Vec<Group<Self>> {
&GENERATOR_G
}
fn g_scalar_multiply(scalar: &Scalar<Self>) -> Group<Self> {
GENERATOR_G
.iter()
.zip_eq(&scalar.to_bits_le())
.filter_map(|(base, bit)| match bit {
true => Some(base),
false => None,
})
.sum()
}
fn varuna_universal_prover() -> &'static UniversalProver<Self::PairingCurve> {
MainnetV0::varuna_universal_prover()
}
fn varuna_universal_verifier() -> &'static UniversalVerifier<Self::PairingCurve> {
MainnetV0::varuna_universal_verifier()
}
fn varuna_fs_parameters() -> &'static FiatShamirParameters<Self> {
&VARUNA_FS_PARAMETERS
}
fn encryption_domain() -> Field<Self> {
*ENCRYPTION_DOMAIN
}
fn graph_key_domain() -> Field<Self> {
*GRAPH_KEY_DOMAIN
}
fn serial_number_domain() -> Field<Self> {
*SERIAL_NUMBER_DOMAIN
}
fn commit_bhp256(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
TESTNET_BHP_256.commit(input, randomizer)
}
fn commit_bhp512(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
TESTNET_BHP_512.commit(input, randomizer)
}
fn commit_bhp768(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
TESTNET_BHP_768.commit(input, randomizer)
}
fn commit_bhp1024(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
TESTNET_BHP_1024.commit(input, randomizer)
}
fn commit_ped64(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
TESTNET_PEDERSEN_64.commit(input, randomizer)
}
fn commit_ped128(input: &[bool], randomizer: &Scalar<Self>) -> Result<Field<Self>> {
TESTNET_PEDERSEN_128.commit(input, randomizer)
}
fn commit_to_group_bhp256(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
TESTNET_BHP_256.commit_uncompressed(input, randomizer)
}
fn commit_to_group_bhp512(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
TESTNET_BHP_512.commit_uncompressed(input, randomizer)
}
fn commit_to_group_bhp768(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
TESTNET_BHP_768.commit_uncompressed(input, randomizer)
}
fn commit_to_group_bhp1024(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
TESTNET_BHP_1024.commit_uncompressed(input, randomizer)
}
fn commit_to_group_ped64(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
TESTNET_PEDERSEN_64.commit_uncompressed(input, randomizer)
}
fn commit_to_group_ped128(input: &[bool], randomizer: &Scalar<Self>) -> Result<Group<Self>> {
TESTNET_PEDERSEN_128.commit_uncompressed(input, randomizer)
}
fn hash_bhp256(input: &[bool]) -> Result<Field<Self>> {
TESTNET_BHP_256.hash(input)
}
fn hash_bhp512(input: &[bool]) -> Result<Field<Self>> {
TESTNET_BHP_512.hash(input)
}
fn hash_bhp768(input: &[bool]) -> Result<Field<Self>> {
TESTNET_BHP_768.hash(input)
}
fn hash_bhp1024(input: &[bool]) -> Result<Field<Self>> {
TESTNET_BHP_1024.hash(input)
}
fn hash_keccak256(input: &[bool]) -> Result<Vec<bool>> {
Keccak256::default().hash(input)
}
fn hash_keccak384(input: &[bool]) -> Result<Vec<bool>> {
Keccak384::default().hash(input)
}
fn hash_keccak512(input: &[bool]) -> Result<Vec<bool>> {
Keccak512::default().hash(input)
}
fn hash_ped64(input: &[bool]) -> Result<Field<Self>> {
TESTNET_PEDERSEN_64.hash(input)
}
fn hash_ped128(input: &[bool]) -> Result<Field<Self>> {
TESTNET_PEDERSEN_128.hash(input)
}
fn hash_psd2(input: &[Field<Self>]) -> Result<Field<Self>> {
TESTNET_POSEIDON_2.hash(input)
}
fn hash_psd4(input: &[Field<Self>]) -> Result<Field<Self>> {
TESTNET_POSEIDON_4.hash(input)
}
fn hash_psd8(input: &[Field<Self>]) -> Result<Field<Self>> {
TESTNET_POSEIDON_8.hash(input)
}
fn hash_sha3_256(input: &[bool]) -> Result<Vec<bool>> {
Sha3_256::default().hash(input)
}
fn hash_sha3_384(input: &[bool]) -> Result<Vec<bool>> {
Sha3_384::default().hash(input)
}
fn hash_sha3_512(input: &[bool]) -> Result<Vec<bool>> {
Sha3_512::default().hash(input)
}
fn hash_many_psd2(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
TESTNET_POSEIDON_2.hash_many(input, num_outputs)
}
fn hash_many_psd4(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
TESTNET_POSEIDON_4.hash_many(input, num_outputs)
}
fn hash_many_psd8(input: &[Field<Self>], num_outputs: u16) -> Vec<Field<Self>> {
TESTNET_POSEIDON_8.hash_many(input, num_outputs)
}
fn hash_to_group_bhp256(input: &[bool]) -> Result<Group<Self>> {
TESTNET_BHP_256.hash_uncompressed(input)
}
fn hash_to_group_bhp512(input: &[bool]) -> Result<Group<Self>> {
TESTNET_BHP_512.hash_uncompressed(input)
}
fn hash_to_group_bhp768(input: &[bool]) -> Result<Group<Self>> {
TESTNET_BHP_768.hash_uncompressed(input)
}
fn hash_to_group_bhp1024(input: &[bool]) -> Result<Group<Self>> {
TESTNET_BHP_1024.hash_uncompressed(input)
}
fn hash_to_group_ped64(input: &[bool]) -> Result<Group<Self>> {
TESTNET_PEDERSEN_64.hash_uncompressed(input)
}
fn hash_to_group_ped128(input: &[bool]) -> Result<Group<Self>> {
TESTNET_PEDERSEN_128.hash_uncompressed(input)
}
fn hash_to_group_psd2(input: &[Field<Self>]) -> Result<Group<Self>> {
TESTNET_POSEIDON_2.hash_to_group(input)
}
fn hash_to_group_psd4(input: &[Field<Self>]) -> Result<Group<Self>> {
TESTNET_POSEIDON_4.hash_to_group(input)
}
fn hash_to_group_psd8(input: &[Field<Self>]) -> Result<Group<Self>> {
TESTNET_POSEIDON_8.hash_to_group(input)
}
fn hash_to_scalar_psd2(input: &[Field<Self>]) -> Result<Scalar<Self>> {
TESTNET_POSEIDON_2.hash_to_scalar(input)
}
fn hash_to_scalar_psd4(input: &[Field<Self>]) -> Result<Scalar<Self>> {
TESTNET_POSEIDON_4.hash_to_scalar(input)
}
fn hash_to_scalar_psd8(input: &[Field<Self>]) -> Result<Scalar<Self>> {
TESTNET_POSEIDON_8.hash_to_scalar(input)
}
fn merkle_tree_bhp<const DEPTH: u8>(leaves: &[Vec<bool>]) -> Result<BHPMerkleTree<Self, DEPTH>> {
MerkleTree::new(&*TESTNET_BHP_1024, &*TESTNET_BHP_512, leaves)
}
fn merkle_tree_psd<const DEPTH: u8>(leaves: &[Vec<Field<Self>>]) -> Result<PoseidonMerkleTree<Self, DEPTH>> {
MerkleTree::new(&*TESTNET_POSEIDON_4, &*TESTNET_POSEIDON_2, leaves)
}
fn verify_merkle_path_bhp<const DEPTH: u8>(
path: &MerklePath<Self, DEPTH>,
root: &Field<Self>,
leaf: &Vec<bool>,
) -> bool {
path.verify(&*TESTNET_BHP_1024, &*TESTNET_BHP_512, root, leaf)
}
fn verify_merkle_path_psd<const DEPTH: u8>(
path: &MerklePath<Self, DEPTH>,
root: &Field<Self>,
leaf: &Vec<Field<Self>>,
) -> bool {
path.verify(&*TESTNET_POSEIDON_4, &*TESTNET_POSEIDON_2, root, leaf)
}
}
#[cfg(test)]
mod tests {
use super::*;
type CurrentNetwork = TestnetV0;
#[test]
fn test_g_scalar_multiply() {
let scalar = Scalar::rand(&mut TestRng::default());
let group = CurrentNetwork::g_scalar_multiply(&scalar);
assert_eq!(group, CurrentNetwork::g_powers()[0] * scalar);
}
}