spec/crypto/chacha20poly1305.bend
bend-collections@1.0.0.0 · 70 lines · 12 definitions
1import Base
2import bend-collections@1.0.0.0/spec/crypto/chacha.bend as CH
3import bend-collections@1.0.0.0/spec/crypto/poly1305.bend as PS
4import bend-collections@1.0.0.0/spec/crypto/subtle.bend as EQ
5
6
7
8
9
10
11
12
13
14
15def poly_key(+key: List<&2, U32>, +nonce: List<&2, U32>) -> List<&2, U32>:
16 CH.prefix(32n, CH.block(key, 0, nonce))
17
18
19
20def pad16(+xs: List<&2, U32>) -> List<&2, U32>:
21 List.replicate(U32, Nat.mod(Nat.sub(16n, Nat.mod(List.length(&2, U32, xs), 16n)), 16n), 0)
22
23
24def le8(n: Nat, +x: Nat) -> List<&2, U32>:
25 match n:
26 case 0n: Nil{}
27 case 1n+k: U32.from_nat(Nat.mod(x, 256n)) <> le8(k, Nat.div(x, 256n))
28
29
30
31def mac_data(+aad: List<&2, U32>, +ct: List<&2, U32>) -> List<&2, U32>:
32 List.append(&2, U32, aad, List.append(&2, U32, pad16(aad), List.append(&2, U32, ct,
33 List.append(&2, U32, pad16(ct), List.append(&2, U32, le8(8n, List.length(&2, U32, aad)), le8(8n, List.length(&2, U32, ct)))))))
34
35def tag(+key: List<&2, U32>, +nonce: List<&2, U32>, +aad: List<&2, U32>, +ct: List<&2, U32>) -> List<&2, U32>:
36 PS.mac(poly_key(key, nonce), mac_data(aad, ct))
37
38
39
40def seal(+key: List<&2, U32>, +nonce: List<&2, U32>, +aad: List<&2, U32>, +pt: List<&2, U32>) -> List<&2, U32>:
41 +ct = CH.encrypt(key, 1, nonce, pt)
42 List.append(&2, U32, ct, tag(key, nonce, aad, ct))
43
44
45
46def open_tag(ok: Bool, +key: List<&2, U32>, +nonce: List<&2, U32>, +ct: List<&2, U32>) -> Maybe<&2, List<&2, U32>>:
47 match ok:
48 case True{}: Some{CH.encrypt(key, 1, nonce, ct)}
49 case False{}: None{}
50
51def open_split(+key: List<&2, U32>, +nonce: List<&2, U32>, +aad: List<&2, U32>, +ct: List<&2, U32>, +t: List<&2, U32>) -> Maybe<&2, List<&2, U32>>:
52 open_tag(EQ.equal(t, tag(key, nonce, aad, ct)), key, nonce, ct)
53
54def open_len(short: Bool, +key: List<&2, U32>, +nonce: List<&2, U32>, +aad: List<&2, U32>, +data: List<&2, U32>) -> Maybe<&2, List<&2, U32>>:
55 match short:
56 case True{}: None{}
57 case False{}:
58 +n = Nat.sub(List.length(&2, U32, data), 16n)
59 open_split(key, nonce, aad, CH.prefix(n, data), CH.suffix(n, data))
60
61def open(+key: List<&2, U32>, +nonce: List<&2, U32>, +aad: List<&2, U32>, +data: List<&2, U32>) -> Maybe<&2, List<&2, U32>>:
62 open_len(Nat.is_lt(List.length(&2, U32, data), 16n), key, nonce, aad, data)
63
64
65
66def xseal(+key: List<&2, U32>, +nonce: List<&2, U32>, +aad: List<&2, U32>, +pt: List<&2, U32>) -> List<&2, U32>:
67 seal(CH.xsubkey(key, nonce), CH.xnonce(nonce), aad, pt)
68
69def xopen(+key: List<&2, U32>, +nonce: List<&2, U32>, +aad: List<&2, U32>, +data: List<&2, U32>) -> Maybe<&2, List<&2, U32>>:
70 open(CH.xsubkey(key, nonce), CH.xnonce(nonce), aad, data)