Skip to content

Commit 739304e

Browse files
authored
bignp256: migrate bundled types to inner of elliptic-curve types (#1908)
1 parent cd04a4b commit 739304e

2 files changed

Lines changed: 90 additions & 122 deletions

File tree

bignp256/src/public_key.rs

Lines changed: 39 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,79 @@
11
//! Public key types and traits
2-
// TODO(tarcieri): replace with `elliptic_curve::PublicKey`
32
43
#[cfg(feature = "pkcs8")]
54
use crate::ALGORITHM_OID;
65
use crate::{AffinePoint, BignP256, NonZeroScalar, ProjectivePoint, Sec1Point};
6+
#[cfg(feature = "pem")]
77
use core::{fmt::Display, str::FromStr};
88
#[cfg(feature = "pkcs8")]
99
use elliptic_curve::pkcs8::{
1010
self, AssociatedOid, DecodePublicKey, EncodePublicKey, ObjectIdentifier,
1111
spki::{AlgorithmIdentifier, AssociatedAlgorithmIdentifier},
1212
};
13-
use elliptic_curve::{
14-
CurveArithmetic, Error, Group,
15-
array::Array,
16-
point::NonIdentity,
17-
sec1::{FromSec1Point, ToSec1Point},
18-
};
13+
use elliptic_curve::{Error, array::Array, point::NonIdentity, sec1::ToSec1Point};
1914

2015
#[cfg(feature = "alloc")]
2116
use alloc::{boxed::Box, fmt};
2217

2318
/// Elliptic curve BignP256 public key.
24-
#[cfg(feature = "arithmetic")]
25-
#[derive(Clone, Debug, Eq, PartialEq)]
26-
pub struct PublicKey {
27-
point: AffinePoint,
28-
}
19+
///
20+
/// A wrapper around [`elliptic_curve::PublicKey`] which uses the raw
21+
/// (untagged) point encoding and the PKCS#8 algorithm identifier defined in
22+
/// STB 34.101.45 instead of the SEC1/RFC 5480 ones.
23+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
24+
pub struct PublicKey(elliptic_curve::PublicKey<BignP256>);
2925

3026
impl PublicKey {
3127
/// Convert an [`AffinePoint`] into a [`PublicKey`]
3228
pub fn from_affine(point: AffinePoint) -> Result<Self, Error> {
33-
if ProjectivePoint::from(point).is_identity().into() {
34-
Err(Error)
35-
} else {
36-
Ok(Self { point })
37-
}
29+
elliptic_curve::PublicKey::from_affine(point).map(Self)
3830
}
3931

4032
/// Compute a [`PublicKey`] from a secret [`NonZeroScalar`] value
4133
/// (i.e. a secret key represented as a raw scalar value)
4234
pub fn from_secret_scalar(scalar: &NonZeroScalar) -> Self {
43-
// `NonZeroScalar` ensures the resulting point is not the identity
44-
#[allow(clippy::arithmetic_side_effects)]
45-
Self {
46-
point: (<BignP256 as CurveArithmetic>::ProjectivePoint::generator() * scalar.as_ref())
47-
.to_affine(),
48-
}
35+
Self(elliptic_curve::PublicKey::from_secret_scalar(scalar))
4936
}
5037

5138
/// Borrow the inner [`AffinePoint`] from this [`PublicKey`].
5239
///
5340
/// In ECC, public keys are elliptic curve points.
5441
pub fn as_affine(&self) -> &AffinePoint {
55-
&self.point
42+
self.0.as_affine()
5643
}
5744

5845
/// Convert this [`PublicKey`] to a [`ProjectivePoint`] for the given curve
5946
pub fn to_projective(&self) -> ProjectivePoint {
60-
self.point.into()
47+
self.0.to_projective()
6148
}
6249

6350
/// Convert this [`PublicKey`] to a [`NonIdentity`] of the inner [`AffinePoint`]
6451
pub fn to_nonidentity(&self) -> NonIdentity<AffinePoint> {
65-
NonIdentity::new(self.point).unwrap()
52+
self.0.to_nonidentity()
6653
}
6754

68-
/// Get [`PublicKey`] from bytes
55+
/// Parse a [`PublicKey`] from the raw (untagged) point encoding defined
56+
/// in STB 34.101.45.
6957
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
7058
let bytes = Array::try_from(bytes).map_err(|_| Error)?;
71-
72-
let point = Sec1Point::from_untagged_bytes(&bytes);
73-
let affine = AffinePoint::from_sec1_point(&point);
74-
if affine.is_none().into() {
75-
Err(Error)
76-
} else {
77-
Ok(Self {
78-
point: affine.unwrap(),
79-
})
80-
}
59+
Self::from_sec1_point(Sec1Point::from_untagged_bytes(&bytes))
8160
}
8261

8362
/// Get [`PublicKey`] from encoded point
8463
pub fn from_sec1_point(point: Sec1Point) -> Result<Self, Error> {
85-
let affine = AffinePoint::from_sec1_point(&point);
86-
if affine.is_none().into() {
87-
Err(Error)
88-
} else {
89-
Ok(Self {
90-
point: affine.unwrap(),
91-
})
92-
}
64+
elliptic_curve::PublicKey::try_from(&point).map(Self)
9365
}
9466

67+
/// Serialize this [`PublicKey`] using the raw (untagged) point encoding
68+
/// defined in STB 34.101.45.
9569
#[cfg(feature = "alloc")]
96-
/// Get bytes from [`PublicKey`]
9770
pub fn to_bytes(&self) -> Box<[u8]> {
98-
let bytes = self.point.to_sec1_point(false).to_bytes();
99-
bytes[1..].to_vec().into_boxed_slice()
71+
self.to_sec1_point().to_bytes()[1..].into()
10072
}
10173

102-
#[cfg(feature = "alloc")]
10374
/// Get encoded point from [`PublicKey`]
10475
pub fn to_sec1_point(&self) -> Sec1Point {
105-
self.point.to_sec1_point(false)
76+
self.0.to_sec1_point(false)
10677
}
10778
}
10879

