@@ -2,7 +2,7 @@ use crate::{convert_to_bytes, sha256::sha256};
2
2
use mpz_garble:: protocol:: semihonest:: { Evaluator , Garbler } ;
3
3
use mpz_ot:: ideal:: cot:: { ideal_cot, IdealCOTReceiver , IdealCOTSender } ;
4
4
use mpz_vm_core:: memory:: correlated:: Delta ;
5
- use rand:: { rngs:: StdRng , SeedableRng } ;
5
+ use rand:: { rngs:: StdRng , Rng , SeedableRng } ;
6
6
7
7
pub ( crate ) const SHA256_IV : [ u32 ; 8 ] = [
8
8
0x6a09e667 , 0xbb67ae85 , 0x3c6ef372 , 0xa54ff53a , 0x510e527f , 0x9b05688c , 0x1f83d9ab , 0x5be0cd19 ,
@@ -139,3 +139,123 @@ pub(crate) fn compress_256(mut state: [u32; 8], msg: &[u8]) -> [u32; 8] {
139
139
buffer. digest_blocks ( msg, |b| compress256 ( & mut state, b) ) ;
140
140
state
141
141
}
142
+
143
+ // Borrowed from Rustls for testing
144
+ // https://github.com/rustls/rustls/blob/main/rustls/src/tls12/prf.rs
145
+ mod ring_prf {
146
+ use ring:: { hmac, hmac:: HMAC_SHA256 } ;
147
+
148
+ fn concat_sign ( key : & hmac:: Key , a : & [ u8 ] , b : & [ u8 ] ) -> hmac:: Tag {
149
+ let mut ctx = hmac:: Context :: with_key ( key) ;
150
+ ctx. update ( a) ;
151
+ ctx. update ( b) ;
152
+ ctx. sign ( )
153
+ }
154
+
155
+ fn p ( out : & mut [ u8 ] , secret : & [ u8 ] , seed : & [ u8 ] ) {
156
+ let hmac_key = hmac:: Key :: new ( HMAC_SHA256 , secret) ;
157
+
158
+ // A(1)
159
+ let mut current_a = hmac:: sign ( & hmac_key, seed) ;
160
+ let chunk_size = HMAC_SHA256 . digest_algorithm ( ) . output_len ( ) ;
161
+ for chunk in out. chunks_mut ( chunk_size) {
162
+ // P_hash[i] = HMAC_hash(secret, A(i) + seed)
163
+ let p_term = concat_sign ( & hmac_key, current_a. as_ref ( ) , seed) ;
164
+ chunk. copy_from_slice ( & p_term. as_ref ( ) [ ..chunk. len ( ) ] ) ;
165
+
166
+ // A(i+1) = HMAC_hash(secret, A(i))
167
+ current_a = hmac:: sign ( & hmac_key, current_a. as_ref ( ) ) ;
168
+ }
169
+ }
170
+
171
+ fn concat ( a : & [ u8 ] , b : & [ u8 ] ) -> Vec < u8 > {
172
+ let mut ret = Vec :: new ( ) ;
173
+ ret. extend_from_slice ( a) ;
174
+ ret. extend_from_slice ( b) ;
175
+ ret
176
+ }
177
+
178
+ pub ( crate ) fn prf ( out : & mut [ u8 ] , secret : & [ u8 ] , label : & [ u8 ] , seed : & [ u8 ] ) {
179
+ let joined_seed = concat ( label, seed) ;
180
+ p ( out, secret, & joined_seed) ;
181
+ }
182
+ }
183
+
184
+ #[ test]
185
+ fn test_prf_reference_ms ( ) {
186
+ use ring_prf:: prf as prf_ref;
187
+
188
+ let mut rng = StdRng :: from_seed ( [ 1 ; 32 ] ) ;
189
+
190
+ let pms: [ u8 ; 32 ] = rng. random ( ) ;
191
+ let label: & [ u8 ] = b"master secret" ;
192
+ let client_random: [ u8 ; 32 ] = rng. random ( ) ;
193
+ let server_random: [ u8 ; 32 ] = rng. random ( ) ;
194
+ let mut seed = Vec :: from ( client_random) ;
195
+ seed. extend_from_slice ( & server_random) ;
196
+
197
+ let ms = prf_ms ( pms, client_random, server_random) ;
198
+
199
+ let mut expected_ms: [ u8 ; 48 ] = [ 0 ; 48 ] ;
200
+ prf_ref ( & mut expected_ms, & pms, label, & seed) ;
201
+
202
+ assert_eq ! ( ms, expected_ms) ;
203
+ }
204
+
205
+ #[ test]
206
+ fn test_prf_reference_ke ( ) {
207
+ use ring_prf:: prf as prf_ref;
208
+
209
+ let mut rng = StdRng :: from_seed ( [ 2 ; 32 ] ) ;
210
+
211
+ let ms: [ u8 ; 48 ] = rng. random ( ) ;
212
+ let label: & [ u8 ] = b"key expansion" ;
213
+ let client_random: [ u8 ; 32 ] = rng. random ( ) ;
214
+ let server_random: [ u8 ; 32 ] = rng. random ( ) ;
215
+ let mut seed = Vec :: from ( server_random) ;
216
+ seed. extend_from_slice ( & client_random) ;
217
+
218
+ let keys = prf_keys ( ms, client_random, server_random) ;
219
+ let keys: Vec < u8 > = keys. into_iter ( ) . flatten ( ) . collect ( ) ;
220
+
221
+ let mut expected_keys: [ u8 ; 40 ] = [ 0 ; 40 ] ;
222
+ prf_ref ( & mut expected_keys, & ms, label, & seed) ;
223
+
224
+ assert_eq ! ( keys, expected_keys) ;
225
+ }
226
+
227
+ #[ test]
228
+ fn test_prf_reference_cf ( ) {
229
+ use ring_prf:: prf as prf_ref;
230
+
231
+ let mut rng = StdRng :: from_seed ( [ 3 ; 32 ] ) ;
232
+
233
+ let ms: [ u8 ; 48 ] = rng. random ( ) ;
234
+ let label: & [ u8 ] = b"client finished" ;
235
+ let handshake_hash: [ u8 ; 32 ] = rng. random ( ) ;
236
+
237
+ let cf_vd = prf_cf_vd ( ms, handshake_hash) ;
238
+
239
+ let mut expected_cf_vd: [ u8 ; 12 ] = [ 0 ; 12 ] ;
240
+ prf_ref ( & mut expected_cf_vd, & ms, label, & handshake_hash) ;
241
+
242
+ assert_eq ! ( cf_vd, expected_cf_vd) ;
243
+ }
244
+
245
+ #[ test]
246
+ fn test_prf_reference_sf ( ) {
247
+ use ring_prf:: prf as prf_ref;
248
+
249
+ let mut rng = StdRng :: from_seed ( [ 4 ; 32 ] ) ;
250
+
251
+ let ms: [ u8 ; 48 ] = rng. random ( ) ;
252
+ let label: & [ u8 ] = b"server finished" ;
253
+ let handshake_hash: [ u8 ; 32 ] = rng. random ( ) ;
254
+
255
+ let sf_vd = prf_sf_vd ( ms, handshake_hash) ;
256
+
257
+ let mut expected_sf_vd: [ u8 ; 12 ] = [ 0 ; 12 ] ;
258
+ prf_ref ( & mut expected_sf_vd, & ms, label, & handshake_hash) ;
259
+
260
+ assert_eq ! ( sf_vd, expected_sf_vd) ;
261
+ }
0 commit comments