@@ -19,11 +19,47 @@ use crate::{
1919} ;
2020use snarkvm_fields:: PrimeField ;
2121
22+ #[ cfg( feature = "save_r1cs_hashes" ) ]
23+ use sha2:: { Digest , Sha256 } ;
2224use 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
2452pub 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 ) ]
2763pub 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
214258impl < F : PrimeField > Display for R1CS < F > {
0 commit comments