Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: reduce all circuits to a single instance col #515

Merged
merged 17 commits into from
Oct 4, 2023
Merged
14 changes: 6 additions & 8 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,13 @@ jobs:
# - name: Conv overflow (wasi)
# run: cargo wasi test conv_col_ultra_overflow -- --include-ignored --nocapture
- name: Conv + relu overflow (wasi)
run: cargo wasi test conv_relu_col_ultra_overflow -- --include-ignored --nocapture
run: cargo wasi test --release conv_relu_col_ultra_overflow -- --include-ignored --nocapture
# - name: Matmul overflow
# run: RUST_LOG=debug cargo nextest run matmul_col_ultra_overflow --no-capture -- --include-ignored
# - name: Conv overflow
# run: RUST_LOG=debug cargo nextest run conv_col_ultra_overflow --no-capture -- --include-ignored
- name: Conv + relu overflow
run: RUST_LOG=debug cargo nextest run conv_relu_col_ultra_overflow --no-capture -- --include-ignored
run: RUST_LOG=debug cargo nextest run --release conv_relu_col_ultra_overflow --no-capture -- --include-ignored

model-serialization:
runs-on: ubuntu-latest-16-cores
Expand Down Expand Up @@ -154,7 +154,6 @@ jobs:
- name: Circuit Render
run: cargo nextest run --release --verbose tests::tutorial_


mock-proving-tests:
runs-on: self-hosted
# needs: [build, library-tests, docs]
Expand Down Expand Up @@ -282,8 +281,8 @@ jobs:
- name: Use Node.js 18.12.1
uses: actions/setup-node@v3
with:
node-version: '18.12.1'
cache: 'pnpm'
node-version: "18.12.1"
cache: "pnpm"
- name: Install dependencies
run: |
pnpm install --no-frozen-lockfile
Expand All @@ -296,10 +295,10 @@ jobs:
locked: true
- name: Build wasm package for nodejs target.
run: |
wasm-pack build --release --target nodejs --out-dir ./tests/wasm/nodejs . -- -Z build-std="panic_abort,std"
wasm-pack build --release --target nodejs --out-dir ./tests/wasm/nodejs . -- -Z build-std="panic_abort,std"
- name: Replace memory definition in nodejs
run: |
sed -i "3s|.*|imports['env'] = {memory: new WebAssembly.Memory({initial:20,maximum:65536,shared:true})}|" tests/wasm/nodejs/ezkl.js
sed -i "3s|.*|imports['env'] = {memory: new WebAssembly.Memory({initial:20,maximum:65536,shared:true})}|" tests/wasm/nodejs/ezkl.js
- name: KZG prove and verify tests (public outputs + column overflow)
run: cargo nextest run --release --verbose tests::kzg_prove_and_verify_with_overflow_::w --test-threads 8
- name: KZG prove and verify tests (public outputs + fixed params + column overflow)
Expand Down Expand Up @@ -584,4 +583,3 @@ jobs:
run: source .env/bin/activate; cargo nextest run py_tests::tests::run_notebook_::tests_6_expects
- name: Gan tutorial
run: source .env/bin/activate; cargo nextest run py_tests::tests::run_notebook_::tests_0_expects

