blob: fd7b531d0ba212a0c4c7e62c33cae8c920cb3877 [file] [log] [blame]
Better Together Rust Devsf6f0ac82023-03-27 15:28:41 -07001// Copyright 2023 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Better Together Rust Devse0af43b2023-11-07 16:49:36 -080015use tinyvec::ArrayVec;
Better Together Rust Devsf6f0ac82023-03-27 15:28:41 -070016
17use crate::elliptic_curve::{Curve, EcdhProvider, PublicKey};
Better Together Rust Devsf6f0ac82023-03-27 15:28:41 -070018use core::fmt::Debug;
19
20/// Marker type for P256 implementation. This is used by EcdhProvider as its type parameter.
21#[derive(Debug, PartialEq, Eq)]
22pub enum P256 {}
23impl Curve for P256 {}
24
Better Together Rust Devse0af43b2023-11-07 16:49:36 -080025/// Longest length for a sec-1 encoded P256 public key, which is the uncompressed format
26/// `04 || X || Y` as defined in section 2.3.3 of the SECG SEC 1 ("Elliptic Curve Cryptography")
27/// standard.
28const P256_PUBLIC_KEY_MAX_LENGTH: usize = 65;
29
30/// Whether an elliptic curve point should be compressed or not.
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32pub enum PointCompression {
33 /// The elliptic curve point should be compressed (`02 || X` or `03 || X`),
34 /// as defined in section 2.3.3 of the SECG SEC 1 ("Elliptic Curve
35 /// Cryptography").
36 Compressed,
37 /// The elliptic curve point should be uncompressed (`04 || X || Y`), as
38 /// defined in section 2.3.3 of the SECG SEC 1 ("Elliptic Curve
39 /// Cryptography").
40 Uncompressed,
41}
42
Better Together Rust Devsf6f0ac82023-03-27 15:28:41 -070043/// Trait for a NIST-P256 public key.
44pub trait P256PublicKey: Sized + PartialEq + Debug {
45 /// The error type associated with this implementation.
46 type Error: Debug;
47
48 /// Creates a public key from the given sec1-encoded bytes, as described in section 2.3.4 of
49 /// the SECG SEC 1 ("Elliptic Curve Cryptography") standard.
50 fn from_sec1_bytes(bytes: &[u8]) -> Result<Self, Self::Error>;
51
52 /// Serializes this key into sec1-encoded bytes, as described in section 2.3.3 of the SECG SEC 1
53 /// ("Elliptic Curve Cryptography") standard. Note that it is not necessarily true that
54 /// `from_sec1_bytes(bytes)?.to_sec1_bytes() == bytes` because of point compression. (But it is
55 /// always true that `from_sec1_bytes(key.to_sec1_bytes())? == key`).
Better Together Rust Devse0af43b2023-11-07 16:49:36 -080056 fn to_sec1_bytes(
57 &self,
58 point_compression: PointCompression,
59 ) -> ArrayVec<[u8; P256_PUBLIC_KEY_MAX_LENGTH]>;
Better Together Rust Devsf6f0ac82023-03-27 15:28:41 -070060
61 /// Converts this public key's x and y coordinates on the elliptic curve to big endian octet
62 /// strings.
63 fn to_affine_coordinates(&self) -> Result<([u8; 32], [u8; 32]), Self::Error>;
64
65 /// Creates a public key from the X and Y coordinates on the elliptic curve.
66 fn from_affine_coordinates(x: &[u8; 32], y: &[u8; 32]) -> Result<Self, Self::Error>;
67}
68
69impl<P: P256PublicKey> PublicKey<P256> for P {
70 type Error = <Self as P256PublicKey>::Error;
Better Together Rust Devse0af43b2023-11-07 16:49:36 -080071 type EncodedPublicKey = ArrayVec<[u8; P256_PUBLIC_KEY_MAX_LENGTH]>;
Better Together Rust Devsf6f0ac82023-03-27 15:28:41 -070072
73 fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Error> {
74 Self::from_sec1_bytes(bytes)
75 }
76
Better Together Rust Devse0af43b2023-11-07 16:49:36 -080077 fn to_bytes(&self) -> Self::EncodedPublicKey {
78 Self::to_sec1_bytes(self, PointCompression::Uncompressed)
Better Together Rust Devsf6f0ac82023-03-27 15:28:41 -070079 }
80}
81
82/// Equivalent to EcdhProvider<P256, PublicKey: P256PublicKey> if associated type bounds are
83/// supported.
84pub trait P256EcdhProvider:
85 EcdhProvider<P256, PublicKey = <Self as P256EcdhProvider>::PublicKey>
86{
87 /// Same as EcdhProvider::PublicKey.
88 type PublicKey: P256PublicKey;
89}
90
91impl<E> P256EcdhProvider for E
92where
93 E: EcdhProvider<P256>,
94 E::PublicKey: P256PublicKey,
95{
96 type PublicKey = E::PublicKey;
97}