55
66//! Contains the keypair types that must be supplied for the OPAQUE API
77
8- use crate :: errors:: { utils:: check_slice_size, InternalPakeError } ;
9- use generic_array:: {
10- sequence:: Concat ,
11- typenum:: { Sum , Unsigned , U32 } ,
12- ArrayLength , GenericArray ,
13- } ;
8+ use crate :: errors:: InternalPakeError ;
9+ use generic_array:: { typenum:: U32 , GenericArray } ;
10+ use generic_bytes:: { SizedBytes , TryFromSizedBytesError } ;
11+ use generic_bytes_derive:: { SizedBytes , TryFromForSizedBytes } ;
1412#[ cfg( test) ]
1513use proptest:: prelude:: * ;
1614#[ cfg( test) ]
@@ -20,25 +18,18 @@ use std::convert::TryInto;
2018use std:: fmt:: Debug ;
2119use x25519_dalek:: { PublicKey , StaticSecret } ;
2220
23- use std:: convert :: TryFrom ;
21+ use std:: ops :: Deref ;
2422
25- use std:: ops:: { Add , Deref } ;
26-
27- /// A trait for sized key material that can be represented within a fixed byte
28- /// array size, used to represent our DH key types
29- pub trait SizedBytes : Sized + PartialEq {
30- /// The typed representation of the byte length
31- type Len : ArrayLength < u8 > ;
32-
33- /// Converts this sized key material to a `GenericArray` of the same
34- /// size. One can convert this to a `&[u8]` with `GenericArray::as_slice()`
35- /// but the size information is then lost from the type.
36- fn to_arr ( & self ) -> GenericArray < u8 , Self :: Len > ;
37-
38- /// How to parse such sized material from a byte slice.
39- fn from_bytes ( key_bytes : & [ u8 ] ) -> Result < Self , InternalPakeError > ;
23+ // Pub(crate) convenience extension trait of SizedBytes for our purposes
24+ pub ( crate ) trait SizedBytesExt : SizedBytes {
25+ fn from_bytes ( bytes : & [ u8 ] ) -> Result < Self , TryFromSizedBytesError > {
26+ <Self as SizedBytes >:: from_arr ( GenericArray :: from_slice ( bytes) )
27+ }
4028}
4129
30+ // blanket implementation
31+ impl < T > SizedBytesExt for T where T : SizedBytes { }
32+
4233/// A Keypair trait with public-private verification
4334pub trait KeyPair : Sized {
4435 /// The single key representation must have a specific byte size itself
@@ -92,62 +83,9 @@ trait KeyPairExt: KeyPair + Debug {
9283#[ cfg( test) ]
9384impl < KP > KeyPairExt for KP where KP : KeyPair + Debug { }
9485
95- /// This assumes you have defined a SizedBytes instance for a `T`, and defines:
96- /// - an `impl TryFrom<&[u8b], Error = InternalPakeError>` for a non-generic `T`
97- /// - an `fn to_bytes(&self) -> Vec<u8>` in an `impl T` block
98- ///
99- /// Because SizedBytes has a strong notion of size, and TryFrom/to_bytes does
100- /// not, it's better to use this macro than the one above, where possible.
101- macro_rules! try_from_and_to_bytes_using_sized_bytes {
102- ( $sized_type: ident) => {
103- impl TryFrom <& [ u8 ] > for $sized_type {
104- type Error = InternalPakeError ;
105-
106- fn try_from( bytes: & [ u8 ] ) -> Result <Self , InternalPakeError > {
107- <$sized_type as SizedBytes >:: from_bytes( bytes)
108- }
109- }
110-
111- #[ allow( dead_code) ]
112- impl $sized_type {
113- fn to_bytes( & self ) -> Vec <u8 > {
114- self . to_arr( ) . to_vec( )
115- }
116- }
117- } ;
118- }
119-
120- /// This is a blanket implementation of SizedBytes for any instance of KeyPair
121- /// with any length of keys. This encodes that we serialize the public key
122- /// first, followed by the private key in binary formats (and expect it in this
123- /// order upon decoding).
124- impl < T , KP > SizedBytes for KP
125- where
126- T : SizedBytes + Clone ,
127- KP : KeyPair < Repr = T > + PartialEq ,
128- T :: Len : Add < T :: Len > ,
129- Sum < T :: Len , T :: Len > : ArrayLength < u8 > ,
130- {
131- type Len = Sum < T :: Len , T :: Len > ;
132-
133- fn to_arr ( & self ) -> GenericArray < u8 , Self :: Len > {
134- let private = self . private ( ) . to_arr ( ) ;
135- let public = self . public ( ) . to_arr ( ) ;
136- public. concat ( private)
137- }
138-
139- fn from_bytes ( key_bytes : & [ u8 ] ) -> Result < Self , InternalPakeError > {
140- let checked_bytes =
141- check_slice_size ( key_bytes, <Self :: Len as Unsigned >:: to_usize ( ) , "key_bytes" ) ?;
142- let single_key_len = <<KP :: Repr as SizedBytes >:: Len as Unsigned >:: to_usize ( ) ;
143- let public = <T as SizedBytes >:: from_bytes ( & checked_bytes[ ..single_key_len] ) ?;
144- let private = <T as SizedBytes >:: from_bytes ( & checked_bytes[ single_key_len..] ) ?;
145- KP :: new ( public, private)
146- }
147- }
148-
14986/// A minimalist key type built around [u8;32]
150- #[ derive( Debug , PartialEq , Eq , Clone ) ]
87+ #[ derive( Debug , PartialEq , Eq , Clone , TryFromForSizedBytes ) ]
88+ #[ ErrorType = "::generic_bytes::TryFromSizedBytesError" ]
15189#[ repr( transparent) ]
15290pub struct Key ( Vec < u8 > ) ;
15391
@@ -166,17 +104,14 @@ impl SizedBytes for Key {
166104 GenericArray :: clone_from_slice ( & self . 0 [ ..] )
167105 }
168106
169- fn from_bytes ( key_bytes : & [ u8 ] ) -> Result < Self , InternalPakeError > {
170- let checked_bytes =
171- check_slice_size ( key_bytes, <Self :: Len as Unsigned >:: to_usize ( ) , "key_bytes" ) ?;
172- Ok ( Key ( checked_bytes. to_vec ( ) ) )
107+ fn from_arr ( key_bytes : & GenericArray < u8 , Self :: Len > ) -> Result < Self , TryFromSizedBytesError > {
108+ Ok ( Key ( key_bytes. to_vec ( ) ) )
173109 }
174110}
175111
176- try_from_and_to_bytes_using_sized_bytes ! ( Key ) ;
177-
178112/// A representation of an X25519 keypair according to RFC7748
179- #[ derive( Debug , PartialEq , Eq ) ]
113+ #[ derive( Debug , PartialEq , Eq , SizedBytes , TryFromForSizedBytes ) ]
114+ #[ ErrorType = "::generic_bytes::TryFromSizedBytesError" ]
180115pub struct X25519KeyPair {
181116 pk : Key ,
182117 sk : Key ,
0 commit comments