lssa/zkvm/src/lib.rs

308 lines
7.9 KiB
Rust
Raw Normal View History

2024-12-22 16:14:52 +02:00
use accounts::account_core::AccountAddress;
2024-11-18 02:09:13 +01:00
use risc0_zkvm::{default_executor, default_prover, sha::Digest, ExecutorEnv, Receipt};
2024-12-20 11:02:12 +02:00
use utxo::utxo_core::{UTXOPayload, UTXO};
2024-12-22 16:14:52 +02:00
pub fn prove_mint_utxo(amount_to_mint: u128, owner: AccountAddress) -> (UTXO, Receipt) {
2024-12-20 11:02:12 +02:00
let mut builder = ExecutorEnv::builder();
builder.write(&amount_to_mint).unwrap();
builder.write(&owner).unwrap();
let env = builder.build().unwrap();
let prover = default_prover();
2024-12-22 16:14:52 +02:00
let receipt = prover
.prove(env, test_methods::MINT_UTXO_ELF)
.unwrap()
.receipt;
2024-12-20 11:02:12 +02:00
let digest: UTXOPayload = receipt.journal.decode().unwrap();
2024-12-22 16:14:52 +02:00
(UTXO::create_utxo_from_payload(digest), receipt)
}
pub fn prove_send_utxo(
spent_utxo: UTXO,
owners_parts: Vec<(u128, AccountAddress)>,
) -> (Vec<(UTXO, AccountAddress)>, Receipt) {
let mut builder = ExecutorEnv::builder();
builder.write(&spent_utxo).unwrap();
builder.write(&owners_parts).unwrap();
let env = builder.build().unwrap();
let prover = default_prover();
let receipt = prover
.prove(env, test_methods::SEND_UTXO_ELF)
.unwrap()
.receipt;
let digest: Vec<(UTXOPayload, AccountAddress)> = receipt.journal.decode().unwrap();
(
digest
.into_iter()
.map(|(payload, addr)| (UTXO::create_utxo_from_payload(payload), addr))
.collect(),
receipt,
)
2024-12-20 11:02:12 +02:00
}
2024-12-22 16:14:52 +02:00
pub fn prove_send_utxo_shielded(
owner: AccountAddress,
amount: u128,
owners_parts: Vec<(u128, AccountAddress)>,
) -> (Vec<(UTXO, AccountAddress)>, Receipt) {
let temp_utxo_to_spend = UTXO::create_utxo_from_payload(UTXOPayload {
owner,
asset: vec![],
amount,
privacy_flag: true,
});
let mut builder = ExecutorEnv::builder();
builder.write(&temp_utxo_to_spend).unwrap();
builder.write(&owners_parts).unwrap();
let env = builder.build().unwrap();
let prover = default_prover();
let receipt = prover
.prove(env, test_methods::SEND_UTXO_ELF)
.unwrap()
.receipt;
let digest: Vec<(UTXOPayload, AccountAddress)> = receipt.journal.decode().unwrap();
(
digest
.into_iter()
.map(|(payload, addr)| (UTXO::create_utxo_from_payload(payload), addr))
.collect(),
receipt,
)
}
pub fn prove_send_utxo_deshielded(
spent_utxo: UTXO,
owners_parts: Vec<(u128, AccountAddress)>,
) -> (Vec<(u128, AccountAddress)>, Receipt) {
2024-12-20 11:02:12 +02:00
let mut builder = ExecutorEnv::builder();
2024-12-30 07:43:27 +02:00
let utxo_payload = spent_utxo.into_payload();
2024-12-20 11:02:12 +02:00
2024-12-30 07:43:27 +02:00
builder.write(&utxo_payload).unwrap();
2024-12-20 11:02:12 +02:00
builder.write(&owners_parts).unwrap();
let env = builder.build().unwrap();
let prover = default_prover();
2024-12-22 16:14:52 +02:00
let receipt = prover
.prove(env, test_methods::SEND_UTXO_ELF)
.unwrap()
.receipt;
let digest: Vec<(UTXOPayload, AccountAddress)> = receipt.journal.decode().unwrap();
2024-12-20 11:02:12 +02:00
2024-12-22 16:14:52 +02:00
(
digest
.into_iter()
.map(|(payload, addr)| (payload.amount, addr))
.collect(),
receipt,
)
2024-12-20 11:02:12 +02:00
}
pub fn execute_mint_utxo(amount_to_mint: u128, owner: AccountAddress) -> UTXO {
let mut builder = ExecutorEnv::builder();
builder.write(&amount_to_mint).unwrap();
builder.write(&owner).unwrap();
let env = builder.build().unwrap();
let executor = default_executor();
let receipt = executor.execute(env, test_methods::MINT_UTXO_ELF).unwrap();
let digest: UTXOPayload = receipt.journal.decode().unwrap();
2024-12-22 16:14:52 +02:00
2024-12-20 11:02:12 +02:00
UTXO::create_utxo_from_payload(digest)
}
2024-12-22 16:14:52 +02:00
pub fn execute_send_utxo(
spent_utxo: UTXO,
owners_parts: Vec<(u128, AccountAddress)>,
) -> (UTXO, Vec<(UTXO, AccountAddress)>) {
2024-12-20 11:02:12 +02:00
let mut builder = ExecutorEnv::builder();
builder.write(&spent_utxo).unwrap();
builder.write(&owners_parts).unwrap();
let env = builder.build().unwrap();
let executor = default_executor();
let receipt = executor.execute(env, test_methods::SEND_UTXO_ELF).unwrap();
2024-12-22 16:14:52 +02:00
let digest: (UTXOPayload, Vec<(UTXOPayload, AccountAddress)>) =
receipt.journal.decode().unwrap();
(
UTXO::create_utxo_from_payload(digest.0),
digest
.1
.into_iter()
.map(|(payload, addr)| (UTXO::create_utxo_from_payload(payload), addr))
.collect(),
)
2024-12-20 11:02:12 +02:00
}
2024-11-10 02:10:20 +01:00
pub fn prove<T: serde::ser::Serialize>(input_vec: Vec<T>, elf: &[u8]) -> (u64, Receipt) {
let mut builder = ExecutorEnv::builder();
for input in input_vec {
2024-11-10 02:14:01 +01:00
builder.write(&input).unwrap();
2024-11-10 02:10:20 +01:00
}
2024-11-10 02:14:01 +01:00
let env = builder.build().unwrap();
2024-11-10 02:10:20 +01:00
let prover = default_prover();
let receipt = prover.prove(env, elf).unwrap().receipt;
let digest = receipt.journal.decode().unwrap();
(digest, receipt)
}
2024-11-10 02:10:37 +01:00
2024-11-18 01:41:30 +01:00
// This only executes the program and does not generate a receipt.
2024-11-18 02:09:13 +01:00
pub fn execute<T: serde::ser::Serialize + for<'de> serde::Deserialize<'de>>(
input_vec: Vec<T>,
elf: &[u8],
) -> T {
2024-11-18 01:41:30 +01:00
let mut builder = ExecutorEnv::builder();
for input in input_vec {
builder.write(&input).unwrap();
}
let env = builder.build().unwrap();
let exec = default_executor();
2024-11-18 02:06:37 +01:00
let session = exec.execute(env, elf).unwrap();
2024-11-18 01:41:30 +01:00
2024-11-18 02:06:37 +01:00
// We read the result committed to the journal by the guest code.
let result: T = session.journal.decode().unwrap();
result
2024-11-18 01:41:30 +01:00
}
2024-11-10 02:10:37 +01:00
pub fn verify(receipt: Receipt, image_id: impl Into<Digest>) {
receipt
2024-11-10 02:14:01 +01:00
.verify(image_id)
.expect("receipt verification failed");
2024-11-10 02:10:37 +01:00
}
2024-11-10 02:12:20 +01:00
#[cfg(test)]
mod tests {
use super::*;
2024-12-22 16:14:52 +02:00
use test_methods::BIG_CALCULATION_ELF;
2024-11-10 02:14:01 +01:00
use test_methods::{MULTIPLICATION_ELF, MULTIPLICATION_ID};
use test_methods::{SUMMATION_ELF, SUMMATION_ID};
2024-11-10 02:12:20 +01:00
#[test]
2024-11-18 02:08:58 +01:00
fn prove_simple_sum() {
2024-11-10 02:12:20 +01:00
let message = 1;
let message_2 = 2;
2024-11-10 02:14:01 +01:00
2024-11-10 02:12:20 +01:00
let (digest, receipt) = prove(vec![message, message_2], SUMMATION_ELF);
2024-11-10 02:14:01 +01:00
2024-11-10 02:12:20 +01:00
verify(receipt, SUMMATION_ID);
2024-11-10 02:14:01 +01:00
assert_eq!(digest, message + message_2);
2024-11-10 02:12:20 +01:00
}
2024-11-10 02:12:37 +01:00
#[test]
2024-11-18 02:08:58 +01:00
fn prove_bigger_sum() {
2024-11-10 02:12:37 +01:00
let message = 123476;
let message_2 = 2342384;
2024-11-10 02:14:01 +01:00
2024-11-10 02:12:37 +01:00
let (digest, receipt) = prove(vec![message, message_2], SUMMATION_ELF);
2024-11-10 02:14:01 +01:00
2024-11-10 02:12:37 +01:00
verify(receipt, SUMMATION_ID);
2024-11-10 02:14:01 +01:00
assert_eq!(digest, message + message_2);
2024-11-10 02:12:37 +01:00
}
2024-11-10 02:12:55 +01:00
#[test]
2024-11-18 02:08:58 +01:00
fn prove_simple_multiplication() {
2024-11-10 02:12:55 +01:00
let message = 1;
let message_2 = 2;
2024-11-10 02:14:01 +01:00
2024-11-10 02:12:55 +01:00
let (digest, receipt) = prove(vec![message, message_2], MULTIPLICATION_ELF);
2024-11-10 02:14:01 +01:00
2024-11-10 02:12:55 +01:00
verify(receipt, MULTIPLICATION_ID);
2024-11-10 02:14:01 +01:00
assert_eq!(digest, message * message_2);
2024-11-10 02:12:55 +01:00
}
2024-11-10 02:13:24 +01:00
#[test]
2024-11-18 02:08:58 +01:00
fn prove_bigger_multiplication() {
2024-11-10 02:13:24 +01:00
let message = 3498;
let message_2 = 438563;
2024-11-10 02:14:01 +01:00
2024-11-10 02:13:24 +01:00
let (digest, receipt) = prove(vec![message, message_2], MULTIPLICATION_ELF);
2024-11-10 02:14:01 +01:00
2024-11-10 02:13:24 +01:00
verify(receipt, MULTIPLICATION_ID);
2024-11-10 02:14:01 +01:00
assert_eq!(digest, message * message_2);
2024-11-10 02:13:24 +01:00
}
2024-11-18 02:07:57 +01:00
#[test]
fn execute_simple_sum() {
let message: u64 = 1;
let message_2: u64 = 2;
let result = execute(vec![message, message_2], SUMMATION_ELF);
assert_eq!(result, message + message_2);
}
2024-11-18 02:08:08 +01:00
#[test]
fn execute_bigger_sum() {
let message: u64 = 123476;
let message_2: u64 = 2342384;
let result = execute(vec![message, message_2], SUMMATION_ELF);
assert_eq!(result, message + message_2);
}
2024-11-18 02:22:07 +01:00
#[test]
fn execute_big_calculation() {
let message: u128 = 1;
let message_2: u128 = 2;
let result = execute(vec![message, message_2], BIG_CALCULATION_ELF);
assert_eq!(result, big_calculation(message, message_2));
}
2024-11-18 02:22:14 +01:00
#[test]
fn execute_big_calculation_long() {
let message: u128 = 20;
let message_2: u128 = 10;
let result = execute(vec![message, message_2], BIG_CALCULATION_ELF);
assert_eq!(result, big_calculation(message, message_2));
}
2024-11-18 02:22:07 +01:00
fn big_calculation(lhs: u128, rhs: u128) -> u128 {
let mut res = 1_u128;
for _ in 0..lhs {
res *= rhs;
res += lhs;
}
res
2024-11-25 10:37:49 +02:00
}
2024-11-10 02:12:20 +01:00
}