@@ -212,8 +212,7 @@ impl<E: IsShortWeierstrass> IsGroup for ShortWeierstrassProjectivePoint<E> {
212
212
#[ derive( PartialEq ) ]
213
213
pub enum PointFormat {
214
214
Projective ,
215
- // TO DO:
216
- // Uncompressed,
215
+ Uncompressed ,
217
216
// Compressed,
218
217
}
219
218
@@ -233,7 +232,7 @@ where
233
232
{
234
233
/// Serialize the points in the given format
235
234
#[ cfg( feature = "std" ) ]
236
- pub fn serialize ( & self , _point_format : PointFormat , endianness : Endianness ) -> Vec < u8 > {
235
+ pub fn serialize ( & self , point_format : PointFormat , endianness : Endianness ) -> Vec < u8 > {
237
236
// TODO: Add more compact serialization formats
238
237
// Uncompressed affine / Compressed
239
238
@@ -242,59 +241,101 @@ where
242
241
let y_bytes: Vec < u8 > ;
243
242
let z_bytes: Vec < u8 > ;
244
243
245
- let [ x, y, z] = self . coordinates ( ) ;
246
- if endianness == Endianness :: BigEndian {
247
- x_bytes = x. to_bytes_be ( ) ;
248
- y_bytes = y. to_bytes_be ( ) ;
249
- z_bytes = z. to_bytes_be ( ) ;
250
- } else {
251
- x_bytes = x. to_bytes_le ( ) ;
252
- y_bytes = y. to_bytes_le ( ) ;
253
- z_bytes = z. to_bytes_le ( ) ;
244
+ match point_format {
245
+ PointFormat :: Projective => {
246
+ let [ x, y, z] = self . coordinates ( ) ;
247
+ if endianness == Endianness :: BigEndian {
248
+ x_bytes = x. to_bytes_be ( ) ;
249
+ y_bytes = y. to_bytes_be ( ) ;
250
+ z_bytes = z. to_bytes_be ( ) ;
251
+ } else {
252
+ x_bytes = x. to_bytes_le ( ) ;
253
+ y_bytes = y. to_bytes_le ( ) ;
254
+ z_bytes = z. to_bytes_le ( ) ;
255
+ }
256
+ bytes. extend ( & x_bytes) ;
257
+ bytes. extend ( & y_bytes) ;
258
+ bytes. extend ( & z_bytes) ;
259
+ }
260
+ PointFormat :: Uncompressed => {
261
+ let affine_representation = self . to_affine ( ) ;
262
+ let [ x, y, _z] = affine_representation. coordinates ( ) ;
263
+ if endianness == Endianness :: BigEndian {
264
+ x_bytes = x. to_bytes_be ( ) ;
265
+ y_bytes = y. to_bytes_be ( ) ;
266
+ } else {
267
+ x_bytes = x. to_bytes_le ( ) ;
268
+ y_bytes = y. to_bytes_le ( ) ;
269
+ }
270
+ bytes. extend ( & x_bytes) ;
271
+ bytes. extend ( & y_bytes) ;
272
+ }
254
273
}
255
-
256
- bytes. extend ( & x_bytes) ;
257
- bytes. extend ( & y_bytes) ;
258
- bytes. extend ( & z_bytes) ;
259
-
260
274
bytes
261
275
}
262
276
263
277
pub fn deserialize (
264
278
bytes : & [ u8 ] ,
265
- _point_format : PointFormat ,
279
+ point_format : PointFormat ,
266
280
endianness : Endianness ,
267
281
) -> Result < Self , DeserializationError > {
268
- if bytes. len ( ) % 3 != 0 {
269
- return Err ( DeserializationError :: InvalidAmountOfBytes ) ;
270
- }
282
+ match point_format {
283
+ PointFormat :: Projective => {
284
+ if bytes. len ( ) % 3 != 0 {
285
+ return Err ( DeserializationError :: InvalidAmountOfBytes ) ;
286
+ }
271
287
272
- let len = bytes. len ( ) / 3 ;
273
- let x: FieldElement < E :: BaseField > ;
274
- let y: FieldElement < E :: BaseField > ;
275
- let z: FieldElement < E :: BaseField > ;
288
+ let len = bytes. len ( ) / 3 ;
289
+ let x: FieldElement < E :: BaseField > ;
290
+ let y: FieldElement < E :: BaseField > ;
291
+ let z: FieldElement < E :: BaseField > ;
276
292
277
- if endianness == Endianness :: BigEndian {
278
- x = ByteConversion :: from_bytes_be ( & bytes[ ..len] ) ?;
279
- y = ByteConversion :: from_bytes_be ( & bytes[ len..len * 2 ] ) ?;
280
- z = ByteConversion :: from_bytes_be ( & bytes[ len * 2 ..] ) ?;
281
- } else {
282
- x = ByteConversion :: from_bytes_le ( & bytes[ ..len] ) ?;
283
- y = ByteConversion :: from_bytes_le ( & bytes[ len..len * 2 ] ) ?;
284
- z = ByteConversion :: from_bytes_le ( & bytes[ len * 2 ..] ) ?;
285
- }
293
+ if endianness == Endianness :: BigEndian {
294
+ x = ByteConversion :: from_bytes_be ( & bytes[ ..len] ) ?;
295
+ y = ByteConversion :: from_bytes_be ( & bytes[ len..len * 2 ] ) ?;
296
+ z = ByteConversion :: from_bytes_be ( & bytes[ len * 2 ..] ) ?;
297
+ } else {
298
+ x = ByteConversion :: from_bytes_le ( & bytes[ ..len] ) ?;
299
+ y = ByteConversion :: from_bytes_le ( & bytes[ len..len * 2 ] ) ?;
300
+ z = ByteConversion :: from_bytes_le ( & bytes[ len * 2 ..] ) ?;
301
+ }
286
302
287
- if z == FieldElement :: zero ( ) {
288
- let point = Self :: new ( [ x, y, z] ) ;
289
- if point. is_neutral_element ( ) {
290
- Ok ( point)
291
- } else {
292
- Err ( DeserializationError :: FieldFromBytesError )
303
+ if z == FieldElement :: zero ( ) {
304
+ let point = Self :: new ( [ x, y, z] ) ;
305
+ if point. is_neutral_element ( ) {
306
+ Ok ( point)
307
+ } else {
308
+ Err ( DeserializationError :: FieldFromBytesError )
309
+ }
310
+ } else if E :: defining_equation ( & ( & x / & z) , & ( & y / & z) ) == FieldElement :: zero ( ) {
311
+ Ok ( Self :: new ( [ x, y, z] ) )
312
+ } else {
313
+ Err ( DeserializationError :: FieldFromBytesError )
314
+ }
315
+ }
316
+ PointFormat :: Uncompressed => {
317
+ if bytes. len ( ) % 2 != 0 {
318
+ return Err ( DeserializationError :: InvalidAmountOfBytes ) ;
319
+ }
320
+
321
+ let len = bytes. len ( ) / 2 ;
322
+ let x: FieldElement < E :: BaseField > ;
323
+ let y: FieldElement < E :: BaseField > ;
324
+
325
+ if endianness == Endianness :: BigEndian {
326
+ x = ByteConversion :: from_bytes_be ( & bytes[ ..len] ) ?;
327
+ y = ByteConversion :: from_bytes_be ( & bytes[ len..] ) ?;
328
+ } else {
329
+ x = ByteConversion :: from_bytes_le ( & bytes[ ..len] ) ?;
330
+ y = ByteConversion :: from_bytes_le ( & bytes[ len..] ) ?;
331
+ }
332
+
333
+ if E :: defining_equation ( & x, & y) == FieldElement :: zero ( ) {
334
+ Ok ( Self :: new ( [ x, y, FieldElement :: one ( ) ] ) )
335
+ } else {
336
+ Err ( DeserializationError :: FieldFromBytesError )
337
+ }
293
338
}
294
- } else if E :: defining_equation ( & ( & x / & z) , & ( & y / & z) ) == FieldElement :: zero ( ) {
295
- Ok ( Self :: new ( [ x, y, z] ) )
296
- } else {
297
- Err ( DeserializationError :: FieldFromBytesError )
298
339
}
299
340
}
300
341
}
@@ -347,7 +388,7 @@ mod tests {
347
388
348
389
#[ cfg( feature = "std" ) ]
349
390
#[ test]
350
- fn byte_conversion_from_and_to_be ( ) {
391
+ fn byte_conversion_from_and_to_be_projective ( ) {
351
392
let expected_point = point ( ) ;
352
393
let bytes_be = expected_point. serialize ( PointFormat :: Projective , Endianness :: BigEndian ) ;
353
394
@@ -361,7 +402,20 @@ mod tests {
361
402
362
403
#[ cfg( feature = "std" ) ]
363
404
#[ test]
364
- fn byte_conversion_from_and_to_le ( ) {
405
+ fn byte_conversion_from_and_to_be_uncompressed ( ) {
406
+ let expected_point = point ( ) ;
407
+ let bytes_be = expected_point. serialize ( PointFormat :: Uncompressed , Endianness :: BigEndian ) ;
408
+ let result = ShortWeierstrassProjectivePoint :: deserialize (
409
+ & bytes_be,
410
+ PointFormat :: Uncompressed ,
411
+ Endianness :: BigEndian ,
412
+ ) ;
413
+ assert_eq ! ( expected_point, result. unwrap( ) ) ;
414
+ }
415
+
416
+ #[ cfg( feature = "std" ) ]
417
+ #[ test]
418
+ fn byte_conversion_from_and_to_le_projective ( ) {
365
419
let expected_point = point ( ) ;
366
420
let bytes_be = expected_point. serialize ( PointFormat :: Projective , Endianness :: LittleEndian ) ;
367
421
@@ -375,7 +429,22 @@ mod tests {
375
429
376
430
#[ cfg( feature = "std" ) ]
377
431
#[ test]
378
- fn byte_conversion_from_and_to_with_mixed_le_and_be_does_not_work ( ) {
432
+ fn byte_conversion_from_and_to_le_uncompressed ( ) {
433
+ let expected_point = point ( ) ;
434
+ let bytes_be =
435
+ expected_point. serialize ( PointFormat :: Uncompressed , Endianness :: LittleEndian ) ;
436
+
437
+ let result = ShortWeierstrassProjectivePoint :: deserialize (
438
+ & bytes_be,
439
+ PointFormat :: Uncompressed ,
440
+ Endianness :: LittleEndian ,
441
+ ) ;
442
+ assert_eq ! ( expected_point, result. unwrap( ) ) ;
443
+ }
444
+
445
+ #[ cfg( feature = "std" ) ]
446
+ #[ test]
447
+ fn byte_conversion_from_and_to_with_mixed_le_and_be_does_not_work_projective ( ) {
379
448
let bytes = point ( ) . serialize ( PointFormat :: Projective , Endianness :: LittleEndian ) ;
380
449
381
450
let result = ShortWeierstrassProjectivePoint :: < BLS12381Curve > :: deserialize (
@@ -392,7 +461,24 @@ mod tests {
392
461
393
462
#[ cfg( feature = "std" ) ]
394
463
#[ test]
395
- fn byte_conversion_from_and_to_with_mixed_be_and_le_does_not_work ( ) {
464
+ fn byte_conversion_from_and_to_with_mixed_le_and_be_does_not_work_uncompressed ( ) {
465
+ let bytes = point ( ) . serialize ( PointFormat :: Uncompressed , Endianness :: LittleEndian ) ;
466
+
467
+ let result = ShortWeierstrassProjectivePoint :: < BLS12381Curve > :: deserialize (
468
+ & bytes,
469
+ PointFormat :: Uncompressed ,
470
+ Endianness :: BigEndian ,
471
+ ) ;
472
+
473
+ assert_eq ! (
474
+ result. unwrap_err( ) ,
475
+ DeserializationError :: FieldFromBytesError
476
+ ) ;
477
+ }
478
+
479
+ #[ cfg( feature = "std" ) ]
480
+ #[ test]
481
+ fn byte_conversion_from_and_to_with_mixed_be_and_le_does_not_work_projective ( ) {
396
482
let bytes = point ( ) . serialize ( PointFormat :: Projective , Endianness :: BigEndian ) ;
397
483
398
484
let result = ShortWeierstrassProjectivePoint :: < BLS12381Curve > :: deserialize (
@@ -407,8 +493,25 @@ mod tests {
407
493
) ;
408
494
}
409
495
496
+ #[ cfg( feature = "std" ) ]
497
+ #[ test]
498
+ fn byte_conversion_from_and_to_with_mixed_be_and_le_does_not_work_uncompressed ( ) {
499
+ let bytes = point ( ) . serialize ( PointFormat :: Uncompressed , Endianness :: BigEndian ) ;
500
+
501
+ let result = ShortWeierstrassProjectivePoint :: < BLS12381Curve > :: deserialize (
502
+ & bytes,
503
+ PointFormat :: Uncompressed ,
504
+ Endianness :: LittleEndian ,
505
+ ) ;
506
+
507
+ assert_eq ! (
508
+ result. unwrap_err( ) ,
509
+ DeserializationError :: FieldFromBytesError
510
+ ) ;
511
+ }
512
+
410
513
#[ test]
411
- fn cannot_create_point_from_wrong_number_of_bytes_le ( ) {
514
+ fn cannot_create_point_from_wrong_number_of_bytes_le_projective ( ) {
412
515
let bytes = & [ 0_u8 ; 13 ] ;
413
516
414
517
let result = ShortWeierstrassProjectivePoint :: < BLS12381Curve > :: deserialize (
@@ -424,7 +527,23 @@ mod tests {
424
527
}
425
528
426
529
#[ test]
427
- fn cannot_create_point_from_wrong_number_of_bytes_be ( ) {
530
+ fn cannot_create_point_from_wrong_number_of_bytes_le_uncompressed ( ) {
531
+ let bytes = & [ 0_u8 ; 13 ] ;
532
+
533
+ let result = ShortWeierstrassProjectivePoint :: < BLS12381Curve > :: deserialize (
534
+ bytes,
535
+ PointFormat :: Uncompressed ,
536
+ Endianness :: LittleEndian ,
537
+ ) ;
538
+
539
+ assert_eq ! (
540
+ result. unwrap_err( ) ,
541
+ DeserializationError :: InvalidAmountOfBytes
542
+ ) ;
543
+ }
544
+
545
+ #[ test]
546
+ fn cannot_create_point_from_wrong_number_of_bytes_be_projective ( ) {
428
547
let bytes = & [ 0_u8 ; 13 ] ;
429
548
430
549
let result = ShortWeierstrassProjectivePoint :: < BLS12381Curve > :: deserialize (
@@ -438,4 +557,20 @@ mod tests {
438
557
DeserializationError :: InvalidAmountOfBytes
439
558
) ;
440
559
}
560
+
561
+ #[ test]
562
+ fn cannot_create_point_from_wrong_number_of_bytes_be_uncompressed ( ) {
563
+ let bytes = & [ 0_u8 ; 13 ] ;
564
+
565
+ let result = ShortWeierstrassProjectivePoint :: < BLS12381Curve > :: deserialize (
566
+ bytes,
567
+ PointFormat :: Uncompressed ,
568
+ Endianness :: BigEndian ,
569
+ ) ;
570
+
571
+ assert_eq ! (
572
+ result. unwrap_err( ) ,
573
+ DeserializationError :: InvalidAmountOfBytes
574
+ ) ;
575
+ }
441
576
}
0 commit comments