structs.nr 6.62 KB
use crate::hash;

global utxo_depth = 4;
global batch_depth = 4;
global state_depth = 20;
global ZERO_VALUE = 0x016a430aa58685aba1311244a973a3bc358859da86784be51094368e8fb6f720;

// Levels of an empty pedersen Merkle tree with zero_leaf = sha256("Momiji") % Field Modulus
global zero_hashes: [Field; 20] = [
    0x016a430aa58685aba1311244a973a3bc358859da86784be51094368e8fb6f720, 
    0x018d39625c19fa2cfbebdb940a66d7040bb0ef1b59ff6afd92a13a6b9b2d9865, 
    0x096c00ebc0c52478316b6b9fd16d0cd94c5f45bbe45bbfa8c606197c6119d41f, 
    0x2eaefd3bdd1bfbddd8fc5d972ded58617f752b3e88bd17b791e85e7b8eaacb47, 
    0x11d25ff6aa8a431fbce8e8d9a87a2d7986adf38e724fbe47f15752d0931f14d8, 
    0x01e8677aa02546bd7105a7a9fd31c4ef16b69d1bde90f36e97585d7cc31d50e4, 
    0x2520a755a532994c78f35b89938fbc864ec31ec4fc00363f83f9b12f04980c6a, 
    0x21a666842842d5323e51fdda10300c763d6b07e1b797ef3b0bd3690d667445bc, 
    0x1ce681d6f42b70668c369e7f786166e421dc840f0529bbd065d6b02d14ae0fe8, 
    0x1819b90a43ee28f652735708b2ef01428e21b84872bb3c7576de6e35d107c8ed, 
    0x063d7001431110a5949f5946a501fd28f64159f36ab4b80601ca305ac107b3db, 
    0x09aeef7a06f7daf368d797c2e686c7e9884f000de0bd9d8e73392378b0b1be38, 
    0x137121fd5d795eeecc61ec6a6de66abc589d241540139178cd5408b6ccb32a6e, 
    0x01a93f70a1b7482e0b32e76ce49a1e3c1fc2b5cd4789b6af749d78c42791c21a, 
    0x217bf2cc1f1b505a29b162a7889866af2728f5c6708560c9cc5e987b194c9c81, 
    0x1461dae57d7df7e580279637e5d94e0d734b908dc22aec5c52ed00187050a030, 
    0x295933dd65294cbf4b2c64d8a0daa6983d35d1f64d5adc2c44bd9d370086d7dc, 
    0x24650084f0db0fa4e8234fb251ad046b3ddcb7d6f59160b35cc4086e9e196b80, 
    0x15086d0394bd68847e3e36241cc7b3966f96efdd30a37e9e1e85027a6dacbed2, 
    0x1f87a17564f06581c1e1b2d716120990f898893ecc0e076363c56c5e3b56ef7b
    ];

//  sha256("Momiji") % Field Modulus
global zero_root: Field = 0x06f93f503e77fcdcacfe622e66adc639b63e8c0083f5cab5d71d461aa4562c92;

struct Verifier {
    key_hash: Field,
    verification_key: [Field; 114],
    proof: [Field; 109],
    aggregation_object: [Field; 16]
}

struct VerifierTx {
    key_hash: Field,
    verification_key: [Field; 114],
    proof: [Field; 93]
}

impl Verifier {
    fn as_fields(self) -> [Field; 208] {
        let mut verifier_as_fields: [Field; 208] = [0; 208];
        verifier_as_fields[0] = self.key_hash;
        for i in 0..114 {
            verifier_as_fields[i + 1] = self.verification_key[i];
        }
        for j in 0..93 {
            verifier_as_fields[j + 115] = self.proof[j];
        }
        verifier_as_fields
    }

    fn concatenate(self) -> [Field; 109] {
        let mut proof_with_agg: [Field; 109] = [0; 109];
        for i in 0..16 {
            proof_with_agg[i] = self.aggregation_object[i];
        }
        for j in 0..93 {
            proof_with_agg[j + 16] = self.proof[j];
        }
        proof_with_agg
    }
}

struct UTXO {
    owner: Field,
    amount: Field,
    asset_type: Field
}

struct UTXO_New {
    secret: Field,
    amount: Field,
    asset_type: Field
}