10 changes: 3 additions & 7 deletions benches/elgamal.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use ark_std::test_rng;
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use ezkl::circuit::modules::elgamal::{
ElGamalConfig, ElGamalGadget, ElGamalVariables, NUM_INSTANCE_COLUMNS,
ElGamalConfig, ElGamalGadget, ElGamalVariables,
};
use ezkl::circuit::modules::Module;
use ezkl::circuit::*;
Expand Down Expand Up @@ -49,11 +49,7 @@ impl Circuit<Fr> for EncryptytionCircuit {
chip.load_variables(self.variables.clone());
let sk: Tensor<ValType<Fr>> =
Tensor::new(Some(&[Value::known(self.variables.sk).into()]), &[1]).unwrap();
chip.layout(
&mut layouter,
&[self.message.clone(), sk.into()],
vec![0; NUM_INSTANCE_COLUMNS],
)?;
chip.layout(&mut layouter, &[self.message.clone(), sk.into()], 0)?;
Ok(())
}
}
Expand Down Expand Up @@ -103,7 +99,7 @@ fn runelgamal(c: &mut Criterion) {
let prover = create_proof_circuit_kzg(
circuit.clone(),
&params,
public_inputs.clone(),
public_inputs[0].clone(),
&pk,
TranscriptType::EVM,
SingleStrategy::new(&params),
Expand Down
10 changes: 3 additions & 7 deletions benches/poseidon.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use ezkl::circuit::modules::poseidon::spec::{PoseidonSpec, POSEIDON_RATE, POSEIDON_WIDTH};
use ezkl::circuit::modules::poseidon::{PoseidonChip, PoseidonConfig, NUM_INSTANCE_COLUMNS};
use ezkl::circuit::modules::poseidon::{PoseidonChip, PoseidonConfig};
use ezkl::circuit::modules::Module;
use ezkl::circuit::*;
use ezkl::pfsys::create_keys;
Expand Down Expand Up @@ -46,11 +46,7 @@ impl Circuit<Fr> for MyCircuit {
) -> Result<(), Error> {
let chip: PoseidonChip<PoseidonSpec, POSEIDON_WIDTH, POSEIDON_RATE, L> =
PoseidonChip::new(config);
chip.layout(
&mut layouter,
&[self.image.clone()],
vec![0; NUM_INSTANCE_COLUMNS],
)?;
chip.layout(&mut layouter, &[self.image.clone()], 0)?;
Ok(())
}
}
Expand Down Expand Up @@ -94,7 +90,7 @@ fn runposeidon(c: &mut Criterion) {
let prover = create_proof_circuit_kzg(
circuit.clone(),
&params,
output.clone(),
output[0].clone(),
&pk,
TranscriptType::EVM,
SingleStrategy::new(&params),
Expand Down
56 changes: 27 additions & 29 deletions src/circuit/modules/elgamal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub const POSEIDON_LEN: usize = 2;
/// A chip implementing ElGamal encryption.
pub struct ElGamalChip {
/// The configuration for this chip.
config: ElGamalConfig,
pub config: ElGamalConfig,
/// The ECC chip.
ecc: BaseFieldEccChip<G1Affine, NUMBER_OF_LIMBS, BIT_LEN_LIMB>,
/// The Poseidon hash chip.
Expand All @@ -71,7 +71,10 @@ pub struct ElGamalConfig {
poseidon_config: PoseidonConfig<POSEIDON_WIDTH, POSEIDON_RATE>,
add_config: AddConfig,
plaintext_col: Column<Advice>,
ciphertext_c1_exp_col: Column<Instance>,
/// The column used for the instance.
pub instance: Column<Instance>,
/// The config has been initialized.
pub initialized: bool,
}

impl ElGamalConfig {
Expand Down Expand Up @@ -115,7 +118,7 @@ impl ElGamalChip {
let main_gate_config = MainGate::<Fr>::configure(meta);
let advices = main_gate_config.advices();
let main_fixed_columns = main_gate_config.fixed();
let ciphertext_c1_exp_col = main_gate_config.instance();
let instance = main_gate_config.instance();

let rc_a = main_fixed_columns[3..5].try_into().unwrap();
let rc_b = [meta.fixed_column(), meta.fixed_column()];
Expand Down Expand Up @@ -154,7 +157,8 @@ impl ElGamalChip {
range_config,
add_config,
plaintext_col,
ciphertext_c1_exp_col,
instance,
initialized: false,
}
}
}
Expand Down Expand Up @@ -232,7 +236,7 @@ pub struct ElGamalCipher {
/// A gadget implementing ElGamal encryption.
pub struct ElGamalGadget {
/// The configuration for this gadget.
config: ElGamalConfig,
pub config: ElGamalConfig,
/// The variables used in this gadget.
variables: Option<ElGamalVariables>,
}
Expand Down Expand Up @@ -344,7 +348,7 @@ impl ElGamalGadget {
chip.poseidon.layout(
&mut layouter.namespace(|| "Poseidon hash (encrypted_msg)"),
&[poseidon_message.into()],
vec![],
0,
)?
};

Expand Down Expand Up @@ -376,7 +380,7 @@ impl ElGamalGadget {
chip.poseidon.layout(
&mut layouter.namespace(|| "Poseidon hash (sk)"),
&[poseidon_message.into()],
vec![],
0,
)?
};

Expand Down Expand Up @@ -456,7 +460,7 @@ impl ElGamalGadget {
chip.poseidon.layout(
&mut layouter.namespace(|| "Poseidon hasher"),
&[poseidon_message.into()],
vec![0],
0,
)?
};

Expand Down Expand Up @@ -555,16 +559,20 @@ impl Module<Fr> for ElGamalGadget {
})
.collect(),
ValTensor::Instance {
inner: col, dims, ..
dims,
inner: col,
idx,
initial_offset,
..
} => {
// this should never ever fail
let num_elems = dims.iter().product::<usize>();
let num_elems = dims[*idx].iter().product::<usize>();
(0..num_elems)
.map(|i| {
region.assign_advice_from_instance(
|| "pub input anchor",
*col,
i,
initial_offset + i,
self.config.plaintext_col,
i,
)
Expand Down Expand Up @@ -598,17 +606,15 @@ impl Module<Fr> for ElGamalGadget {
&self,
layouter: &mut impl Layouter<Fr>,
inputs: &[ValTensor<Fr>],
row_offsets: Vec<usize>,
row_offset: usize,
) -> Result<ValTensor<Fr>, Error> {
let start_time = instant::Instant::now();

// if all equivalent to 0, then we are in the first row of the circuit
if row_offsets.iter().all(|&x| x == 0) {
self.config.config_range(layouter)?;
if !self.config.initialized {
self.config.config_range(layouter).unwrap();
}

let row_offset = row_offsets[0];

let (msg_var, sk_var) = self.layout_inputs(layouter, inputs)?;

let [s, c1] = self.verify_secret(
Expand All @@ -627,17 +633,17 @@ impl Module<Fr> for ElGamalGadget {
layouter
.constrain_instance(
c1.x().native().cell(),
self.config.ciphertext_c1_exp_col,
self.config.instance,
C1_X + row_offset,
)
.and(layouter.constrain_instance(
c1.y().native().cell(),
self.config.ciphertext_c1_exp_col,
self.config.instance,
C1_Y + row_offset,
))
.and(layouter.constrain_instance(
sk_hash.cell(),
self.config.ciphertext_c1_exp_col,
self.config.instance,
SK_H + row_offset,
))?;

Expand All @@ -661,11 +667,7 @@ impl Module<Fr> for ElGamalGadget {
&c2,
)?;

layouter.constrain_instance(
c2_hash.cell(),
self.config.ciphertext_c1_exp_col,
C2_H + row_offset,
)?;
layouter.constrain_instance(c2_hash.cell(), self.config.instance, C2_H + row_offset)?;

let mut assigned_input: Tensor<ValType<Fr>> =
msg_var.iter().map(|e| ValType::from(e.clone())).into();
Expand Down Expand Up @@ -757,11 +759,7 @@ mod tests {
chip.load_variables(self.variables.clone());
let sk: Tensor<ValType<Fr>> =
Tensor::new(Some(&[Value::known(self.variables.sk).into()]), &[1]).unwrap();
chip.layout(
&mut layouter,
&[self.message.clone(), sk.into()],
vec![0; NUM_INSTANCE_COLUMNS],
)?;
chip.layout(&mut layouter, &[self.message.clone(), sk.into()], 0)?;
Ok(())
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/circuit/modules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub trait Module<F: PrimeField + TensorType + PartialOrd> {
&self,
layouter: &mut impl Layouter<F>,
input: &[ValTensor<F>],
row_offsets: Vec<usize>,
row_offset: usize,
) -> Result<ValTensor<F>, Error>;
/// Number of instance values the module uses every time it is applied
fn instance_increment_input(&self) -> Vec<usize>;
Expand Down
25 changes: 13 additions & 12 deletions src/circuit/modules/poseidon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ impl<S: Spec<Fp, WIDTH, RATE> + Sync, const WIDTH: usize, const RATE: usize, con
PoseidonChip<S, WIDTH, RATE, L>
{
/// Configuration of the PoseidonChip
pub fn configure_without_instance(
pub fn configure_with_optional_instance(
meta: &mut ConstraintSystem<Fp>,
instance: Option<Column<Instance>>,
) -> PoseidonConfig<WIDTH, RATE> {
// instantiate the required columns
let hash_inputs = (0..WIDTH).map(|_| meta.advice_column()).collect::<Vec<_>>();
Expand All @@ -108,7 +109,7 @@ impl<S: Spec<Fp, WIDTH, RATE> + Sync, const WIDTH: usize, const RATE: usize, con
rc_a.try_into().unwrap(),
rc_b.try_into().unwrap(),
hash_inputs,
None,
instance,
)
}
}
Expand Down Expand Up @@ -210,18 +211,22 @@ impl<S: Spec<Fp, WIDTH, RATE> + Sync, const WIDTH: usize, const RATE: usize, con
})
.collect(),
ValTensor::Instance {
inner: col, dims, ..
dims,
inner: col,
idx,
initial_offset,
..
} => {
// this should never ever fail
let num_elems = dims.iter().product::<usize>();
let num_elems = dims[*idx].iter().product::<usize>();
(0..num_elems)
.map(|i| {
let x = i % WIDTH;
let y = i / WIDTH;
region.assign_advice_from_instance(
|| "pub input anchor",
*col,
i,
initial_offset + i,
self.config.hash_inputs[x],
y,
)
Expand Down Expand Up @@ -259,7 +264,7 @@ impl<S: Spec<Fp, WIDTH, RATE> + Sync, const WIDTH: usize, const RATE: usize, con
&self,
layouter: &mut impl Layouter<Fp>,
input: &[ValTensor<Fp>],
row_offset: Vec<usize>,
row_offset: usize,
) -> Result<ValTensor<Fp>, Error> {
let (mut input_cells, zero_val) = self.layout_inputs(layouter, input)?;
// extract the values from the input cells
Expand Down Expand Up @@ -327,7 +332,7 @@ impl<S: Spec<Fp, WIDTH, RATE> + Sync, const WIDTH: usize, const RATE: usize, con
let expected_var = region.assign_advice_from_instance(
|| "pub input anchor",
instance,
row_offset[0],
row_offset,
self.config.hash_inputs[0],
0,
)?;
Expand Down Expand Up @@ -458,11 +463,7 @@ mod tests {
mut layouter: impl Layouter<Fp>,
) -> Result<(), Error> {
let chip: PoseidonChip<PoseidonSpec, WIDTH, RATE, L> = PoseidonChip::new(config);
chip.layout(
&mut layouter,
&[self.message.clone()],
vec![0; NUM_INSTANCE_COLUMNS],
)?;
chip.layout(&mut layouter, &[self.message.clone()], 0)?;

Ok(())
}
Expand Down
2 changes: 1 addition & 1 deletion src/circuit/ops/chip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ impl<F: PrimeField + TensorType + PartialOrd> BaseConfig<F> {
for x in 0..input.num_cols() {
let qlookup = cs.complex_selector();
selectors.insert((nl.clone(), x), qlookup);
let _ = cs.lookup("", |cs| {
cs.lookup("", |cs| {
let qlookup = cs.query_selector(qlookup);
let not_qlookup = Expression::Constant(<F as Field>::ONE) - qlookup.clone();
let (default_x, default_y): (F, F) = nl.default_pair();
Expand Down
Loading