Skip to content

Commit

Permalink
Merge branch 'main' into feat/icicle
Browse files Browse the repository at this point in the history
  • Loading branch information
diegokingston authored Feb 21, 2024
2 parents a91cbc6 + 601ab67 commit 038b5da
Show file tree
Hide file tree
Showing 31 changed files with 338 additions and 174 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[workspace]

members = ["math", "crypto", "gpu", "benches", "provers/plonk", "provers/stark", "provers/cairo", "provers/groth16", "provers/groth16/arkworks-adapter", "provers/groth16/circom-adapter", "examples/merkle-tree-cli", "examples/prove-miden", "provers/winterfell_adapter", "examples/shamir_secret_sharing", "examples/prove-verify-circom"]
members = ["math", "crypto", "gpu", "benches", "provers/plonk", "provers/stark", "provers/cairo", "provers/groth16", "provers/groth16/arkworks-adapter", "provers/groth16/circom-adapter", "examples/merkle-tree-cli", "examples/prove-miden", "provers/winterfell_adapter", "examples/shamir_secret_sharing", "examples/prove-verify-circom", "provers/cairo/ffi"]
exclude = ["ensure-no_std"]
resolver = "2"

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,4 @@ The following links, repos and projects have been important in the development o
- [EthSTARK](https://github.com/starkware-libs/ethSTARK/tree/master)
- [CAIRO whitepaper](https://eprint.iacr.org/2021/1063.pdf)
- [Gnark](https://github.com/Consensys/gnark)
- [Constantine](https://github.com/mratsim/constantine)
85 changes: 62 additions & 23 deletions crypto/src/fiat_shamir/default_transcript.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
use super::transcript::Transcript;
use alloc::borrow::ToOwned;
use super::is_transcript::IsTranscript;
use crate::alloc::borrow::ToOwned;
use core::marker::PhantomData;
use lambdaworks_math::{
field::{element::FieldElement, traits::IsField},
traits::ByteConversion,
};
use sha3::{Digest, Keccak256};

pub struct DefaultTranscript {
pub struct DefaultTranscript<F: IsField> {
hasher: Keccak256,
phantom: PhantomData<F>,
}

impl Transcript for DefaultTranscript {
fn append(&mut self, new_data: &[u8]) {
self.hasher.update(&mut new_data.to_owned());
impl<F> DefaultTranscript<F>
where
F: IsField,
FieldElement<F>: ByteConversion,
{
pub fn new(data: &[u8]) -> Self {
let mut res = Self {
hasher: Keccak256::new(),
phantom: PhantomData,
};
res.append_bytes(data);
res
}

fn challenge(&mut self) -> [u8; 32] {
pub fn sample(&mut self) -> [u8; 32] {
let mut result_hash = [0_u8; 32];
result_hash.copy_from_slice(&self.hasher.finalize_reset());
result_hash.reverse();
Expand All @@ -20,37 +35,61 @@ impl Transcript for DefaultTranscript {
}
}

impl Default for DefaultTranscript {
impl<F> Default for DefaultTranscript<F>
where
F: IsField,
FieldElement<F>: ByteConversion,
{
fn default() -> Self {
Self::new()
Self::new(&[])
}
}

impl DefaultTranscript {
pub fn new() -> Self {
Self {
hasher: Keccak256::new(),
}
impl<F> IsTranscript<F> for DefaultTranscript<F>
where
F: IsField,
FieldElement<F>: ByteConversion,
{
fn append_bytes(&mut self, new_bytes: &[u8]) {
self.hasher.update(&mut new_bytes.to_owned());
}

fn append_field_element(&mut self, element: &FieldElement<F>) {
self.append_bytes(&element.to_bytes_be());
}

fn state(&self) -> [u8; 32] {
self.hasher.clone().finalize().into()
}

fn sample_field_element(&mut self) -> FieldElement<F> {
FieldElement::from_bytes_be(&self.sample()).unwrap()
}

fn sample_u64(&mut self, upper_bound: u64) -> u64 {
u64::from_be_bytes(self.state()[..8].try_into().unwrap()) % upper_bound
}
}

#[cfg(test)]
mod tests {
use alloc::vec::Vec;

use super::*;

extern crate alloc;
use alloc::vec::Vec;
use lambdaworks_math::elliptic_curve::short_weierstrass::curves::bls12_381::default_types::FrField;

#[test]
fn basic_challenge() {
let mut transcript = DefaultTranscript::new();
let mut transcript = DefaultTranscript::<FrField>::default();

let point_a: Vec<u8> = vec![0xFF, 0xAB];
let point_b: Vec<u8> = vec![0xDD, 0x8C, 0x9D];

transcript.append(&point_a); // point_a
transcript.append(&point_b); // point_a + point_b
transcript.append_bytes(&point_a); // point_a
transcript.append_bytes(&point_b); // point_a + point_b

let challenge1 = transcript.challenge(); // Hash(point_a + point_b)
let challenge1 = transcript.sample(); // Hash(point_a + point_b)

assert_eq!(
challenge1,
Expand All @@ -64,10 +103,10 @@ mod tests {
let point_c: Vec<u8> = vec![0xFF, 0xAB];
let point_d: Vec<u8> = vec![0xDD, 0x8C, 0x9D];

transcript.append(&point_c); // Hash(point_a + point_b) + point_c
transcript.append(&point_d); // Hash(point_a + point_b) + point_c + point_d
transcript.append_bytes(&point_c); // Hash(point_a + point_b) + point_c
transcript.append_bytes(&point_d); // Hash(point_a + point_b) + point_c + point_d

let challenge2 = transcript.challenge(); // Hash(Hash(point_a + point_b) + point_c + point_d)
let challenge2 = transcript.sample(); // Hash(Hash(point_a + point_b) + point_c + point_d)
assert_eq!(
challenge2,
[
Expand Down
43 changes: 43 additions & 0 deletions crypto/src/fiat_shamir/is_transcript.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use lambdaworks_math::{
field::{
element::FieldElement,
traits::{IsField, IsSubFieldOf},
},
traits::AsBytes,
};

/// The functionality of a transcript to be used in the STARK Prove and Verify protocols.
pub trait IsTranscript<F: IsField> {
/// Appends a field element to the transcript.
fn append_field_element(&mut self, element: &FieldElement<F>);
/// Appends a bytes to the transcript.
fn append_bytes(&mut self, new_bytes: &[u8]);
/// Returns the inner state of the transcript that fully determines its outputs.
fn state(&self) -> [u8; 32];
/// Returns a random field element.
fn sample_field_element(&mut self) -> FieldElement<F>;
/// Returns a random index between 0 and `upper_bound`.
fn sample_u64(&mut self, upper_bound: u64) -> u64;
/// Returns a field element not contained in `lde_roots_of_unity_coset` or `trace_roots_of_unity`.
fn sample_z_ood<S: IsSubFieldOf<F>>(
&mut self,
lde_roots_of_unity_coset: &[FieldElement<S>],
trace_roots_of_unity: &[FieldElement<S>],
) -> FieldElement<F>
where
FieldElement<F>: AsBytes,
{
loop {
let value: FieldElement<F> = self.sample_field_element();
if !lde_roots_of_unity_coset
.iter()
.any(|x| x.clone().to_extension() == value)
&& !trace_roots_of_unity
.iter()
.any(|x| x.clone().to_extension() == value)
{
return value;
}
}
}
}
2 changes: 1 addition & 1 deletion crypto/src/fiat_shamir/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub mod default_transcript;
pub mod is_transcript;
#[cfg(feature = "test_fiat_shamir")]
pub mod test_transcript;
pub mod transcript;
4 changes: 0 additions & 4 deletions crypto/src/fiat_shamir/transcript.rs

This file was deleted.

2 changes: 1 addition & 1 deletion provers/cairo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ path = "src/main.rs"
required-features = ["cli"]

[lib]
name = "platinum_prover"
name = "cairo_platinum_prover"
crate-type = ["cdylib", "rlib"]

[dependencies]
Expand Down
16 changes: 15 additions & 1 deletion provers/cairo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,18 @@ This prover is still in development and may contain bugs. It is not intended to

Please check issues under security label, and wait for them to be resolved if they are relevant to your project.

## [Cairo Platinum Prover Docs](<[lambdaclass.github.io/lambdaworks/](https://github.com/lambdaclass/lambdaworks/blob/main/provers/cairo/README.md)>)
## [Cairo Platinum Prover Docs](https://lambdaclass.github.io/lambdaworks/starks/cairo.html)

## Proof file

Currently, the .proof file contains the following elements concatenated:
- Proof size
- Proof
- Public inputs

It uses the bincode as protocol to encode the structs of the files. Fields are stored as the bytes of canonical non-Montgomery form. It is in full big-endian form. Limbs are ordered in big-endian, and each u64 of the Montgomery field is in big-endian.

⚠️: There may be changes to how this file represents the proof, always check here to ensure you have the latest encoding. We will add presets of verifications to the public inputs so you should not need to handle the file, just enable them.

### Cairo Platinum Prover - Introduction

Expand All @@ -21,6 +31,10 @@ CLI currently runs with 100 bits of conjecturable security.

Cairo / Cairo1 programs full integration is on the way. It can already be used generating a trace and a memory with the Cairo VM Runner, and fed to the prover with the prove command.

For using Cairo1, use the following [VM version](https://github.com/lambdaclass/cairo-vm/commit/070aeb9dbaf55875bf1cba2cef36fccafbb4851a) until it gets fixed in main

Notice in this version you don't need the flag ```--proof_mode``` as it's enabled by default.

### Usage:

To prove Cairo programs, they first need to be compiled. For compilation you need to have `cairo-lang` or `docker` installed.
Expand Down
6 changes: 3 additions & 3 deletions provers/cairo/benches/criterion_prover.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use cairo_platinum_prover::{
air::generate_cairo_proof, cairo_layout::CairoLayout, runner::run::generate_prover_args,
};
use criterion::{
black_box, criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, Criterion,
};
use platinum_prover::{
air::generate_cairo_proof, cairo_layout::CairoLayout, runner::run::generate_prover_args,
};
use stark_platinum_prover::proof::options::{ProofOptions, SecurityLevel};

pub mod functions;
Expand Down
4 changes: 2 additions & 2 deletions provers/cairo/benches/criterion_prover_70k.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use cairo_platinum_prover::cairo_layout::CairoLayout;
use cairo_platinum_prover::{air::generate_cairo_proof, runner::run::generate_prover_args};
use criterion::{
black_box, criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, Criterion,
SamplingMode,
};
use platinum_prover::cairo_layout::CairoLayout;
use platinum_prover::{air::generate_cairo_proof, runner::run::generate_prover_args};
use stark_platinum_prover::proof::options::{ProofOptions, SecurityLevel};

pub mod functions;
Expand Down
2 changes: 1 addition & 1 deletion provers/cairo/benches/criterion_verifier.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use cairo_platinum_prover::air::{verify_cairo_proof, PublicInputs};
use criterion::{
black_box, criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, Criterion,
};
use lambdaworks_math::{
field::fields::fft_friendly::stark_252_prime_field::Stark252PrimeField, traits::Deserializable,
};
use platinum_prover::air::{verify_cairo_proof, PublicInputs};
use stark_platinum_prover::proof::{
options::{ProofOptions, SecurityLevel},
stark::StarkProof,
Expand Down
2 changes: 1 addition & 1 deletion provers/cairo/benches/criterion_verifier_70k.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use cairo_platinum_prover::air::{verify_cairo_proof, PublicInputs};
use criterion::{
black_box, criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, Criterion,
SamplingMode,
};
use lambdaworks_math::{
field::fields::fft_friendly::stark_252_prime_field::Stark252PrimeField, traits::Deserializable,
};
use platinum_prover::air::{verify_cairo_proof, PublicInputs};
use stark_platinum_prover::proof::{
options::{ProofOptions, SecurityLevel},
stark::StarkProof,
Expand Down
2 changes: 1 addition & 1 deletion provers/cairo/benches/functions/stark.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use platinum_prover::{cairo_mem::CairoMemory, register_states::RegisterStates};
use cairo_platinum_prover::{cairo_mem::CairoMemory, register_states::RegisterStates};

pub fn generate_cairo_trace(filename: &str) -> (RegisterStates, CairoMemory) {
let base_dir = env!("CARGO_MANIFEST_DIR").to_string() + "/src/cairo_vm/test_data/";
Expand Down
21 changes: 21 additions & 0 deletions provers/cairo/cairo_programs/cairo0/fibonacci_10000_loop.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

// Looped fibonacci is more efficient
// than calling the fibo function with recursion
// For n = 5, it's 31 steps vs 49 steps
// This is useful to compare with other vms that are not validating the call stack for fibonacci

func main{}() {
tempvar x0 = 0;
tempvar x1 = 1;
tempvar fib_acc = x0 + x1;
tempvar n = 10000;
loop:
tempvar x0 = x1;
tempvar x1 = fib_acc;
tempvar fib_acc = x0 + x1;
tempvar n = n - 1;
jmp loop if n != 0;

assert fib_acc = 2287375788429092341882876480321135809824733217263858843173749298459021701670;
return ();
}
15 changes: 15 additions & 0 deletions provers/cairo/ffi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "cairo-platinum-ffi"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
# libc = "0.2"
stark-platinum-prover = { path = "../../stark" }
cairo-platinum-prover = { path = "../" }
bincode = { version = "2.0.0-rc.2", tag = "v2.0.0-rc.2", git = "https://github.com/bincode-org/bincode.git", features = ['serde'] }

[lib]
crate-type = ["cdylib", "staticlib", "lib"]
Binary file added provers/cairo/ffi/fibo_5.proof
Binary file not shown.
Loading

0 comments on commit 038b5da

Please sign in to comment.