@@ -111,37 +82,46 @@ impl AsRef<AffinePoint> for PublicKey {
11182
self.as_affine()
11283
}
11384
}
114-
impl Copy for PublicKey {}
85+
11586
impl From<NonIdentity<AffinePoint>> for PublicKey {
11687
fn from(value: NonIdentity<AffinePoint>) -> Self {
117-
Self::from(&value)
88+
Self(value.into())
11889
}
11990
}
12091

12192
impl From<&NonIdentity<AffinePoint>> for PublicKey {
12293
fn from(value: &NonIdentity<AffinePoint>) -> Self {
123-
Self {
124-
point: value.to_point(),
125-
}
94+
Self(value.into())
12695
}
12796
}
12897

12998
impl From<PublicKey> for NonIdentity<AffinePoint> {
13099
fn from(value: PublicKey) -> Self {
131-
Self::from(&value)
100+
value.0.into()
132101
}
133102
}
134103

135104
impl From<&PublicKey> for NonIdentity<AffinePoint> {
136105
fn from(value: &PublicKey) -> Self {
137-
PublicKey::to_nonidentity(value)
106+
value.0.into()
138107
}
139108
}
140109

141110
impl From<PublicKey> for elliptic_curve::PublicKey<BignP256> {
142111
fn from(value: PublicKey) -> Self {
143-
elliptic_curve::PublicKey::<BignP256>::from_affine(value.point)
144-
.expect("should be non-identity")
112+
value.0
113+
}
114+
}
115+
116+
impl From<elliptic_curve::PublicKey<BignP256>> for PublicKey {
117+
fn from(value: elliptic_curve::PublicKey<BignP256>) -> Self {
118+
Self(value)
119+
}
120+
}
121+
122+
impl From<PublicKey> for Sec1Point {
123+
fn from(value: PublicKey) -> Self {
124+
value.to_sec1_point()
145125
}
146126
}
147127

@@ -194,12 +174,6 @@ impl EncodePublicKey for PublicKey {
194174
}
195175
}
196176

