Skip to content

Commit

Permalink
add witness api
Browse files Browse the repository at this point in the history
  • Loading branch information
0x8f701 committed Sep 18, 2024
1 parent 43f13dc commit 0d18f33
Show file tree
Hide file tree
Showing 19 changed files with 1,039 additions and 108 deletions.
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.PHONY: verify
verify:
cargo run --release --bin ark_swiftness_cli --features starknet_with_keccak,keccak --no-default-features -- --proof ./proofs/starknet_with_keccak/cairo0_example_proof.json

.PHONY: fix
fix:
@cargo fix --all-targets --allow-dirty --allow-staged
11 changes: 5 additions & 6 deletions air/src/diluted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,16 @@ use swiftness_hash::poseidon::PoseidonHash;
// q_i = q_{i-1} * (1 + z * x_{i-1}) * p_{i-1} + x_{i-1}^2 * p_{i-1} + q_{i-1}
//
// Now we can compute p_{n_bits} and q_{n_bits} in just n_bits recursive steps and we are done.
pub fn get_diluted_product<F: SimpleField + PoseidonHash>(n_bits: F, spacing: F, z: F, alpha: F) -> F {
let diff_multiplier = F::two().powers_felt(&spacing);
pub fn get_diluted_product<F: SimpleField + PoseidonHash>(n_bits: usize, spacing: usize, z: F, alpha: F) -> F {
let diff_multiplier = F::two().powers([spacing as u64]);
let mut diff_x: F = diff_multiplier.clone() - F::two();
let mut x: F = F::one();
let mut p: F = z.clone() + F::one();
let mut q: F = F::one();

let mut i = F::zero();
let mut i = 0;
loop {
// TODO: remove get_value()
if (i).get_value() == (n_bits.clone() - F::one()).get_value() {
if i == n_bits - 1 {
break p + q * alpha;
}

Expand All @@ -45,6 +44,6 @@ pub fn get_diluted_product<F: SimpleField + PoseidonHash>(n_bits: F, spacing: F,
q = q.clone() * &y + x.clone() * &x_p + &q;
p *= &y;

i = i + F::one();
i = i + 1;
}
}
4 changes: 2 additions & 2 deletions air/src/layout/recursive/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ impl<F: SimpleField + PoseidonHash> LayoutTrait<F> for Layout {
let diluted_z = interaction_elements.diluted_check_interaction_z.clone();
let diluted_alpha = interaction_elements.diluted_check_interaction_alpha.clone();
let diluted_prod = get_diluted_product(
F::from_constant(DILUTED_N_BITS as u128),
F::from_constant(DILUTED_SPACING as u128),
DILUTED_N_BITS,
DILUTED_SPACING,
diluted_z.clone(),
diluted_alpha.clone(),
);
Expand Down
4 changes: 2 additions & 2 deletions air/src/layout/recursive_with_poseidon/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ impl<F: SimpleField + PoseidonHash> LayoutTrait<F> for Layout {
let diluted_z = interaction_elements.diluted_check_interaction_z.clone();
let diluted_alpha = interaction_elements.diluted_check_interaction_alpha.clone();
let diluted_prod = get_diluted_product(
F::from_constant(DILUTED_N_BITS as u128),
F::from_constant(DILUTED_SPACING as u128),
DILUTED_N_BITS,
DILUTED_SPACING,
diluted_z.clone(),
diluted_alpha.clone(),
);
Expand Down
4 changes: 2 additions & 2 deletions air/src/layout/starknet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ impl<F: SimpleField + PoseidonHash> LayoutTrait<F> for Layout {
let diluted_z = interaction_elements.diluted_check_interaction_z.clone();
let diluted_alpha = interaction_elements.diluted_check_interaction_alpha.clone();
let diluted_prod = get_diluted_product(
F::from_constant(DILUTED_N_BITS as u128),
F::from_constant(DILUTED_SPACING as u128),
DILUTED_N_BITS,
DILUTED_SPACING,
diluted_z.clone(),
diluted_alpha.clone(),
);
Expand Down
4 changes: 2 additions & 2 deletions air/src/layout/starknet_with_keccak/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ impl<F: SimpleField + PoseidonHash> LayoutTrait<F> for Layout {
let diluted_z = interaction_elements.diluted_check_interaction_z.clone();
let diluted_alpha = interaction_elements.diluted_check_interaction_alpha.clone();
let diluted_prod = get_diluted_product(
F::from_constant(DILUTED_N_BITS as u128),
F::from_constant(DILUTED_SPACING as u128),
DILUTED_N_BITS,
DILUTED_SPACING,
diluted_z.clone(),
diluted_alpha.clone(),
);
Expand Down
7 changes: 7 additions & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ version = "0.0.8"
[dependencies]
clap = { workspace = true }

ark-r1cs-std = { workspace = true }
ark-relations = { workspace = true }
ark-groth16 = { workspace = true }
ark-bls12-381 = { workspace = true }
ark-snark = { workspace = true }
serde_json = { workspace = true }

swiftness_air = { workspace = true }
swiftness_field = { workspace = true }
swiftness_hash = { workspace = true }
Expand Down
9 changes: 5 additions & 4 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::path::PathBuf;
use swiftness_field::Fp;
use ark_r1cs_std::fields::fp::FpVar;
use swiftness_field::{Fp, SimpleField};
pub use swiftness_proof_parser::*;
pub use swiftness_stark::*;

Expand Down Expand Up @@ -30,8 +31,8 @@ struct CairoVMVerifier {
fn main() -> Result<(), Box<dyn std::error::Error>> {
let cli = CairoVMVerifier::parse();
let stark_proof = parse(std::fs::read_to_string(cli.proof)?)?;
let security_bits: Fp = stark_proof.config.security_bits();
let result = stark_proof.verify::<StarkwareCurve, Layout>(security_bits)?;
println!("{:?}", result);
let security_bits: FpVar<Fp> = stark_proof.config.security_bits();
let (program_hash, output_hash) = stark_proof.verify::<StarkwareCurve, Layout>(security_bits).unwrap();
println!("program_hash: {}, output_hash: {}", program_hash.get_value(), output_hash.get_value());
Ok(())
}
2 changes: 2 additions & 0 deletions commitment/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ thiserror-no-std.workspace = true
blake2.workspace = true
ark-r1cs-std = { workspace = true }
cfg-if = { workspace = true }
ark-ff = { workspace = true }
ark-relations = { workspace = true }

swiftness_transcript.workspace = true
swiftness_field = { workspace = true }
Expand Down
6 changes: 3 additions & 3 deletions commitment/src/vector/decommit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ pub fn compute_root_from_queries<F: SimpleField + PoseidonHash + KeccakHash + Bl
F::from_constant((auth_start + 1) as u64),
);

// into_biguint is safe here because we know it's constant
start = next_start.into_biguint().try_into().unwrap();
auth_start = next_auth_start.into_biguint().try_into().unwrap();
// into_constant is safe here because we know it's constant
start = next_start.into_constant();
auth_start = next_auth_start.into_constant();
queue.push(next_query);
}

Expand Down
4 changes: 4 additions & 0 deletions fri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ starknet-crypto.workspace = true
thiserror = { optional = true, workspace = true }
thiserror-no-std.workspace = true
num-traits = { workspace = true }
ark-r1cs-std = { workspace = true }
ark-ff = { workspace = true }
ark-relations = { workspace = true }
ark-snark = { workspace = true }

swiftness_commitment.workspace = true
swiftness_transcript.workspace = true
Expand Down
105 changes: 57 additions & 48 deletions fri/src/formula.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,16 @@ fn fri_formula4<F: SimpleField + PoseidonHash>(
eval_point: F,
x_inv: F,
) -> Result<F, Error> {
if values.len() != 4 {
return Err(Error::InvalidValuesLength {
expected: 4,
got: values.len(),
});
}
// Applying the first layer of folding.
let g0 = fri_formula2(
values[0].clone(),
values[1].clone(),
values.get(0).cloned().unwrap_or(F::zero()),
values.get(1).cloned().unwrap_or(F::zero()),
eval_point.clone(),
x_inv.clone(),
);
let g1 = fri_formula2(
values[2].clone(),
values[3].clone(),
values.get(2).cloned().unwrap_or(F::zero()),
values.get(3).cloned().unwrap_or(F::zero()),
eval_point.clone(),
x_inv.clone()
* F::from_stark_felt(Felt::from_hex_unchecked(
Expand All @@ -52,16 +46,20 @@ fn fri_formula8<F: SimpleField + PoseidonHash>(
eval_point: F,
x_inv: F,
) -> Result<F, Error> {
if values.len() != 8 {
return Err(Error::InvalidValuesLength {
expected: 8,
got: values.len(),
});
}
// Applying the first layer of folding.
let g0 = fri_formula4(values[0..4].to_vec(), eval_point.clone(), x_inv.clone())?;
let g0 = fri_formula4(
values
.get(0..4)
.map(|x| x.into_iter().cloned().collect::<Vec<_>>())
.unwrap_or(core::iter::repeat_n(F::zero(), 4).collect::<Vec<_>>()),
eval_point.clone(),
x_inv.clone(),
)?;
let g1 = fri_formula4(
values[4..8].to_vec(),
values
.get(4..8)
.map(|x| x.into_iter().cloned().collect::<Vec<_>>())
.unwrap_or(core::iter::repeat_n(F::zero(), 4).collect::<Vec<_>>()),
eval_point.clone(),
x_inv.clone()
* F::from_stark_felt(Felt::from_hex_unchecked(
Expand All @@ -85,16 +83,20 @@ fn fri_formula16<F: SimpleField + PoseidonHash>(
eval_point: F,
x_inv: F,
) -> Result<F, Error> {
if values.len() != 16 {
return Err(Error::InvalidValuesLength {
expected: 16,
got: values.len(),
});
}
// Applying the first layer of folding.
let g0 = fri_formula8(values[0..8].to_vec(), eval_point.clone(), x_inv.clone())?;
let g0 = fri_formula8(
values
.get(0..8)
.map(|x| x.into_iter().cloned().collect::<Vec<_>>())
.unwrap_or(core::iter::repeat_n(F::zero(), 4).collect::<Vec<_>>()),
eval_point.clone(),
x_inv.clone(),
)?;
let g1 = fri_formula8(
values[8..16].to_vec(),
values
.get(8..16)
.map(|x| x.into_iter().cloned().collect::<Vec<_>>())
.unwrap_or(core::iter::repeat_n(F::zero(), 4).collect::<Vec<_>>()),
eval_point.clone(),
x_inv.clone()
* F::from_stark_felt(Felt::from_hex_unchecked(
Expand Down Expand Up @@ -122,28 +124,35 @@ pub fn fri_formula<F: SimpleField + PoseidonHash>(
x_inv: F,
coset_size: F,
) -> Result<F, Error> {
let coset_size: u64 = coset_size.into_biguint().try_into().unwrap();
// Sort by usage frequency.
match coset_size {
2 => {
if values.len() != 2 {
return Err(Error::InvalidValuesLength {
expected: 2,
got: values.len(),
});
}
Ok(fri_formula2(
values[0].clone(),
values[1].clone(),
eval_point,
x_inv,
))
}
4 => fri_formula4(values, eval_point, x_inv),
8 => fri_formula8(values, eval_point, x_inv),
16 => fri_formula16(values, eval_point, x_inv),
_ => panic!("Invalid coset size: {}", coset_size),
}
let is_coset_2 = coset_size.is_equal(&F::from_constant(2u64));
let is_coset_4 = coset_size.is_equal(&F::from_constant(4u64));
let is_coset_8 = coset_size.is_equal(&F::from_constant(8u64));
let is_coset_16 = coset_size.is_equal(&F::from_constant(16u64));
F::assert_true(F::or(
&F::or(&F::or(&is_coset_2, &is_coset_4), &is_coset_8),
&is_coset_16,
));

let result_2 = fri_formula2(
values[0].clone(),
values[1].clone(),
eval_point.clone(),
x_inv.clone(),
);

let result_4 = fri_formula4(values.clone(), eval_point.clone(), x_inv.clone())?;
let result_8 = fri_formula8(values.clone(), eval_point.clone(), x_inv.clone())?;
let result_16 = fri_formula16(values, eval_point, x_inv)?;

Ok(F::select(
&is_coset_2,
result_2,
F::select(
&is_coset_4,
result_4,
F::select(&is_coset_8, result_8, result_16),
),
))
}

use starknet_crypto::Felt;
Expand Down
8 changes: 2 additions & 6 deletions fri/src/layer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use alloc::vec::Vec;
use starknet_crypto::Felt;
use num_traits::ops::bytes::ToBytes;

pub struct FriLayerComputationParams<F: SimpleField + PoseidonHash> {
pub coset_size: F,
Expand Down Expand Up @@ -77,10 +75,8 @@ pub fn compute_next_layer<F: SimpleField + PoseidonHash>(

let coset_size = params.coset_size.clone();
while !queries.is_empty() {
let query_uint = queries.first().unwrap().index.into_biguint();
let coset_size_uint = coset_size.into_biguint();
let coset_index =
F::from_stark_felt(Felt::from_bytes_be_slice((query_uint / coset_size_uint).to_bytes_be().as_slice()));
let query_index = queries.first().unwrap().index.clone();
let coset_index = query_index.div_rem(&coset_size).0;

verify_indices.push(coset_index.clone());

Expand Down
4 changes: 4 additions & 0 deletions proof_parser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ anyhow = { workspace = true }
clap = { workspace = true }
regex = { workspace = true }
serde_json = { workspace = true }
ark-r1cs-std = { workspace = true}
ark-snark = { workspace = true }
ark-relations = { workspace = true }
ark-ff = { workspace = true }

swiftness_air = { workspace = true }
swiftness_commitment = { workspace = true }
Expand Down
Loading

0 comments on commit 0d18f33

Please sign in to comment.