33use crate :: { DecapsulationKey , EncapsulationKey } ;
44use core:: marker:: PhantomData ;
55use elliptic_curve:: {
6- AffinePoint , CurveArithmetic , Error , FieldBytesSize , PublicKey ,
6+ AffinePoint , CurveArithmetic , Error , FieldBytes , FieldBytesSize , PublicKey , SecretKey ,
77 ecdh:: EphemeralSecret ,
88 sec1:: {
99 FromEncodedPoint , ModulusSize , ToEncodedPoint , UncompressedPoint , UncompressedPointSize ,
@@ -15,16 +15,6 @@ use kem::{
1515} ;
1616use rand_core:: { CryptoRng , TryCryptoRng } ;
1717
18- /// Elliptic Curve Diffie-Hellman Decapsulation Key (i.e. secret decryption key)
19- ///
20- /// Generic around an elliptic curve `C`.
21- pub type EcdhDecapsulationKey < C > = DecapsulationKey < EphemeralSecret < C > , PublicKey < C > > ;
22-
23- /// Elliptic Curve Diffie-Hellman Encapsulation Key (i.e. public encryption key)
24- ///
25- /// Generic around an elliptic curve `C`.
26- pub type EcdhEncapsulationKey < C > = EncapsulationKey < PublicKey < C > > ;
27-
2818/// Generic Elliptic Curve Diffie-Hellman KEM adapter compatible with curves implemented using
2919/// traits from the `elliptic-curve` crate.
3020///
@@ -45,13 +35,94 @@ where
4535 type SharedKeySize = FieldBytesSize < C > ;
4636}
4737
38+ /// Elliptic Curve Diffie-Hellman Decapsulation Key (i.e. secret decryption key)
39+ ///
40+ /// Generic around an elliptic curve `C`.
41+ pub type EcdhDecapsulationKey < C > = DecapsulationKey < SecretKey < C > , PublicKey < C > > ;
42+
43+ impl < C > KeySizeUser for EcdhDecapsulationKey < C >
44+ where
45+ C : CurveArithmetic ,
46+ {
47+ type KeySize = FieldBytesSize < C > ;
48+ }
49+
50+ /// From [RFC9810 §7.1.2]: `SerializePrivateKey` and `DeserializePrivateKey`:
51+ ///
52+ /// > DeserializePrivateKey() performs the Octet-String-to-Field-Element conversion
53+ /// > according to [SECG].
54+ ///
55+ /// [RFC9810 §7.1.2]: https://datatracker.ietf.org/doc/html/rfc9180#section-7.1.2
56+ /// [SECG]: https://www.secg.org/sec1-v2.pdf
57+ impl < C > TryKeyInit for EcdhDecapsulationKey < C >
58+ where
59+ C : CurveArithmetic ,
60+ {
61+ fn new ( key : & FieldBytes < C > ) -> Result < Self , InvalidKey > {
62+ SecretKey :: from_bytes ( key)
63+ . map ( Into :: into)
64+ . map_err ( |_| InvalidKey )
65+ }
66+ }
67+
68+ /// From [RFC9810 §7.1.2]: `SerializePrivateKey` and `DeserializePrivateKey`:
69+ ///
70+ /// > the SerializePrivateKey() function of the KEM performs the Field-Element-to-Octet-String
71+ /// > conversion according to [SECG]. If the private key is an integer outside the range
72+ /// > `[0, order-1]`, where order is the order of the curve being used, the private key MUST be
73+ /// > reduced to its representative in `[0, order-1]` before being serialized.
74+ ///
75+ /// [RFC9810 §7.1.2]: https://datatracker.ietf.org/doc/html/rfc9180#section-7.1.2
76+ /// [SECG]: https://www.secg.org/sec1-v2.pdf
77+ impl < C > KeyExport for EcdhDecapsulationKey < C >
78+ where
79+ C : CurveArithmetic ,
80+ {
81+ fn to_bytes ( & self ) -> FieldBytes < C > {
82+ self . dk . to_bytes ( )
83+ }
84+ }
85+
86+ impl < C > Generate for EcdhDecapsulationKey < C >
87+ where
88+ C : CurveArithmetic ,
89+ FieldBytesSize < C > : ModulusSize ,
90+ {
91+ fn try_generate_from_rng < R : TryCryptoRng + ?Sized > ( rng : & mut R ) -> Result < Self , R :: Error > {
92+ Ok ( SecretKey :: try_generate_from_rng ( rng) ?. into ( ) )
93+ }
94+ }
95+
96+ impl < C > TryDecapsulate < EcdhKem < C > > for EcdhDecapsulationKey < C >
97+ where
98+ C : CurveArithmetic ,
99+ FieldBytesSize < C > : ModulusSize ,
100+ AffinePoint < C > : FromEncodedPoint < C > + ToEncodedPoint < C > ,
101+ {
102+ type Error = Error ;
103+
104+ fn try_decapsulate (
105+ & self ,
106+ encapsulated_key : & Ciphertext < EcdhKem < C > > ,
107+ ) -> Result < SharedKey < EcdhKem < C > > , Error > {
108+ let encapsulated_key = PublicKey :: < C > :: from_sec1_bytes ( encapsulated_key) ?;
109+ let shared_secret = self . dk . diffie_hellman ( & encapsulated_key) ;
110+ Ok ( shared_secret. raw_secret_bytes ( ) . clone ( ) )
111+ }
112+ }
113+
114+ /// Elliptic Curve Diffie-Hellman Encapsulation Key (i.e. public encryption key)
115+ ///
116+ /// Generic around an elliptic curve `C`.
117+ pub type EcdhEncapsulationKey < C > = EncapsulationKey < PublicKey < C > > ;
118+
48119/// From [RFC9810 §7.1.1]: `SerializePublicKey` and `DeserializePublicKey`:
49120///
50121/// > For P-256, P-384, and P-521, the SerializePublicKey() function of the
51122/// > KEM performs the uncompressed Elliptic-Curve-Point-to-Octet-String
52123/// > conversion according to [SECG].
53124///
54- /// [RFC9810 §7.1.1]: https://datatracker.ietf.org/doc/html/rfc9180#name-serializepublickey-and-dese
125+ /// [RFC9810 §7.1.1]: https://datatracker.ietf.org/doc/html/rfc9180#section-7.1.1
55126/// [SECG]: https://www.secg.org/sec1-v2.pdf
56127impl < C > KeySizeUser for EcdhEncapsulationKey < C >
57128where
66137/// > DeserializePublicKey() performs the uncompressed
67138/// > Octet-String-to-Elliptic-Curve-Point conversion.
68139///
69- /// [RFC9810 §7.1.1]: https://datatracker.ietf.org/doc/html/rfc9180#name-serializepublickey-and-dese
140+ /// [RFC9810 §7.1.1]: https://datatracker.ietf.org/doc/html/rfc9180#section-7.1.1
70141impl < C > TryKeyInit for EcdhEncapsulationKey < C >
71142where
72143 C : CurveArithmetic ,
86157/// > KEM performs the uncompressed Elliptic-Curve-Point-to-Octet-String
87158/// > conversion according to [SECG].
88159///
89- /// [RFC9810 §7.1.1]: https://datatracker.ietf.org/doc/html/rfc9180#name-serializepublickey-and-dese
160+ /// [RFC9810 §7.1.1]: https://datatracker.ietf.org/doc/html/rfc9180#section-7.1.1
90161/// [SECG]: https://www.secg.org/sec1-v2.pdf
91162impl < C > KeyExport for EcdhEncapsulationKey < C >
92163where
@@ -95,20 +166,7 @@ where
95166 AffinePoint < C > : FromEncodedPoint < C > + ToEncodedPoint < C > ,
96167{
97168 fn to_bytes ( & self ) -> UncompressedPoint < C > {
98- // TODO(tarcieri): self.0.to_uncompressed_point()
99- let mut ret = UncompressedPoint :: < C > :: default ( ) ;
100- ret. copy_from_slice ( self . to_encoded_point ( false ) . as_bytes ( ) ) ;
101- ret
102- }
103- }
104-
105- impl < C > Generate for EcdhDecapsulationKey < C >
106- where
107- C : CurveArithmetic ,
108- FieldBytesSize < C > : ModulusSize ,
109- {
110- fn try_generate_from_rng < R : TryCryptoRng + ?Sized > ( rng : & mut R ) -> Result < Self , R :: Error > {
111- Ok ( EphemeralSecret :: try_generate_from_rng ( rng) ?. into ( ) )
169+ self . 0 . to_uncompressed_point ( )
112170 }
113171}
114172
@@ -133,21 +191,3 @@ where
133191 ( pk, ss. raw_secret_bytes ( ) . clone ( ) )
134192 }
135193}
136-
137- impl < C > TryDecapsulate < EcdhKem < C > > for EcdhDecapsulationKey < C >
138- where
139- C : CurveArithmetic ,
140- FieldBytesSize < C > : ModulusSize ,
141- AffinePoint < C > : FromEncodedPoint < C > + ToEncodedPoint < C > ,
142- {
143- type Error = Error ;
144-
145- fn try_decapsulate (
146- & self ,
147- encapsulated_key : & Ciphertext < EcdhKem < C > > ,
148- ) -> Result < SharedKey < EcdhKem < C > > , Error > {
149- let encapsulated_key = PublicKey :: < C > :: from_sec1_bytes ( encapsulated_key) ?;
150- let shared_secret = self . dk . diffie_hellman ( & encapsulated_key) ;
151- Ok ( shared_secret. raw_secret_bytes ( ) . clone ( ) )
152- }
153- }
0 commit comments