zksvm_lib/
commit.rs

1use std::collections::BTreeMap;
2
3use bincode::serialize;
4use sha2::{Digest, Sha256};
5use solana_program::pubkey::Pubkey;
6use solana_sdk::{account::Account, transaction::Transaction};
7
8use crate::{
9    merkle::{merkelize_accounts_root, merkelize_transactions_root},
10    Privacy,
11};
12
13impl Privacy {
14    pub fn commit_inputs(
15        &self,
16        genesis_accounts: &BTreeMap<Pubkey, Account>,
17        transactions: &Vec<Transaction>,
18    ) {
19        match self {
20            Privacy::Transparent => {
21                sp1_zkvm::io::commit::<BTreeMap<Pubkey, Account>>(genesis_accounts);
22                sp1_zkvm::io::commit::<Vec<Transaction>>(transactions);
23            }
24            Privacy::Simple => {
25                let hash = hash_accounts(genesis_accounts);
26                sp1_zkvm::io::commit_slice(&hash);
27
28                let hash = hash_transactions(transactions);
29                sp1_zkvm::io::commit_slice(&hash);
30            }
31            Privacy::Merkle => {
32                let hash = merkelize_accounts_root(genesis_accounts);
33                sp1_zkvm::io::commit_slice(&hash);
34
35                let hash = merkelize_transactions_root(transactions);
36                sp1_zkvm::io::commit_slice(&hash);
37            }
38        };
39    }
40
41    pub fn commit_outputs(&self, accounts: &BTreeMap<Pubkey, Account>) {
42        match self {
43            Privacy::Transparent => {
44                sp1_zkvm::io::commit::<BTreeMap<Pubkey, Account>>(accounts);
45            }
46            Privacy::Simple => {
47                sp1_zkvm::io::commit_slice(&hash_accounts(accounts));
48            }
49            Privacy::Merkle => {
50                sp1_zkvm::io::commit_slice(&merkelize_accounts_root(accounts));
51            }
52        }
53    }
54}
55
56// compile the inputs to bytes, sha hash, then return the singular hash
57fn hash_accounts(accounts: &BTreeMap<Pubkey, Account>) -> [u8; 32] {
58    let mut account_bytes = Vec::new();
59    for (pubkey, acc) in accounts {
60        account_bytes.extend(pubkey.as_ref());
61        account_bytes.extend(serialize(acc).expect("Failed to serialize account"));
62    }
63
64    let mut hasher = Sha256::new();
65    hasher.update(account_bytes);
66    hasher.finalize().into()
67}
68
69fn hash_transactions(transactions: &Vec<Transaction>) -> [u8; 32] {
70    let mut bytes = Vec::new();
71    for tx in transactions {
72        bytes.extend(serialize(tx).expect("Failed to serialize transaction"));
73    }
74    let mut hasher = Sha256::new();
75    hasher.update(bytes);
76    hasher.finalize().into()
77}