silk.crypto.hkdf.
Derive keys with HKDF (RFC 5869) over SHA-256 or SHA-384.
When to use#
Use HkdfSha256 or HkdfSha384 to turn a shared secret, such as the result of an X25519
key exchange, into one or more keys of the length that you need. Give each key a different
info label so that the keys are independent.
Details#
HKDF has two steps. extract mixes the input key material with a salt and returns a
pseudorandom key (PRK) of one digest length. expand turns the PRK and an info label into
output of any length up to 255 digests: 8160 bytes for SHA-256, 12240 bytes for SHA-384. Nothing
allocates.
Errors#
OutputTooLongErrorfromexpandif the output is longer than the maximum. The output does not change.
Gotchas#
HKDF is not for passwords. A password needs a slow function such as Argon2 or scrypt. The PRK is a secret and is not erased.
Examples#
Derive two keys from one secret#
import silk.crypto.hkdf { HkdfSha256, OutputTooLongError }
import silk.core.result { Result }
pub fn main() -> i32 {
let prk = HkdfSha256.extract(b"salt", b"shared secret")
let mut encryption: [u8; 32] = [0; 32]
let mut authentication: [u8; 32] = [0; 32]
match HkdfSha256.expand(&prk, b"app v1 encryption", &mut encryption) {
Result<(), OutputTooLongError>.Success { value: _ } => {}
Result<(), OutputTooLongError>.Failure { error: _ } => {
return 1
}
}
match HkdfSha256.expand(&prk, b"app v1 authentication", &mut authentication) {
Result<(), OutputTooLongError>.Success { value: _ } => {}
Result<(), OutputTooLongError>.Failure { error: _ } => {
return 1
}
}
// Different labels give different keys.
if encryption[0] == authentication[0] && encryption[1] == authentication[1] {
return 1
}
return 0
}Import as HkdfSha256 with import silk.crypto.hkdf { HkdfSha256 }.
Public declarations: 3.
OutputTooLongError#
pub struct OutputTooLongErrorThe error that expand returns when the output is longer than 255 digests.
Field requested#
pub requested: usizeThe output length that you asked for.
Field maximum#
pub maximum: usizeThe maximum output length: 8160 for SHA-256 and 12240 for SHA-384.
Implementation Debug for OutputTooLongError#
impl Debug for OutputTooLongErrorOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites the fields, as OutputTooLongError { requested: ..., maximum: ... }.
HkdfSha256#
pub struct HkdfSha256HKDF with SHA-256 as the hash (RFC 5869). The PRK is 32 bytes and the output is at most 8160 bytes.
When to use#
Use it to turn a shared secret, such as the result of an X25519 key exchange, into one or more
keys of the length that you need. Give each key a different info label so that the keys are
independent.
Details#
HKDF has two steps. extract mixes the input key material with a salt and returns a
pseudorandom key (PRK). expand turns the PRK and an info label into output of any length up
to 8160 bytes. Nothing allocates.
Gotchas#
HKDF is not for passwords. A password needs a slow function such as Argon2 or scrypt. The PRK is a secret and is not erased.
Implementation HkdfSha256#
impl HkdfSha256Associated function extract#
pub fn extract(salt: &[u8], ikm: &[u8]) -> [u8; 32]Returns the 32-byte pseudorandom key (PRK) for the input key material ikm and salt.
An empty salt is the same as 32 zero bytes. Use a random salt if the protocol has one. Pass
the result to HkdfSha256.expand.
Gotchas#
The program traps if salt or ikm is longer than the hash allows (2^64 bits).
Associated function expand#
pub fn expand(prk: &([u8; 32]), info: &[u8], output: &mut [u8]) -> Result<(), OutputTooLongError>Fills all of output with key material from prk and the label info.
prk must come from HkdfSha256.extract, or be another uniformly random key of 32 bytes.
An empty info and an empty output are valid. The same prk and info always give the
same bytes, and a shorter output is a prefix of a longer one.
Errors#
OutputTooLongErrorifoutputis longer than 8160 bytes.outputdoes not change.
HkdfSha384#
pub struct HkdfSha384HKDF with SHA-384 as the hash (RFC 5869). The PRK is 48 bytes and the output is at most 12240 bytes.
When to use#
Use it to turn a shared secret, such as the result of an X25519 key exchange, into one or more
keys of the length that you need. Give each key a different info label so that the keys are
independent.
Details#
HKDF has two steps. extract mixes the input key material with a salt and returns a
pseudorandom key (PRK). expand turns the PRK and an info label into output of any length up
to 12240 bytes. Nothing allocates.
Gotchas#
HKDF is not for passwords. A password needs a slow function such as Argon2 or scrypt. The PRK is a secret and is not erased.
Implementation HkdfSha384#
impl HkdfSha384Associated function extract#
pub fn extract(salt: &[u8], ikm: &[u8]) -> [u8; 48]Returns the 48-byte pseudorandom key (PRK) for the input key material ikm and salt.
An empty salt is the same as 48 zero bytes. Use a random salt if the protocol has one. Pass
the result to HkdfSha384.expand.
Gotchas#
The program traps if salt or ikm is longer than the hash allows (2^128 bits).
Associated function expand#
pub fn expand(prk: &([u8; 48]), info: &[u8], output: &mut [u8]) -> Result<(), OutputTooLongError>Fills all of output with key material from prk and the label info.
prk must come from HkdfSha384.extract, or be another uniformly random key of 48 bytes.
An empty info and an empty output are valid. The same prk and info always give the
same bytes, and a shorter output is a prefix of a longer one.
Errors#
OutputTooLongErrorifoutputis longer than 12240 bytes.outputdoes not change.
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.