Skip to content
This repository has been archived by the owner on Nov 4, 2024. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
bb55c84
ccs: first commit
10to4 Mar 12, 2024
3f45e67
ccs: minor
10to4 Mar 13, 2024
14f8931
tmp update
10to4 Apr 2, 2024
28e3a62
Merge branch 'main' into develop-ccs-backend
10to4 May 6, 2024
90e4b56
ccs: first commit
10to4 Jun 13, 2024
c01d0e1
ccs: tidy up
10to4 Jun 17, 2024
ba71c66
ccs: clean code
10to4 Jun 20, 2024
1d5151b
ccs: refactor sonobe integration and clean code
10to4 Jun 21, 2024
c41caf9
ccs: add factorization for polynomials
10to4 Jun 24, 2024
511473f
ccs: minor
10to4 Jun 24, 2024
b53527d
ccs: improve fr_convert function
10to4 Jul 2, 2024
2c57657
ccs: add sonobe hypernova examples & bugfix
10to4 Jul 8, 2024
0fd2f9c
ccs: minor
10to4 Jul 8, 2024
ea2496e
ccs: fix
10to4 Jul 17, 2024
b4a1c82
Merge branch 'main' into develop-ccs-backend
10to4 Jul 25, 2024
18a7d5a
ccs: move ccs circuit to ir
10to4 Aug 22, 2024
9fc3569
ccs: move ccs circuit to ir
10to4 Aug 22, 2024
6e8171b
ccs: backend/sonobe -> backend/sonobe_hypernova
10to4 Aug 22, 2024
fee7bef
ccs: update test for ccscircuit
10to4 Aug 22, 2024
5de4502
ccs: update rust-toolchain
10to4 Aug 27, 2024
6858064
ccs: update toolchain-> 1.78.0 & modify for clippy
10to4 Aug 27, 2024
c78b5dc
ccs: modify serde version for Clippy Check
10to4 Aug 27, 2024
da8a22d
ccs: modify serde version for Clippy Check
10to4 Aug 27, 2024
0ea3586
ccs: modify serde version for Clippy Check
10to4 Aug 27, 2024
9b73dd6
ccs: refactor some functions for matrix, z and CCSCircuit
10to4 Aug 28, 2024
72bbde7
ccs: refactor ccs circuit in ir
10to4 Aug 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ authors = ["Leo Lara <[email protected]>"]

[patch.crates-io]
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v0.3.0" }
ark-grumpkin = { git = "https://github.com/arnaucube/ark-curves-cherry-picked", branch="cherry-pick"}

[patch."https://github.com/scroll-tech/halo2.git"]
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v0.3.0" }
Expand All @@ -24,11 +25,16 @@ halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.gi
polyexen = { git = "https://github.com/Dhole/polyexen.git", rev = "16a85c5411f804dc49bbf373d24ff9eedadedfbe" }
num-bigint = { version = "0.4", features = ["rand"] }
uuid = { version = "1.4.0", features = ["v1", "rng"] }
serde = { version = "1.0", features = ["derive"] }
serde = { version = "1.0", default-features = false, features = ["derive"] }
serde_json = "1.0"
hyperplonk_benchmark = { git = "https://github.com/qwang98/plonkish.git", branch = "main", package = "benchmark" }
plonkish_backend = { git = "https://github.com/qwang98/plonkish.git", branch = "main", package = "plonkish_backend" }
hyperplonk_benchmark = { git = "https://github.com/10to4/plonkish.git", branch = "main", package = "benchmark" }
plonkish_backend = { git = "https://github.com/10to4/plonkish.git", branch = "main", package = "plonkish_backend" }
regex = "1"

ark-ff = "^0.4.0"
ark-std = "^0.4.0"
ark-bn254 = "0.4.0"
folding-schemes = { git = "https://github.com/privacy-scaling-explorations/sonobe.git", rev = "bda8ad6ce16b2bfdaf93347e7e54d0c7800f16ab"}

