@@ -11,12 +11,12 @@ use core::{
11
11
cmp:: Ordering ,
12
12
fmt:: { self , Debug } ,
13
13
hash:: { Hash , Hasher } ,
14
- ops:: Add ,
14
+ ops:: { Add , Sub } ,
15
15
str,
16
16
} ;
17
- use generic_array :: {
17
+ use hybrid_array :: {
18
18
typenum:: { U1 , U24 , U28 , U32 , U48 , U66 } ,
19
- ArrayLength , GenericArray ,
19
+ Array , ArraySize ,
20
20
} ;
21
21
22
22
#[ cfg( feature = "alloc" ) ]
@@ -31,23 +31,31 @@ use subtle::{Choice, ConditionallySelectable};
31
31
#[ cfg( feature = "zeroize" ) ]
32
32
use zeroize:: Zeroize ;
33
33
34
- /// Trait for supported modulus sizes which precomputes the typenums for
35
- /// various point encodings so they don't need to be included as bounds.
34
+ /// Trait for supported modulus sizes which precomputes the typenums for various point encodings so
35
+ /// they don't need to be included as bounds.
36
36
// TODO(tarcieri): replace this all with const generic expressions.
37
- pub trait ModulusSize : ' static + ArrayLength < u8 > + Copy + Debug {
38
- /// Size of a compressed point for the given elliptic curve when encoded
39
- /// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm
40
- /// (including leading `0x02` or `0x03` tag byte).
41
- type CompressedPointSize : ' static + ArrayLength < u8 > + Copy + Debug ;
42
-
43
- /// Size of an uncompressed point for the given elliptic curve when encoded
44
- /// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm
45
- /// (including leading `0x04` tag byte).
46
- type UncompressedPointSize : ' static + ArrayLength < u8 > + Copy + Debug ;
47
-
48
- /// Size of an untagged point for given elliptic curve, i.e. size of two
49
- /// serialized base field elements.
50
- type UntaggedPointSize : ' static + ArrayLength < u8 > + Copy + Debug ;
37
+ pub trait ModulusSize : ' static + ArraySize + Copy + Debug {
38
+ /// Size of a compressed point for the given elliptic curve when encoded using the SEC1
39
+ /// `Elliptic-Curve-Point-to-Octet-String` algorithm (including leading `0x02` or `0x03`
40
+ /// tag byte).
41
+ type CompressedPointSize : ' static
42
+ + ArraySize
43
+ + Copy
44
+ + Debug
45
+ + Add < Self , Output = Self :: UncompressedPointSize > ;
46
+
47
+ /// Size of an uncompressed point for the given elliptic curve when encoded using the SEC1
48
+ /// `Elliptic-Curve-Point-to-Octet-String` algorithm (including leading `0x04` tag byte).
49
+ type UncompressedPointSize : ' static + ArraySize + Copy + Debug ;
50
+
51
+ /// Size of an untagged point for given elliptic curve, i.e. size of two serialized base field
52
+ /// elements when concatenated.
53
+ type UntaggedPointSize : ' static
54
+ + ArraySize
55
+ + Copy
56
+ + Debug
57
+ + Add < U1 , Output = Self :: UncompressedPointSize >
58
+ + Sub < Self , Output = Self > ;
51
59
}
52
60
53
61
macro_rules! impl_modulus_size {
@@ -60,6 +68,7 @@ macro_rules! impl_modulus_size {
60
68
}
61
69
}
62
70
71
+ // Support for 192-bit, 224-bit, 256-bit, 384-bit, and 521-bit modulus sizes
63
72
impl_modulus_size ! ( U24 , U28 , U32 , U48 , U66 ) ;
64
73
65
74
/// SEC1 encoded curve point.
@@ -72,7 +81,7 @@ pub struct EncodedPoint<Size>
72
81
where
73
82
Size : ModulusSize ,
74
83
{
75
- bytes : GenericArray < u8 , Size :: UncompressedPointSize > ,
84
+ bytes : Array < u8 , Size :: UncompressedPointSize > ,
76
85
}
77
86
78
87
#[ allow( clippy:: len_without_is_empty) ]
@@ -103,24 +112,24 @@ where
103
112
return Err ( Error :: PointEncoding ) ;
104
113
}
105
114
106
- let mut bytes = GenericArray :: default ( ) ;
115
+ let mut bytes = Array :: default ( ) ;
107
116
bytes[ ..expected_len] . copy_from_slice ( input) ;
108
117
Ok ( Self { bytes } )
109
118
}
110
119
111
120
/// Decode elliptic curve point from raw uncompressed coordinates, i.e.
112
121
/// encoded as the concatenated `x || y` coordinates with no leading SEC1
113
122
/// tag byte (which would otherwise be `0x04` for an uncompressed point).
114
- pub fn from_untagged_bytes ( bytes : & GenericArray < u8 , Size :: UntaggedPointSize > ) -> Self {
115
- let ( x, y) = bytes. split_at ( Size :: to_usize ( ) ) ;
116
- Self :: from_affine_coordinates ( x. into ( ) , y. into ( ) , false )
123
+ pub fn from_untagged_bytes ( bytes : & Array < u8 , Size :: UntaggedPointSize > ) -> Self {
124
+ let ( x, y) = bytes. split_ref ( ) ;
125
+ Self :: from_affine_coordinates ( x, y, false )
117
126
}
118
127
119
128
/// Encode an elliptic curve point from big endian serialized coordinates
120
129
/// (with optional point compression)
121
130
pub fn from_affine_coordinates (
122
- x : & GenericArray < u8 , Size > ,
123
- y : & GenericArray < u8 , Size > ,
131
+ x : & Array < u8 , Size > ,
132
+ y : & Array < u8 , Size > ,
124
133
compress : bool ,
125
134
) -> Self {
126
135
let tag = if compress {
@@ -129,7 +138,7 @@ where
129
138
Tag :: Uncompressed
130
139
} ;
131
140
132
- let mut bytes = GenericArray :: default ( ) ;
141
+ let mut bytes = Array :: default ( ) ;
133
142
bytes[ 0 ] = tag. into ( ) ;
134
143
bytes[ 1 ..( Size :: to_usize ( ) + 1 ) ] . copy_from_slice ( x) ;
135
144
@@ -200,27 +209,28 @@ where
200
209
return Coordinates :: Identity ;
201
210
}
202
211
203
- let ( x, y) = self . bytes [ 1 ..] . split_at ( Size :: to_usize ( ) ) ;
212
+ let ( x_bytes, y_bytes) = self . bytes [ 1 ..] . split_at ( Size :: to_usize ( ) ) ;
213
+ let x = Array :: ref_from_slice ( x_bytes) ;
204
214
205
215
if self . is_compressed ( ) {
206
216
Coordinates :: Compressed {
207
- x : x . into ( ) ,
217
+ x,
208
218
y_is_odd : self . tag ( ) as u8 & 1 == 1 ,
209
219
}
210
220
} else if self . is_compact ( ) {
211
- Coordinates :: Compact { x : x . into ( ) }
221
+ Coordinates :: Compact { x }
212
222
} else {
213
223
Coordinates :: Uncompressed {
214
- x : x . into ( ) ,
215
- y : y . into ( ) ,
224
+ x,
225
+ y : Array :: ref_from_slice ( y_bytes ) ,
216
226
}
217
227
}
218
228
}
219
229
220
230
/// Get the x-coordinate for this [`EncodedPoint`].
221
231
///
222
232
/// Returns `None` if this point is the identity point.
223
- pub fn x ( & self ) -> Option < & GenericArray < u8 , Size > > {
233
+ pub fn x ( & self ) -> Option < & Array < u8 , Size > > {
224
234
match self . coordinates ( ) {
225
235
Coordinates :: Identity => None ,
226
236
Coordinates :: Compressed { x, .. } => Some ( x) ,
@@ -232,7 +242,7 @@ where
232
242
/// Get the y-coordinate for this [`EncodedPoint`].
233
243
///
234
244
/// Returns `None` if this point is compressed or the identity point.
235
- pub fn y ( & self ) -> Option < & GenericArray < u8 , Size > > {
245
+ pub fn y ( & self ) -> Option < & Array < u8 , Size > > {
236
246
match self . coordinates ( ) {
237
247
Coordinates :: Compressed { .. } | Coordinates :: Identity => None ,
238
248
Coordinates :: Uncompressed { y, .. } => Some ( y) ,
@@ -255,10 +265,10 @@ where
255
265
impl < Size > ConditionallySelectable for EncodedPoint < Size >
256
266
where
257
267
Size : ModulusSize ,
258
- <Size :: UncompressedPointSize as ArrayLength < u8 > > :: ArrayType : Copy ,
268
+ <Size :: UncompressedPointSize as ArraySize > :: ArrayType < u8 > : Copy ,
259
269
{
260
270
fn conditional_select ( a : & Self , b : & Self , choice : Choice ) -> Self {
261
- let mut bytes = GenericArray :: default ( ) ;
271
+ let mut bytes = Array :: default ( ) ;
262
272
263
273
for ( i, byte) in bytes. iter_mut ( ) . enumerate ( ) {
264
274
* byte = u8:: conditional_select ( & a. bytes [ i] , & b. bytes [ i] , choice) ;
@@ -271,7 +281,7 @@ where
271
281
impl < Size > Copy for EncodedPoint < Size >
272
282
where
273
283
Size : ModulusSize ,
274
- <Size :: UncompressedPointSize as ArrayLength < u8 > > :: ArrayType : Copy ,
284
+ <Size :: UncompressedPointSize as ArraySize > :: ArrayType < u8 > : Copy ,
275
285
{
276
286
}
277
287
@@ -382,7 +392,7 @@ where
382
392
type Err = Error ;
383
393
384
394
fn from_str ( hex : & str ) -> Result < Self > {
385
- let mut buf = GenericArray :: < u8 , Size :: UncompressedPointSize > :: default ( ) ;
395
+ let mut buf = Array :: < u8 , Size :: UncompressedPointSize > :: default ( ) ;
386
396
base16ct:: mixed:: decode ( hex, & mut buf)
387
397
. map_err ( |_| Error :: PointEncoding )
388
398
. and_then ( Self :: from_bytes)
@@ -426,13 +436,13 @@ pub enum Coordinates<'a, Size: ModulusSize> {
426
436
/// Compact curve point
427
437
Compact {
428
438
/// x-coordinate
429
- x : & ' a GenericArray < u8 , Size > ,
439
+ x : & ' a Array < u8 , Size > ,
430
440
} ,
431
441
432
442
/// Compressed curve point
433
443
Compressed {
434
444
/// x-coordinate
435
- x : & ' a GenericArray < u8 , Size > ,
445
+ x : & ' a Array < u8 , Size > ,
436
446
437
447
/// Is the y-coordinate odd?
438
448
y_is_odd : bool ,
@@ -441,10 +451,10 @@ pub enum Coordinates<'a, Size: ModulusSize> {
441
451
/// Uncompressed curve point
442
452
Uncompressed {
443
453
/// x-coordinate
444
- x : & ' a GenericArray < u8 , Size > ,
454
+ x : & ' a Array < u8 , Size > ,
445
455
446
456
/// y-coordinate
447
- y : & ' a GenericArray < u8 , Size > ,
457
+ y : & ' a Array < u8 , Size > ,
448
458
} ,
449
459
}
450
460
@@ -556,8 +566,8 @@ impl From<Tag> for u8 {
556
566
mod tests {
557
567
use super :: { Coordinates , Tag } ;
558
568
use core:: str:: FromStr ;
559
- use generic_array:: { typenum:: U32 , GenericArray } ;
560
569
use hex_literal:: hex;
570
+ use hybrid_array:: typenum:: U32 ;
561
571
562
572
#[ cfg( feature = "alloc" ) ]
563
573
use alloc:: string:: ToString ;
@@ -600,7 +610,7 @@ mod tests {
600
610
601
611
assert_eq ! (
602
612
compressed_even_y. x( ) . unwrap( ) ,
603
- & hex!( "0100000000000000000000000000000000000000000000000000000000000000" ) . into ( )
613
+ & hex!( "0100000000000000000000000000000000000000000000000000000000000000" )
604
614
) ;
605
615
assert_eq ! ( compressed_even_y. y( ) , None ) ;
606
616
@@ -625,7 +635,7 @@ mod tests {
625
635
626
636
assert_eq ! (
627
637
compressed_odd_y. x( ) . unwrap( ) ,
628
- & hex!( "0200000000000000000000000000000000000000000000000000000000000000" ) . into ( )
638
+ & hex!( "0200000000000000000000000000000000000000000000000000000000000000" )
629
639
) ;
630
640
assert_eq ! ( compressed_odd_y. y( ) , None ) ;
631
641
}
@@ -649,11 +659,11 @@ mod tests {
649
659
650
660
assert_eq ! (
651
661
uncompressed_point. x( ) . unwrap( ) ,
652
- & hex!( "1111111111111111111111111111111111111111111111111111111111111111" ) . into ( )
662
+ & hex!( "1111111111111111111111111111111111111111111111111111111111111111" )
653
663
) ;
654
664
assert_eq ! (
655
665
uncompressed_point. y( ) . unwrap( ) ,
656
- & hex!( "2222222222222222222222222222222222222222222222222222222222222222" ) . into ( )
666
+ & hex!( "2222222222222222222222222222222222222222222222222222222222222222" )
657
667
) ;
658
668
}
659
669
@@ -701,8 +711,7 @@ mod tests {
701
711
#[ test]
702
712
fn from_untagged_point ( ) {
703
713
let untagged_bytes = hex ! ( "11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222" ) ;
704
- let uncompressed_point =
705
- EncodedPoint :: from_untagged_bytes ( GenericArray :: from_slice ( & untagged_bytes[ ..] ) ) ;
714
+ let uncompressed_point = EncodedPoint :: from_untagged_bytes ( & untagged_bytes. into ( ) ) ;
706
715
assert_eq ! ( uncompressed_point. as_bytes( ) , & UNCOMPRESSED_BYTES [ ..] ) ;
707
716
}
708
717
0 commit comments