Skip to content

Commit

Permalink
elliptic-curve: basic OID support
Browse files Browse the repository at this point in the history
Adds a (very simple, const-and-no_std-friendly) `ObjectIdentifier` type
and an `Identifier` trait for attaching an OID to a curve.

No validation of the nodes is presently performed (and since it's impl'd
as a `const fn`, it'd require a MSRV bump to do so). Also requires the
OID be specified as an array literal: no parsing is supported for either
string or binary-encoded OIDs.

Only string serialization is supported for now. A `no_std`-friendly
binary serializer will be somewhat tricky.
  • Loading branch information
tarcieri committed Jul 31, 2020
1 parent 2eb3134 commit f52c062
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 1 deletion.
9 changes: 8 additions & 1 deletion elliptic-curve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
extern crate std;

pub mod error;
pub mod oid;
pub mod ops;
pub mod secret_key;

Expand All @@ -30,7 +31,7 @@ pub mod secret_key;
#[cfg_attr(docsrs, doc(cfg(feature = "weierstrass")))]
pub mod weierstrass;

pub use self::{error::Error, secret_key::SecretKey};
pub use self::{error::Error, oid::ObjectIdentifier, secret_key::SecretKey};
pub use generic_array::{self, typenum::consts};
pub use subtle;

Expand Down Expand Up @@ -72,6 +73,12 @@ pub trait Arithmetic: Curve {
type AffinePoint: ConditionallySelectable + ops::MulBase<Scalar = Self::Scalar>;
}

/// Associate an object identifier (OID) with a curve
pub trait Identifier: Curve {
/// Object Identifier (OID) for this curve
const OID: ObjectIdentifier;
}

/// Randomly generate a value.
///
/// Primarily intended for use with scalar types for a particular curve.
Expand Down
48 changes: 48 additions & 0 deletions elliptic-curve/src/oid.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//! Object identifiers (OIDs)

use core::fmt;

/// Object identifier (OID)
pub struct ObjectIdentifier(&'static [u32]);

impl ObjectIdentifier {
/// Create a new OID
pub const fn new(nodes: &'static [u32]) -> Self {
// TODO(tarcieri): validate nodes
Self(nodes)
}
}

impl AsRef<[u32]> for ObjectIdentifier {
fn as_ref(&self) -> &[u32] {
self.0
}
}

impl fmt::Display for ObjectIdentifier {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for (i, node) in self.0.iter().enumerate() {
write!(f, "{}", node)?;

if i < self.0.len() - 1 {
write!(f, ".")?;
}
}

Ok(())
}
}

#[cfg(all(test, std))]
mod tests {
use super::ObjectIdentifier;
use std::string::ToString;

const EXAMPLE_OID: ObjectIdentifier = ObjectIdentifier::new(&[1, 2, 840, 10045, 3, 1, 7]);

#[test]
fn display_test() {
let oid = EXAMPLE_OID.to_string();
assert_eq!(oid, "1.2.840.10045.3.1.7");
}
}

0 comments on commit f52c062

Please sign in to comment.