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

r1cs replaced with gr1cs #378

Merged
merged 25 commits into from
Feb 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e686eea
r1cs replaced with gr1cs
alireza-shirzad Aug 6, 2024
09975dd
addressed the PR comments
alireza-shirzad Oct 12, 2024
6b20253
instance assignment getter created
alireza-shirzad Oct 12, 2024
1e6a438
instance assignment fixed outer
alireza-shirzad Oct 12, 2024
8f1d015
nax_arity added
alireza-shirzad Oct 13, 2024
d70c71e
predicate num constraints added
alireza-shirzad Oct 13, 2024
c50aee6
bump version to 0.5.0 and update dependencies
alireza-shirzad Nov 22, 2024
bfbbc65
refactor: changed the constraint storage method in the predicates
alireza-shirzad Nov 22, 2024
cf1884b
Fix: predicate weakly references to a constraint system
alireza-shirzad Nov 26, 2024
cda7768
polish
alireza-shirzad Nov 26, 2024
9deb379
feat: expose R1CS_PREDICATE_LABEL from gr1cs module
alireza-shirzad Nov 28, 2024
8e6585d
refactor: move make_row method to ConstraintSystem and ConstraintSyst…
alireza-shirzad Nov 28, 2024
8d57cce
refactor: update make_row method to improve error handling and clarity
alireza-shirzad Nov 28, 2024
6710556
refactor: Replaced the weak reference with downstreaming constraint s…
alireza-shirzad Nov 28, 2024
863af0d
tracing checked
alireza-shirzad Dec 20, 2024
a3d284d
work
alireza-shirzad Jan 8, 2025
d9ae715
works
alireza-shirzad Jan 31, 2025
6ae7f76
ready to review
alireza-shirzad Jan 31, 2025
1e4033b
finalized
alireza-shirzad Jan 31, 2025
1c9ab00
Update
Pratyush Jan 31, 2025
d2df2b1
Fix
Pratyush Feb 1, 2025
b8032cc
Fix
Pratyush Feb 1, 2025
0144dd3
Merge branch 'master' into master
Pratyush Feb 1, 2025
6d41df3
Remove patches
Pratyush Feb 1, 2025
c93dcf0
Merge branch 'master' of /~https://github.com/alireza-shirzad/snark int…
Pratyush Feb 1, 2025
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
8 changes: 1 addition & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,4 @@ opt-level = 3
lto = "thin"
incremental = true
debug-assertions = true
debug = true

[patch.crates-io]
ark-ff = { git = "/~https://github.com/arkworks-rs/algebra/" }
ark-ec = { git = "/~https://github.com/arkworks-rs/algebra/" }
ark-poly = { git = "/~https://github.com/arkworks-rs/algebra/" }
ark-serialize = { git = "/~https://github.com/arkworks-rs/algebra/" }
debug = true
27 changes: 20 additions & 7 deletions relations/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[package]
name = "ark-relations"
version = "0.4.0"
version = "0.5.0"
authors = [ "arkworks contributors" ]
description = "A library for rank-one constraint systems"
description = "A library for generalized rank-one constraint systems"
homepage = "https://arkworks.rs"
repository = "/~https://github.com/arkworks-rs/snark"
documentation = "https://docs.rs/ark-relations/"
Expand All @@ -13,14 +13,27 @@ license = "MIT/Apache-2.0"
edition = "2021"

[dependencies]
ark-ff = { version = "0.4.0", default-features = false }
ark-std = { version = "0.4.0", default-features = false }
tracing = { version = "0.1", default-features = false }
tracing-subscriber = { version = "0.2", default-features = false, optional = true }
ark-ff = { version = "0.5.0", default-features = false }
ark-std = { version = "0.5.0", default-features = false }
ark-poly = { version = "0.5.0", default-features = false }
ark-serialize = { version = "0.5.0", default-features = false }
tracing = { version = "0.1", default-features = false, features = ["attributes"]}
tracing-subscriber = { version = "0.3", default-features = true, optional = true }

[dev-dependencies]
ark-test-curves = { version = "0.4.0", default-features = false, features = [ "bls12_381_scalar_field" ] }
ark-test-curves = { version = "0.5.0", default-features = false, features = [ "bls12_381_scalar_field" ] }

