|
1 local bit = require("bit"); |
|
2 |
|
3 -- finite field with base 2 and modulo irreducible polynom x^8+x^4+x^3+x+1 = 0x11d |
|
4 local private = {}; |
|
5 local public = {}; |
|
6 |
|
7 local aeslua = require("aeslua"); |
|
8 aeslua.gf = public; |
|
9 |
|
10 -- private data of gf |
|
11 private.n = 0x100; |
|
12 private.ord = 0xff; |
|
13 private.irrPolynom = 0x11b; |
|
14 private.exp = {}; |
|
15 private.log = {}; |
|
16 |
|
17 -- |
|
18 -- add two polynoms (its simply xor) |
|
19 -- |
|
20 function public.add(operand1, operand2) |
|
21 return bit.bxor(operand1,operand2); |
|
22 end |
|
23 |
|
24 -- |
|
25 -- subtract two polynoms (same as addition) |
|
26 -- |
|
27 function public.sub(operand1, operand2) |
|
28 return bit.bxor(operand1,operand2); |
|
29 end |
|
30 |
|
31 -- |
|
32 -- inverts element |
|
33 -- a^(-1) = g^(order - log(a)) |
|
34 -- |
|
35 function public.invert(operand) |
|
36 -- special case for 1 |
|
37 if (operand == 1) then |
|
38 return 1; |
|
39 end; |
|
40 -- normal invert |
|
41 local exponent = private.ord - private.log[operand]; |
|
42 return private.exp[exponent]; |
|
43 end |
|
44 |
|
45 -- |
|
46 -- multiply two elements using a logarithm table |
|
47 -- a*b = g^(log(a)+log(b)) |
|
48 -- |
|
49 function public.mul(operand1, operand2) |
|
50 if (operand1 == 0 or operand2 == 0) then |
|
51 return 0; |
|
52 end |
|
53 |
|
54 local exponent = private.log[operand1] + private.log[operand2]; |
|
55 if (exponent >= private.ord) then |
|
56 exponent = exponent - private.ord; |
|
57 end |
|
58 return private.exp[exponent]; |
|
59 end |
|
60 |
|
61 -- |
|
62 -- divide two elements |
|
63 -- a/b = g^(log(a)-log(b)) |
|
64 -- |
|
65 function public.div(operand1, operand2) |
|
66 if (operand1 == 0) then |
|
67 return 0; |
|
68 end |
|
69 -- TODO: exception if operand2 == 0 |
|
70 local exponent = private.log[operand1] - private.log[operand2]; |
|
71 if (exponent < 0) then |
|
72 exponent = exponent + private.ord; |
|
73 end |
|
74 return private.exp[exponent]; |
|
75 end |
|
76 |
|
77 -- |
|
78 -- print logarithmic table |
|
79 -- |
|
80 function public.printLog() |
|
81 for i = 1, private.n do |
|
82 print("log(", i-1, ")=", private.log[i-1]); |
|
83 end |
|
84 end |
|
85 |
|
86 -- |
|
87 -- print exponentiation table |
|
88 -- |
|
89 function public.printExp() |
|
90 for i = 1, private.n do |
|
91 print("exp(", i-1, ")=", private.exp[i-1]); |
|
92 end |
|
93 end |
|
94 |
|
95 -- |
|
96 -- calculate logarithmic and exponentiation table |
|
97 -- |
|
98 function private.initMulTable() |
|
99 local a = 1; |
|
100 |
|
101 for i = 0,private.ord-1 do |
|
102 private.exp[i] = a; |
|
103 private.log[a] = i; |
|
104 |
|
105 -- multiply with generator x+1 -> left shift + 1 |
|
106 a = bit.bxor(bit.lshift(a, 1), a); |
|
107 |
|
108 -- if a gets larger than order, reduce modulo irreducible polynom |
|
109 if a > private.ord then |
|
110 a = public.sub(a, private.irrPolynom); |
|
111 end |
|
112 end |
|
113 end |
|
114 |
|
115 private.initMulTable(); |
|
116 |
|
117 return public; |