[dev-dependencies]
rand_chacha = "0.3"
14 changes: 7 additions & 7 deletions examples/blake2f.rs
Original file line number Diff line number Diff line change
Expand Up @@ -871,15 +871,15 @@ fn blake2f_circuit<F: PrimeField + Hash>(
let mut output_vec = v_mid1_vec.clone();
if i >= 8 {
if i % 2 == 0 {
input_vec = v_mid2_vec.clone();
output_vec = v_mid3_vec.clone();
input_vec.clone_from(&v_mid2_vec);
output_vec.clone_from(&v_mid3_vec)
} else {
input_vec = v_mid3_vec.clone();
output_vec = v_mid4_vec.clone();
input_vec.clone_from(&v_mid3_vec);
output_vec.clone_from(&v_mid4_vec)
}
} else if i % 2 == 1 {
input_vec = v_mid1_vec.clone();
output_vec = v_mid2_vec.clone();
input_vec.clone_from(&v_mid1_vec);
output_vec.clone_from(&v_mid2_vec);
}
let (mut a, mut b, mut c, mut d) =
(i / 2, 4 + i / 2, 8 + i / 2, 12 + i / 2);
Expand Down Expand Up @@ -1319,7 +1319,7 @@ fn blake2f_circuit<F: PrimeField + Hash>(
b_3bits_vec,
};
ctx.add(&blake2f_g_setup_vec[r as usize], ginputs);
v_vec_values = v_mid4_vec_values.clone();
v_vec_values.clone_from(&v_mid4_vec_values);
}

let output_vec_values: Vec<u64> = h_vec_values
Expand Down
208 changes: 208 additions & 0 deletions examples/fibonacci_ccs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
use ark_bn254::{Fr as FFr, G1Projective as Projective};
use ark_ff::BigInt;
use halo2_proofs::halo2curves::{bn256::Fr, ff::PrimeField};
use std::hash::Hash;

use chiquito::{
ccs::{
compiler::{
cell_manager::SingleRowCellManager,
compile, // input for constructing the compiler
config,
step_selector::SimpleStepSelectorBuilder,
},
ir::{assignments::AssignmentGenerator, circuit::Circuit},
},
field::Field,
frontend::dsl::circuit,
poly::ToField,
sbpir::SBPIR,
};

use folding_schemes::{
ccs::CCS,
commitment::{pedersen::Pedersen, CommitmentScheme},
folding::hypernova::nimfs::NIMFS,
transcript::{
poseidon::{poseidon_canonical_config, PoseidonTranscript},
Transcript,
},
};

// the main circuit function: returns the compiled IR of a Chiquito circuit
// Generic types F, (), (u64, 64) stand for:
// 1. type that implements a field trait
// 2. empty trace arguments, i.e. (), because there are no external inputs to the Chiquito circuit
// 3. two witness generation arguments both of u64 type, i.e. (u64, u64)

type FiboReturn<F> = (Circuit<F>, Option<AssignmentGenerator<F, ()>>, SBPIR<F, ()>);