[features]
default = []
std = [ "ark-std/std", "ark-ff/std", "tracing-subscriber", "tracing/std" ]


[[example]]
name = "non-satisfiable"
path = "examples/non_satisfiable.rs"
required-features = ["std"]

[[example]]
name = "satisfiable"
path = "examples/satisfiable.rs"
required-features = ["std"]
8 changes: 8 additions & 0 deletions relations/examples/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
To run the examples, use the following commands:

```bash
# Run the satisfiable example
cargo run --example satisfiable

# Run the non-satisfiable example with the `std` feature enabled to see the output trace
cargo run --example non-satisfiable --features std
167 changes: 167 additions & 0 deletions relations/examples/non_satisfiable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
use ark_ff::Field;
use ark_relations::gr1cs::{
trace::{ConstraintLayer, TracingMode},
ConstraintSystem, ConstraintSystemRef, LinearCombination, SynthesisError, Variable,
};
use ark_test_curves::bls12_381::Fr;

use tracing_subscriber::{fmt, layer::SubscriberExt, Registry};

fn main() {
// Set up tracing with a ConstraintLayer
let constraint_layer = ConstraintLayer::new(TracingMode::All);
let subscriber = Registry::default()
.with(fmt::layer()) // Optional: Log formatted output to stdout
.with(constraint_layer);

tracing::subscriber::set_global_default(subscriber)
.expect("Failed to set global default subscriber");

// Initialize a constraint system
let cs = ConstraintSystem::<Fr>::new_ref();

// Create input variables
let p1 = cs.new_input_variable(|| Ok(Fr::from(3u32))).unwrap();
let p2 = cs.new_input_variable(|| Ok(Fr::from(4u32))).unwrap();
let p3 = cs.new_input_variable(|| Ok(Fr::from(6u32))).unwrap();
let p4 = cs.new_input_variable(|| Ok(Fr::from(7u32))).unwrap();

// Create witness variables
// Note that w3 has a wrong value
let w1 = cs.new_witness_variable(|| Ok(Fr::from(2u32))).unwrap();
let w2 = cs.new_witness_variable(|| Ok(Fr::from(5u32))).unwrap();
let w3 = cs.new_witness_variable(|| Ok(Fr::from(8u32))).unwrap();
let w4 = cs.new_witness_variable(|| Ok(Fr::from(9u32))).unwrap();
// Create expected result as a witness
let expected_result = cs.new_input_variable(|| Ok(Fr::from(198))).unwrap();
// Build the circuit
let _result_var =
generate_constraints(cs.clone(), p1, p2, p3, p4, w1, w2, w3, w4, expected_result).unwrap();
let trace = cs.which_predicate_is_unsatisfied().unwrap().unwrap();
println!(
"This is the trace of non-satisfied scenario, Check out the trace:\n{}",
trace
)
}
// Function to enforce the overall constraints by combining subcircuits
#[tracing::instrument(target = "gr1cs")]
fn generate_constraints<F: Field>(
cs: ConstraintSystemRef<F>,
p1: Variable,
p2: Variable,
p3: Variable,
p4: Variable,
w1: Variable,
w2: Variable,
w3: Variable,
w4: Variable,
expected_result: Variable,
) -> Result<Variable, SynthesisError> {
// Subcircuit 1
let subcircuit1_result = enforce_subcircuit1(cs.clone(), p1, p2, w1, w2)?;

// Subcircuit 2
let subcircuit2_result = enforce_subcircuit2(cs.clone(), p3, p4, w3, w4)?;

// Final operation: sum the results of the two subcircuits
let final_result = enforce_addition(cs.clone(), subcircuit1_result, subcircuit2_result)?;
// Verify that the final result matches the expected result
cs.enforce_r1cs_constraint(
LinearCombination::from(final_result),
LinearCombination::from(Variable::One),
LinearCombination::from(expected_result),
)?;

Ok(final_result)
}

// Enforces the constraints for Subcircuit 1
#[tracing::instrument(target = "gr1cs")]
fn enforce_subcircuit1<F: Field>(
cs: ConstraintSystemRef<F>,
p1: Variable,
p2: Variable,
w1: Variable,
w2: Variable,
) -> Result<Variable, SynthesisError> {
// let cs = ns!(cs, "subcircuit1").cs();

// Multiplication gate: p1 * p2
let product = enforce_multiplication(cs.clone(), p1, p2)?;

// Addition gate: w1 + w2
let sum = enforce_addition(cs.clone(), w1, w2)?;

// Final multiplication: sum * product
let result = enforce_multiplication(cs, sum, product)?;

Ok(result)
}

// Enforces the constraints for Subcircuit 2
#[tracing::instrument(target = "gr1cs")]
fn enforce_subcircuit2<F: Field>(
cs: ConstraintSystemRef<F>,
p3: Variable,
p4: Variable,
w3: Variable,
w4: Variable,
) -> Result<Variable, SynthesisError> {
// let cs = ns!(cs, "subcircuit2").cs();

// Multiplication gate 1: p3 * w3
let product1 = enforce_multiplication(cs.clone(), p3, p4)?;

// Multiplication gate 2: p4 * w4
let product2 = enforce_multiplication(cs.clone(), w3, w4)?;

// Final addition: product1 + product2
let result = enforce_addition(cs, product1, product2)?;

Ok(result)
}

// Function to enforce a multiplication constraint
#[tracing::instrument(target = "gr1cs")]
fn enforce_multiplication<F: Field>(
cs: ConstraintSystemRef<F>,
left: Variable,
right: Variable,
) -> Result<Variable, SynthesisError> {
// let cs = ns!(cs, "multiplication").cs();

let product = cs.new_witness_variable(|| {
Ok(cs.assigned_value(left).unwrap() * cs.assigned_value(right).unwrap())
})?; // Placeholder for product

cs.enforce_r1cs_constraint(
LinearCombination::from(left),
LinearCombination::from(right),
LinearCombination::from(product),
)?;

Ok(product)
}

// Function to enforce an addition constraint
#[tracing::instrument(target = "gr1cs")]
fn enforce_addition<F: Field>(
cs: ConstraintSystemRef<F>,
left: Variable,
right: Variable,
) -> Result<Variable, SynthesisError> {
// let cs = ns!(cs, "addition").cs();

// Instead of + we use *, This is intentioanlly made to fail
let sum = cs.new_witness_variable(|| {
Ok(cs.assigned_value(left).unwrap() * cs.assigned_value(right).unwrap())
})?; // Placeholder for sum

cs.enforce_r1cs_constraint(
LinearCombination::from(left) + LinearCombination::from(right),
LinearCombination::from(Variable::One),
LinearCombination::from(sum),
)?;

Ok(sum)
}
154 changes: 154 additions & 0 deletions relations/examples/satisfiable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
use ark_ff::Field;
use ark_relations::gr1cs::{
ConstraintSystem, ConstraintSystemRef, LinearCombination, SynthesisError, Variable,
};
use ark_test_curves::bls12_381::Fr;

fn main() {
// Initialize a constraint system
let cs = ConstraintSystem::<Fr>::new_ref();

// Create input variables
let p1 = cs.new_input_variable(|| Ok(Fr::from(3u32))).unwrap();
let p2 = cs.new_input_variable(|| Ok(Fr::from(4u32))).unwrap();
let p3 = cs.new_input_variable(|| Ok(Fr::from(6u32))).unwrap();
let p4 = cs.new_input_variable(|| Ok(Fr::from(7u32))).unwrap();

// Create witness variables
let w1 = cs.new_witness_variable(|| Ok(Fr::from(2u32))).unwrap();
let w2 = cs.new_witness_variable(|| Ok(Fr::from(5u32))).unwrap();
let w3 = cs.new_witness_variable(|| Ok(Fr::from(8u32))).unwrap();
let w4 = cs.new_witness_variable(|| Ok(Fr::from(9u32))).unwrap();
// Create expected result as a witness
let expected_result = cs.new_input_variable(|| Ok(Fr::from(198))).unwrap();

// Build the circuit
let _result_var =
generate_constraints(cs.clone(), p1, p2, p3, p4, w1, w2, w3, w4, expected_result).unwrap();

// Verify the constraint system
assert!(cs.is_satisfied().unwrap());
println!("Satisfied scenario successful!",);
}

// Function to enforce the overall constraints by combining subcircuits
#[tracing::instrument(target = "gr1cs")]
fn generate_constraints<F: Field>(
cs: ConstraintSystemRef<F>,
p1: Variable,
p2: Variable,
p3: Variable,
p4: Variable,
w1: Variable,
w2: Variable,
w3: Variable,
w4: Variable,
expected_result: Variable,
) -> Result<Variable, SynthesisError> {
// Subcircuit 1
let subcircuit1_result = enforce_subcircuit1(cs.clone(), p1, p2, w1, w2)?;

// Subcircuit 2
let subcircuit2_result = enforce_subcircuit2(cs.clone(), p3, p4, w3, w4)?;

// Final operation: sum the results of the two subcircuits
let final_result = enforce_addition(cs.clone(), subcircuit1_result, subcircuit2_result)?;
// Verify that the final result matches the expected result
cs.enforce_r1cs_constraint(
LinearCombination::from(final_result),
LinearCombination::from(Variable::One),
LinearCombination::from(expected_result),
)?;

Ok(final_result)
}

// Enforces the constraints for Subcircuit 1
#[tracing::instrument(target = "gr1cs")]
fn enforce_subcircuit1<F: Field>(
cs: ConstraintSystemRef<F>,
p1: Variable,
p2: Variable,
w1: Variable,
w2: Variable,
) -> Result<Variable, SynthesisError> {
// let cs = ns!(cs, "subcircuit1").cs();

// Multiplication gate: p1 * p2
let product = enforce_multiplication(cs.clone(), p1, p2)?;

// Addition gate: w1 + w2
let sum = enforce_addition(cs.clone(), w1, w2)?;

// Final multiplication: sum * product
let result = enforce_multiplication(cs, sum, product)?;

Ok(result)
}

// Enforces the constraints for Subcircuit 2
#[tracing::instrument(target = "gr1cs")]
fn enforce_subcircuit2<F: Field>(
cs: ConstraintSystemRef<F>,
p3: Variable,
p4: Variable,
w3: Variable,
w4: Variable,
) -> Result<Variable, SynthesisError> {
// let cs = ns!(cs, "subcircuit2").cs();

// Multiplication gate 1: p3 * w3
let product1 = enforce_multiplication(cs.clone(), p3, p4)?;

// Multiplication gate 2: p4 * w4
let product2 = enforce_multiplication(cs.clone(), w3, w4)?;

// Final addition: product1 + product2
let result = enforce_addition(cs, product1, product2)?;

Ok(result)
}

// Function to enforce a multiplication constraint
#[tracing::instrument(target = "gr1cs")]
fn enforce_multiplication<F: Field>(
cs: ConstraintSystemRef<F>,
left: Variable,
right: Variable,
) -> Result<Variable, SynthesisError> {
// let cs = ns!(cs, "multiplication").cs();

let product = cs.new_witness_variable(|| {
Ok(cs.assigned_value(left).unwrap() * cs.assigned_value(right).unwrap())
})?; // Placeholder for product

cs.enforce_r1cs_constraint(
LinearCombination::from(left),
LinearCombination::from(right),
LinearCombination::from(product),
)?;

Ok(product)
}

// Function to enforce an addition constraint
#[tracing::instrument(target = "gr1cs")]
fn enforce_addition<F: Field>(
cs: ConstraintSystemRef<F>,
left: Variable,
right: Variable,
) -> Result<Variable, SynthesisError> {
// let cs = ns!(cs, "addition").cs();

let sum = cs.new_witness_variable(|| {
Ok(cs.assigned_value(left).unwrap() + cs.assigned_value(right).unwrap())
})?; // Placeholder for sum

cs.enforce_r1cs_constraint(
LinearCombination::from(left) + LinearCombination::from(right),
LinearCombination::from(Variable::One),
LinearCombination::from(sum),
)?;

Ok(sum)
}
Loading
Loading