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

Added concatenated balance for nonzero constraint process #294

Merged
merged 8 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
47 changes: 0 additions & 47 deletions .github/workflows/benchmark.yml

This file was deleted.

23 changes: 0 additions & 23 deletions .github/workflows/contracts.yml

This file was deleted.

68 changes: 23 additions & 45 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,53 +14,31 @@ env:
CARGO_TERM_COLOR: always

jobs:
wakeup:
test-zk-prover:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read

steps:
- uses: actions/checkout@v3

- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::490752553772:role/summa-solvency-ec2-slc
role-duration-seconds: 900
aws-region: us-west-2

- name: Wakeup runner
run: .github/scripts/wakeup.sh

build:
runs-on: [summa-solvency-runner]
needs: [wakeup]

steps:
- uses: actions/checkout@v3

- name: Set Environment
run: echo "PATH=/home/ubuntu/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" >> "$GITHUB_ENV"

- name: Install solc
run: (hash svm 2>/dev/null || cargo install --version 0.2.23 svm-rs) && svm install 0.8.20 && solc --version

- name: Test Prover
- name: Test Zk Prover
run: |
cd prover
cargo test --release -- --nocapture

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1

# TODO restore workflow
# - name: Test backend
# run: |
# cd backend
# cargo test --release -- --nocapture

# - name: Test example
# run: |
# cd backend
# cargo run --release --example summa_solvency_flow
cargo test --release --features dev-graph -- --nocapture

# TODO: restore workflow after fix backend
# test-backend:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v3
# - name: Test backend
# run: |
# cd backend
# cargo test --release -- --nocapture

# test-backend-examples:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v3
# - name: Test backend example
# run: |
# cd backend
# cargo run --release --example summa_solvency_flow

2 changes: 1 addition & 1 deletion backend/examples/summa_solvency_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
//
// Initialize the `Round` instance to submit the liability commitment.
let entry_csv = "../csv/entry_16.csv";
let mut entries: Vec<Entry<N_CURRENCIES>> = vec![Entry::init_empty(); N_USERS];
let mut entries: Vec<Entry<N_USERS, N_CURRENCIES>> = vec![Entry::init_empty(); N_USERS];
let mut cryptos = vec![Cryptocurrency::init_empty(); N_CURRENCIES];
parse_csv_to_entries::<&str, N_CURRENCIES>(entry_csv, &mut entries, &mut cryptos).unwrap();

