cloacina::crypto::signing
Rust
Ed25519 signing utilities for package signatures.
Provides functions for:
- Generating Ed25519 signing keypairs
- Computing SHA256 key fingerprints
- Signing package hashes
- Verifying signatures
Structs
Section titled “Structs”struct GeneratedKeypair
Section titled “struct GeneratedKeypair”pub
A generated Ed25519 keypair.
Fields
Section titled “Fields”| Name | Type | Description |
|---|---|---|
private_key |
Vec<u8> |
The 32-byte private key seed (should be encrypted before storage) |
public_key |
Vec<u8> |
The 32-byte public key |
fingerprint |
String |
SHA256 hex fingerprint of the public key |
enum SigningError
Section titled “enum SigningError”pub
Errors that can occur during signing operations.
Variants
Section titled “Variants”InvalidPrivateKeyLengthInvalidPublicKeyLengthInvalidSignatureLengthKeyCreationFailedSignatureFailedVerificationFailed
Functions
Section titled “Functions”fn generate_signing_keypair
Section titled “fn generate_signing_keypair”pub
fn generate_signing_keypair() -> GeneratedKeypairGenerates a new Ed25519 signing keypair.
Returns:
A GeneratedKeypair containing the private key, public key, and fingerprint.
Source
pub fn generate_signing_keypair() -> GeneratedKeypair { // ed25519-dalek 2 wants a rand_core 0.6 RNG; draw the 32-byte seed // from rand 0.10 instead (CLOACINA-T-0963). let mut seed = [0u8; 32]; rand::Rng::fill_bytes(&mut rand::rng(), &mut seed); let signing_key = SigningKey::from_bytes(&seed); let verifying_key = signing_key.verifying_key();
let public_key_bytes = verifying_key.to_bytes(); let fingerprint = compute_key_fingerprint(&public_key_bytes);
GeneratedKeypair { private_key: signing_key.to_bytes().to_vec(), public_key: public_key_bytes.to_vec(), fingerprint, }}fn compute_key_fingerprint
Section titled “fn compute_key_fingerprint”pub
fn compute_key_fingerprint(public_key: &[u8]) -> StringComputes the SHA256 hex fingerprint of a public key.
Parameters:
| Name | Type | Description |
|---|---|---|
public_key |
&[u8] |
The 32-byte Ed25519 public key |
Returns:
A 64-character hex string representing the SHA256 hash of the public key.
Source
pub fn compute_key_fingerprint(public_key: &[u8]) -> String { let mut hasher = Sha256::new(); hasher.update(public_key); let hash = hasher.finalize(); hex::encode(hash)}fn sign_package
Section titled “fn sign_package”pub
fn sign_package( package_hash: &[u8], private_key: &[u8],) -> Result<Vec<u8>, SigningError>Signs a package hash using an Ed25519 private key.
Parameters:
| Name | Type | Description |
|---|---|---|
package_hash |
&[u8] |
The SHA256 hash of the package (as raw bytes or hex string bytes) |
private_key |
&[u8] |
The 32-byte Ed25519 private key seed |
Returns:
The 64-byte Ed25519 signature.
Errors:
Returns SigningError if the private key is invalid.
Source
pub fn sign_package(package_hash: &[u8], private_key: &[u8]) -> Result<Vec<u8>, SigningError> { if private_key.len() != 32 { return Err(SigningError::InvalidPrivateKeyLength(private_key.len())); }
let key_bytes: [u8; 32] = private_key .try_into() .map_err(|_| SigningError::InvalidPrivateKeyLength(private_key.len()))?;
let signing_key = SigningKey::from_bytes(&key_bytes); let signature = signing_key.sign(package_hash);
Ok(signature.to_bytes().to_vec())}fn verify_signature
Section titled “fn verify_signature”pub
fn verify_signature( package_hash: &[u8], signature: &[u8], public_key: &[u8],) -> Result<(), SigningError>Verifies a package signature using an Ed25519 public key.
Parameters:
| Name | Type | Description |
|---|---|---|
package_hash |
&[u8] |
The SHA256 hash of the package that was signed |
signature |
&[u8] |
The 64-byte Ed25519 signature |
public_key |
&[u8] |
The 32-byte Ed25519 public key |
Returns:
Ok(()) if the signature is valid.
Errors:
Returns SigningError if the signature is invalid or verification fails.
Source
pub fn verify_signature( package_hash: &[u8], signature: &[u8], public_key: &[u8],) -> Result<(), SigningError> { if public_key.len() != 32 { return Err(SigningError::InvalidPublicKeyLength(public_key.len())); } if signature.len() != 64 { return Err(SigningError::InvalidSignatureLength(signature.len())); }
let key_bytes: [u8; 32] = public_key .try_into() .map_err(|_| SigningError::InvalidPublicKeyLength(public_key.len()))?;
let sig_bytes: [u8; 64] = signature .try_into() .map_err(|_| SigningError::InvalidSignatureLength(signature.len()))?;
let verifying_key = VerifyingKey::from_bytes(&key_bytes) .map_err(|e| SigningError::KeyCreationFailed(e.to_string()))?;
let sig = Signature::from_bytes(&sig_bytes);
verifying_key .verify(package_hash, &sig) .map_err(|_| SigningError::VerificationFailed)}fn compute_package_hash
Section titled “fn compute_package_hash”pub
fn compute_package_hash(data: &[u8]) -> StringComputes the SHA256 hash of package data.
Parameters:
| Name | Type | Description |
|---|---|---|
data |
&[u8] |
The package binary data |
Returns:
A 64-character hex string representing the SHA256 hash.
Source
pub fn compute_package_hash(data: &[u8]) -> String { let mut hasher = Sha256::new(); hasher.update(data); let hash = hasher.finalize(); hex::encode(hash)}