197-
impl From<PublicKey> for Sec1Point {
198-
fn from(value: PublicKey) -> Self {
199-
value.point.to_sec1_point(false)
200-
}
201-
}
202-
203177
#[cfg(feature = "pem")]
204178
impl FromStr for PublicKey {
205179
type Err = Error;

bignp256/src/secret_key.rs

Lines changed: 51 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,41 @@
11
//! Bign256 secret key.
2-
// TODO(tarcieri): replace with `elliptic_curve::SecretKey`
32
3+
use core::fmt::{self, Debug};
4+
#[cfg(feature = "pem")]
45
use core::str::FromStr;
6+
#[cfg(feature = "pkcs8")]
57
use der::{SecretDocument, asn1::OctetStringRef};
68

79
#[cfg(feature = "pkcs8")]
810
use crate::ALGORITHM_OID;
9-
use crate::{PublicKey, ScalarValue};
11+
use crate::{BignP256, FieldBytes, NonZeroScalar, PublicKey, Result, ScalarValue};
12+
#[cfg(feature = "pem")]
13+
use elliptic_curve::Error;
1014
#[cfg(feature = "pkcs8")]
1115
use elliptic_curve::pkcs8::{
1216
self, AssociatedOid, DecodePrivateKey, EncodePrivateKey, ObjectIdentifier,
1317
spki::{AlgorithmIdentifier, AssociatedAlgorithmIdentifier},
1418
};
15-
use elliptic_curve::{Error, Generate, array::typenum::Unsigned, zeroize::Zeroizing};
16-
17-
#[cfg(feature = "arithmetic")]
18-
use crate::{BignP256, FieldBytes, NonZeroScalar, Result, elliptic_curve::rand_core::TryCryptoRng};
19+
use elliptic_curve::{Generate, rand_core::TryCryptoRng, zeroize::ZeroizeOnDrop};
1920

20-
/// Elliptic curve BignP256 Secret Key
21-
#[cfg(feature = "arithmetic")]
22-
#[derive(Copy, Clone, Debug)]
23-
pub struct SecretKey {
24-
inner: ScalarValue,
25-
}
21+
/// Elliptic curve BignP256 Secret Key.
22+
///
23+
/// A wrapper around [`elliptic_curve::SecretKey`] which uses the PKCS#8
24+
/// encoding defined in STB 34.101.45 (the raw secret scalar as an octet
25+
/// string with the bign algorithm identifier) instead of SEC1.
26+
#[derive(Clone)]
27+
pub struct SecretKey(elliptic_curve::SecretKey<BignP256>);
2628

2729
impl SecretKey {
28-
const MIN_SIZE: usize = 24;
29-
3030
/// Borrow the inner secret [`elliptic_curve::ScalarValue`] value.
3131
///
3232
/// # ⚠️ Warning
3333
///
3434
/// This value is key material.
3535
///
3636
/// Please treat it with the care it deserves!
37-
pub fn as_scalar_primitive(&self) -> &ScalarValue {
38-
&self.inner
37+
pub fn as_scalar_value(&self) -> &ScalarValue {
38+
self.0.as_scalar_value()
3939
}
4040

4141
/// Get the secret [`elliptic_curve::NonZeroScalar`] value for this key.
@@ -45,26 +45,18 @@ impl SecretKey {
4545
/// This value is key material.
4646
///
4747
/// Please treat it with the care it deserves!
48-
#[cfg(feature = "arithmetic")]
4948
pub fn to_nonzero_scalar(&self) -> NonZeroScalar {
50-
(*self).into()
49+
self.0.to_nonzero_scalar()
5150
}
5251

5352
/// Get the [`PublicKey`] which corresponds to this secret key
54-
#[cfg(feature = "arithmetic")]
5553
pub fn public_key(&self) -> PublicKey {
56-
PublicKey::from_secret_scalar(&self.to_nonzero_scalar())
54+
self.0.public_key().into()
5755
}
5856

5957
/// Deserialize secret key from an encoded secret scalar.
6058
pub fn from_bytes(bytes: &FieldBytes) -> Result<Self> {
61-
let inner = ScalarValue::from_bytes(bytes).into_option().ok_or(Error)?;
62-
63-
if inner.is_zero().into() {
64-
return Err(Error);
65-
}
66-
67-
Ok(Self { inner })
59+
elliptic_curve::SecretKey::from_bytes(bytes).map(Self)
6860
}
6961

7062
/// Deserialize secret key from an encoded secret scalar passed as a byte slice.
@@ -77,68 +69,70 @@ impl SecretKey {
7769
/// NOTE: this function is variable-time with respect to the input length. To avoid a timing
7870
/// sidechannel, always ensure that the input has been pre-padded to `C::FieldBytesSize`.
7971
pub fn from_slice(slice: &[u8]) -> Result<Self> {
80-
if slice.len() == <BignP256 as elliptic_curve::Curve>::FieldBytesSize::USIZE {
81-
Self::from_bytes(&FieldBytes::try_from(slice).map_err(|_| Error)?)
82-
} else if (Self::MIN_SIZE..<BignP256 as elliptic_curve::Curve>::FieldBytesSize::USIZE)
83-
.contains(&slice.len())
84-
{
85-
let mut bytes = Zeroizing::new(FieldBytes::default());
86-
let offset = <BignP256 as elliptic_curve::Curve>::FieldBytesSize::USIZE
87-
.saturating_sub(slice.len());
88-
bytes[offset..].copy_from_slice(slice);
89-
Self::from_bytes(&bytes)
90-
} else {
91-
Err(Error)
92-
}
72+
elliptic_curve::SecretKey::from_slice(slice).map(Self)
9373
}
9474

9575
/// Serialize raw secret scalar as a big endian integer.
9676
pub fn to_bytes(&self) -> FieldBytes {
97-
self.inner.to_bytes()
77+
self.0.to_bytes()
9878
}
9979
}
10080

101-
#[cfg(feature = "pkcs8")]
102-
impl AssociatedAlgorithmIdentifier for SecretKey {
103-
type Params = ObjectIdentifier;
104-
const ALGORITHM_IDENTIFIER: AlgorithmIdentifier<Self::Params> = AlgorithmIdentifier {
105-
oid: ALGORITHM_OID,
106-
parameters: Some(BignP256::OID),
107-
};
81+
impl Debug for SecretKey {
82+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83+
self.0.fmt(f)
84+
}
10885
}
10986

87+
impl ZeroizeOnDrop for SecretKey {}
88+
11089
impl From<SecretKey> for NonZeroScalar {
11190
fn from(secret_key: SecretKey) -> NonZeroScalar {
11291
secret_key.to_nonzero_scalar()
11392
}
11493
}
11594

116-
#[cfg(feature = "arithmetic")]
11795
impl From<NonZeroScalar> for SecretKey {
11896
fn from(scalar: NonZeroScalar) -> SecretKey {
119-
SecretKey::from(&scalar)
97+
Self(scalar.into())
12098
}
12199
}
122100

123-
#[cfg(feature = "arithmetic")]
124101
impl From<&NonZeroScalar> for SecretKey {
125102
fn from(scalar: &NonZeroScalar) -> SecretKey {
126-
SecretKey {
127-
inner: scalar.into(),
128-
}
103+
Self(scalar.into())
104+
}
105+
}
106+
107+
impl From<SecretKey> for elliptic_curve::SecretKey<BignP256> {
108+
fn from(secret_key: SecretKey) -> Self {
109+
secret_key.0
110+
}
111+
}
112+
113+
impl From<elliptic_curve::SecretKey<BignP256>> for SecretKey {
114+
fn from(secret_key: elliptic_curve::SecretKey<BignP256>) -> Self {
115+
Self(secret_key)
129116
}
130117
}
131118

132119
impl Generate for SecretKey {
133120
fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(
134121
rng: &mut R,
135122
) -> core::result::Result<Self, R::Error> {
136-
Ok(Self {
137-
inner: ScalarValue::try_generate_from_rng(rng)?,
138-
})
123+
elliptic_curve::SecretKey::try_generate_from_rng(rng).map(Self)
139124
}
140125
}
141126

127+
#[cfg(feature = "pkcs8")]
128+
impl AssociatedAlgorithmIdentifier for SecretKey {
129+
type Params = ObjectIdentifier;
130+
const ALGORITHM_IDENTIFIER: AlgorithmIdentifier<Self::Params> = AlgorithmIdentifier {
131+
oid: ALGORITHM_OID,
132+
parameters: Some(BignP256::OID),
133+
};
134+
}
135+
142136
#[cfg(feature = "pkcs8")]
143137
impl TryFrom<pkcs8::PrivateKeyInfoRef<'_>> for SecretKey {
144138
type Error = pkcs8::Error;

0 commit comments

Comments
 (0)