xref: /OK3568_Linux_fs/external/rkupdate/CRC.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun #include "DefineHeader.h"
2*4882a593Smuzhiyun UINT gTable_Crc32[256] =
3*4882a593Smuzhiyun {
4*4882a593Smuzhiyun     0x00000000, 0x04c10db7, 0x09821b6e, 0x0d4316d9,
5*4882a593Smuzhiyun     0x130436dc, 0x17c53b6b, 0x1a862db2, 0x1e472005,
6*4882a593Smuzhiyun     0x26086db8, 0x22c9600f, 0x2f8a76d6, 0x2b4b7b61,
7*4882a593Smuzhiyun     0x350c5b64, 0x31cd56d3, 0x3c8e400a, 0x384f4dbd,
8*4882a593Smuzhiyun     0x4c10db70, 0x48d1d6c7, 0x4592c01e, 0x4153cda9,
9*4882a593Smuzhiyun     0x5f14edac, 0x5bd5e01b, 0x5696f6c2, 0x5257fb75,
10*4882a593Smuzhiyun     0x6a18b6c8, 0x6ed9bb7f, 0x639aada6, 0x675ba011,
11*4882a593Smuzhiyun     0x791c8014, 0x7ddd8da3, 0x709e9b7a, 0x745f96cd,
12*4882a593Smuzhiyun     0x9821b6e0, 0x9ce0bb57, 0x91a3ad8e, 0x9562a039,
13*4882a593Smuzhiyun     0x8b25803c, 0x8fe48d8b, 0x82a79b52, 0x866696e5,
14*4882a593Smuzhiyun     0xbe29db58, 0xbae8d6ef, 0xb7abc036, 0xb36acd81,
15*4882a593Smuzhiyun     0xad2ded84, 0xa9ece033, 0xa4aff6ea, 0xa06efb5d,
16*4882a593Smuzhiyun     0xd4316d90, 0xd0f06027, 0xddb376fe, 0xd9727b49,
17*4882a593Smuzhiyun     0xc7355b4c, 0xc3f456fb, 0xceb74022, 0xca764d95,
18*4882a593Smuzhiyun     0xf2390028, 0xf6f80d9f, 0xfbbb1b46, 0xff7a16f1,
19*4882a593Smuzhiyun     0xe13d36f4, 0xe5fc3b43, 0xe8bf2d9a, 0xec7e202d,
20*4882a593Smuzhiyun     0x34826077, 0x30436dc0, 0x3d007b19, 0x39c176ae,
21*4882a593Smuzhiyun     0x278656ab, 0x23475b1c, 0x2e044dc5, 0x2ac54072,
22*4882a593Smuzhiyun     0x128a0dcf, 0x164b0078, 0x1b0816a1, 0x1fc91b16,
23*4882a593Smuzhiyun     0x018e3b13, 0x054f36a4, 0x080c207d, 0x0ccd2dca,
24*4882a593Smuzhiyun     0x7892bb07, 0x7c53b6b0, 0x7110a069, 0x75d1adde,
25*4882a593Smuzhiyun     0x6b968ddb, 0x6f57806c, 0x621496b5, 0x66d59b02,
26*4882a593Smuzhiyun     0x5e9ad6bf, 0x5a5bdb08, 0x5718cdd1, 0x53d9c066,
27*4882a593Smuzhiyun     0x4d9ee063, 0x495fedd4, 0x441cfb0d, 0x40ddf6ba,
28*4882a593Smuzhiyun     0xaca3d697, 0xa862db20, 0xa521cdf9, 0xa1e0c04e,
29*4882a593Smuzhiyun     0xbfa7e04b, 0xbb66edfc, 0xb625fb25, 0xb2e4f692,
30*4882a593Smuzhiyun     0x8aabbb2f, 0x8e6ab698, 0x8329a041, 0x87e8adf6,
31*4882a593Smuzhiyun     0x99af8df3, 0x9d6e8044, 0x902d969d, 0x94ec9b2a,
32*4882a593Smuzhiyun     0xe0b30de7, 0xe4720050, 0xe9311689, 0xedf01b3e,
33*4882a593Smuzhiyun     0xf3b73b3b, 0xf776368c, 0xfa352055, 0xfef42de2,
34*4882a593Smuzhiyun     0xc6bb605f, 0xc27a6de8, 0xcf397b31, 0xcbf87686,
35*4882a593Smuzhiyun     0xd5bf5683, 0xd17e5b34, 0xdc3d4ded, 0xd8fc405a,
36*4882a593Smuzhiyun     0x6904c0ee, 0x6dc5cd59, 0x6086db80, 0x6447d637,
37*4882a593Smuzhiyun     0x7a00f632, 0x7ec1fb85, 0x7382ed5c, 0x7743e0eb,
38*4882a593Smuzhiyun     0x4f0cad56, 0x4bcda0e1, 0x468eb638, 0x424fbb8f,
39*4882a593Smuzhiyun     0x5c089b8a, 0x58c9963d, 0x558a80e4, 0x514b8d53,
40*4882a593Smuzhiyun     0x25141b9e, 0x21d51629, 0x2c9600f0, 0x28570d47,
41*4882a593Smuzhiyun     0x36102d42, 0x32d120f5, 0x3f92362c, 0x3b533b9b,
42*4882a593Smuzhiyun     0x031c7626, 0x07dd7b91, 0x0a9e6d48, 0x0e5f60ff,
43*4882a593Smuzhiyun     0x101840fa, 0x14d94d4d, 0x199a5b94, 0x1d5b5623,
44*4882a593Smuzhiyun     0xf125760e, 0xf5e47bb9, 0xf8a76d60, 0xfc6660d7,
45*4882a593Smuzhiyun     0xe22140d2, 0xe6e04d65, 0xeba35bbc, 0xef62560b,
46*4882a593Smuzhiyun     0xd72d1bb6, 0xd3ec1601, 0xdeaf00d8, 0xda6e0d6f,
47*4882a593Smuzhiyun     0xc4292d6a, 0xc0e820dd, 0xcdab3604, 0xc96a3bb3,
48*4882a593Smuzhiyun     0xbd35ad7e, 0xb9f4a0c9, 0xb4b7b610, 0xb076bba7,
49*4882a593Smuzhiyun     0xae319ba2, 0xaaf09615, 0xa7b380cc, 0xa3728d7b,
50*4882a593Smuzhiyun     0x9b3dc0c6, 0x9ffccd71, 0x92bfdba8, 0x967ed61f,
51*4882a593Smuzhiyun     0x8839f61a, 0x8cf8fbad, 0x81bbed74, 0x857ae0c3,
52*4882a593Smuzhiyun     0x5d86a099, 0x5947ad2e, 0x5404bbf7, 0x50c5b640,
53*4882a593Smuzhiyun     0x4e829645, 0x4a439bf2, 0x47008d2b, 0x43c1809c,
54*4882a593Smuzhiyun     0x7b8ecd21, 0x7f4fc096, 0x720cd64f, 0x76cddbf8,
55*4882a593Smuzhiyun     0x688afbfd, 0x6c4bf64a, 0x6108e093, 0x65c9ed24,
56*4882a593Smuzhiyun     0x11967be9, 0x1557765e, 0x18146087, 0x1cd56d30,
57*4882a593Smuzhiyun     0x02924d35, 0x06534082, 0x0b10565b, 0x0fd15bec,
58*4882a593Smuzhiyun     0x379e1651, 0x335f1be6, 0x3e1c0d3f, 0x3add0088,
59*4882a593Smuzhiyun     0x249a208d, 0x205b2d3a, 0x2d183be3, 0x29d93654,
60*4882a593Smuzhiyun     0xc5a71679, 0xc1661bce, 0xcc250d17, 0xc8e400a0,
61*4882a593Smuzhiyun     0xd6a320a5, 0xd2622d12, 0xdf213bcb, 0xdbe0367c,
62*4882a593Smuzhiyun     0xe3af7bc1, 0xe76e7676, 0xea2d60af, 0xeeec6d18,
63*4882a593Smuzhiyun     0xf0ab4d1d, 0xf46a40aa, 0xf9295673, 0xfde85bc4,
64*4882a593Smuzhiyun     0x89b7cd09, 0x8d76c0be, 0x8035d667, 0x84f4dbd0,
65*4882a593Smuzhiyun     0x9ab3fbd5, 0x9e72f662, 0x9331e0bb, 0x97f0ed0c,
66*4882a593Smuzhiyun     0xafbfa0b1, 0xab7ead06, 0xa63dbbdf, 0xa2fcb668,
67*4882a593Smuzhiyun     0xbcbb966d, 0xb87a9bda, 0xb5398d03, 0xb1f880b4,
68*4882a593Smuzhiyun };
69*4882a593Smuzhiyun #define rr_max  104 /* Number of parity checks, rr = deg[g(x)] */
70*4882a593Smuzhiyun #define parallel 8 //bit count
71*4882a593Smuzhiyun #define mm 13//limit count
72*4882a593Smuzhiyun #define nn 8191//code size
73*4882a593Smuzhiyun #define kk 4120//info length
74*4882a593Smuzhiyun #define tt 8//correct count
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun #define tt2 2*tt
77*4882a593Smuzhiyun UINT s[tt2 + 1]; // Syndrome values
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun UINT rr;//redundant length      // BCH code parameters
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun UINT p[mm + 1];
83*4882a593Smuzhiyun UINT alpha_to[nn + 1], index_of[nn + 1] ; // Galois field
84*4882a593Smuzhiyun UINT gg[rr_max + 1] ;   // Generator polynomial
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun UINT ggx1 = 0;
87*4882a593Smuzhiyun UINT ggx2 = 0;
88*4882a593Smuzhiyun UINT ggx3 = 0;
89*4882a593Smuzhiyun UINT ggx4 = 0;
90*4882a593Smuzhiyun // get crc32 value
CRC_32(unsigned char * pData,UINT ulSize,UINT uiPreviousValue=0)91*4882a593Smuzhiyun UINT CRC_32(unsigned char *pData, UINT ulSize, UINT uiPreviousValue = 0)
92*4882a593Smuzhiyun {
93*4882a593Smuzhiyun     UINT i;
94*4882a593Smuzhiyun     UINT nAccum = uiPreviousValue;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun     for (i = 0; i < ulSize; i++)
97*4882a593Smuzhiyun     {
98*4882a593Smuzhiyun         nAccum = (nAccum << 8)^gTable_Crc32[(nAccum >> 24) ^ (*pData++)];
99*4882a593Smuzhiyun     }
100*4882a593Smuzhiyun     return nAccum;
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun #define CRC16_CCITT         0x1021  //CRC operator
CRCBuildTable16(unsigned short aPoly,unsigned short * crcTable)103*4882a593Smuzhiyun void CRCBuildTable16(unsigned short aPoly, unsigned short *crcTable)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun     unsigned short i, j;
106*4882a593Smuzhiyun     unsigned short nData;
107*4882a593Smuzhiyun     unsigned short nAccum;
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun     for (i = 0; i < 256; i++)
110*4882a593Smuzhiyun     {
111*4882a593Smuzhiyun         nData = (unsigned short)(i << 8);
112*4882a593Smuzhiyun         nAccum = 0;
113*4882a593Smuzhiyun         for (j = 0; j < 8; j++)
114*4882a593Smuzhiyun         {
115*4882a593Smuzhiyun             if ((nData ^ nAccum) & 0x8000)
116*4882a593Smuzhiyun             {
117*4882a593Smuzhiyun                 nAccum = (nAccum << 1) ^ aPoly;
118*4882a593Smuzhiyun             }
119*4882a593Smuzhiyun             else
120*4882a593Smuzhiyun             {
121*4882a593Smuzhiyun                 nAccum <<= 1;
122*4882a593Smuzhiyun             }
123*4882a593Smuzhiyun             nData <<= 1;
124*4882a593Smuzhiyun         }
125*4882a593Smuzhiyun         crcTable[i] = nAccum;
126*4882a593Smuzhiyun     }
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun 
CRC_16(unsigned char * aData,UINT aSize)129*4882a593Smuzhiyun unsigned short CRC_16(unsigned char *aData, UINT aSize)
130*4882a593Smuzhiyun {
131*4882a593Smuzhiyun     UINT i;
132*4882a593Smuzhiyun     unsigned short nAccum = 0;
133*4882a593Smuzhiyun     unsigned short crcTable[256];
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun     CRCBuildTable16(CRC16_CCITT, crcTable);
136*4882a593Smuzhiyun     for (i = 0; i < aSize; i++)
137*4882a593Smuzhiyun     {
138*4882a593Smuzhiyun         nAccum = (nAccum << 8) ^ crcTable[(nAccum >> 8) ^ *aData++];
139*4882a593Smuzhiyun     }
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun     return nAccum;
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun 
P_RC4(unsigned char * buf,unsigned short len)144*4882a593Smuzhiyun void P_RC4(unsigned char *buf, unsigned short len)
145*4882a593Smuzhiyun {
146*4882a593Smuzhiyun     unsigned char S[256], K[256], temp;
147*4882a593Smuzhiyun     unsigned short i, j, t, x;
148*4882a593Smuzhiyun     unsigned char key[16] = {124, 78, 3, 4, 85, 5, 9, 7, 45, 44, 123, 56, 23, 13, 23, 17};
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun     j = 0;
151*4882a593Smuzhiyun     for (i = 0; i < 256; i++)
152*4882a593Smuzhiyun     {
153*4882a593Smuzhiyun         S[i] = (unsigned char)i;
154*4882a593Smuzhiyun         j &= 0x0f;
155*4882a593Smuzhiyun         K[i] = key[j];
156*4882a593Smuzhiyun         j++;
157*4882a593Smuzhiyun     }
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun     j = 0;
160*4882a593Smuzhiyun     for (i = 0; i < 256; i++)
161*4882a593Smuzhiyun     {
162*4882a593Smuzhiyun         j = (j + S[i] + K[i]) % 256;
163*4882a593Smuzhiyun         temp = S[i];
164*4882a593Smuzhiyun         S[i] = S[j];
165*4882a593Smuzhiyun         S[j] = temp;
166*4882a593Smuzhiyun     }
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun     i = j = 0;
169*4882a593Smuzhiyun     for (x = 0; x < len; x++)
170*4882a593Smuzhiyun     {
171*4882a593Smuzhiyun         i = (i + 1) % 256;
172*4882a593Smuzhiyun         j = (j + S[i]) % 256;
173*4882a593Smuzhiyun         temp = S[i];
174*4882a593Smuzhiyun         S[i] = S[j];
175*4882a593Smuzhiyun         S[j] = temp;
176*4882a593Smuzhiyun         t = (S[i] + (S[j] % 256)) % 256;
177*4882a593Smuzhiyun         buf[x] = buf[x] ^ S[t];
178*4882a593Smuzhiyun     }
179*4882a593Smuzhiyun }
180*4882a593Smuzhiyun 
bch_encode(unsigned char * encode_in,unsigned char * encode_out)181*4882a593Smuzhiyun void bch_encode(unsigned char *encode_in, unsigned char *encode_out)
182*4882a593Smuzhiyun {
183*4882a593Smuzhiyun     UINT i, j;
184*4882a593Smuzhiyun     bool feed_back;
185*4882a593Smuzhiyun     UINT bch1 = 0;
186*4882a593Smuzhiyun     UINT bch2 = 0;
187*4882a593Smuzhiyun     UINT bch3 = 0;
188*4882a593Smuzhiyun     UINT bch4 = 0;
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun     for (i = 0; i < 515; i++)
191*4882a593Smuzhiyun     {
192*4882a593Smuzhiyun         for (j = 0; j < 8; j++)
193*4882a593Smuzhiyun         {
194*4882a593Smuzhiyun             feed_back = (bch1 & 1) ^ ((encode_in[i] >> j) & 1);
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun             bch1 = ((bch1 >> 1) | ((bch2 & 1) * 0x80000000)) ^ (ggx1 * feed_back);
197*4882a593Smuzhiyun             bch2 = ((bch2 >> 1) | ((bch3 & 1) * 0x80000000)) ^ (ggx2 * feed_back);
198*4882a593Smuzhiyun             bch3 = ((bch3 >> 1) | ((bch4 & 1) * 0x80000000)) ^ (ggx3 * feed_back);
199*4882a593Smuzhiyun             bch4 = (((bch4 >> 1) ^ (ggx4 * feed_back))) | (feed_back * 0x80);
200*4882a593Smuzhiyun         }
201*4882a593Smuzhiyun     }
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun     //********Handle FF***********************
204*4882a593Smuzhiyun     bch1 = ~(bch1 ^ 0xad6273b1);
205*4882a593Smuzhiyun     bch2 = ~(bch2 ^ 0x348393d2);
206*4882a593Smuzhiyun     bch3 = ~(bch3 ^ 0xe6ebed3c);
207*4882a593Smuzhiyun     bch4 = ~(bch4 ^ 0xc8);
208*4882a593Smuzhiyun     //*********************************************
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun     for (i = 0; i < 515; i++)
211*4882a593Smuzhiyun     {
212*4882a593Smuzhiyun         encode_out[i] = encode_in[i];
213*4882a593Smuzhiyun     }
214*4882a593Smuzhiyun     encode_out[515] = bch1 & 0x000000ff;
215*4882a593Smuzhiyun     encode_out[516] = (bch1 & 0x0000ff00) >> 8;
216*4882a593Smuzhiyun     encode_out[517] = (bch1 & 0x00ff0000) >> 16;
217*4882a593Smuzhiyun     encode_out[518] = (bch1 & 0xff000000) >> 24;
218*4882a593Smuzhiyun     encode_out[519] = bch2 & 0x000000ff;
219*4882a593Smuzhiyun     encode_out[520] = (bch2 & 0x0000ff00) >> 8;
220*4882a593Smuzhiyun     encode_out[521] = (bch2 & 0x00ff0000) >> 16;
221*4882a593Smuzhiyun     encode_out[522] = (bch2 & 0xff000000) >> 24;
222*4882a593Smuzhiyun     encode_out[523] = bch3 & 0x000000ff;
223*4882a593Smuzhiyun     encode_out[524] = (bch3 & 0x0000ff00) >> 8;
224*4882a593Smuzhiyun     encode_out[525] = (bch3 & 0x00ff0000) >> 16;
225*4882a593Smuzhiyun     encode_out[526] = (bch3 & 0xff000000) >> 24;
226*4882a593Smuzhiyun     encode_out[527] = bch4 & 0x000000ff;
227*4882a593Smuzhiyun }
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun #define poly16_CCITT    0x1021          /* crc-ccitt mask */
230*4882a593Smuzhiyun 
CRC_Calculate(unsigned short crc,unsigned char ch)231*4882a593Smuzhiyun unsigned short CRC_Calculate(unsigned short crc, unsigned char ch)
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun     UINT i;
234*4882a593Smuzhiyun     for (i = 0x80; i != 0; i >>= 1)
235*4882a593Smuzhiyun     {
236*4882a593Smuzhiyun         if ((crc & 0x8000) != 0)
237*4882a593Smuzhiyun         {
238*4882a593Smuzhiyun             crc <<= 1;
239*4882a593Smuzhiyun             crc ^= poly16_CCITT;
240*4882a593Smuzhiyun         }
241*4882a593Smuzhiyun         else
242*4882a593Smuzhiyun         {
243*4882a593Smuzhiyun             crc <<= 1;
244*4882a593Smuzhiyun         }
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun         if ((ch & i) != 0)
247*4882a593Smuzhiyun         {
248*4882a593Smuzhiyun             crc ^= poly16_CCITT;
249*4882a593Smuzhiyun         }
250*4882a593Smuzhiyun     }
251*4882a593Smuzhiyun     return crc;
252*4882a593Smuzhiyun }
CRC_CCITT(unsigned char * p,UINT CalculateNumber)253*4882a593Smuzhiyun unsigned short CRC_CCITT(unsigned char *p, UINT CalculateNumber)
254*4882a593Smuzhiyun {
255*4882a593Smuzhiyun     unsigned short crc = 0xffff;
256*4882a593Smuzhiyun     while (CalculateNumber--)
257*4882a593Smuzhiyun     {
258*4882a593Smuzhiyun         crc = CRC_Calculate(crc, *p);
259*4882a593Smuzhiyun         p++;
260*4882a593Smuzhiyun     }
261*4882a593Smuzhiyun     return crc;
262*4882a593Smuzhiyun }
263*4882a593Smuzhiyun 
gen_poly()264*4882a593Smuzhiyun void gen_poly()
265*4882a593Smuzhiyun {
266*4882a593Smuzhiyun     UINT gen_roots[nn + 1], gen_roots_true[nn + 1] ;    // Roots of generator polynomial
267*4882a593Smuzhiyun     UINT i, j, Temp ;
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun     // Initialization of gen_roots
270*4882a593Smuzhiyun     for (i = 0; i <= nn; i++)
271*4882a593Smuzhiyun     {
272*4882a593Smuzhiyun         gen_roots_true[i] = 0;
273*4882a593Smuzhiyun         gen_roots[i] = 0;
274*4882a593Smuzhiyun     }
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun     // Cyclotomic cosets of gen_roots
277*4882a593Smuzhiyun     for (i = 1; i <= 2 * tt ; i++)
278*4882a593Smuzhiyun     {
279*4882a593Smuzhiyun         for (j = 0; j < mm; j++)
280*4882a593Smuzhiyun         {
281*4882a593Smuzhiyun             Temp = ((1 << j) * i) % nn;
282*4882a593Smuzhiyun             gen_roots_true[Temp] = 1;
283*4882a593Smuzhiyun         }
284*4882a593Smuzhiyun     }
285*4882a593Smuzhiyun     rr = 0;     // Count thenumber of parity check bits
286*4882a593Smuzhiyun     for (i = 0; i < nn; i++)
287*4882a593Smuzhiyun     {
288*4882a593Smuzhiyun         if (gen_roots_true[i] == 1)
289*4882a593Smuzhiyun         {
290*4882a593Smuzhiyun             rr++;
291*4882a593Smuzhiyun             gen_roots[rr] = i;
292*4882a593Smuzhiyun         }
293*4882a593Smuzhiyun     }
294*4882a593Smuzhiyun     // Compute generator polynomial based on its roots
295*4882a593Smuzhiyun     gg[0] = 2 ; // g(x) = (X + alpha) initially
296*4882a593Smuzhiyun     gg[1] = 1 ;
297*4882a593Smuzhiyun     for (i = 2; i <= rr; i++)
298*4882a593Smuzhiyun     {
299*4882a593Smuzhiyun         gg[i] = 1 ;
300*4882a593Smuzhiyun         for (j = i - 1; j > 0; j--)
301*4882a593Smuzhiyun             if (gg[j] != 0)
302*4882a593Smuzhiyun             {
303*4882a593Smuzhiyun                 gg[j] = gg[j - 1] ^ alpha_to[(index_of[gg[j]] + index_of[alpha_to[gen_roots[i]]]) % nn] ;
304*4882a593Smuzhiyun             }
305*4882a593Smuzhiyun             else
306*4882a593Smuzhiyun             {
307*4882a593Smuzhiyun                 gg[j] = gg[j - 1] ;
308*4882a593Smuzhiyun             }
309*4882a593Smuzhiyun         gg[0] = alpha_to[(index_of[gg[0]] + index_of[alpha_to[gen_roots[i]]]) % nn] ;
310*4882a593Smuzhiyun     }
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun     ggx1 = gg[103] | (gg[102] << 1) | (gg[101] << 2) | (gg[100] << 3) | (gg[99] << 4) | (gg[98] << 5) | (gg[97] << 6) | (gg[96] << 7)
313*4882a593Smuzhiyun            | (gg[95] << 8) | (gg[94] << 9) | (gg[93] << 10) | (gg[92] << 11) | (gg[91] << 12) | (gg[90] << 13) | (gg[89] << 14) |
314*4882a593Smuzhiyun            (gg[88] << 15)
315*4882a593Smuzhiyun            | (gg[87] << 16) | (gg[86] << 17) | (gg[85] << 18) | (gg[84] << 19) | (gg[83] << 20) | (gg[82] << 21) | (gg[81] << 22) |
316*4882a593Smuzhiyun            (gg[80] << 23)
317*4882a593Smuzhiyun            | (gg[79] << 24) | (gg[78] << 25) | (gg[77] << 26) | (gg[76] << 27) | (gg[75] << 28) | (gg[74] << 29) | (gg[73] << 30) |
318*4882a593Smuzhiyun            (gg[72] << 31);
319*4882a593Smuzhiyun     ggx2 = gg[71] | (gg[70] << 1) | (gg[69] << 2) | (gg[68] << 3) | (gg[67] << 4) | (gg[66] << 5) | (gg[65] << 6) | (gg[64] << 7)
320*4882a593Smuzhiyun            | (gg[63] << 8) | (gg[62] << 9) | (gg[61] << 10) | (gg[60] << 11) | (gg[59] << 12) | (gg[58] << 13) | (gg[57] << 14) |
321*4882a593Smuzhiyun            (gg[56] << 15)
322*4882a593Smuzhiyun            | (gg[55] << 16) | (gg[54] << 17) | (gg[53] << 18) | (gg[52] << 19) | (gg[51] << 20) | (gg[50] << 21) | (gg[49] << 22) |
323*4882a593Smuzhiyun            (gg[48] << 23)
324*4882a593Smuzhiyun            | (gg[47] << 24) | (gg[46] << 25) | (gg[45] << 26) | (gg[44] << 27) | (gg[43] << 28) | (gg[42] << 29) | (gg[41] << 30) |
325*4882a593Smuzhiyun            (gg[40] << 31);
326*4882a593Smuzhiyun     ggx3 = gg[39] | (gg[38] << 1) | (gg[37] << 2) | (gg[36] << 3) | (gg[35] << 4) | (gg[34] << 5) | (gg[33] << 6) | (gg[32] << 7)
327*4882a593Smuzhiyun            | (gg[31] << 8) | (gg[30] << 9) | (gg[29] << 10) | (gg[28] << 11) | (gg[27] << 12) | (gg[26] << 13) | (gg[25] << 14) |
328*4882a593Smuzhiyun            (gg[24] << 15)
329*4882a593Smuzhiyun            | (gg[23] << 16) | (gg[22] << 17) | (gg[21] << 18) | (gg[20] << 19) | (gg[19] << 20) | (gg[18] << 21) | (gg[17] << 22) |
330*4882a593Smuzhiyun            (gg[16] << 23)
331*4882a593Smuzhiyun            | (gg[15] << 24) | (gg[14] << 25) | (gg[13] << 26) | (gg[12] << 27) | (gg[11] << 28) | (gg[10] << 29) | (gg[9] << 30) |
332*4882a593Smuzhiyun            (gg[8] << 31);
333*4882a593Smuzhiyun     ggx4 = gg[7] | (gg[6] << 1) | (gg[5] << 2) | (gg[4] << 3) | (gg[3] << 4) | (gg[2] << 5) | (gg[1] << 6);
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun }
336*4882a593Smuzhiyun 
generate_gf()337*4882a593Smuzhiyun void generate_gf()
338*4882a593Smuzhiyun {
339*4882a593Smuzhiyun     UINT i;
340*4882a593Smuzhiyun     UINT mask ; // Register states
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun     // Primitive polynomials
343*4882a593Smuzhiyun     for (i = 1; i < mm; i++)
344*4882a593Smuzhiyun     {
345*4882a593Smuzhiyun         p[i] = 0;
346*4882a593Smuzhiyun     }
347*4882a593Smuzhiyun     p[0] = p[mm] = 1;
348*4882a593Smuzhiyun     if (mm == 2)
349*4882a593Smuzhiyun     {
350*4882a593Smuzhiyun         p[1] = 1;
351*4882a593Smuzhiyun     }
352*4882a593Smuzhiyun     else if (mm == 3)
353*4882a593Smuzhiyun     {
354*4882a593Smuzhiyun         p[1] = 1;
355*4882a593Smuzhiyun     }
356*4882a593Smuzhiyun     else if (mm == 4)
357*4882a593Smuzhiyun     {
358*4882a593Smuzhiyun         p[1] = 1;
359*4882a593Smuzhiyun     }
360*4882a593Smuzhiyun     else if (mm == 5)
361*4882a593Smuzhiyun     {
362*4882a593Smuzhiyun         p[2] = 1;
363*4882a593Smuzhiyun     }
364*4882a593Smuzhiyun     else if (mm == 6)
365*4882a593Smuzhiyun     {
366*4882a593Smuzhiyun         p[1] = 1;
367*4882a593Smuzhiyun     }
368*4882a593Smuzhiyun     else if (mm == 7)
369*4882a593Smuzhiyun     {
370*4882a593Smuzhiyun         p[1] = 1;
371*4882a593Smuzhiyun     }
372*4882a593Smuzhiyun     else if (mm == 8)
373*4882a593Smuzhiyun     {
374*4882a593Smuzhiyun         p[4] = p[5] = p[6] = 1;
375*4882a593Smuzhiyun     }
376*4882a593Smuzhiyun     else if (mm == 9)
377*4882a593Smuzhiyun     {
378*4882a593Smuzhiyun         p[4] = 1;
379*4882a593Smuzhiyun     }
380*4882a593Smuzhiyun     else if (mm == 10)
381*4882a593Smuzhiyun     {
382*4882a593Smuzhiyun         p[3] = 1;
383*4882a593Smuzhiyun     }
384*4882a593Smuzhiyun     else if (mm == 11)
385*4882a593Smuzhiyun     {
386*4882a593Smuzhiyun         p[2] = 1;
387*4882a593Smuzhiyun     }
388*4882a593Smuzhiyun     else if (mm == 12)
389*4882a593Smuzhiyun     {
390*4882a593Smuzhiyun         p[3] = p[4] = p[7] = 1;
391*4882a593Smuzhiyun     }
392*4882a593Smuzhiyun     else if (mm == 13)
393*4882a593Smuzhiyun     {
394*4882a593Smuzhiyun         p[1] = p[2] = p[3] = p[5] = p[7] = p[8] = p[10] = 1;    // 25AF
395*4882a593Smuzhiyun     }
396*4882a593Smuzhiyun     else if (mm == 14)
397*4882a593Smuzhiyun     {
398*4882a593Smuzhiyun         p[2] = p[4] = p[6] = p[7] = p[8] = 1;    // 41D5
399*4882a593Smuzhiyun     }
400*4882a593Smuzhiyun     else if (mm == 15)
401*4882a593Smuzhiyun     {
402*4882a593Smuzhiyun         p[1] = 1;
403*4882a593Smuzhiyun     }
404*4882a593Smuzhiyun     else if (mm == 16)
405*4882a593Smuzhiyun     {
406*4882a593Smuzhiyun         p[2] = p[3] = p[5] = 1;
407*4882a593Smuzhiyun     }
408*4882a593Smuzhiyun     else if (mm == 17)
409*4882a593Smuzhiyun     {
410*4882a593Smuzhiyun         p[3] = 1;
411*4882a593Smuzhiyun     }
412*4882a593Smuzhiyun     else if (mm == 18)
413*4882a593Smuzhiyun     {
414*4882a593Smuzhiyun         p[7] = 1;
415*4882a593Smuzhiyun     }
416*4882a593Smuzhiyun     else if (mm == 19)
417*4882a593Smuzhiyun     {
418*4882a593Smuzhiyun         p[1] = p[5] = p[6] = 1;
419*4882a593Smuzhiyun     }
420*4882a593Smuzhiyun     else if (mm == 20)
421*4882a593Smuzhiyun     {
422*4882a593Smuzhiyun         p[3] = 1;
423*4882a593Smuzhiyun     }
424*4882a593Smuzhiyun     // Galois field implementation with shift registers
425*4882a593Smuzhiyun     // Ref: L&C, Chapter 6.7, pp. 217
426*4882a593Smuzhiyun     mask = 1 ;
427*4882a593Smuzhiyun     alpha_to[mm] = 0 ;
428*4882a593Smuzhiyun     for (i = 0; i < mm; i++)
429*4882a593Smuzhiyun     {
430*4882a593Smuzhiyun         alpha_to[i] = mask ;
431*4882a593Smuzhiyun         index_of[alpha_to[i]] = i ;
432*4882a593Smuzhiyun         if (p[i] != 0)
433*4882a593Smuzhiyun         {
434*4882a593Smuzhiyun             alpha_to[mm] ^= mask ;
435*4882a593Smuzhiyun         }
436*4882a593Smuzhiyun         mask <<= 1 ;
437*4882a593Smuzhiyun     }
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun     index_of[alpha_to[mm]] = mm ;
440*4882a593Smuzhiyun     mask >>= 1 ;
441*4882a593Smuzhiyun     for (i = mm + 1; i < nn; i++)
442*4882a593Smuzhiyun     {
443*4882a593Smuzhiyun         if (alpha_to[i - 1] >= mask)
444*4882a593Smuzhiyun         {
445*4882a593Smuzhiyun             alpha_to[i] = alpha_to[mm] ^ ((alpha_to[i - 1] ^ mask) << 1) ;
446*4882a593Smuzhiyun         }
447*4882a593Smuzhiyun         else
448*4882a593Smuzhiyun         {
449*4882a593Smuzhiyun             alpha_to[i] = alpha_to[i - 1] << 1 ;
450*4882a593Smuzhiyun         }
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun         index_of[alpha_to[i]] = i ;
453*4882a593Smuzhiyun     }
454*4882a593Smuzhiyun     index_of[0] = -1 ;
455*4882a593Smuzhiyun }