fn fibo_circuit_ccs<F: Field + From<u64> + Hash>() -> FiboReturn<F> {
use chiquito::frontend::dsl::cb::*; // functions for constraint building

let fibo = circuit::<F, (), _>("fibonacci", |ctx| {
// the following objects (forward signals, steptypes) are defined on the circuit-level

// forward signals can have constraints across different steps
let a = ctx.forward("a");
let b = ctx.forward("b");

// define step type
let fibo_step = ctx.step_type_def("fibo step", |ctx| {
// the following objects (constraints, transition constraints, witness generation
// function) are defined on the step type-level

// internal signals can only have constraints within the same step
let c = ctx.internal("c");

// in setup we define the constraints of the step
ctx.setup(move |ctx| {
// regular constraints are for signals without rotation only

// `auto_eq` creates a constraint and also auto generates the witness of the left
// side.
ctx.auto_eq(c, a + b);

// transition constraints accepts forward signals as well
// constrain that b is equal to the next instance of a by calling `eq` function from
// constraint builder and `next` on forward signal
ctx.transition(eq(b, a.next()));
// constrain that c is equal to the next instance of c, by calling `next` on forward
// signal
ctx.transition(eq(c, b.next()));
});

// witness generation (wg) function is Turing complete and allows arbitrary user defined
// logics for assigning witness values wg function is defined here but no
// witness value is assigned yet
ctx.wg(move |ctx, (a_value, b_value): (u32, u32)| {
// println!("fib line wg: {} {} {}", a_value, b_value, a_value + b_value);
// assign arbitrary input values from witness generation function to witnesses
ctx.assign(a, a_value.field());
ctx.assign(b, b_value.field());

// c is auto generated by `auto_eq`
})
});

ctx.pragma_num_steps(16);

// trace function is responsible for adding step instantiations defined in step_type_def
// function above trace function is Turing complete and allows arbitrary user
// defined logics for assigning witness values
ctx.trace(move |ctx: _, _| {
// add function adds a step instantiation to the main circuit and calls witness
// generation function defined in step_type_def input values for witness
// generation function are (1, 1) in this step instance
ctx.add(&fibo_step, (1, 1));
let mut a = 1;
let mut b = 2;

for _i in 1..16 {
ctx.add(&fibo_step, (a, b));

let prev_a = a;
a = b;
b += prev_a;
}
})
});

let compiled = compile(
config(SingleRowCellManager {}, SimpleStepSelectorBuilder {}),
&fibo,
);

(compiled.0, compiled.1, fibo)
}

fn main() {
let (mut chiquito, wit_gen, _) = fibo_circuit_ccs::<Fr>();
let witness = wit_gen.map(|g| g.generate(()));

let z = chiquito.generate(witness);
let compiled = chiquito.ccs;
let result = compiled.is_satisfied(&z);
println!("fibonacci {:#?}", result);

let (mut chiquito, wit_gen, _) = fibo_circuit_ccs::<Fr>();
let witness = wit_gen.map(|g| g.generate(()));

let z = chiquito.generate(witness);
let compiled = chiquito.ccs;

let ccs = compiled.convert_to_sonobe_circuit(fr_convert);
let inputs = z.convert_to_sonobe_inputs(fr_convert);

let result = ccs.check_relation(&inputs);
println!("sonobe fibonacci = {:?}", result);

run_hypernova(ccs, inputs);
}

fn run_hypernova(ccs: CCS<FFr>, z: Vec<FFr>) {
use ark_ff::PrimeField;

let mut rng = ark_std::test_rng();
let n: usize = 64;
// setup params
let (params, _) = Pedersen::<Projective>::setup(&mut rng, n).unwrap();

let (running_instance, running_wit) = ccs.to_lcccs(&mut rng, &params, &z).unwrap();
let res = running_instance.check_relation(&params, &ccs, &running_wit);
println!("sonobe fibonacci lcccs check_relation = {:?}", res);

let (new_instance, new_wit) = ccs.to_cccs(&mut rng, &params, &z).unwrap();
let res = new_instance.check_relation(&params, &ccs, &new_wit);
println!("sonobe fibonacci cccs check_relation = {:?}", res);

// Prover's transcript
let poseidon_config = poseidon_canonical_config::<FFr>();
let mut transcript_p: PoseidonTranscript<Projective> =
PoseidonTranscript::<Projective>::new(&poseidon_config);
transcript_p.absorb(&FFr::from_le_bytes_mod_order(b"init init"));

let (proof, folded_lcccs, folded_witness) =
NIMFS::<Projective, PoseidonTranscript<Projective>>::prove(
&mut transcript_p,
&ccs,
&[running_instance.clone()],
&[new_instance.clone()],
&[running_wit],
&[new_wit],
)
.unwrap();

// Verifier's transcript
let mut transcript_v: PoseidonTranscript<Projective> =
PoseidonTranscript::<Projective>::new(&poseidon_config);
transcript_v.absorb(&FFr::from_le_bytes_mod_order(b"init init"));

let folded_lcccs_v = NIMFS::<Projective, PoseidonTranscript<Projective>>::verify(
&mut transcript_v,
&ccs,
&[running_instance.clone()],
&[new_instance.clone()],
proof,
)
.unwrap();
println!("sonobe hypernova verify...ok");

assert_eq!(folded_lcccs, folded_lcccs_v);
let res = folded_lcccs.check_relation(&params, &ccs, &folded_witness);
println!("sonobe fibonacci folded lcccs check_relation = {:?}", res);
}

