silk.crypto.ec_key.
Read and write elliptic-curve keys in DER: SEC1 private keys, PKCS #8 private keys, and
SubjectPublicKeyInfo public keys, for the named curves of EcCurve.
When to use#
Use EcKeyDer to load a key that OpenSSL, a browser, or Node.js wrote, or to export a key in
one of those forms. The reader tells you the curve, so you can pick silk.crypto.p256,
silk.crypto.p384, silk.crypto.p521, or silk.crypto.ec for any other curve.
Details#
SEC1 is the EC PRIVATE KEY form of RFC 5915. PKCS #8 is the PRIVATE KEY form of RFC 5958
with the algorithm id-ecPublicKey. SubjectPublicKeyInfo is the PUBLIC KEY form of RFC 5480.
The readers return views into the DER and do not copy. The writers give the same bytes as
OpenSSL. Nothing allocates. PEM is DER in Base64 between header lines; use
silk.encoding.base64 for it.
Errors#
EcKeyErrorfor DER that is not valid, or for an algorithm or curve that is not supported.
Gotchas#
The readers check the structure and the lengths, but not the values. Pass the secret to
P256.fromBytes, P384.fromBytes, or P521.fromBytes, and the public key to validatePublicKey or
decompressPublicKey, before you use them. A private key file can hold a public key that does
not belong to its secret; compare it with the public key of the secret if that matters.
Examples#
Read a public key#
import silk.collections.slice { Slice }
import silk.crypto.ec_key { EcCurve, EcKeyDer, EcKeyError, EcPublicKeyDer }
import silk.core.result { Result }
pub fn main() -> i32 {
let mut point: [u8; 65] = [0; 65]
point[0] = 0x04
let mut der: [u8; 120] = [0; 120]
let length = match EcKeyDer.writeSpki(EcCurve.P256, &point, &mut der) {
Result<usize, EcKeyError>.Success { value } => value
Result<usize, EcKeyError>.Failure {..} => {
return 1
}
}
// A P-256 SubjectPublicKeyInfo is 91 bytes.
if length != 91 {
return 1
}
// The reader takes exactly one key, so pass only the bytes that were written.
return match EcKeyDer.readSpki(Slice.view<u8>(&der, 0, length)) {
Result<EcPublicKeyDer, EcKeyError>.Success { value } => {
if value.curve == EcCurve.P256 && value.publicKey.length == 65 {
return 0
}
return 1
}
Result<EcPublicKeyDer, EcKeyError>.Failure {..} => 1
}
}Import as EcKeyDer with import silk.crypto.ec_key { EcKeyDer }.
Public declarations: 5.
EcCurve#
pub enum EcCurveA named elliptic curve over a prime field, as OpenSSL and Node.js crypto.getCurves list
them.
Secp112r1#
Secp112r1The curve that OpenSSL names secp112r1.
Secp112r2#
Secp112r2The curve that OpenSSL names secp112r2.
Secp128r1#
Secp128r1The curve that OpenSSL names secp128r1.
Secp128r2#
Secp128r2The curve that OpenSSL names secp128r2.
Secp160k1#
Secp160k1The curve that OpenSSL names secp160k1.
Secp160r1#
Secp160r1The curve that OpenSSL names secp160r1.
Secp160r2#
Secp160r2The curve that OpenSSL names secp160r2.
Secp192k1#
Secp192k1The curve that OpenSSL names secp192k1.
Secp224k1#
Secp224k1The curve that OpenSSL names secp224k1.
P224#
P224NIST P-224, which OpenSSL and SEC 2 name secp224r1.
Secp256k1#
Secp256k1The curve that OpenSSL names secp256k1.
P384#
P384NIST P-384, which OpenSSL and SEC 2 name secp384r1.
P521#
P521NIST P-521, which OpenSSL and SEC 2 name secp521r1.
P192#
P192NIST P-192, which OpenSSL names prime192v1 and SEC 2 names secp192r1.
Prime192v2#
Prime192v2The curve that OpenSSL names prime192v2.
Prime192v3#
Prime192v3The curve that OpenSSL names prime192v3.
Prime239v1#
Prime239v1The curve that OpenSSL names prime239v1.
Prime239v2#
Prime239v2The curve that OpenSSL names prime239v2.
Prime239v3#
Prime239v3The curve that OpenSSL names prime239v3.
P256#
P256NIST P-256, which OpenSSL names prime256v1 and SEC 2 names secp256r1.
Wtls6#
Wtls6The curve that OpenSSL names wap-wsg-idm-ecid-wtls6.
Wtls7#
Wtls7The curve that OpenSSL names wap-wsg-idm-ecid-wtls7.
Wtls8#
Wtls8The curve that OpenSSL names wap-wsg-idm-ecid-wtls8.
Wtls9#
Wtls9The curve that OpenSSL names wap-wsg-idm-ecid-wtls9.
Wtls12#
Wtls12The curve that OpenSSL names wap-wsg-idm-ecid-wtls12.
BrainpoolP160r1#
BrainpoolP160r1The curve that OpenSSL names brainpoolP160r1.
BrainpoolP160t1#
BrainpoolP160t1The curve that OpenSSL names brainpoolP160t1.
BrainpoolP192r1#
BrainpoolP192r1The curve that OpenSSL names brainpoolP192r1.
BrainpoolP192t1#
BrainpoolP192t1The curve that OpenSSL names brainpoolP192t1.
BrainpoolP224r1#
BrainpoolP224r1The curve that OpenSSL names brainpoolP224r1.
BrainpoolP224t1#
BrainpoolP224t1The curve that OpenSSL names brainpoolP224t1.
BrainpoolP256r1#
BrainpoolP256r1The curve that OpenSSL names brainpoolP256r1.
BrainpoolP256t1#
BrainpoolP256t1The curve that OpenSSL names brainpoolP256t1.
BrainpoolP320r1#
BrainpoolP320r1The curve that OpenSSL names brainpoolP320r1.
BrainpoolP320t1#
BrainpoolP320t1The curve that OpenSSL names brainpoolP320t1.
BrainpoolP384r1#
BrainpoolP384r1The curve that OpenSSL names brainpoolP384r1.
BrainpoolP384t1#
BrainpoolP384t1The curve that OpenSSL names brainpoolP384t1.
BrainpoolP512r1#
BrainpoolP512r1The curve that OpenSSL names brainpoolP512r1.
BrainpoolP512t1#
BrainpoolP512t1The curve that OpenSSL names brainpoolP512t1.
Sm2#
Sm2The Chinese SM2 curve, which OpenSSL names SM2.
Implementation EcCurve#
impl EcCurveMethod secretLength#
pub fn secretLength(self: &Self) -> usizeReturns the length in bytes of a secret and of each half of an ECDSA signature: the byte length of the order of the base point, such as 32 for P-256 and 66 for P-521.
Method fieldLength#
pub fn fieldLength(self: &Self) -> usizeReturns the length in bytes of a field element, which is the length of a shared secret and of each coordinate of a public key, such as 32 for P-256 and 66 for P-521.
Method publicKeyLength#
pub fn publicKeyLength(self: &Self) -> usizeReturns the length of an uncompressed public key in bytes: twice
EcCurve.fieldLength plus 1, such as 65 for P-256.
Method compressedPublicKeyLength#
pub fn compressedPublicKeyLength(self: &Self) -> usizeReturns the length of a compressed public key in bytes: EcCurve.fieldLength plus 1,
such as 33 for P-256.
Method objectIdentifier#
pub fn objectIdentifier(self: &Self) -> &[u8]Returns the content bytes of the object identifier that names the curve, without the tag and length.
Method name#
pub fn name(self: &Self) -> stringReturns the name of the curve in OpenSSL and in Node.js crypto.getCurves, such as
prime256v1 or brainpoolP256r1.
Associated function fromName#
pub fn fromName(name: string) -> Option<EcCurve>Returns the curve for a name of OpenSSL, such as prime256v1 or secp256k1, or a NIST
name: P-192, P-224, P-256, P-384, or P-521, as Node.js crypto.createECDH
accepts. Names are case-sensitive.
Associated function fromObjectIdentifier#
pub fn fromObjectIdentifier(identifier: &[u8]) -> Option<EcCurve>Returns the curve whose object identifier has the content bytes identifier, without the
tag and length, or None.
Implementation Debug for EcCurve#
impl Debug for EcCurveOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> ()
! WriterError
? &mut WriterWrites the name of the variant, such as P256.
EcKeyError#
pub enum EcKeyErrorThe reason that an elliptic-curve key in DER could not be read or written.
InvalidEncoding#
InvalidEncodingThe bytes are not strict DER of the expected structure, or a version is not supported.
UnsupportedAlgorithm#
UnsupportedAlgorithmThe key algorithm is not id-ecPublicKey.
UnsupportedCurve#
UnsupportedCurveThe curve is not one of EcCurve, the curve is given by explicit parameters, or no curve
is named.
InvalidLength#
InvalidLengthA secret or a public key does not have a length that the curve allows.
Implementation Debug for EcKeyError#
impl Debug for EcKeyErrorOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> ()
! WriterError
? &mut WriterWrites the name of the variant, such as InvalidEncoding.
EcPrivateKeyDer#
pub struct EcPrivateKeyDer<'a>A private key that EcKeyDer.readSec1 or EcKeyDer.readPkcs8 read. The slices point into
the DER.
Field curve#
pub curve: EcCurveThe curve of the key.
Field secret#
pub secret: &'a [u8]The secret, big-endian, of EcCurve.secretLength bytes.
Field publicKey#
pub publicKey: Option<&'a [u8]>The public key that the file holds, compressed, uncompressed, or hybrid, or None.
EcPublicKeyDer#
pub struct EcPublicKeyDer<'a>A public key that EcKeyDer.readSpki read. The slice points into the DER.
Field curve#
pub curve: EcCurveThe curve of the key.
Field publicKey#
pub publicKey: &'a [u8]The public key in SEC1 form, compressed, uncompressed, or hybrid.
EcKeyDer#
pub struct EcKeyDerFunctions that read and write elliptic-curve keys in DER.
When to use#
Use it to load or export a key on a curve of EcCurve as SEC1, PKCS #8, or
SubjectPublicKeyInfo.
Details#
The writers give the same bytes as OpenSSL: SEC1 names the curve and holds the public key, PKCS #8 holds the public key in the inner SEC1 key, and SubjectPublicKeyInfo names the curve. A SEC1 key is at most 223 bytes, a PKCS #8 key at most 241 bytes, and a SubjectPublicKeyInfo at most 158 bytes.
Gotchas#
The readers do not check that the secret is in range or that the public key is on the curve.
Implementation EcKeyDer#
impl EcKeyDerAssociated function readSec1#
pub fn readSec1<'a>(der: &'a [u8]) -> Result<EcPrivateKeyDer<'a>, EcKeyError>Reads a SEC1 ECPrivateKey (RFC 5915), the form of an EC PRIVATE KEY PEM file.
The key must name its curve. The public key is optional.
Errors#
InvalidEncodingifderis not one strict DERECPrivateKeyof version 1.UnsupportedCurveif the curve is missing, explicit, or not one ofEcCurve.InvalidLengthif the secret or the public key has the wrong length for the curve.
Associated function readPkcs8#
pub fn readPkcs8<'a>(der: &'a [u8]) -> Result<EcPrivateKeyDer<'a>, EcKeyError>Reads a PKCS #8 PrivateKeyInfo or OneAsymmetricKey (RFC 5958) with an elliptic-curve key,
the form of a PRIVATE KEY PEM file.
Versions 0 and 1 are accepted. Attributes are skipped. A public key of version 1 is used when the inner key has none.
Errors#
InvalidEncodingifderis not strict DER of that structure, or the inner key names another curve.UnsupportedAlgorithmif the algorithm is notid-ecPublicKey.UnsupportedCurveif the curve is explicit, or not one ofEcCurve.InvalidLengthif the secret or the public key has the wrong length for the curve.
Associated function readSpki#
pub fn readSpki<'a>(der: &'a [u8]) -> Result<EcPublicKeyDer<'a>, EcKeyError>Reads a SubjectPublicKeyInfo (RFC 5480) with an elliptic-curve key, the form of a
PUBLIC KEY PEM file and of the key in an X.509 certificate.
Errors#
InvalidEncodingifderis not one strict DERSubjectPublicKeyInfo.UnsupportedAlgorithmif the algorithm is notid-ecPublicKey.UnsupportedCurveif the curve is explicit, or not one ofEcCurve.InvalidLengthif the public key has the wrong length for the curve.
Associated function writeSec1#
pub fn writeSec1(curve: EcCurve, secret: &[u8], publicKey: &[u8], output: &mut [u8]) -> Result<
usize,
EcKeyError,
>Writes secret and publicKey as a SEC1 ECPrivateKey that names curve, and returns the
length. The bytes of output after the DER do not change.
Errors#
InvalidLengthifsecretis notEcCurve.secretLengthbytes, orpublicKeyis not a compressed, uncompressed, or hybrid key of that length for the curve.outputdoes not change.
Gotchas#
The program traps if output is shorter than the DER, at most 223 bytes.
Associated function writePkcs8#
pub fn writePkcs8(curve: EcCurve, secret: &[u8], publicKey: &[u8], output: &mut [u8]) -> Result<
usize,
EcKeyError,
>Writes secret and publicKey as a PKCS #8 PrivateKeyInfo of version 0 for curve, and
returns the length. The inner SEC1 key holds the public key and does not repeat the curve.
The bytes of output after the DER do not change.
Errors#
InvalidLength, as forEcKeyDer.writeSec1.
Gotchas#
The program traps if output is shorter than the DER, at most 241 bytes.
Associated function writeSpki#
pub fn writeSpki(curve: EcCurve, publicKey: &[u8], output: &mut [u8]) -> Result<
usize,
EcKeyError
>Writes publicKey as a SubjectPublicKeyInfo for curve, and returns the length. The bytes
of output after the DER do not change.
Errors#
InvalidLengthifpublicKeyis not a compressed, uncompressed, or hybrid key of the right length for the curve.outputdoes not change.
Gotchas#
The program traps if output is shorter than the DER, at most 158 bytes.
Category: Cryptography.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2, x86_64-pc-windows-msvc, wasm64-unknown-unknown.