Skip to content

Commit

Permalink
Document CLI and API
Browse files Browse the repository at this point in the history
  • Loading branch information
imikushin committed Jan 21, 2025
1 parent 6d737af commit d38c688
Show file tree
Hide file tree
Showing 14 changed files with 144 additions and 170 deletions.
4 changes: 2 additions & 2 deletions charms-spell-checker/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ fn to_public_values<T: Serialize>(t: &T) -> SP1PublicValues {
}

#[derive(Serialize, Deserialize)]
pub struct AppContractVK {
pub(crate) struct AppContractVK {
pub vk: Option<[u32; 8]>,
}

impl AppContractVK {
pub fn verify(&self, app: &App, tx: &Transaction, x: &Data) -> bool {
pub(crate) fn verify(&self, app: &App, tx: &Transaction, x: &Data) -> bool {
match &self.vk {
Some(vk) => {
let Ok(pv) = to_public_values(&(app, tx, x)).hash().try_into() else {
Expand Down
5 changes: 3 additions & 2 deletions charms-spell-checker/src/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ pub fn main() {
eprintln!("about to commit");

// Commit to the public values of the program.
sp1_zkvm::io::commit_slice(util::write(&output).unwrap().as_slice());
let output_vec = util::write(&output).unwrap();
sp1_zkvm::io::commit_slice(output_vec.as_slice());
}

pub fn run(input: SpellProverInput) -> (String, NormalizedSpell) {
pub(crate) fn run(input: SpellProverInput) -> (String, NormalizedSpell) {
let SpellProverInput {
self_spell_vk,
prev_txs,
Expand Down
24 changes: 21 additions & 3 deletions charms-spell-checker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ use charms_data::{App, Charms, Data, Transaction, TxId, UtxoId};
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, BTreeSet};

/// Version `0` of the protocol.
pub const V0: u32 = 0u32;
/// Verification key for version `0` of the `charms-spell-checker` binary.
pub const V0_SPELL_VK: &str = "0x00e9398ac819e6dd281f81db3ada3fe5159c3cc40222b5ddb0e7584ed2327c5d";

/// Version `1` of the protocol.
pub const V1: u32 = 1u32;
/// Current version of the protocol.
pub const CURRENT_VERSION: u32 = V1;

#[derive(Clone, Debug, Serialize, Deserialize)]
Expand All @@ -23,8 +27,11 @@ pub struct SpellProverInput {
pub app_contract_proofs: BTreeSet<usize>, // proofs are provided in input stream data
}

/// Maps the index of the charm's app (in [`NormalizedSpell`].`app_public_inputs`) to the charm's
/// data.
pub type NormalizedCharms = BTreeMap<usize, Data>;

/// Normalized representation of a Charms transaction.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct NormalizedTransaction {
/// (Optional) input UTXO list. Is None when serialized in the transaction: the transaction
Expand All @@ -42,25 +49,31 @@ pub struct NormalizedTransaction {
}

impl NormalizedTransaction {
/// Return a sorted set of transaction IDs of the inputs.
pub fn prev_txids(&self) -> Option<BTreeSet<&TxId>> {
self.ins
.as_ref()
.map(|ins| ins.iter().map(|utxo_id| &utxo_id.0).collect())
}
}

/// Proof of correctness of a spell.
pub type Proof = Box<[u8]>;

/// Normalized representation of a spell.
/// Can be committed as public input.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct NormalizedSpell {
/// Protocol version.
pub version: u32,
/// Transaction data.
pub tx: NormalizedTransaction,
/// Maps all `App`s in the transaction to (potentially empty) data.
/// Maps all `App`s in the transaction to (potentially empty) public input data.
pub app_public_inputs: BTreeMap<App, Data>,
}

impl NormalizedSpell {
/// Check if the spell is well-formed.
pub fn well_formed(
&self,
prev_spells: &BTreeMap<TxId, (Option<NormalizedSpell>, usize)>,
Expand Down Expand Up @@ -102,10 +115,12 @@ impl NormalizedSpell {
true
}

/// Return the list of apps in the spell.
pub fn apps(&self) -> Vec<App> {
self.app_public_inputs.keys().cloned().collect()
}

/// Convert normalized spell to [`charms_data::Transaction`].
pub fn to_tx(
&self,
prev_spells: &BTreeMap<TxId, (Option<NormalizedSpell>, usize)>,
Expand Down Expand Up @@ -138,7 +153,8 @@ impl NormalizedSpell {
}
}

pub fn is_correct(
/// Check if the spell is correct.
pub(crate) fn is_correct(
&self,
prev_txs: &Vec<bitcoin::Transaction>,
app_contract_vks: &Vec<(App, AppContractVK)>,
Expand Down Expand Up @@ -177,7 +193,8 @@ impl NormalizedSpell {
true
}

fn charms(&self, n_charms: &NormalizedCharms) -> Charms {
/// Return [`charms_data::Charms`] for the given [`NormalizedCharms`].
pub fn charms(&self, n_charms: &NormalizedCharms) -> Charms {
let apps = self.apps();
n_charms
.iter()
Expand All @@ -186,6 +203,7 @@ impl NormalizedSpell {
}
}

/// Extract spells from previous transactions.
pub fn prev_spells(
prev_txs: &Vec<bitcoin::Transaction>,
spell_vk: &str,
Expand Down
19 changes: 16 additions & 3 deletions charms-spell-checker/src/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use serde::Serialize;
use sp1_primitives::io::SP1PublicValues;
use sp1_verifier::Groth16Verifier;

/// Extract a [`NormalizedSpell`] from a transaction and verify it.
/// Incorrect spells are rejected.
pub fn extract_spell(
tx: &bitcoin::Transaction,
spell_vk: &str,
Expand Down Expand Up @@ -78,7 +80,7 @@ pub fn extract_spell(

Groth16Verifier::verify(
&proof,
to_sp1_pv(&(spell_vk, &spell)).as_slice(),
to_sp1_pv(spell.version, &(spell_vk, &spell)).as_slice(),
spell_vk,
groth16_vk,
)
Expand All @@ -97,8 +99,19 @@ fn vks(spell_version: u32, spell_vk: &str) -> anyhow::Result<(&str, &[u8])> {

const V0_GROTH16_VK_BYTES: &'static [u8] = include_bytes!("../vk/v0/groth16_vk.bin");

fn to_sp1_pv<T: Serialize>(t: &T) -> SP1PublicValues {
fn to_sp1_pv<T: Serialize>(spell_version: u32, t: &T) -> SP1PublicValues {
let mut pv = SP1PublicValues::new();
pv.write_slice(util::write(t).unwrap().as_slice());
match spell_version {
CURRENT_VERSION => {
// we commit to CBOR-encoded tuple `(spell_vk, n_spell)`
pv.write_slice(util::write(t).unwrap().as_slice());
}
V0 => {
// we used to commit to the tuple `(spell_vk, n_spell)`, which was serialized internally
// by SP1
pv.write(t);
}
_ => unreachable!(),
}
pv
}
2 changes: 1 addition & 1 deletion src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl Prover {
}
}

pub fn prove(
pub(crate) fn prove(
&self,
app_binaries: &BTreeMap<B32, Vec<u8>>,
tx: Transaction,
Expand Down
Binary file modified src/bin/charms-spell-checker
Binary file not shown.
Loading

0 comments on commit d38c688

Please sign in to comment.