impl UTXO_New {
    fn owner(self) -> Field {
        hash::hash([self.secret])
    }

    fn nullifier_hash(self) -> Field {
        hash::hash([self.secret, self.secret])
    }

    fn to_commitment(self) -> Field {
        hash::hash([self.owner(), self.amount, self.asset_type])
    }
}

struct UTXO_Spendable {
    secret: Field,
    amount: Field,
    asset_type: Field,
    oracle: Field,
    old_root_proof: Field,
    merkle_proof: MerkleProof,
    spend_in_same_batch: bool
}

impl UTXO_Spendable {
    fn owner(self) -> Field {
        hash::hash([self.secret])
    }

    fn nullifier_hash(self) -> Field {
        hash::hash([self.secret, self.secret])
    }

    fn to_commitment(self) -> Field {
        hash::hash([self.owner(), self.amount, self.asset_type])
    }
}

struct PublicInputs {
    current_root: Field, 
    utxo_root: Field,
    deposit_amount: Field,
    withdrawals: Field,
    commitment_in: [Field; 16],
    commitment_out: [Field; 16],
    nullifier_hashes: [Field; 16],
    contract_only_inputs: Field 
}

impl PublicInputs {
    fn as_fields(self) -> [Field; 53] {
        let mut public_fields: [Field; 53] = [0; 53];
        public_fields[0] = self.current_root;
        public_fields[1] = self.utxo_root;
        public_fields[2] = self.deposit_amount;
        public_fields[3] = self.withdrawals;
        for i in 0..16 {        
            public_fields[4 + i] = self.commitment_in[i];
            public_fields[20 + i] = self.commitment_out[i];
            public_fields[36 + i] = self.nullifier_hashes[i];
        }
        public_fields[50] = self.contract_only_inputs;
        public_fields
    }
    fn as_hash(self) -> Field {
        hash::hash_tx(self)
    }
    fn as_keccak(self) -> Field {
        hash::keccak_tx(self)
    }
    fn as_u8(self) -> [u8; 1696] {
        hash::tx_to_u8(self.as_fields())
    }
}

struct PrivateInputs {
    oracle: [Field; 16],
    old_root_proof: [Field; 16],
    secrets: [Field; 16],
    utxo_in: [UTXO; 16], 
    merkle_proofs: [MerkleProof; 16],
    utxo_out: [UTXO; 16],
}


struct TransactionInputs {
    public_inputs_hash: Field,
    public_inputs: PublicInputs,
    private_inputs: PrivateInputs
}


struct RecursionInputs {
    accumulator: Field,
    tx_verifier: VerifierTx,
    recursion_verifier: Verifier,
    previous_accumulator: Field,
    tx: PublicInputs
}


struct PublishInputs {
    pi_contract_hash: Field,
    accumulator: Field,
    batch: Batch,
    tx_verifier: VerifierTx,
    recursion_verifier: Verifier
}

struct Batch {
    hist_tree: HistoricTree,
    old_state_root: Field, 
    new_state_root: Field, 
    batch_oracle: Field, 
    utxo_roots: [Field; 16]
}

struct EncryptedUTXO {
    secret: Field,
    amount: Field,
    data: Field
}

struct ContractOnlyInputs {
    timestamp: Field,
    deadline: Field,
    signature_hash: Field,
    price_limit: Field,
    recipients: [Field; 16],
    swap_amounts: [Field; 16],
    uids: [Field; 16],
    encrypted_utxo: [EncryptedUTXO; 16]
}

impl ContractOnlyInputs {
    fn as_keccak_without_deposit(self) -> Field {
        hash::keccak_contract_only_inputs_without_deposit(self)
    }

    fn as_keccak(self) -> Field {
        hash::keccak_contract_only_inputs(self)
    }
}

struct MerkleProof {
    path_utxo: [Field; utxo_depth],
    path_tx: [Field; batch_depth],
    path_historic: [Field; state_depth],
    index_utxo: Field,
    index_tx: Field,
    index_historic: Field
}

struct HistoricTree {
    root: Field,
    new_root: Field,
    leaf: Field,
    index: Field,
    old_path: [Field; state_depth],
    new_path: [Field; state_depth],
}

struct HistoricTreeInput {
    root: Field,
    leaf: Field,
    index: Field,
    path: [Field; state_depth],
    utxo_roots: [Field; 16],
}