48 lines
1.3 KiB
Typst
48 lines
1.3 KiB
Typst
#import "utils.typ": xor-bytes
|
|
#import "sha.typ": sha1
|
|
|
|
#let _compute-block-sized-key(key, hash-func: sha1, block-size: 64) = {
|
|
if key.len() > block-size {
|
|
key = hash-func(key)
|
|
}
|
|
|
|
if key.len() < block-size {
|
|
key = bytes((0,) * (block-size - key.len())) + key
|
|
}
|
|
|
|
return key
|
|
}
|
|
|
|
/// Hash-based Message Authentication Code
|
|
/// ```example
|
|
/// #bytes-to-hex(hmac("Key", "Hello World!"))
|
|
/// ```
|
|
/// -> bytes
|
|
#let hmac(
|
|
/// Hashing key
|
|
/// -> str | bytes
|
|
key,
|
|
/// Message to hash
|
|
/// -> str | bytes
|
|
message,
|
|
/// Hashing function
|
|
/// -> function
|
|
hash-func: sha1,
|
|
/// Block size
|
|
/// -> number
|
|
block-size: 64
|
|
) = {
|
|
let key = if type(key) == str {bytes(key)} else {key}
|
|
let message = if type(message) == str {bytes(message)} else {message}
|
|
assert(type(key) == bytes, message: "key must be a string or bytes, but is " + repr(type(key)))
|
|
assert(type(message) == bytes, message: "message must be a string or bytes, but is " + repr(type(message)))
|
|
|
|
let block-sized-key = _compute-block-sized-key(key, hash-func: hash-func, block-size: block-size)
|
|
|
|
let i-pad = bytes((0x36,) * block-size)
|
|
let o-pad = bytes((0x5c,) * block-size)
|
|
let i-key-pad = xor-bytes(key, i-pad)
|
|
let o-key-pad = xor-bytes(key, o-pad)
|
|
|
|
return hash-func(o-key-pad + hash-func(i-key-pad + message))
|
|
} |