silk.crypto.ed25519.
Ed25519 signature verification for 32-byte public keys and 64-byte signatures (RFC 8032).
When to use#
Use Ed25519PublicKey to check that a message was signed by the holder of a known Ed25519
key, such as a release signing key. This module verifies only; it cannot sign.
Details#
fromBytes decodes and checks the public key once. verify borrows the message and the
signature, requires the scalar half of the signature to be below the group order, and checks
the cofactorless equation [S]B = R + [k]A with k = SHA-512(R || A || M) mod L. Arithmetic
uses bounded local storage, without an allocator.
Gotchas#
Verification works on public data and does not try to run in constant time. A valid
signature proves only that the key holder signed these exact bytes. For prehashed formats, such
as minisign's ED algorithm, pass the digest as the message.
Examples#
Reject a signature over a different message#
import silk.crypto.ed25519 {Ed25519PublicKey}
import silk.core.result {Result}
pub fn main() -> i32 {
// RFC 8032 section 7.1, test 1: the empty message.
let key: [u8; 32] = [
215, 90, 152, 1, 130, 177, 10, 183, 213, 75, 254, 211, 201, 100, 7, 58,
14, 225, 114, 243, 218, 166, 35, 37, 175, 2, 26, 104, 247, 7, 81, 26,
]
let signature: [u8; 64] = [
229, 86, 67, 0, 195, 96, 172, 114, 144, 134, 226, 204, 128, 110, 130, 138,
132, 135, 127, 30, 184, 229, 217, 116, 216, 115, 224, 101, 34, 73, 1, 85,
95, 184, 130, 21, 144, 163, 59, 172, 198, 30, 57, 112, 28, 249, 180, 107,
210, 91, 245, 240, 89, 91, 190, 36, 101, 81, 65, 67, 142, 122, 16, 11,
]
let empty: [u8; 0] = []
let other: [u8; 1] = [0]
return match Ed25519PublicKey.fromBytes(&key) {
Result.Failure { error } => 1
Result.Success { value: verifier } => {
let accepted = match verifier.verify(&empty, &signature) {
Result.Success { value } => true
Result.Failure { error } => false
}
let forged = match verifier.verify(&other, &signature) {
Result.Success { value } => true
Result.Failure { error } => false
}
if !accepted || forged {
return 2
}
return 0
}
}
}Import as Ed25519PublicKey with import silk.crypto.ed25519 { Ed25519PublicKey }.
Public declarations: 2.
Ed25519Error#
pub enum Ed25519ErrorA rejected Ed25519 input, without the input bytes in the error.
InvalidKeyLength#
InvalidKeyLengthA public key encoding whose length is not 32 bytes.
InvalidKey#
InvalidKeyA public key that does not encode a point on the curve.
InvalidSignatureLength#
InvalidSignatureLengthA signature whose length is not 64 bytes.
InvalidSignature#
InvalidSignatureA signature that does not verify for this key and message.
Implementation Debug for Ed25519Error#
impl Debug for Ed25519ErrorOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the name of the variant, such as InvalidKeyLength.
Ed25519PublicKey#
pub struct Ed25519PublicKeyA decoded Ed25519 public key, for signature verification only (RFC 8032).
When to use#
Use it to check that a message was signed by the holder of a known Ed25519 key, such as a
release signing key. Decode the key once with Ed25519PublicKey.fromBytes, then call
Ed25519PublicKey.verify. It cannot sign.
Gotchas#
Verification works on public data and does not try to run in constant time. A valid signature
proves only that the key holder signed these exact bytes. For prehashed formats, such as
minisign's ED algorithm, pass the digest as the message.
Implementation Ed25519PublicKey#
impl Ed25519PublicKeyAssociated function fromBytes#
pub fn fromBytes(bytes: &[u8]) -> Result<Ed25519PublicKey, Ed25519Error>Decodes exactly 32 borrowed public key bytes.
Errors#
InvalidKeyLength when bytes is not 32 bytes long, and InvalidKey when it does not
encode a curve point.
Method bytes#
pub fn bytes(self: &Ed25519PublicKey) -> [u8; 32]Returns the 32-byte encoding this key was decoded from.
Method verify#
pub fn verify(self: &Ed25519PublicKey, message: &[u8], signature: &[u8]) -> Result<
(),
Ed25519Error
>Checks that signature is this key's Ed25519 signature of message.
It borrows the message and the signature, requires the scalar half of the signature to be
below the group order, and checks the cofactorless equation [S]B = R + [k]A with
k = SHA-512(R || A || M) mod L. It does not allocate.
Gotchas#
It does not try to run in constant time. A valid signature proves only that the key holder
signed these exact bytes. For prehashed formats, such as minisign's ED algorithm, pass the
digest as the message.
Errors#
InvalidSignatureLength when signature is not 64 bytes long, and InvalidSignature when
its scalar is not below the group order or the verification equation does not hold.
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.