@@ -60,8 +60,8 @@ impl<F: PrimeField> Data<F> {
60
60
61
61
/// Commit a `data` of length smaller than `SRS_SIZE`
62
62
/// If greater data is provided, anything above `SRS_SIZE` is ignored
63
- pub fn to_commitment < G : KimchiCurve < ScalarField = F > > ( & self , srs : & SRS < G > ) -> G {
64
- commit_to_field_elems :: < G > ( srs, & self . data ) [ 0 ]
63
+ pub fn to_commitment < G : KimchiCurve < ScalarField = F > > ( & self , srs : & SRS < G > ) -> Commitment < G > {
64
+ Commitment :: from_data ( srs, & self . data )
65
65
}
66
66
67
67
/// Modifies inplace the provided data with `diff`
@@ -111,23 +111,45 @@ pub fn read<F: PrimeField>(path: &str) -> std::io::Result<Data<F>> {
111
111
/// new scalar value expected for the new data.
112
112
/// Note that this only update the file, not the commitment
113
113
pub fn update < F : PrimeField > ( path : & str , diff : & Diff < F > ) -> std:: io:: Result < ( ) > {
114
- let mut file = OpenOptions :: new ( ) . write ( true ) . open ( path) ?;
114
+ // Open the file in read mode to get the old value & write mode to write the new value
115
+ let mut file = OpenOptions :: new ( ) . read ( true ) . write ( true ) . open ( path) ?;
115
116
let region_offset = diff. region * ( SRS_SIZE as u64 ) ;
116
117
let scalar_size = encoding:: encoding_size_full :: < F > ( ) as u64 ;
117
- for ( index, new_value ) in diff. addresses . iter ( ) . zip ( diff. new_values . iter ( ) ) {
118
+ for ( index, diff_value ) in diff. addresses . iter ( ) . zip ( diff. diff_values . iter ( ) ) {
118
119
let corresponding_bytes_index = ( region_offset + index) * scalar_size;
119
120
file. seek ( SeekFrom :: Start ( corresponding_bytes_index) ) ?;
120
- let new_value_bytes = encoding:: decode_full ( * new_value) ;
121
+ let new_value: F = {
122
+ // The old value is taken directly from the file
123
+ let old_value: F = {
124
+ // Save the current cursor position to be able to reset the
125
+ // cursor after the read later
126
+ let pos = file. stream_position ( ) ?;
127
+ let mut old_value_bytes = vec ! [ 0u8 ; encoding:: encoding_size_full:: <F >( ) ] ;
128
+ file. read_exact ( & mut old_value_bytes) ?;
129
+ // Go back to the previous position in the file, so the read value
130
+ // will be overwritten by the new one
131
+ file. seek ( SeekFrom :: Start ( pos) ) ?;
132
+ encoding:: encode ( & old_value_bytes)
133
+ } ;
134
+ old_value + diff_value
135
+ } ;
136
+ let new_value_bytes = encoding:: decode_full ( new_value) ;
121
137
file. write_all ( & new_value_bytes) ?;
122
138
}
123
139
Ok ( ( ) )
124
140
}
125
141
126
142
#[ cfg( test) ]
127
143
mod tests {
128
- use crate :: { diff:: Diff , encoding, storage, storage:: Data , Curve , ScalarField , SRS_SIZE } ;
144
+ use crate :: {
145
+ diff:: Diff ,
146
+ encoding, storage,
147
+ storage:: { Commitment , Data } ,
148
+ Curve , ScalarField , SRS_SIZE ,
149
+ } ;
129
150
use ark_ff:: { One , UniformRand , Zero } ;
130
151
use mina_curves:: pasta:: Fp ;
152
+ use poly_commitment:: ipa:: SRS ;
131
153
use rand:: Rng ;
132
154
use std:: fs;
133
155
use tempfile:: NamedTempFile ;
@@ -139,7 +161,7 @@ mod tests {
139
161
fn test_data_consistency ( ) {
140
162
let mut rng = o1_utils:: tests:: make_test_rng ( None ) ;
141
163
142
- let srs = poly_commitment:: precomputed_srs:: get_srs_test ( ) ;
164
+ let srs: SRS < Curve > = poly_commitment:: precomputed_srs:: get_srs_test ( ) ;
143
165
144
166
// Path of the file that will contain the test data
145
167
let file = NamedTempFile :: new ( ) . unwrap ( ) ;
@@ -148,7 +170,10 @@ mod tests {
148
170
let data_bytes: Vec < u8 > = ( 0 ..( SRS_SIZE * ( encoding:: encoding_size_full :: < ScalarField > ( ) ) ) )
149
171
. map ( |_| rng. gen ( ) )
150
172
. collect ( ) ;
151
- let data = Data :: of_bytes ( & data_bytes) ;
173
+ let mut data = Data :: of_bytes ( & data_bytes) ;
174
+ // Setting the first value of data to zero will make the updated bytes
175
+ // with the well chosen diff
176
+ data. data [ 0 ] = Fp :: zero ( ) ;
152
177
let data_comm = data. to_commitment ( & srs) ;
153
178
154
179
let read_consistency = {
@@ -157,10 +182,10 @@ mod tests {
157
182
let read_data_comm = read_data. to_commitment ( & srs) ;
158
183
159
184
// True if read data are the same as initial data
160
- Curve :: eq ( & data_comm, & read_data_comm)
185
+ Commitment :: eq ( & data_comm, & read_data_comm)
161
186
} ;
162
187
163
- let ( data_updated, update_consistency) = {
188
+ let ( data_updated, update_consistency, diff_comm_consistency ) = {
164
189
let diff = {
165
190
// The number of updates is proportional to the data length,
166
191
// but we make sure to have at least one update if the data is
@@ -170,16 +195,16 @@ mod tests {
170
195
let addresses: Vec < u64 > = ( 0 ..nb_updates)
171
196
. map ( |_| ( rng. gen_range ( 0 ..data. len ( ) as u64 ) ) )
172
197
. collect ( ) ;
173
- let mut new_values : Vec < ScalarField > =
198
+ let mut diff_values : Vec < ScalarField > =
174
199
addresses. iter ( ) . map ( |_| Fp :: rand ( & mut rng) ) . collect ( ) ;
175
200
// The first value is replaced by a scalar that would
176
201
// overflow 31 bytes, so the update is not consistent and the
177
202
// test fails if this case is not handled
178
- new_values [ 0 ] = Fp :: zero ( ) - Fp :: one ( ) ;
203
+ diff_values [ 0 ] = Fp :: zero ( ) - Fp :: one ( ) ;
179
204
Diff {
180
205
region,
181
206
addresses,
182
- new_values ,
207
+ diff_values ,
183
208
}
184
209
} ;
185
210
@@ -191,10 +216,15 @@ mod tests {
191
216
let updated_read_data = storage:: read ( path) . unwrap ( ) ;
192
217
let updated_read_data_comm = updated_read_data. to_commitment ( & srs) ;
193
218
219
+ let updated_diff_data_comm = data_comm. update ( & srs, diff) ;
220
+
194
221
(
195
- Curve :: ne ( & updated_data_comm, & data_comm) ,
222
+ // True if the data have changed because of the update
223
+ Commitment :: ne ( & updated_data_comm, & data_comm) ,
196
224
// True if read data from updated file are the same as updated data
197
- Curve :: eq ( & updated_data_comm, & updated_read_data_comm) ,
225
+ Commitment :: eq ( & updated_data_comm, & updated_read_data_comm) ,
226
+ // True if the commitments are the same as the commitment obtained by direct diff application
227
+ Commitment :: eq ( & updated_diff_data_comm, & updated_data_comm) ,
198
228
)
199
229
} ;
200
230
@@ -203,5 +233,6 @@ mod tests {
203
233
assert ! ( read_consistency) ;
204
234
assert ! ( data_updated) ;
205
235
assert ! ( update_consistency) ;
236
+ assert ! ( diff_comm_consistency) ;
206
237
}
207
238
}
0 commit comments