Expand Down
4 changes: 2 additions & 2 deletions backend/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ mod test {
.await?;

let entry_csv = "../csv/entry_16.csv";
let mut entries: Vec<Entry<N_CURRENCIES>> = vec![Entry::init_empty(); N_USERS];
let mut entries: Vec<Entry<N_USERS, N_CURRENCIES>> = vec![Entry::init_empty(); N_USERS];
let mut cryptos = vec![Cryptocurrency::init_empty(); N_CURRENCIES];
parse_csv_to_entries::<&str, N_CURRENCIES>(entry_csv, &mut entries, &mut cryptos).unwrap();

Expand Down Expand Up @@ -299,7 +299,7 @@ mod test {

// Initialize Round.
let entry_csv = "../csv/entry_16.csv";
let mut entries: Vec<Entry<N_CURRENCIES>> = vec![Entry::init_empty(); N_USERS];
let mut entries: Vec<Entry<N_USERS, N_CURRENCIES>> = vec![Entry::init_empty(); N_USERS];
let mut cryptos = vec![Cryptocurrency::init_empty(); N_CURRENCIES];
parse_csv_to_entries::<&str, N_CURRENCIES>(entry_csv, &mut entries, &mut cryptos).unwrap();

Expand Down
Binary file modified prover/prints/range-check-layout.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified prover/prints/summa-hyperplonk-layout.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions prover/rust-toolchain
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nightly-2023-07-11
85 changes: 42 additions & 43 deletions prover/src/circuits/config/circuit_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,64 +36,63 @@ pub trait CircuitConfig<const N_CURRENCIES: usize, const N_USERS: usize>: Clone
fn synthesize(
&self,
mut layouter: impl Layouter<Fp>,
entries: &[Entry<N_CURRENCIES>],
entries: &[Entry<N_USERS, N_CURRENCIES>],
concatenated_grand_total: &Fp,
) -> Result<(), Error> {
// Initiate the range check chips
let range_check_chips = self.initialize_range_check_chips();

for (i, entry) in entries.iter().enumerate() {
let last_decompositions: Vec<halo2_proofs::circuit::AssignedCell<Fp, Fp>> = layouter
.assign_region(
|| format!("assign entry {} to the table", i),
|mut region| {
region.assign_advice(
|| "username",
self.get_username(),
let last_decompositions = layouter.assign_region(
|| format!("assign entry {} to the table", i),
|mut region| {
region.assign_advice(
|| "username",
self.get_username(),
0,
|| Value::known(big_uint_to_fp::<Fp>(entry.username_as_big_uint())),
)?;

region.assign_advice(
|| "concatenated balance",
self.get_concatenated_balance(),
0,
|| {
Value::known(big_uint_to_fp::<Fp>(
&entry.concatenated_balance().unwrap(),
))
},
)?;

// Decompose the balances
let mut assigned_balances = Vec::new();

for (j, balance) in entry.balances().iter().enumerate() {
let assigned_balance = region.assign_advice(
|| format!("balance {}", j),
self.get_balances()[j],
0,
|| Value::known(big_uint_to_fp::<Fp>(entry.username_as_big_uint())),
|| Value::known(big_uint_to_fp(balance)),
)?;

region.assign_advice(
|| "concatenated balance",
self.get_concatenated_balance(),
0,
|| Value::known(big_uint_to_fp::<Fp>(&entry.concatenated_balance())),
)?;
assigned_balances.push(assigned_balance);
}

// Decompose the balances
let mut assigned_balances = Vec::new();
let mut last_decompositions = vec![];

for (j, balance) in entry.balances().iter().enumerate() {
let assigned_balance = region.assign_advice(
|| format!("balance {}", j),
self.get_balances()[j],
0,
|| Value::known(big_uint_to_fp(balance)),
)?;

assigned_balances.push(assigned_balance);
}
for (j, assigned_balance) in assigned_balances.iter().enumerate() {
let mut zs = Vec::with_capacity(4);

let mut last_decompositions = vec![];
if !range_check_chips.is_empty() {
range_check_chips[j].assign(&mut region, &mut zs, assigned_balance)?;

for (j, assigned_balance) in assigned_balances.iter().enumerate() {
let mut zs = Vec::with_capacity(4);

if !range_check_chips.is_empty() {
range_check_chips[j].assign(
&mut region,
&mut zs,
assigned_balance,
)?;

last_decompositions.push(zs[3].clone());
}
last_decompositions.push(zs[3].clone());
}
}

Ok(last_decompositions)
},
)?;
Ok(last_decompositions)
},
)?;

self.constrain_decompositions(last_decompositions, &mut layouter)?;
}
Expand Down
56 changes: 36 additions & 20 deletions prover/src/circuits/summa_circuit.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
use std::marker::PhantomData;

use halo2_proofs::{
arithmetic::Field,
circuit::{Layouter, SimpleFloorPlanner},
halo2curves::{bn256::Fr as Fp, ff::PrimeField},
plonk::{Circuit, ConstraintSystem, Error, Expression},
poly::Rotation,
};

use crate::{entry::Entry, utils::big_uint_to_fp};

use halo2_proofs::arithmetic::Field;
use halo2_proofs::halo2curves::bn256::Fr as Fp;
use plonkish_backend::frontend::halo2::CircuitExt;
use rand::RngCore;
use std::marker::PhantomData;

use super::config::circuit_config::CircuitConfig;
use crate::{
entry::Entry,
utils::{big_uint_to_fp, calculate_shift_bits},
};

#[derive(Clone, Default)]
pub struct SummaHyperplonk<
const N_USERS: usize,
const N_CURRENCIES: usize,
CONFIG: CircuitConfig<N_CURRENCIES, N_USERS>,
> {
pub entries: Vec<Entry<N_CURRENCIES>>,
pub entries: Vec<Entry<N_USERS, N_CURRENCIES>>,
pub concatenated_grand_total: Fp,
_marker: PhantomData<CONFIG>,
}
Expand All @@ -32,11 +32,12 @@ impl<
CONFIG: CircuitConfig<N_CURRENCIES, N_USERS>,
> SummaHyperplonk<N_USERS, N_CURRENCIES, CONFIG>
{
pub fn init(user_entries: Vec<Entry<N_CURRENCIES>>) -> Self {
pub fn init(user_entries: Vec<Entry<N_USERS, N_CURRENCIES>>) -> Self {
let mut concatenated_grand_total = Fp::ZERO;

for entry in user_entries.iter() {
concatenated_grand_total += big_uint_to_fp::<Fp>(&entry.concatenated_balance());
concatenated_grand_total +=
big_uint_to_fp::<Fp>(&entry.concatenated_balance().unwrap());
}

Self {
Expand All @@ -49,7 +50,7 @@ impl<
/// Initialize the circuit with an invalid grand total
/// (for testing purposes only).
#[cfg(test)]
pub fn init_invalid_grand_total(user_entries: Vec<Entry<N_CURRENCIES>>) -> Self {
pub fn init_invalid_grand_total(user_entries: Vec<Entry<N_USERS, N_CURRENCIES>>) -> Self {
use plonkish_backend::util::test::seeded_std_rng;

let concatenated_grand_total = Fp::random(seeded_std_rng());
Expand Down Expand Up @@ -103,19 +104,34 @@ impl<
// Right-most balance column is for the least significant balance in concatenated balance.
let mut balances_expr = meta.query_advice(balances[N_CURRENCIES - 1], Rotation::cur());

// Base shift value for 84 bits.
let base_shift = Fp::from(1 << 63).mul(&Fp::from(1 << 21));
let shift_bits = calculate_shift_bits::<N_USERS, N_CURRENCIES>().unwrap();

let mut current_shift = Expression::Constant(base_shift);
// The shift bits would not be exceed 93 bits
let base_shift = Fp::from_u128(1u128 << shift_bits);

for i in (0..N_CURRENCIES - 1).rev() {
let balance = meta.query_advice(balances[i], Rotation::cur());
let shifted_balance = balance * current_shift.clone();
balances_expr = balances_expr + shifted_balance;
let mut current_shift = Expression::Constant(base_shift);

if i != 0 {
current_shift = current_shift * Expression::Constant(base_shift);
// The number of currencies is limited 1 or 3 because the range check chip logic.
// In other words, more than 3 currencies would exceed the maximum bit count of 254, which is number of bits in Bn254.
match N_CURRENCIES {
1 => {
// No need to add any shift for the only balance
println!("For a better performance for single currency, check out V3c. More details at: https://github.com/summa-dev/summa-solvency/tree/v3c");
},
3 => {
for i in (0..N_CURRENCIES - 1).rev() {
let balance = meta.query_advice(balances[i], Rotation::cur());
let shifted_balance = balance * current_shift.clone();
balances_expr = balances_expr + shifted_balance;

if i != 0 {
current_shift = current_shift * Expression::Constant(base_shift);
}
}
}
_ => panic!(
"Unsupported number of currencies, Only 1 and 3 currencies are supported"
),
}

// Ensure that the whole expression equals to the concatenated_balance
Expand Down
Loading
Loading