src/math/random/chacha8.bend
bend-collections-laws-crypto@1.0.0.0 · 123 lines · 15 definitions
1import Base
2import bend-collections-laws-crypto@1.0.0.0/src/math/u64.bend as W
3import bend-collections-laws-crypto@1.0.0.0/src/math/random/chacha8/block.bend as B
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30type Phase is Data:
31 G0{}
32 G1{}
33 G2{}
34 G3{}
35
36type ChaCha8 is Data:
37 C{key: B.Key, phase: Phase, buf: List<&2, W.U64>}
38
39def zero() -> W.U64:
40 W.U64{0, 0}
41
42def of_key(k: B.Key) -> ChaCha8:
43 C{k, G0{}, []}
44
45
46def rekey(l: List<&2, W.U64>) -> B.Key:
47 match l:
48 case [W.U64{k0, k1}, W.U64{k2, k3}, W.U64{k4, k5}, W.U64{k6, k7}]:
49 B.K{k0, k1, k2, k3, k4, k5, k6, k7}
50 case _:
51 B.K{0, 0, 0, 0, 0, 0, 0, 0}
52
53
54def last(+g: List<&2, W.U64>) -> ChaCha8:
55 C{rekey(List.drop(&2, W.U64, g, 28n)), G0{}, List.take(&2, W.U64, g, 28n)}
56
57def refill(+k: B.Key, p: Phase) -> ChaCha8:
58 match p:
59 case G0{}:
60 C{k, G1{}, B.group(k, 0)}
61 case G1{}:
62 C{k, G2{}, B.group(k, 4)}
63 case G2{}:
64 C{k, G3{}, B.group(k, 8)}
65 case G3{}:
66 last(B.group(k, 12))
67
68def pop(g: ChaCha8) -> W.U64 & ChaCha8:
69 match g:
70 case C{k, p, buf}:
71 match buf:
72 case Con{x, rest}:
73 (x, C{k, p, rest})
74 case Nil{}:
75 (zero(), C{k, p, []})
76
77
78def next(g: ChaCha8) -> W.U64 & ChaCha8:
79 match g:
80 case C{+k, p, buf}:
81 match buf:
82 case Con{x, rest}:
83 (x, C{k, p, rest})
84 case Nil{}:
85 pop(refill(k, p))
86
87
88
89
90def le32(+b0: U32, +b1: U32, +b2: U32, +b3: U32) -> U32:
91 U32.or(U32.or(U32.or(b0, U32.shln(b1, 8n)), U32.shln(b2, 16n)), U32.shln(b3, 24n))
92
93def all_bytes(bs: List<&2, U32>) -> Bool:
94 match bs:
95 case Nil{}:
96 True{}
97 case Con{+b, rest}:
98 Bool.and(U32.is_lt(b, 256), all_bytes(rest))
99
100def key_of(bs: List<&2, U32>) -> Maybe<&2, B.Key>:
101 match bs:
102 case [a0, a1, a2, a3, b0, b1, b2, b3, c0, c1, c2, c3, d0, d1, d2, d3, e0, e1, e2, e3, f0, f1, f2, f3, g0, g1, g2, g3, h0, h1, h2, h3]:
103 Some{B.K{le32(a0, a1, a2, a3), le32(b0, b1, b2, b3), le32(c0, c1, c2, c3), le32(d0, d1, d2, d3), le32(e0, e1, e2, e3), le32(f0, f1, f2, f3), le32(g0, g1, g2, g3), le32(h0, h1, h2, h3)}}
104 case _:
105 None{}
106
107def lift(m: Maybe<&2, B.Key>) -> Maybe<&2, ChaCha8>:
108 match m:
109 case None{}:
110 None{}
111 case Some{k}:
112 Some{of_key(k)}
113
114def seed_ok(bs: List<&2, U32>, ok: Bool) -> Maybe<&2, ChaCha8>:
115 match ok:
116 case False{}:
117 None{}
118 case True{}:
119 lift(key_of(bs))
120
121
122def new(+seed: List<&2, U32>) -> Maybe<&2, ChaCha8>:
123 seed_ok(seed, all_bytes(seed))