Skip to content

Commit 8159e73

Browse files
authored
Merge pull request #2633 from ljedrz/feat/r1cs_hash
[Feat] Feature-gated R1CS hash collection
2 parents 595d807 + 3b66c09 commit 8159e73

File tree

9 files changed

+62
-4
lines changed

9 files changed

+62
-4
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ cli = [
131131
aleo-cli = [ "snarkvm-synthesizer/aleo-cli" ]
132132
async = [ "snarkvm-ledger/async", "snarkvm-synthesizer/async" ]
133133
cuda = [ "snarkvm-algorithms/cuda" ]
134+
save_r1cs_hashes = [ "snarkvm-circuit/save_r1cs_hashes" ]
134135
history = [ "snarkvm-synthesizer/history" ]
135136
parameters_no_std_out = [ "snarkvm-parameters/no_std_out" ]
136137
noconfig = [ ]

circuit/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ]
2323
license = "Apache-2.0"
2424
edition = "2021"
2525

26+
[features]
27+
save_r1cs_hashes = [ "snarkvm-circuit-environment/save_r1cs_hashes" ]
28+
2629
[dependencies.snarkvm-circuit-account]
2730
path = "./account"
2831
version = "=1.3.0"

circuit/environment/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ version = "0.2"
5959
[dependencies.once_cell]
6060
version = "1.18.0"
6161

62+
[dependencies.sha2]
63+
version = "0.10"
64+
default-features = false
65+
optional = true
66+
6267
[dev-dependencies.snarkvm-algorithms]
6368
path = "../../algorithms"
6469
features = [ "polycommit_full", "snark", "test" ]
@@ -77,3 +82,4 @@ version = "2.0.0"
7782

7883
[features]
7984
default = [ "snarkvm-curves/default" ]
85+
save_r1cs_hashes = [ "dep:sha2" ] # used in regression-checking

circuit/environment/src/helpers/assignment.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ pub struct Assignment<F: PrimeField> {
9999
impl<F: PrimeField> From<crate::R1CS<F>> for Assignment<F> {
100100
/// Converts an R1CS to an assignment.
101101
fn from(r1cs: crate::R1CS<F>) -> Self {
102+
#[cfg(feature = "save_r1cs_hashes")]
103+
r1cs.save_hash();
104+
102105
Self {
103106
public: FromIterator::from_iter(
104107
r1cs.to_public_variables().iter().map(|variable| (variable.index(), variable.value())),

circuit/environment/src/helpers/constraint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
use crate::{prelude::*, *};
1717
use snarkvm_fields::PrimeField;
1818

19-
#[derive(Clone, Debug)]
19+
#[derive(Clone, Debug, Hash)]
2020
pub struct Constraint<F: PrimeField>(
2121
pub(crate) Scope,
2222
pub(crate) LinearCombination<F>,

circuit/environment/src/helpers/counter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use snarkvm_fields::PrimeField;
1818

1919
use std::{mem, rc::Rc};
2020

21-
#[derive(Debug, Default)]
21+
#[derive(Debug, Default, Hash)]
2222
pub(crate) struct Counter<F: PrimeField> {
2323
scope: Scope,
2424
constraints: Vec<Rc<Constraint<F>>>,

circuit/environment/src/helpers/linear_combination.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use core::{
3131
// \end{itemize}
3232
// The constant and variable terms directly refer to how often the R1CS variables are invoked in a row.
3333
// A full R1CS row is "completed" when we introduce a multiplication between three non-const linear combinations (a*b=c).
34-
#[derive(Clone)]
34+
#[derive(Clone, Hash)]
3535
pub struct LinearCombination<F: PrimeField> {
3636
constant: F,
3737
/// The list of terms is kept sorted in order to speed up lookups.

circuit/environment/src/helpers/r1cs.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,47 @@ use crate::{
1919
};
2020
use snarkvm_fields::PrimeField;
2121

22+
#[cfg(feature = "save_r1cs_hashes")]
23+
use sha2::{Digest, Sha256};
2224
use std::rc::Rc;
25+
#[cfg(feature = "save_r1cs_hashes")]
26+
use std::{
27+
hash::{Hash, Hasher},
28+
sync::Mutex,
29+
};
30+
31+
#[cfg(feature = "save_r1cs_hashes")]
32+
struct Sha256Hasher(Sha256);
33+
34+
#[cfg(feature = "save_r1cs_hashes")]
35+
impl Hasher for Sha256Hasher {
36+
fn write(&mut self, bytes: &[u8]) {
37+
self.0.update(bytes);
38+
}
39+
40+
fn finish(&self) -> u64 {
41+
unimplemented!("Use Digest::finalize instead to get the full SHA-256 digest");
42+
}
43+
}
44+
45+
#[cfg(feature = "save_r1cs_hashes")]
46+
fn hash_to_sha256<T: Hash>(t: &T) -> [u8; 32] {
47+
let mut hasher = Sha256Hasher(Sha256::new());
48+
t.hash(&mut hasher);
49+
hasher.0.finalize().into()
50+
}
2351

2452
pub type Scope = String;
2553

26-
#[derive(Debug)]
54+
/// A list of hashes of all the R1CS objects that have reached the
55+
/// coversion to Assignment stage. It's a vector in case there are
56+
/// any duplicates (which could indicate no change or redundant
57+
/// work) and since they need to eventually be sorted in order to
58+
/// have deterministic order, as they may be created in parallel.
59+
#[cfg(feature = "save_r1cs_hashes")]
60+
pub static R1CS_HASHES: Mutex<Vec<[u8; 32]>> = Mutex::new(Vec::new());
61+
62+
#[derive(Debug, Hash)]
2763
pub struct R1CS<F: PrimeField> {
2864
constants: Vec<Variable<F>>,
2965
public: Vec<Variable<F>>,
@@ -209,6 +245,14 @@ impl<F: PrimeField> R1CS<F> {
209245
pub fn to_constraints(&self) -> &Vec<Rc<Constraint<F>>> {
210246
&self.constraints
211247
}
248+
249+
/// Register the current hash of the entire R1CS and add
250+
/// it to the R1CS_HASHES collection.
251+
#[cfg(feature = "save_r1cs_hashes")]
252+
pub(crate) fn save_hash(&self) {
253+
let r1cs_hash = hash_to_sha256(self);
254+
R1CS_HASHES.lock().unwrap().push(r1cs_hash);
255+
}
212256
}
213257

214258
impl<F: PrimeField> Display for R1CS<F> {

0 commit comments

Comments
 (0)