fn fr_convert(r: &Fr) -> FFr {
let converted = (0..4)
.map(|i| {
let mut values = [0u8; 8];
values.copy_from_slice(&r.to_repr().as_ref()[i * 8..i * 8 + 8]);
u64::from_le_bytes(values)
})
.collect::<Vec<_>>()
.try_into()
.unwrap();

FFr::from(BigInt::new(converted))
}
10 changes: 8 additions & 2 deletions examples/keccak.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1635,9 +1635,15 @@ fn keccak_circuit<F: PrimeField<Repr = [u8; 32]> + Eq + Hash>(
let mut tmp_pi_sum_split_xor_vec = setup_theta_sum_split_xor_vec.clone();
for i in 0..PART_SIZE as usize {
for j in 0..PART_SIZE as usize {
// tmp_pi_sum_split_xor_vec
// [j * PART_SIZE as usize + ((2 * i + 3 * j) % PART_SIZE as usize)]
// = setup_theta_sum_split_xor_vec[i *
// PART_SIZE as usize + j].clone();
tmp_pi_sum_split_xor_vec
[j * PART_SIZE as usize + ((2 * i + 3 * j) % PART_SIZE as usize)] =
setup_theta_sum_split_xor_vec[i * PART_SIZE as usize + j].clone();
[j * PART_SIZE as usize + ((2 * i + 3 * j) % PART_SIZE as usize)]
.clone_from(
&setup_theta_sum_split_xor_vec[i * PART_SIZE as usize + j],
);
}
}

Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain
Original file line number Diff line number Diff line change
@@ -1 +1 @@
nightly-2024-02-14
1.78.0
1 change: 1 addition & 0 deletions src/ccs/backend/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod sonobe_hypernova;
57 changes: 57 additions & 0 deletions src/ccs/backend/sonobe_hypernova.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use ark_ff::PrimeField;
use ark_std::log2;
use folding_schemes::{ccs::CCS, utils::vec::dense_matrix_to_sparse};

use crate::{
ccs::ir::circuit::{CCSCircuit, Z},
field::Field,
};

impl<F: Field> CCSCircuit<F> {
pub fn convert_to_sonobe_circuit<Fr: PrimeField>(&self, f: fn(&F) -> Fr) -> CCS<Fr> {
let matrices = self
.matrices
.iter()
.map(|matrix| {
let values = matrix
.values()
.iter()
.map(|values| values.iter().map(f).collect())
.collect();
dense_matrix_to_sparse(values)
})
.collect();
let selectors = self
.selectors
.iter()
.map(|selectors| selectors.iter().map(|(idx, _)| *idx).collect())
.collect();
CCS {
m: self.m,
n: self.n,
l: self.l,
t: self.t,
q: self.q,
d: self.d,
s: log2(self.m) as usize,
s_prime: log2(self.n) as usize,
M: matrices,
S: selectors,
c: (0..self.q).map(|_| Fr::from(1u64)).collect(),
}
}
}

impl<F: Field> Z<F> {
pub fn convert_to_sonobe_inputs<Fr: PrimeField>(&self, f: fn(&F) -> Fr) -> Vec<Fr> {
[
vec![F::from(1u64)],
self.assignments.clone(),
self.public_inputs.clone(),
]
.concat()
.iter()
.map(f)
.collect()
}
}
Loading
Loading