gf.bend
bend-osdev-gf@0.1.1.0 · 175 lines · 30 definitions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import Base
18
19type Gf8Field is Data:
20 Gf8Field{poly: U32, gen: U32}
21
22
23
24
25def Gf8.aes() -> Gf8Field:
26 Gf8Field{283, 3}
27
28
29def Gf8.rs() -> Gf8Field:
30 Gf8Field{285, 2}
31
32def Gf8.raid6() -> Gf8Field:
33 Gf8.rs()
34
35def Gf8.poly(f: Gf8Field) -> U32:
36 match f:
37 case Gf8Field{poly, gen}:
38 poly
39
40def Gf8.gen(f: Gf8Field) -> U32:
41 match f:
42 case Gf8Field{poly, gen}:
43 gen
44
45
46
47type Gf8Bits is Data:
48 Gf8Bits{b0: Bool, b1: Bool, b2: Bool, b3: Bool, b4: Bool, b5: Bool, b6: Bool, b7: Bool}
49
50
51def Gf8Bits.of(a: U32) -> Gf8Bits:
52 match a:
53 case U32{WCon{b0, WCon{b1, WCon{b2, WCon{b3, WCon{b4, WCon{b5, WCon{b6, WCon{b7, r}}}}}}}}}:
54 Gf8Bits{b0, b1, b2, b3, b4, b5, b6, b7}
55
56def Gf8Bits.to(r: Gf8Bits) -> U32:
57 match r:
58 case Gf8Bits{b0, b1, b2, b3, b4, b5, b6, b7}:
59 U32{WCon{b0, WCon{b1, WCon{b2, WCon{b3, WCon{b4, WCon{b5, WCon{b6, WCon{b7, Word.zero(24n)}}}}}}}}}
60
61def Gf8Bits.zero() -> Gf8Bits:
62 Gf8Bits{False{}, False{}, False{}, False{}, False{}, False{}, False{}, False{}}
63
64def Gf8Bits.xor(a: Gf8Bits, b: Gf8Bits) -> Gf8Bits:
65 match a b:
66 case Gf8Bits{a0, a1, a2, a3, a4, a5, a6, a7} Gf8Bits{c0, c1, c2, c3, c4, c5, c6, c7}:
67 Gf8Bits{Bool.xor(a0, c0), Bool.xor(a1, c1), Bool.xor(a2, c2), Bool.xor(a3, c3), Bool.xor(a4, c4), Bool.xor(a5, c5), Bool.xor(a6, c6), Bool.xor(a7, c7)}
68
69
70def Gf8Bits.sel(t: Bool, a: Gf8Bits) -> Gf8Bits:
71 match t:
72 case True{}:
73 a
74 case False{}:
75 Gf8Bits.zero()
76
77
78
79def Gf8Bits.x(a: Gf8Bits, p: Gf8Bits) -> Gf8Bits:
80 match a p:
81 case Gf8Bits{a0, a1, a2, a3, a4, a5, a6, +a7} Gf8Bits{p0, p1, p2, p3, p4, p5, p6, p7}:
82 Gf8Bits{Bool.and(a7, p0), Bool.xor(a0, Bool.and(a7, p1)), Bool.xor(a1, Bool.and(a7, p2)), Bool.xor(a2, Bool.and(a7, p3)), Bool.xor(a3, Bool.and(a7, p4)), Bool.xor(a4, Bool.and(a7, p5)), Bool.xor(a5, Bool.and(a7, p6)), Bool.xor(a6, Bool.and(a7, p7))}
83
84
85def Gf8Bits.step(t: Bool, acc: Gf8Bits, +b: Gf8Bits, +p: Gf8Bits) -> Gf8Bits:
86 Gf8Bits.xor(Gf8Bits.x(acc, p), Gf8Bits.sel(t, b))
87
88
89def Gf8Bits.horner(ts: List<&2, Bool>, acc: Gf8Bits, +b: Gf8Bits, +p: Gf8Bits) -> Gf8Bits:
90 match ts:
91 case Nil{}:
92 acc
93 case Con{t, rest}:
94 Gf8Bits.horner(rest, Gf8Bits.step(t, acc, b, p), b, p)
95
96
97def Gf8Bits.top(a: Gf8Bits) -> List<&2, Bool>:
98 match a:
99 case Gf8Bits{b0, b1, b2, b3, b4, b5, b6, b7}:
100 [b7, b6, b5, b4, b3, b2, b1, b0]
101
102def Gf8Bits.mul(a: Gf8Bits, +b: Gf8Bits, +p: Gf8Bits) -> Gf8Bits:
103 Gf8Bits.horner(Gf8Bits.top(a), Gf8Bits.zero(), b, p)
104
105
106
107
108def Gf8.elt(a: U32) -> U32:
109 Gf8Bits.to(Gf8Bits.of(a))
110
111
112def Gf8Bits.is_zero(a: Gf8Bits) -> Bool:
113 match a:
114 case Gf8Bits{b0, b1, b2, b3, b4, b5, b6, b7}:
115 Bool.not(Bool.or(b0, Bool.or(b1, Bool.or(b2, Bool.or(b3, Bool.or(b4, Bool.or(b5, Bool.or(b6, b7))))))))
116
117def Gf8.is_zero(a: U32) -> Bool:
118 Gf8Bits.is_zero(Gf8Bits.of(a))
119
120def Gf8.add(a: U32, b: U32) -> U32:
121 Gf8Bits.to(Gf8Bits.xor(Gf8Bits.of(a), Gf8Bits.of(b)))
122
123
124def Gf8.sub(a: U32, b: U32) -> U32:
125 Gf8.add(a, b)
126
127def Gf8.mul(f: Gf8Field, a: U32, b: U32) -> U32:
128 match f:
129 case Gf8Field{poly, gen}:
130 Gf8Bits.to(Gf8Bits.mul(Gf8Bits.of(a), Gf8Bits.of(b), Gf8Bits.of(poly)))
131
132
133def Gf8.xtime(f: Gf8Field, a: U32) -> U32:
134 match f:
135 case Gf8Field{poly, gen}:
136 Gf8Bits.to(Gf8Bits.x(Gf8Bits.of(a), Gf8Bits.of(poly)))
137
138
139def Gf8.pow(+f: Gf8Field, +a: U32, n: Nat) -> U32:
140 match n:
141 case 0n:
142 1
143 case 1n+k:
144 Gf8.mul(f, a, Gf8.pow(f, a, k))
145
146
147
148def Gf8.inv(+f: Gf8Field, +a: U32) -> U32:
149 Gf8.pow(f, a, 254n)
150
151
152def Gf8.div(+f: Gf8Field, a: U32, +b: U32) -> U32:
153 Gf8.mul(f, a, Gf8.inv(f, b))
154
155
156
157
158def Gf8.exp(+f: Gf8Field, i: Nat) -> U32:
159 Gf8.pow(f, Gf8.gen(f), i)
160
161
162
163def Gf8.log.go(n: Nat, hit: Bool, +f: Gf8Field, +a: U32, +cur: U32, +i: Nat) -> Nat:
164 match n hit:
165 case _ True{}:
166 i
167 case 0n False{}:
168 0n
169 case 1n+k False{}:
170 +nxt = Gf8.mul(f, Gf8.gen(f), cur)
171 Gf8.log.go(k, U32.is_eq(nxt, a), f, a, nxt, 1n+i)
172
173def Gf8.log(+f: Gf8Field, a: U32) -> Nat:
174 +e = Gf8.elt(a)
175 Gf8.log.go(254n, U32.is_eq(1, e), f, e, 1, 0n)