spec/crypto/hkdf.bend
bend-collections-laws-crypto@1.0.0.0 · 53 lines · 9 definitions
1import Base
2import bend-collections-laws-crypto@1.0.0.0/spec/crypto/hmac.bend as HMAC
3
4
5
6
7
8def hash_len() -> Nat:
9 32n
10
11
12def max_length() -> Nat:
13 8160n
14
15
16
17
18def extract(+salt: List<&2, U32>, ikm: List<&2, U32>) -> List<&2, U32>:
19 HMAC.hmac(salt, ikm)
20
21
22
23
24def t_blocks(n: Nat, +prk: List<&2, U32>, +info: List<&2, U32>, prev: List<&2, U32>, +i: Nat) -> List<&2, U32>:
25 match n:
26 case 0n:
27 Nil{}
28 case 1n+p:
29 +t = HMAC.hmac(prk, List.append(&2, U32, prev,
30 List.append(&2, U32, info, [U32.from_nat(1n+i)])))
31 List.append(&2, U32, t, t_blocks(p, prk, info, t, 1n+i))
32
33
34def block_count(+len: Nat) -> Nat:
35 Nat.div(Nat.add(len, 31n), hash_len())
36
37
38def okm(+prk: List<&2, U32>, +info: List<&2, U32>, +len: Nat) -> List<&2, U32>:
39 List.take(&2, U32, t_blocks(block_count(len), prk, info, Nil{}, 0n), len)
40
41
42def expand_if(+prk: List<&2, U32>, +info: List<&2, U32>, +len: Nat, ok: Bool) -> Maybe<&2, List<&2, U32>>:
43 match ok:
44 case True{}:
45 Some{okm(prk, info, len)}
46 case False{}:
47 None{}
48
49def expand(+prk: List<&2, U32>, +info: List<&2, U32>, +len: Nat) -> Maybe<&2, List<&2, U32>>:
50 expand_if(prk, info, len, Nat.is_le(len, max_length()))
51
52def hkdf(+salt: List<&2, U32>, ikm: List<&2, U32>, +info: List<&2, U32>, +len: Nat) -> Maybe<&2, List<&2, U32>>:
53 expand(extract(salt, ikm), info, len)