davidrusu 2c7c483707
CL spec (#92)
* feat(cl/noir): provide an ergonomic Noir api for use within Python.

* Add a python wrapper over the bigger constraint

* Add the Bigger wrapper

* cl/noir: document the NargoConstraint wrapper api

* rewrite Bigger constraint as a dataclass

* WIP: Cl/executable spec (#93)

* wip: executable spec

* WIP: test_1_to_1_transfer

* hack: Vacous hash function

* crypto: make sure prf returns field elements, fix ECC math in pedcom

* hack(crypto): mock up a hash_to_curve implementation

* feat(cl/1to1_xfr): fungibility domain uses hash_to_curve

* cl: add type checking to InnerNote

* cl/ptx: get balance commitments working

* cl/noir: mv noir_constraint wrapper into cl/constraints/...

* cl/ptx-note-proofs: start data modelling input and outputs

* cl/ptx: 1-to-1 test is passing, but still, not quite finished

* cl: remove tx_output from 1-to-1 transfer

* cl: remove unused classes

* cl: testing the balance commitments

* wip: cl

* cl: split main.rs into crypto.rs and note.rs

* cl: split balance test

* cl: add nullifier module

* cl: partial_tx; input; output

* cl: output proof tests

* cl: partial transactions can now be built and verified

* drop python cl spec

* cl: test partial transaction balance commitment

* cl: reverse partial tx balance (inputs are neg, outputs are pos)

* cl: bundle of ptx

* cl: verify bundle isn't balanced with just one unbalanced partial tx

* cl: swap out ExtendedPoint for SubgroupPoint

* cl: integrate groth16 death constraint validation

* add risc0 zone

* refactor risc0 zone

* fix zone PoC

* Add separate bin for stark2snark conv

* cl: rename Note to NoteWitness

* cl: merkle proofs

* cl: merkle tree helper to pad elements

* cl: ptx root implemented via merkle roots over inputs and outputs

* cl: move from Commitment::from_witness to Witness::commit()

* cl: tests passing again

* cl: turn data model into library

* cl: partial tx can compute paths to inputs / outputs

* cl: begin integrating zone into cl data modal

* cl: integrate simple zone into CL data model

* cl: add missing cl patches

* cl: swap jubjub for accel k256

* cl: pre-compute balance unit point outside stark

* switch balance commitment to linear combination

* cl: pre-compute pederson blinding

* fix risc0 patching

* switch to curve25519-dalek

* cl: drop blake2; print prover time

---------

Co-authored-by: Giacomo Pasini <g.pasini98@gmail.com>

---------

Co-authored-by: Giacomo Pasini <g.pasini98@gmail.com>
2024-07-09 17:10:32 +04:00

97 lines
3.4 KiB
Rust

use blake2::{Blake2s256, Digest};
use risc0_zkvm::guest::env;
use common::*;
use cl::merkle;
use cl::input::InputWitness;
use cl::output::OutputWitness;
/// Public Inputs:
/// * ptx_root: the root of the partial tx merkle tree of inputs/outputs
/// Private inputs:
/// TODO
fn execute(
ptx_root: [u8; 32],
input_root: [u8; 32],
output_root: [u8; 32],
in_ptx_path: Vec<merkle::PathNode>,
out_ptx_path: Vec<merkle::PathNode>,
in_note: InputWitness,
out_note: OutputWitness,
input: Input,
state: State,
mut journal: Journal,
) {
// verify ptx/cl preconditions
eprintln!("start exec: {}", env::cycle_count());
assert_eq!(ptx_root, merkle::node(input_root, output_root));
eprintln!("ptx_root: {}", env::cycle_count());
// Glue the zone and the cl together, specifically, it verifies the note requesting
// a transfer is included as part of the same transaction in the cl
let in_comm = in_note.commit().to_bytes();
eprintln!("input comm: {}", env::cycle_count());
assert!(merkle::verify_path(merkle::leaf(&in_comm), &in_ptx_path, input_root));
eprintln!("input merkle path: {}", env::cycle_count());
// check the commitments match the actual data
let state_cm = calculate_state_hash(&state);
let journal_cm = calculate_journal_hash(&journal);
let state_root = merkle::node(state_cm, journal_cm);
assert_eq!(state_root, in_note.note.state);
eprintln!("input state root: {}", env::cycle_count());
// then run the state transition function
let state = stf(state, input);
journal.push(input);
eprintln!("stf: {}", env::cycle_count());
// verifying ptx/cl postconditions
let out_state_cm = calculate_state_hash(&state);
let out_journal_cm = calculate_journal_hash(&journal);
let out_state_root = merkle::node(out_state_cm, out_journal_cm);
// TODO: verify death constraints are propagated
assert_eq!(out_state_root, out_note.note.state);
eprintln!("out state root: {}", env::cycle_count());
// Glue the zone and the cl together, specifically, it verifies an output note
// containing the zone state is included as part of the same transaction in the cl
// (this is done in the death condition to disallow burning)
let out_comm = out_note.commit().to_bytes();
eprintln!("output comm: {}", env::cycle_count());
assert!(merkle::verify_path(merkle::leaf(&out_comm), &out_ptx_path, output_root));
eprintln!("out merkle proof: {}", env::cycle_count());
}
fn main() {
// public input
let ptx_root: [u8; 32] = env::read();
// private input
let input_root: [u8; 32] = env::read();
let output_root: [u8; 32] = env::read();
let in_ptx_path: Vec<merkle::PathNode> = env::read();
let out_ptx_path: Vec<merkle::PathNode> = env::read();
let in_note: InputWitness = env::read();
let out_note: OutputWitness = env::read();
let input: Input = env::read();
let state: State = env::read();
let journal: Journal = env::read();
eprintln!("parse input: {}", env::cycle_count());
execute(ptx_root, input_root, output_root, in_ptx_path, out_ptx_path, in_note, out_note, input, state, journal);
}
fn calculate_state_hash(state: &State) -> [u8; 32] {
let bytes = bincode::serialize(state).unwrap();
Blake2s256::digest(&bytes).into()
}
fn calculate_journal_hash(journal: &Journal) -> [u8; 32] {
let bytes = bincode::serialize(journal).unwrap();
Blake2s256::digest(&bytes).into()
}