stream.bend
bend-osdev-crypto@0.1.0.0 · 115 lines · 15 definitions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28import Base
29import bend-osdev-bytes@0.1.0.0/bytes.bend as B
30import bend-osdev-crypto@0.1.0.0/crypto.bend as Cr
31
32
33def CrStream.crypt(~S: Data, ~O: Data, ~start: B.Octets -> B.Octets -> Result<&2, &2, Cr.CrError, S>, ~update: S -> B.Octets -> O, ~out_data: O -> B.Octets, key: B.Octets, iv: B.Octets, m: B.Octets) -> Result<&2, &2, Cr.CrError, B.Octets>:
34 Result.map(&2, &2, Cr.CrError, S, B.Octets, s => out_data(update(s, m)), start(key, iv))
35
36
37def CrStream.keystream(~S: Data, ~O: Data, ~update: S -> B.Octets -> O, ~out_data: O -> B.Octets, s: S, n: Nat) -> B.Octets:
38 out_data(update(s, B.Octets.zeros(n)))
39
40
41
42
43type CrKsStep<-S: Data> is Data:
44 CrKsStep{k: U32, st: S}
45
46
47
48type CrXorOut<-S: Data> is Data:
49 CrXorOut{state: S, data: B.Octets}
50
51def CrKsStep.k(~S: Data, r: CrKsStep<S>) -> U32:
52 match r:
53 case CrKsStep{k, st}:
54 k
55
56def CrKsStep.st(~S: Data, r: CrKsStep<S>) -> S:
57 match r:
58 case CrKsStep{k, st}:
59 st
60
61
62
63def cr.ks.xs(~S: Data, ~next: S -> CrKsStep<S>, ys: List<&2, U32>, +s: S) -> List<&2, U32>:
64 match ys:
65 case Nil{}:
66 Nil{}
67 case Con{x, t}:
68 Con{B.byte(U32.xor(x, CrKsStep.k(~S, next(s)))), cr.ks.xs(~S, ~next, t, CrKsStep.st(~S, next(s)))}
69
70def cr.ks.after(~S: Data, ~next: S -> CrKsStep<S>, ys: List<&2, U32>, +s: S) -> S:
71 match ys:
72 case Nil{}:
73 s
74 case Con{x, t}:
75 cr.ks.after(~S, ~next, t, CrKsStep.st(~S, next(s)))
76
77
78
79type CrKsRun<-S: Data> is Data:
80 CrKsRun{st: S, rev: List<&2, U32>}
81
82def cr.rev_onto(xs: List<&2, U32>, acc: List<&2, U32>) -> List<&2, U32>:
83 match xs:
84 case Nil{}:
85 acc
86 case Con{h, t}:
87 cr.rev_onto(t, Con{h, acc})
88
89def cr.ks.go(~S: Data, ~next: S -> CrKsStep<S>, ys: List<&2, U32>, +s: S, acc: List<&2, U32>) -> CrKsRun<S>:
90 match ys:
91 case Nil{}:
92 CrKsRun{s, acc}
93 case Con{x, t}:
94 +r = next(s)
95 cr.ks.go(~S, ~next, t, CrKsStep.st(~S, r), Con{B.byte(U32.xor(x, CrKsStep.k(~S, r))), acc})
96
97def cr.ks.out(~S: Data, r: CrKsRun<S>) -> CrXorOut<S>:
98 match r:
99 case CrKsRun{st, rev}:
100 CrXorOut{st, B.Octets.of_list(cr.rev_onto(rev, Nil{}))}
101
102
103
104def CrXor.update(~S: Data, ~next: S -> CrKsStep<S>, s: S, m: B.Octets) -> CrXorOut<S>:
105 cr.ks.out(~S, cr.ks.go(~S, ~next, B.Octets.to_list(m), s, Nil{}))
106
107def CrXor.out_state(~S: Data, o: CrXorOut<S>) -> S:
108 match o:
109 case CrXorOut{st, d}:
110 st
111
112def CrXor.out_data(~S: Data, o: CrXorOut<S>) -> B.Octets:
113 match o:
114 case CrXorOut{st, d}:
115 d