-
Notifications
You must be signed in to change notification settings - Fork 0
/
GF28.cry
44 lines (33 loc) · 1.29 KB
/
GF28.cry
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
module GF28 where
type GF28 = [8]
/** The irreducable polynomial */
irreducible = <| x^^8 + x^^7 + x^^6 + x + 1 |>
/** Sum up a bunch of GF28 values */
gf28Add : {n} (fin n) => [n]GF28 -> GF28
gf28Add ps = sums ! 0
where sums = [zero] # [ p ^ s | p <- ps | s <- sums ]
/** Multiply two GF28 values */
gf28Mult : GF28 -> GF28 -> GF28
gf28Mult x y = pmod (pmult x y) irreducible
/** A GF28 value to a scalar power */
gf28Pow : GF28 -> [8] -> GF28
gf28Pow n k = pow k
where sq x = gf28Mult x x
odd x = x ! 0
pow i = if i == 0 then 1
else if odd i
then gf28Mult n (sq (pow (i >> 1)))
else sq (pow (i >> 1))
/** Compute the inverse of a value */
gf28Inverse : GF28 -> GF28
gf28Inverse x = gf28Pow x 254
/** Dot product of two vectors */
gf28DotProduct : {n} (fin n) => [n]GF28 -> [n]GF28 -> GF28
gf28DotProduct xs ys = gf28Add [ gf28Mult x y | x <- xs | y <- ys ]
/** Multiply a matrix by a vector */
gf28VectorMult : {n, m} (fin n) => [n]GF28 -> [m][n]GF28 -> [m]GF28
gf28VectorMult v ms = [ gf28DotProduct v m | m <- ms ]
/** Multiply two matrices */
gf28MatrixMult : {n, m, k} (fin m) => [n][m]GF28 -> [m][k]GF28 -> [n][k]GF28
gf28MatrixMult xss yss = [ gf28VectorMult xs yss' | xs <- xss ]
where yss' = transpose yss