summaryrefslogtreecommitdiffstats
path: root/vendor/elliptic-curve/src/secret_key.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /vendor/elliptic-curve/src/secret_key.rs
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/elliptic-curve/src/secret_key.rs')
-rw-r--r--vendor/elliptic-curve/src/secret_key.rs150
1 files changed, 76 insertions, 74 deletions
diff --git a/vendor/elliptic-curve/src/secret_key.rs b/vendor/elliptic-curve/src/secret_key.rs
index 0fc3dafb1..97b3d58bd 100644
--- a/vendor/elliptic-curve/src/secret_key.rs
+++ b/vendor/elliptic-curve/src/secret_key.rs
@@ -8,10 +8,9 @@
#[cfg(all(feature = "pkcs8", feature = "sec1"))]
mod pkcs8;
-use crate::{Curve, Error, FieldBytes, Result, ScalarCore};
+use crate::{Curve, Error, FieldBytes, Result, ScalarPrimitive};
use core::fmt::{self, Debug};
-use crypto_bigint::Encoding;
-use generic_array::GenericArray;
+use generic_array::typenum::Unsigned;
use subtle::{Choice, ConstantTimeEq};
use zeroize::{Zeroize, ZeroizeOnDrop};
@@ -22,19 +21,21 @@ use {
AffinePoint,
},
alloc::vec::Vec,
- der::Encode,
zeroize::Zeroizing,
};
#[cfg(feature = "arithmetic")]
-use crate::{
- rand_core::{CryptoRng, RngCore},
- NonZeroScalar, ProjectiveArithmetic, PublicKey,
-};
+use crate::{rand_core::CryptoRngCore, CurveArithmetic, NonZeroScalar, PublicKey};
#[cfg(feature = "jwk")]
use crate::jwk::{JwkEcKey, JwkParameters};
+#[cfg(feature = "sec1")]
+use sec1::der;
+
+#[cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1"))]
+use sec1::der::Encode;
+
#[cfg(all(feature = "arithmetic", any(feature = "jwk", feature = "pem")))]
use alloc::string::String;
@@ -47,10 +48,10 @@ use pem_rfc7468 as pem;
#[cfg(feature = "sec1")]
use crate::{
sec1::{EncodedPoint, ModulusSize, ValidatePublicKey},
- FieldSize,
+ FieldBytesSize,
};
-#[cfg(all(docsrs, feature = "pkcs8"))]
+#[cfg(all(doc, feature = "pkcs8"))]
use {crate::pkcs8::DecodePrivateKey, core::str::FromStr};
/// Type label for PEM-encoded SEC1 private keys.
@@ -83,7 +84,7 @@ pub(crate) const SEC1_PEM_TYPE_LABEL: &str = "EC PRIVATE KEY";
#[derive(Clone)]
pub struct SecretKey<C: Curve> {
/// Scalar value
- inner: ScalarCore<C>,
+ inner: ScalarPrimitive<C>,
}
impl<C> SecretKey<C>
@@ -92,10 +93,9 @@ where
{
/// Generate a random [`SecretKey`].
#[cfg(feature = "arithmetic")]
- #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
- pub fn random(rng: impl CryptoRng + RngCore) -> Self
+ pub fn random(rng: &mut impl CryptoRngCore) -> Self
where
- C: ProjectiveArithmetic,
+ C: CurveArithmetic,
{
Self {
inner: NonZeroScalar::<C>::random(rng).into(),
@@ -103,18 +103,18 @@ where
}
/// Create a new secret key from a scalar value.
- pub fn new(scalar: ScalarCore<C>) -> Self {
+ pub fn new(scalar: ScalarPrimitive<C>) -> Self {
Self { inner: scalar }
}
- /// Borrow the inner secret [`ScalarCore`] value.
+ /// Borrow the inner secret [`ScalarPrimitive`] value.
///
/// # ⚠️ Warning
///
/// This value is key material.
///
/// Please treat it with the care it deserves!
- pub fn as_scalar_core(&self) -> &ScalarCore<C> {
+ pub fn as_scalar_primitive(&self) -> &ScalarPrimitive<C> {
&self.inner
}
@@ -126,54 +126,75 @@ where
///
/// Please treat it with the care it deserves!
#[cfg(feature = "arithmetic")]
- #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
pub fn to_nonzero_scalar(&self) -> NonZeroScalar<C>
where
- C: Curve + ProjectiveArithmetic,
+ C: CurveArithmetic,
{
self.into()
}
/// Get the [`PublicKey`] which corresponds to this secret key
#[cfg(feature = "arithmetic")]
- #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
pub fn public_key(&self) -> PublicKey<C>
where
- C: Curve + ProjectiveArithmetic,
+ C: CurveArithmetic,
{
PublicKey::from_secret_scalar(&self.to_nonzero_scalar())
}
- /// Deserialize raw secret scalar as a big endian integer.
- pub fn from_be_bytes(bytes: &[u8]) -> Result<Self> {
- if bytes.len() != C::UInt::BYTE_SIZE {
+ /// Deserialize secret key from an encoded secret scalar.
+ pub fn from_bytes(bytes: &FieldBytes<C>) -> Result<Self> {
+ let inner: ScalarPrimitive<C> =
+ Option::from(ScalarPrimitive::from_bytes(bytes)).ok_or(Error)?;
+
+ if inner.is_zero().into() {
return Err(Error);
}
- let inner: ScalarCore<C> = Option::from(ScalarCore::from_be_bytes(
- GenericArray::clone_from_slice(bytes),
- ))
- .ok_or(Error)?;
+ Ok(Self { inner })
+ }
- if inner.is_zero().into() {
+ /// Deserialize secret key from an encoded secret scalar passed as a
+ /// byte slice.
+ ///
+ /// The slice is expected to be at most `C::FieldBytesSize` bytes in
+ /// length but may be up to 4-bytes shorter than that, which is handled by
+ /// zero-padding the value.
+ pub fn from_slice(slice: &[u8]) -> Result<Self> {
+ if slice.len() > C::FieldBytesSize::USIZE {
return Err(Error);
}
- Ok(Self { inner })
+ /// Maximum number of "missing" bytes to interpret as zeroes.
+ const MAX_LEADING_ZEROES: usize = 4;
+
+ let offset = C::FieldBytesSize::USIZE.saturating_sub(slice.len());
+
+ if offset == 0 {
+ Self::from_bytes(FieldBytes::<C>::from_slice(slice))
+ } else if offset <= MAX_LEADING_ZEROES {
+ let mut bytes = FieldBytes::<C>::default();
+ bytes[offset..].copy_from_slice(slice);
+
+ let ret = Self::from_bytes(&bytes);
+ bytes.zeroize();
+ ret
+ } else {
+ Err(Error)
+ }
}
/// Serialize raw secret scalar as a big endian integer.
- pub fn to_be_bytes(&self) -> FieldBytes<C> {
- self.inner.to_be_bytes()
+ pub fn to_bytes(&self) -> FieldBytes<C> {
+ self.inner.to_bytes()
}
/// Deserialize secret key encoded in the SEC1 ASN.1 DER `ECPrivateKey` format.
#[cfg(all(feature = "sec1"))]
- #[cfg_attr(docsrs, doc(cfg(feature = "sec1")))]
pub fn from_sec1_der(der_bytes: &[u8]) -> Result<Self>
where
C: Curve + ValidatePublicKey,
- FieldSize<C>: ModulusSize,
+ FieldBytesSize<C>: ModulusSize,
{
sec1::EcPrivateKey::try_from(der_bytes)?
.try_into()
@@ -182,18 +203,13 @@ where
/// Serialize secret key in the SEC1 ASN.1 DER `ECPrivateKey` format.
#[cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1"))]
- #[cfg_attr(
- docsrs,
- doc(cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1")))
- )]
pub fn to_sec1_der(&self) -> der::Result<Zeroizing<Vec<u8>>>
where
- C: Curve + ProjectiveArithmetic,
+ C: CurveArithmetic,
AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
- FieldSize<C>: ModulusSize,
+ FieldBytesSize<C>: ModulusSize,
{
- // TODO(tarcieri): wrap `secret_key_bytes` in `Zeroizing`
- let mut private_key_bytes = self.to_be_bytes();
+ let private_key_bytes = Zeroizing::new(self.to_bytes());
let public_key_bytes = self.public_key().to_encoded_point(false);
let ec_private_key = Zeroizing::new(
@@ -202,12 +218,9 @@ where
parameters: None,
public_key: Some(public_key_bytes.as_bytes()),
}
- .to_vec()?,
+ .to_der()?,
);
- // TODO(tarcieri): wrap `private_key_bytes` in `Zeroizing`
- private_key_bytes.zeroize();
-
Ok(ec_private_key)
}
@@ -219,11 +232,10 @@ where
/// -----BEGIN EC PRIVATE KEY-----
/// ```
#[cfg(feature = "pem")]
- #[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
pub fn from_sec1_pem(s: &str) -> Result<Self>
where
C: Curve + ValidatePublicKey,
- FieldSize<C>: ModulusSize,
+ FieldBytesSize<C>: ModulusSize,
{
let (label, der_bytes) = pem::decode_vec(s.as_bytes()).map_err(|_| Error)?;
@@ -231,7 +243,7 @@ where
return Err(Error);
}
- Self::from_sec1_der(&*der_bytes).map_err(|_| Error)
+ Self::from_sec1_der(&der_bytes).map_err(|_| Error)
}
/// Serialize private key as self-zeroizing PEM-encoded SEC1 `ECPrivateKey`
@@ -239,12 +251,11 @@ where
///
/// Pass `Default::default()` to use the OS's native line endings.
#[cfg(feature = "pem")]
- #[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
- pub fn to_pem(&self, line_ending: pem::LineEnding) -> Result<Zeroizing<String>>
+ pub fn to_sec1_pem(&self, line_ending: pem::LineEnding) -> Result<Zeroizing<String>>
where
- C: Curve + ProjectiveArithmetic,
+ C: CurveArithmetic,
AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
- FieldSize<C>: ModulusSize,
+ FieldBytesSize<C>: ModulusSize,
{
self.to_sec1_der()
.ok()
@@ -255,48 +266,42 @@ where
/// Parse a [`JwkEcKey`] JSON Web Key (JWK) into a [`SecretKey`].
#[cfg(feature = "jwk")]
- #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
pub fn from_jwk(jwk: &JwkEcKey) -> Result<Self>
where
C: JwkParameters + ValidatePublicKey,
- FieldSize<C>: ModulusSize,
+ FieldBytesSize<C>: ModulusSize,
{
Self::try_from(jwk)
}
/// Parse a string containing a JSON Web Key (JWK) into a [`SecretKey`].
#[cfg(feature = "jwk")]
- #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
pub fn from_jwk_str(jwk: &str) -> Result<Self>
where
C: JwkParameters + ValidatePublicKey,
- FieldSize<C>: ModulusSize,
+ FieldBytesSize<C>: ModulusSize,
{
jwk.parse::<JwkEcKey>().and_then(|jwk| Self::from_jwk(&jwk))
}
/// Serialize this secret key as [`JwkEcKey`] JSON Web Key (JWK).
#[cfg(all(feature = "arithmetic", feature = "jwk"))]
- #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
- #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
pub fn to_jwk(&self) -> JwkEcKey
where
- C: Curve + JwkParameters + ProjectiveArithmetic,
+ C: CurveArithmetic + JwkParameters,
AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
- FieldSize<C>: ModulusSize,
+ FieldBytesSize<C>: ModulusSize,
{
self.into()
}
/// Serialize this secret key as JSON Web Key (JWK) string.
#[cfg(all(feature = "arithmetic", feature = "jwk"))]
- #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
- #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
pub fn to_jwk_string(&self) -> Zeroizing<String>
where
- C: Curve + JwkParameters + ProjectiveArithmetic,
+ C: CurveArithmetic + JwkParameters,
AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
- FieldSize<C>: ModulusSize,
+ FieldBytesSize<C>: ModulusSize,
{
Zeroizing::new(self.to_jwk().to_string())
}
@@ -316,8 +321,8 @@ where
C: Curve,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- // TODO(tarcieri): use `debug_struct` and `finish_non_exhaustive` when stable
- write!(f, "SecretKey<{:?}>{{ ... }}", C::default())
+ f.debug_struct(core::any::type_name::<Self>())
+ .finish_non_exhaustive()
}
}
@@ -344,16 +349,15 @@ where
}
#[cfg(all(feature = "sec1"))]
-#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))]
impl<C> TryFrom<sec1::EcPrivateKey<'_>> for SecretKey<C>
where
C: Curve + ValidatePublicKey,
- FieldSize<C>: ModulusSize,
+ FieldBytesSize<C>: ModulusSize,
{
type Error = der::Error;
fn try_from(sec1_private_key: sec1::EcPrivateKey<'_>) -> der::Result<Self> {
- let secret_key = Self::from_be_bytes(sec1_private_key.private_key)
+ let secret_key = Self::from_slice(sec1_private_key.private_key)
.map_err(|_| der::Tag::Sequence.value_error())?;
// TODO(tarcieri): validate `sec1_private_key.params`?
@@ -371,10 +375,9 @@ where
}
#[cfg(feature = "arithmetic")]
-#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
impl<C> From<NonZeroScalar<C>> for SecretKey<C>
where
- C: Curve + ProjectiveArithmetic,
+ C: CurveArithmetic,
{
fn from(scalar: NonZeroScalar<C>) -> SecretKey<C> {
SecretKey::from(&scalar)
@@ -382,10 +385,9 @@ where
}
#[cfg(feature = "arithmetic")]
-#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
impl<C> From<&NonZeroScalar<C>> for SecretKey<C>
where
- C: Curve + ProjectiveArithmetic,
+ C: CurveArithmetic,
{
fn from(scalar: &NonZeroScalar<C>) -> SecretKey<C> {
SecretKey {