@@ -72,15 +72,15 @@ pub const METADATA_SIZE_BYTES: usize = 5;
72
72
pub const MIN_SERIALIZE_SIZE_BYTES : usize = METADATA_SIZE_BYTES + MIN_SECRET_LEN ;
73
73
74
74
mod encoding;
75
- pub use encoding:: { sskr_generate, sskr_generate_using, sskr_combine} ;
75
+ pub use encoding:: { sskr_generate, sskr_generate_using, sskr_combine } ;
76
76
77
77
mod share;
78
78
79
79
mod secret;
80
80
pub use secret:: Secret ;
81
81
82
82
mod spec;
83
- pub use spec:: { Spec , GroupSpec } ;
83
+ pub use spec:: { Spec , GroupSpec } ;
84
84
85
85
mod error;
86
86
pub use error:: SSKRError ;
@@ -129,15 +129,20 @@ mod tests {
129
129
}
130
130
131
131
let recovered_share_indexes = [ 1 , 2 , 4 ] ;
132
- let recovered_shares = recovered_share_indexes. iter ( ) . map ( |index| flattened_shares[ * index] . clone ( ) ) . collect :: < Vec < _ > > ( ) ;
132
+ let recovered_shares = recovered_share_indexes
133
+ . iter ( )
134
+ . map ( |index| flattened_shares[ * index] . clone ( ) )
135
+ . collect :: < Vec < _ > > ( ) ;
133
136
let recovered_secret = sskr_combine ( & recovered_shares) . unwrap ( ) ;
134
137
assert_eq ! ( recovered_secret, secret) ;
135
138
}
136
139
137
140
#[ test]
138
141
fn test_split_2_7 ( ) {
139
142
let mut rng = FakeRandomNumberGenerator ;
140
- let secret = Secret :: new ( hex ! ( "204188bfa6b440a1bdfd6753ff55a8241e07af5c5be943db917e3efabc184b1a" ) ) . unwrap ( ) ;
143
+ let secret = Secret :: new (
144
+ hex ! ( "204188bfa6b440a1bdfd6753ff55a8241e07af5c5be943db917e3efabc184b1a" )
145
+ ) . unwrap ( ) ;
141
146
let group = GroupSpec :: new ( 2 , 7 ) . unwrap ( ) ;
142
147
let spec = Spec :: new ( 1 , vec ! [ group] ) . unwrap ( ) ;
143
148
let shares = sskr_generate_using ( & spec, & secret, & mut rng) . unwrap ( ) ;
@@ -152,15 +157,20 @@ mod tests {
152
157
}
153
158
154
159
let recovered_share_indexes = [ 3 , 4 ] ;
155
- let recovered_shares = recovered_share_indexes. iter ( ) . map ( |index| flattened_shares[ * index] . clone ( ) ) . collect :: < Vec < _ > > ( ) ;
160
+ let recovered_shares = recovered_share_indexes
161
+ . iter ( )
162
+ . map ( |index| flattened_shares[ * index] . clone ( ) )
163
+ . collect :: < Vec < _ > > ( ) ;
156
164
let recovered_secret = sskr_combine ( & recovered_shares) . unwrap ( ) ;
157
165
assert_eq ! ( recovered_secret, secret) ;
158
166
}
159
167
160
168
#[ test]
161
169
fn test_split_2_3_2_3 ( ) {
162
170
let mut rng = FakeRandomNumberGenerator ;
163
- let secret = Secret :: new ( hex ! ( "204188bfa6b440a1bdfd6753ff55a8241e07af5c5be943db917e3efabc184b1a" ) ) . unwrap ( ) ;
171
+ let secret = Secret :: new (
172
+ hex ! ( "204188bfa6b440a1bdfd6753ff55a8241e07af5c5be943db917e3efabc184b1a" )
173
+ ) . unwrap ( ) ;
164
174
let group1 = GroupSpec :: new ( 2 , 3 ) . unwrap ( ) ;
165
175
let group2 = GroupSpec :: new ( 2 , 3 ) . unwrap ( ) ;
166
176
let spec = Spec :: new ( 2 , vec ! [ group1, group2] ) . unwrap ( ) ;
@@ -177,7 +187,10 @@ mod tests {
177
187
}
178
188
179
189
let recovered_share_indexes = [ 0 , 1 , 3 , 5 ] ;
180
- let recovered_shares = recovered_share_indexes. iter ( ) . map ( |index| flattened_shares[ * index] . clone ( ) ) . collect :: < Vec < _ > > ( ) ;
190
+ let recovered_shares = recovered_share_indexes
191
+ . iter ( )
192
+ . map ( |index| flattened_shares[ * index] . clone ( ) )
193
+ . collect :: < Vec < _ > > ( ) ;
181
194
let recovered_secret = sskr_combine ( & recovered_shares) . unwrap ( ) ;
182
195
assert_eq ! ( recovered_secret, secret) ;
183
196
}
@@ -197,16 +210,16 @@ mod tests {
197
210
let mut v = ( 0 ..100 ) . collect :: < Vec < _ > > ( ) ;
198
211
fisher_yates_shuffle ( & mut v, & mut rng) ;
199
212
assert_eq ! ( v. len( ) , 100 ) ;
200
- assert_eq ! ( v , [ 79 , 70 , 40 , 53 , 25 , 30 , 31 , 88 , 10 , 1 ,
201
- 45 , 54 , 81 , 58 , 55 , 59 , 69 , 78 , 65 , 47 ,
202
- 75 , 61 , 0 , 72 , 20 , 9 , 80 , 13 , 73 , 11 ,
203
- 60 , 56 , 19 , 42 , 33 , 12 , 36 , 38 , 6 , 35 ,
204
- 68 , 77 , 50 , 18 , 97 , 49 , 98 , 85 , 89 , 91 ,
205
- 15 , 71 , 99 , 67 , 84 , 23 , 64 , 14 , 57 , 48 ,
206
- 62 , 29 , 28 , 94 , 44 , 8 , 66 , 34 , 43 , 21 ,
207
- 63 , 16 , 92 , 95 , 27 , 51 , 26 , 86 , 22 , 41 ,
208
- 93 , 82 , 7 , 87 , 74 , 37 , 46 , 3 , 96 , 24 ,
209
- 90 , 39 , 32 , 17 , 76 , 4 , 83 , 2 , 52 , 5 ] ) ;
213
+ assert_eq ! (
214
+ v ,
215
+ [
216
+ 79 , 70 , 40 , 53 , 25 , 30 , 31 , 88 , 10 , 1 , 45 , 54 , 81 , 58 , 55 , 59 , 69 , 78 , 65 , 47 , 75 , 61 ,
217
+ 0 , 72 , 20 , 9 , 80 , 13 , 73 , 11 , 60 , 56 , 19 , 42 , 33 , 12 , 36 , 38 , 6 , 35 , 68 , 77 , 50 , 18 ,
218
+ 97 , 49 , 98 , 85 , 89 , 91 , 15 , 71 , 99 , 67 , 84 , 23 , 64 , 14 , 57 , 48 , 62 , 29 , 28 , 94 , 44 , 8 ,
219
+ 66 , 34 , 43 , 21 , 63 , 16 , 92 , 95 , 27 , 51 , 26 , 86 , 22 , 41 , 93 , 82 , 7 , 87 , 74 , 37 , 46 , 3 ,
220
+ 96 , 24 , 90 , 39 , 32 , 17 , 76 , 4 , 83 , 2 , 52 , 5 ,
221
+ ]
222
+ ) ;
210
223
}
211
224
212
225
struct RecoverSpec {
@@ -219,7 +232,12 @@ mod tests {
219
232
}
220
233
221
234
impl RecoverSpec {
222
- fn new ( secret : Secret , spec : Spec , shares : Vec < Vec < Vec < u8 > > > , rng : & mut impl RandomNumberGenerator ) -> Self {
235
+ fn new (
236
+ secret : Secret ,
237
+ spec : Spec ,
238
+ shares : Vec < Vec < Vec < u8 > > > ,
239
+ rng : & mut impl RandomNumberGenerator
240
+ ) -> Self {
223
241
let mut group_indexes = ( 0 ..spec. group_count ( ) ) . collect :: < Vec < _ > > ( ) ;
224
242
fisher_yates_shuffle ( & mut group_indexes, rng) ;
225
243
let recovered_group_indexes = group_indexes[ ..spec. group_threshold ( ) ] . to_vec ( ) ;
@@ -228,7 +246,8 @@ mod tests {
228
246
let group = & spec. groups ( ) [ * group_index] ;
229
247
let mut member_indexes = ( 0 ..group. member_count ( ) ) . collect :: < Vec < _ > > ( ) ;
230
248
fisher_yates_shuffle ( & mut member_indexes, rng) ;
231
- let recovered_member_indexes_for_group = member_indexes[ ..group. member_threshold ( ) ] . to_vec ( ) ;
249
+ let recovered_member_indexes_for_group =
250
+ member_indexes[ ..group. member_threshold ( ) ] . to_vec ( ) ;
232
251
recovered_member_indexes. push ( recovered_member_indexes_for_group) ;
233
252
}
234
253
@@ -268,7 +287,7 @@ mod tests {
268
287
Err ( e) => {
269
288
println ! ( "error: {:?}" , e) ;
270
289
false
271
- } ,
290
+ }
272
291
} ;
273
292
274
293
if !success {
@@ -282,11 +301,13 @@ mod tests {
282
301
let secret_len = rng. next_in_closed_range ( & ( MIN_SECRET_LEN ..=MAX_SECRET_LEN ) ) & !1 ;
283
302
let secret = Secret :: new ( rng. random_data ( secret_len) ) . unwrap ( ) ;
284
303
let group_count = rng. next_in_closed_range ( & ( 1 ..=MAX_GROUPS_COUNT ) ) ;
285
- let group_specs = ( 0 ..group_count) . map ( |_| {
286
- let member_count = rng. next_in_closed_range ( & ( 1 ..=MAX_SHARE_COUNT ) ) ;
287
- let member_threshold = rng. next_in_closed_range ( & ( 1 ..=member_count) ) ;
288
- GroupSpec :: new ( member_threshold, member_count) . unwrap ( )
289
- } ) . collect :: < Vec < _ > > ( ) ;
304
+ let group_specs = ( 0 ..group_count)
305
+ . map ( |_| {
306
+ let member_count = rng. next_in_closed_range ( & ( 1 ..=MAX_SHARE_COUNT ) ) ;
307
+ let member_threshold = rng. next_in_closed_range ( & ( 1 ..=member_count) ) ;
308
+ GroupSpec :: new ( member_threshold, member_count) . unwrap ( )
309
+ } )
310
+ . collect :: < Vec < _ > > ( ) ;
290
311
let group_threshold = rng. next_in_closed_range ( & ( 1 ..=group_count) ) ;
291
312
let spec = Spec :: new ( group_threshold, group_specs) . unwrap ( ) ;
292
313
let shares = sskr_generate_using ( & spec, & secret, rng) . unwrap ( ) ;
@@ -316,7 +337,7 @@ mod tests {
316
337
317
338
#[ test]
318
339
fn example_encode ( ) {
319
- use crate :: { Secret , GroupSpec , Spec , sskr_generate, sskr_combine} ;
340
+ use crate :: { Secret , GroupSpec , Spec , sskr_generate, sskr_combine } ;
320
341
321
342
let secret_string = b"my secret belongs to me." ;
322
343
let secret = Secret :: new ( secret_string) . unwrap ( ) ;
@@ -348,10 +369,44 @@ mod tests {
348
369
// Three shares from the second group.
349
370
shares[ 1 ] [ 0 ] . clone( ) ,
350
371
shares[ 1 ] [ 1 ] . clone( ) ,
351
- shares[ 1 ] [ 4 ] . clone( ) ,
372
+ shares[ 1 ] [ 4 ] . clone( )
352
373
] ;
353
374
354
375
let recovered_secret = sskr_combine ( & recovered_shares) . unwrap ( ) ;
355
376
assert_eq ! ( recovered_secret, secret) ;
356
377
}
378
+
379
+ /// Test fix for [#1](https://github.com/BlockchainCommons/bc-sskr-rust/issues/1).
380
+ #[ test]
381
+ fn example_encode_3 ( ) {
382
+ use crate :: { SSKRError , Secret , GroupSpec , Spec , sskr_generate, sskr_combine } ;
383
+ use std:: str:: from_utf8;
384
+
385
+ const TEXT : & str = "my secret belongs to me." ;
386
+
387
+ fn roundtrip ( m : usize , n : usize ) -> Result < Secret , SSKRError > {
388
+ let secret = Secret :: new ( TEXT ) . unwrap ( ) ;
389
+ let spec = Spec :: new ( 1 , vec ! [ GroupSpec :: new( m, n) . unwrap( ) ] ) . unwrap ( ) ;
390
+ let shares: Vec < Vec < Vec < u8 > > > = sskr_generate ( & spec, & secret) . unwrap ( ) ;
391
+ sskr_combine ( & shares. iter ( ) . flatten ( ) . collect :: < Vec < & Vec < u8 > > > ( ) )
392
+ }
393
+
394
+ // Good, uses a 2/3 group
395
+ {
396
+ let result = roundtrip ( 2 , 3 ) ;
397
+ assert_eq ! ( from_utf8( result. unwrap( ) . data( ) ) . unwrap( ) , TEXT ) ;
398
+ }
399
+
400
+ // Still ok, uses a 1/1 group
401
+ {
402
+ let result = roundtrip ( 1 , 1 ) ;
403
+ assert_eq ! ( from_utf8( result. unwrap( ) . data( ) ) . unwrap( ) , TEXT ) ;
404
+ }
405
+
406
+ // Fixed, uses a 1/3 group
407
+ {
408
+ let result = roundtrip ( 1 , 3 ) ;
409
+ assert_eq ! ( from_utf8( result. unwrap( ) . data( ) ) . unwrap( ) , TEXT ) ;
410
+ }
411
+ }
357
412
}
0 commit comments