xref: /rkdeveloptool/crc.cpp (revision 21b25fd4a70331819b557fe93015b635b9594543)
1 /*
2  * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
3  * Seth Liu 2017.03.01
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 #include "DefineHeader.h"
8 UINT gTable_Crc32[256] =
9 {//crc32 factor 0x04C10DB7
10 		0x00000000, 0x04c10db7, 0x09821b6e, 0x0d4316d9,
11 		0x130436dc, 0x17c53b6b, 0x1a862db2, 0x1e472005,
12 		0x26086db8, 0x22c9600f, 0x2f8a76d6, 0x2b4b7b61,
13 		0x350c5b64, 0x31cd56d3, 0x3c8e400a, 0x384f4dbd,
14 		0x4c10db70, 0x48d1d6c7, 0x4592c01e, 0x4153cda9,
15 		0x5f14edac, 0x5bd5e01b, 0x5696f6c2, 0x5257fb75,
16 		0x6a18b6c8, 0x6ed9bb7f, 0x639aada6, 0x675ba011,
17 		0x791c8014, 0x7ddd8da3, 0x709e9b7a, 0x745f96cd,
18 		0x9821b6e0, 0x9ce0bb57, 0x91a3ad8e, 0x9562a039,
19 		0x8b25803c, 0x8fe48d8b, 0x82a79b52, 0x866696e5,
20 		0xbe29db58, 0xbae8d6ef, 0xb7abc036, 0xb36acd81,
21 		0xad2ded84, 0xa9ece033, 0xa4aff6ea, 0xa06efb5d,
22 		0xd4316d90, 0xd0f06027, 0xddb376fe, 0xd9727b49,
23 		0xc7355b4c, 0xc3f456fb, 0xceb74022, 0xca764d95,
24 		0xf2390028, 0xf6f80d9f, 0xfbbb1b46, 0xff7a16f1,
25 		0xe13d36f4, 0xe5fc3b43, 0xe8bf2d9a, 0xec7e202d,
26 		0x34826077, 0x30436dc0, 0x3d007b19, 0x39c176ae,
27 		0x278656ab, 0x23475b1c, 0x2e044dc5, 0x2ac54072,
28 		0x128a0dcf, 0x164b0078, 0x1b0816a1, 0x1fc91b16,
29 		0x018e3b13, 0x054f36a4, 0x080c207d, 0x0ccd2dca,
30 		0x7892bb07, 0x7c53b6b0, 0x7110a069, 0x75d1adde,
31 		0x6b968ddb, 0x6f57806c, 0x621496b5, 0x66d59b02,
32 		0x5e9ad6bf, 0x5a5bdb08, 0x5718cdd1, 0x53d9c066,
33 		0x4d9ee063, 0x495fedd4, 0x441cfb0d, 0x40ddf6ba,
34 		0xaca3d697, 0xa862db20, 0xa521cdf9, 0xa1e0c04e,
35 		0xbfa7e04b, 0xbb66edfc, 0xb625fb25, 0xb2e4f692,
36 		0x8aabbb2f, 0x8e6ab698, 0x8329a041, 0x87e8adf6,
37 		0x99af8df3, 0x9d6e8044, 0x902d969d, 0x94ec9b2a,
38 		0xe0b30de7, 0xe4720050, 0xe9311689, 0xedf01b3e,
39 		0xf3b73b3b, 0xf776368c, 0xfa352055, 0xfef42de2,
40 		0xc6bb605f, 0xc27a6de8, 0xcf397b31, 0xcbf87686,
41 		0xd5bf5683, 0xd17e5b34, 0xdc3d4ded, 0xd8fc405a,
42 		0x6904c0ee, 0x6dc5cd59, 0x6086db80, 0x6447d637,
43 		0x7a00f632, 0x7ec1fb85, 0x7382ed5c, 0x7743e0eb,
44 		0x4f0cad56, 0x4bcda0e1, 0x468eb638, 0x424fbb8f,
45 		0x5c089b8a, 0x58c9963d, 0x558a80e4, 0x514b8d53,
46 		0x25141b9e, 0x21d51629, 0x2c9600f0, 0x28570d47,
47 		0x36102d42, 0x32d120f5, 0x3f92362c, 0x3b533b9b,
48 		0x031c7626, 0x07dd7b91, 0x0a9e6d48, 0x0e5f60ff,
49 		0x101840fa, 0x14d94d4d, 0x199a5b94, 0x1d5b5623,
50 		0xf125760e, 0xf5e47bb9, 0xf8a76d60, 0xfc6660d7,
51 		0xe22140d2, 0xe6e04d65, 0xeba35bbc, 0xef62560b,
52 		0xd72d1bb6, 0xd3ec1601, 0xdeaf00d8, 0xda6e0d6f,
53 		0xc4292d6a, 0xc0e820dd, 0xcdab3604, 0xc96a3bb3,
54 		0xbd35ad7e, 0xb9f4a0c9, 0xb4b7b610, 0xb076bba7,
55 		0xae319ba2, 0xaaf09615, 0xa7b380cc, 0xa3728d7b,
56 		0x9b3dc0c6, 0x9ffccd71, 0x92bfdba8, 0x967ed61f,
57 		0x8839f61a, 0x8cf8fbad, 0x81bbed74, 0x857ae0c3,
58 		0x5d86a099, 0x5947ad2e, 0x5404bbf7, 0x50c5b640,
59 		0x4e829645, 0x4a439bf2, 0x47008d2b, 0x43c1809c,
60 		0x7b8ecd21, 0x7f4fc096, 0x720cd64f, 0x76cddbf8,
61 		0x688afbfd, 0x6c4bf64a, 0x6108e093, 0x65c9ed24,
62 		0x11967be9, 0x1557765e, 0x18146087, 0x1cd56d30,
63 		0x02924d35, 0x06534082, 0x0b10565b, 0x0fd15bec,
64 		0x379e1651, 0x335f1be6, 0x3e1c0d3f, 0x3add0088,
65 		0x249a208d, 0x205b2d3a, 0x2d183be3, 0x29d93654,
66 		0xc5a71679, 0xc1661bce, 0xcc250d17, 0xc8e400a0,
67 		0xd6a320a5, 0xd2622d12, 0xdf213bcb, 0xdbe0367c,
68 		0xe3af7bc1, 0xe76e7676, 0xea2d60af, 0xeeec6d18,
69 		0xf0ab4d1d, 0xf46a40aa, 0xf9295673, 0xfde85bc4,
70 		0x89b7cd09, 0x8d76c0be, 0x8035d667, 0x84f4dbd0,
71 		0x9ab3fbd5, 0x9e72f662, 0x9331e0bb, 0x97f0ed0c,
72 		0xafbfa0b1, 0xab7ead06, 0xa63dbbdf, 0xa2fcb668,
73 		0xbcbb966d, 0xb87a9bda, 0xb5398d03, 0xb1f880b4,
74 };
75 #define tole(x)		(x)
76 /*factor is 0xedb88320*/
77 unsigned int crc32table_le[] = {
78 tole(0x00000000L), tole(0x77073096L), tole(0xee0e612cL), tole(0x990951baL),
79 tole(0x076dc419L), tole(0x706af48fL), tole(0xe963a535L), tole(0x9e6495a3L),
80 tole(0x0edb8832L), tole(0x79dcb8a4L), tole(0xe0d5e91eL), tole(0x97d2d988L),
81 tole(0x09b64c2bL), tole(0x7eb17cbdL), tole(0xe7b82d07L), tole(0x90bf1d91L),
82 tole(0x1db71064L), tole(0x6ab020f2L), tole(0xf3b97148L), tole(0x84be41deL),
83 tole(0x1adad47dL), tole(0x6ddde4ebL), tole(0xf4d4b551L), tole(0x83d385c7L),
84 tole(0x136c9856L), tole(0x646ba8c0L), tole(0xfd62f97aL), tole(0x8a65c9ecL),
85 tole(0x14015c4fL), tole(0x63066cd9L), tole(0xfa0f3d63L), tole(0x8d080df5L),
86 tole(0x3b6e20c8L), tole(0x4c69105eL), tole(0xd56041e4L), tole(0xa2677172L),
87 tole(0x3c03e4d1L), tole(0x4b04d447L), tole(0xd20d85fdL), tole(0xa50ab56bL),
88 tole(0x35b5a8faL), tole(0x42b2986cL), tole(0xdbbbc9d6L), tole(0xacbcf940L),
89 tole(0x32d86ce3L), tole(0x45df5c75L), tole(0xdcd60dcfL), tole(0xabd13d59L),
90 tole(0x26d930acL), tole(0x51de003aL), tole(0xc8d75180L), tole(0xbfd06116L),
91 tole(0x21b4f4b5L), tole(0x56b3c423L), tole(0xcfba9599L), tole(0xb8bda50fL),
92 tole(0x2802b89eL), tole(0x5f058808L), tole(0xc60cd9b2L), tole(0xb10be924L),
93 tole(0x2f6f7c87L), tole(0x58684c11L), tole(0xc1611dabL), tole(0xb6662d3dL),
94 tole(0x76dc4190L), tole(0x01db7106L), tole(0x98d220bcL), tole(0xefd5102aL),
95 tole(0x71b18589L), tole(0x06b6b51fL), tole(0x9fbfe4a5L), tole(0xe8b8d433L),
96 tole(0x7807c9a2L), tole(0x0f00f934L), tole(0x9609a88eL), tole(0xe10e9818L),
97 tole(0x7f6a0dbbL), tole(0x086d3d2dL), tole(0x91646c97L), tole(0xe6635c01L),
98 tole(0x6b6b51f4L), tole(0x1c6c6162L), tole(0x856530d8L), tole(0xf262004eL),
99 tole(0x6c0695edL), tole(0x1b01a57bL), tole(0x8208f4c1L), tole(0xf50fc457L),
100 tole(0x65b0d9c6L), tole(0x12b7e950L), tole(0x8bbeb8eaL), tole(0xfcb9887cL),
101 tole(0x62dd1ddfL), tole(0x15da2d49L), tole(0x8cd37cf3L), tole(0xfbd44c65L),
102 tole(0x4db26158L), tole(0x3ab551ceL), tole(0xa3bc0074L), tole(0xd4bb30e2L),
103 tole(0x4adfa541L), tole(0x3dd895d7L), tole(0xa4d1c46dL), tole(0xd3d6f4fbL),
104 tole(0x4369e96aL), tole(0x346ed9fcL), tole(0xad678846L), tole(0xda60b8d0L),
105 tole(0x44042d73L), tole(0x33031de5L), tole(0xaa0a4c5fL), tole(0xdd0d7cc9L),
106 tole(0x5005713cL), tole(0x270241aaL), tole(0xbe0b1010L), tole(0xc90c2086L),
107 tole(0x5768b525L), tole(0x206f85b3L), tole(0xb966d409L), tole(0xce61e49fL),
108 tole(0x5edef90eL), tole(0x29d9c998L), tole(0xb0d09822L), tole(0xc7d7a8b4L),
109 tole(0x59b33d17L), tole(0x2eb40d81L), tole(0xb7bd5c3bL), tole(0xc0ba6cadL),
110 tole(0xedb88320L), tole(0x9abfb3b6L), tole(0x03b6e20cL), tole(0x74b1d29aL),
111 tole(0xead54739L), tole(0x9dd277afL), tole(0x04db2615L), tole(0x73dc1683L),
112 tole(0xe3630b12L), tole(0x94643b84L), tole(0x0d6d6a3eL), tole(0x7a6a5aa8L),
113 tole(0xe40ecf0bL), tole(0x9309ff9dL), tole(0x0a00ae27L), tole(0x7d079eb1L),
114 tole(0xf00f9344L), tole(0x8708a3d2L), tole(0x1e01f268L), tole(0x6906c2feL),
115 tole(0xf762575dL), tole(0x806567cbL), tole(0x196c3671L), tole(0x6e6b06e7L),
116 tole(0xfed41b76L), tole(0x89d32be0L), tole(0x10da7a5aL), tole(0x67dd4accL),
117 tole(0xf9b9df6fL), tole(0x8ebeeff9L), tole(0x17b7be43L), tole(0x60b08ed5L),
118 tole(0xd6d6a3e8L), tole(0xa1d1937eL), tole(0x38d8c2c4L), tole(0x4fdff252L),
119 tole(0xd1bb67f1L), tole(0xa6bc5767L), tole(0x3fb506ddL), tole(0x48b2364bL),
120 tole(0xd80d2bdaL), tole(0xaf0a1b4cL), tole(0x36034af6L), tole(0x41047a60L),
121 tole(0xdf60efc3L), tole(0xa867df55L), tole(0x316e8eefL), tole(0x4669be79L),
122 tole(0xcb61b38cL), tole(0xbc66831aL), tole(0x256fd2a0L), tole(0x5268e236L),
123 tole(0xcc0c7795L), tole(0xbb0b4703L), tole(0x220216b9L), tole(0x5505262fL),
124 tole(0xc5ba3bbeL), tole(0xb2bd0b28L), tole(0x2bb45a92L), tole(0x5cb36a04L),
125 tole(0xc2d7ffa7L), tole(0xb5d0cf31L), tole(0x2cd99e8bL), tole(0x5bdeae1dL),
126 tole(0x9b64c2b0L), tole(0xec63f226L), tole(0x756aa39cL), tole(0x026d930aL),
127 tole(0x9c0906a9L), tole(0xeb0e363fL), tole(0x72076785L), tole(0x05005713L),
128 tole(0x95bf4a82L), tole(0xe2b87a14L), tole(0x7bb12baeL), tole(0x0cb61b38L),
129 tole(0x92d28e9bL), tole(0xe5d5be0dL), tole(0x7cdcefb7L), tole(0x0bdbdf21L),
130 tole(0x86d3d2d4L), tole(0xf1d4e242L), tole(0x68ddb3f8L), tole(0x1fda836eL),
131 tole(0x81be16cdL), tole(0xf6b9265bL), tole(0x6fb077e1L), tole(0x18b74777L),
132 tole(0x88085ae6L), tole(0xff0f6a70L), tole(0x66063bcaL), tole(0x11010b5cL),
133 tole(0x8f659effL), tole(0xf862ae69L), tole(0x616bffd3L), tole(0x166ccf45L),
134 tole(0xa00ae278L), tole(0xd70dd2eeL), tole(0x4e048354L), tole(0x3903b3c2L),
135 tole(0xa7672661L), tole(0xd06016f7L), tole(0x4969474dL), tole(0x3e6e77dbL),
136 tole(0xaed16a4aL), tole(0xd9d65adcL), tole(0x40df0b66L), tole(0x37d83bf0L),
137 tole(0xa9bcae53L), tole(0xdebb9ec5L), tole(0x47b2cf7fL), tole(0x30b5ffe9L),
138 tole(0xbdbdf21cL), tole(0xcabac28aL), tole(0x53b39330L), tole(0x24b4a3a6L),
139 tole(0xbad03605L), tole(0xcdd70693L), tole(0x54de5729L), tole(0x23d967bfL),
140 tole(0xb3667a2eL), tole(0xc4614ab8L), tole(0x5d681b02L), tole(0x2a6f2b94L),
141 tole(0xb40bbe37L), tole(0xc30c8ea1L), tole(0x5a05df1bL), tole(0x2d02ef8dL)
142 };
143 
144 
145 #define rr_max  104	/* Number of parity checks, rr = deg[g(x)] */
146 #define parallel 8 //bit count
147 #define mm 13//limit count
148 #define nn 8191//code size
149 #define kk 4120//info length
150 #define tt 8//correct count
151 
152 #define tt2 2*tt
153 UINT s[tt2+1]; // Syndrome values
154 
155 UINT rr;//redundant length		// BCH code parameters
156 
157 
158 UINT p[mm + 1];
159 UINT alpha_to[nn+1], index_of[nn+1] ;	// Galois field
160 UINT gg[rr_max+1] ;		// Generator polynomial
161 
162 UINT ggx1=0;
163 UINT ggx2=0;
164 UINT ggx3=0;
165 UINT ggx4=0;
166 
167 // get crc32 value
168 UINT CRC_32(unsigned char* pData, UINT ulSize)
169 {
170     UINT i;
171     UINT nAccum = 0;
172 
173     for ( i = 0; i < ulSize; i++)
174         nAccum = (nAccum << 8) ^ gTable_Crc32[(nAccum >> 24) ^ (*pData++)];
175     return nAccum;
176 }
177 #define DO_CRC(x) crc = tab[ (crc ^ (x)) & 255 ] ^ (crc>>8)
178 
179 unsigned int crc32_le(unsigned int crc, unsigned char *p, unsigned int len)
180 {
181 /*
182 	UINT i;
183 	UINT nAccum = crc;
184 
185 	for ( i = 0; i < len; i++) {
186 		nAccum = (nAccum >> 8) ^ crc32table_le[(nAccum ^ (*p)) & 0xFF];
187 		p++;
188 	}
189 	return nAccum;
190 */
191 	unsigned int      *b =(unsigned int *)p;
192 	unsigned int      *tab = crc32table_le;
193 	crc = crc ^ 0xFFFFFFFF;
194 	if((((uintptr_t)b)&3 && len)){
195 		do {
196 			unsigned char *p = (unsigned char *)b;
197 			DO_CRC(*p++);
198 			b = (unsigned int *)p;
199 		} while ((--len) && ((uintptr_t)b)&3 );
200 	}
201 	if((len >= 4)){
202 		unsigned int save_len = len & 3;
203 		len = len >> 2;
204 		--b;
205 		do {
206 			crc ^= *++b;
207 			DO_CRC(0);
208 			DO_CRC(0);
209 			DO_CRC(0);
210 			DO_CRC(0);
211 		} while (--len);
212 		b++;
213 		len = save_len;
214 	}
215 	if(len){
216 		do {
217 			unsigned char *p = (unsigned char *)b;
218 			DO_CRC(*p++);
219 			b = (unsigned int *)p;
220 		} while (--len);
221 	}
222 	crc = crc ^ 0xFFFFFFFF;
223 	return crc;
224 
225 }
226 
227 #define CRC16_CCITT         0x1021  //CRC operator
228 void CRCBuildTable16(unsigned short aPoly , unsigned short *crcTable)
229 {
230     unsigned short i, j;
231     unsigned short nData;
232     unsigned short nAccum;
233 
234     for (i = 0; i < 256; i++)
235     {
236         nData = (unsigned short)(i << 8);
237         nAccum = 0;
238         for (j = 0; j < 8; j++)
239         {
240             if ((nData ^ nAccum) & 0x8000)
241                 nAccum = (nAccum << 1) ^ aPoly;
242             else
243                 nAccum <<= 1;
244             nData <<= 1;
245         }
246         crcTable[i] = nAccum;
247     }
248 }
249 
250 unsigned short CRC_16(unsigned char* aData, UINT aSize)
251 {
252     UINT i;
253     unsigned short nAccum = 0;
254     unsigned short crcTable[256];
255 
256     CRCBuildTable16(CRC16_CCITT , crcTable);
257     for (i = 0; i < aSize; i++)
258         nAccum = (nAccum << 8) ^ crcTable[(nAccum >> 8) ^ *aData++];
259 
260     return nAccum;
261 }
262 
263 void P_RC4(unsigned char* buf, unsigned short len)
264 {
265 	unsigned char S[256],K[256],temp;
266 	unsigned short i,j,t,x;
267 	unsigned char key[16]={124,78,3,4,85,5,9,7,45,44,123,56,23,13,23,17};
268 
269 	j = 0;
270 	for(i=0; i<256; i++){
271 		S[i] = (unsigned char)i;
272 		j&=0x0f;
273 		K[i] = key[j];
274 		j++;
275 	}
276 
277 	j = 0;
278 	for(i=0; i<256; i++){
279 		j = (j + S[i] + K[i]) % 256;
280 		temp = S[i];
281 		S[i] = S[j];
282 		S[j] = temp;
283 	}
284 
285 	i = j = 0;
286 	for(x=0; x<len; x++){
287 		i = (i+1) % 256;
288 		j = (j + S[i]) % 256;
289 		temp = S[i];
290 		S[i] = S[j];
291 		S[j] = temp;
292 		t = (S[i] + (S[j] % 256)) % 256;
293 		buf[x] = buf[x] ^ S[t];
294 	}
295 }
296 
297 void bch_encode(unsigned char* encode_in, unsigned char* encode_out)
298 {
299 	UINT i,j;
300 	bool feed_back;
301 	UINT bch1=0;
302 	UINT bch2=0;
303 	UINT bch3=0;
304 	UINT bch4=0;
305 
306 	for (i=0;i<515;i++)
307 	{
308 		for (j=0;j<8;j++)
309 		{
310 			feed_back = (bch1&1) ^ ((encode_in[i]>>j) & 1);
311 			bch1=((bch1>>1)|((bch2&1)*0x80000000))^(ggx1*feed_back);
312 			bch2=((bch2>>1)|((bch3&1)*0x80000000))^(ggx2*feed_back);
313 			bch3=((bch3>>1)|((bch4&1)*0x80000000))^(ggx3*feed_back);
314 			bch4=(((bch4>>1)^(ggx4*feed_back))) | (feed_back*0x80);
315 		}
316 	}
317 
318 	//********Handle FF***********************
319 	bch1 = ~(bch1 ^ 0xad6273b1);
320 	bch2 = ~(bch2 ^ 0x348393d2);
321 	bch3 = ~(bch3 ^ 0xe6ebed3c);
322 	bch4 = ~(bch4 ^ 0xc8);
323 	//*********************************************
324 
325 	for (i=0;i<515;i++)
326 		encode_out[i] = encode_in[i];
327 	encode_out[515] = bch1&0x000000ff;
328 	encode_out[516] = (bch1&0x0000ff00)>>8;
329 	encode_out[517] = (bch1&0x00ff0000)>>16;
330 	encode_out[518] = (bch1&0xff000000)>>24;
331 	encode_out[519] = bch2&0x000000ff;
332 	encode_out[520] = (bch2&0x0000ff00)>>8;
333 	encode_out[521] = (bch2&0x00ff0000)>>16;
334 	encode_out[522] = (bch2&0xff000000)>>24;
335 	encode_out[523] = bch3&0x000000ff;
336 	encode_out[524] = (bch3&0x0000ff00)>>8;
337 	encode_out[525] = (bch3&0x00ff0000)>>16;
338 	encode_out[526] = (bch3&0xff000000)>>24;
339 	encode_out[527] = bch4&0x000000ff;
340 }
341 
342 #define poly16_CCITT	0x1021          /* crc-ccitt mask */
343 
344 unsigned short CRC_Calculate(unsigned short crc, unsigned char ch)
345 {
346 	UINT i;
347 	for(i=0x80; i!=0; i>>=1)
348 	{
349 		if((crc & 0x8000) != 0)
350 		{
351 			crc <<= 1;
352 			crc ^= poly16_CCITT;
353 		}
354 		else
355 			crc <<= 1;
356 		if((ch & i)!=0)
357 			crc ^= poly16_CCITT;
358 	}
359 	return crc;
360 }
361 unsigned short CRC_CCITT(unsigned char* p, UINT CalculateNumber)
362 {
363     unsigned short crc = 0xffff;
364     while(CalculateNumber--)
365 	{
366 		crc = CRC_Calculate(crc, *p);
367 		p++;
368     }
369     return crc;
370 }
371 void gen_poly()
372 {
373 	UINT gen_roots[nn + 1], gen_roots_true[nn + 1] ; 	// Roots of generator polynomial
374 	UINT i, j, Temp ;
375 
376 // Initialization of gen_roots
377 	for (i = 0; i <= nn; i++)
378 	{	gen_roots_true[i] = 0;
379 		gen_roots[i] = 0;
380 	}
381 
382 // Cyclotomic cosets of gen_roots
383 	for (i = 1; i <= 2*tt ; i++)
384 	{
385 		for (j = 0; j < mm; j++)
386 		{
387 			Temp = ((1<<j)*i)%nn;
388 			gen_roots_true[Temp] = 1;
389 		}
390 	}
391 	rr = 0;		// Count thenumber of parity check bits
392 	for (i = 0; i < nn; i++)
393 	{
394 		if (gen_roots_true[i] == 1)
395 		{
396 			rr++;
397 			gen_roots[rr] = i;
398 		}
399 	}
400 // Compute generator polynomial based on its roots
401 	gg[0] = 2 ;	// g(x) = (X + alpha) initially
402 	gg[1] = 1 ;
403 	for (i = 2; i <= rr; i++)
404 	{
405 		gg[i] = 1 ;
406 		for (j = i - 1; j > 0; j--)
407 			if (gg[j] != 0)
408 				gg[j] = gg[j-1]^ alpha_to[(index_of[gg[j]] + index_of[alpha_to[gen_roots[i]]]) % nn] ;
409 			else
410 				gg[j] = gg[j-1] ;
411 		gg[0] = alpha_to[(index_of[gg[0]] + index_of[alpha_to[gen_roots[i]]]) % nn] ;
412 	}
413 
414 ggx1 = gg[103] | (gg[102]<<1) | (gg[101]<<2) | (gg[100]<<3) | (gg[99]<<4) |(gg[98]<<5)| (gg[97]<<6)|(gg[96]<<7)
415 	| (gg[95]<<8) | (gg[94]<<9) | (gg[93]<<10) | (gg[92]<<11) |(gg[91]<<12)| (gg[90]<<13)|(gg[89]<<14) |(gg[88]<<15)
416 	| (gg[87]<<16) | (gg[86]<<17) | (gg[85]<<18) | (gg[84]<<19) | (gg[83]<<20) |(gg[82]<<21)| (gg[81]<<22)|(gg[80]<<23)
417 	| (gg[79]<<24) | (gg[78]<<25) | (gg[77]<<26) | (gg[76]<<27) |(gg[75]<<28)| (gg[74]<<29)|(gg[73]<<30) |(gg[72]<<31);
418 ggx2 = gg[71] | (gg[70]<<1) | (gg[69]<<2) | (gg[68]<<3) | (gg[67]<<4) |(gg[66]<<5)| (gg[65]<<6)|(gg[64]<<7)
419 	| (gg[63]<<8) | (gg[62]<<9) | (gg[61]<<10) | (gg[60]<<11) |(gg[59]<<12)| (gg[58]<<13)|(gg[57]<<14) |(gg[56]<<15)
420 	| (gg[55]<<16) | (gg[54]<<17) | (gg[53]<<18) | (gg[52]<<19) | (gg[51]<<20) |(gg[50]<<21)| (gg[49]<<22)|(gg[48]<<23)
421 	| (gg[47]<<24) | (gg[46]<<25) | (gg[45]<<26) | (gg[44]<<27) |(gg[43]<<28)| (gg[42]<<29)|(gg[41]<<30) |(gg[40]<<31);
422 ggx3 = gg[39] | (gg[38]<<1) | (gg[37]<<2) | (gg[36]<<3) | (gg[35]<<4) |(gg[34]<<5)| (gg[33]<<6)|(gg[32]<<7)
423 	| (gg[31]<<8) | (gg[30]<<9) | (gg[29]<<10) | (gg[28]<<11) |(gg[27]<<12)| (gg[26]<<13)|(gg[25]<<14) |(gg[24]<<15)
424 	| (gg[23]<<16) | (gg[22]<<17) | (gg[21]<<18) | (gg[20]<<19) | (gg[19]<<20) |(gg[18]<<21)| (gg[17]<<22)|(gg[16]<<23)
425 	| (gg[15]<<24) | (gg[14]<<25) | (gg[13]<<26) | (gg[12]<<27) |(gg[11]<<28)| (gg[10]<<29)|(gg[9]<<30) |(gg[8]<<31);
426 ggx4 = gg[7] | (gg[6]<<1) | (gg[5]<<2) | (gg[4]<<3) | (gg[3]<<4) |(gg[2]<<5)| (gg[1]<<6);
427 
428 }
429 
430 void generate_gf()
431 {
432 	UINT i;
433 	UINT mask ;	// Register states
434 
435 	// Primitive polynomials
436 	for (i = 1; i < mm; i++)
437 		p[i] = 0;
438 	p[0] = p[mm] = 1;
439 	if (mm == 2)		p[1] = 1;
440 	else if (mm == 3)	p[1] = 1;
441 	else if (mm == 4)	p[1] = 1;
442 	else if (mm == 5)	p[2] = 1;
443 	else if (mm == 6)	p[1] = 1;
444 	else if (mm == 7)	p[1] = 1;
445 	else if (mm == 8)	p[4] = p[5] = p[6] = 1;
446 	else if (mm == 9)	p[4] = 1;
447 	else if (mm == 10)	p[3] = 1;
448 	else if (mm == 11)	p[2] = 1;
449 	else if (mm == 12)	p[3] = p[4] = p[7] = 1;
450 	else if (mm == 13)	p[1] = p[2] = p[3] = p[5] = p[7] = p[8] = p[10] = 1;	// 25AF
451 	else if (mm == 14)	p[2] = p[4] = p[6] = p[7] = p[8] = 1;	// 41D5
452 	else if (mm == 15)	p[1] = 1;
453 	else if (mm == 16)	p[2] = p[3] = p[5] = 1;
454 	else if (mm == 17)	p[3] = 1;
455 	else if (mm == 18)	p[7] = 1;
456 	else if (mm == 19)	p[1] = p[5] = p[6] = 1;
457 	else if (mm == 20)	p[3] = 1;
458 	// Galois field implementation with shift registers
459 	// Ref: L&C, Chapter 6.7, pp. 217
460 	mask = 1 ;
461 	alpha_to[mm] = 0 ;
462 	for (i = 0; i < mm; i++)
463 	{
464 		alpha_to[i] = mask ;
465 		index_of[alpha_to[i]] = i ;
466 		if (p[i] != 0)
467 			alpha_to[mm] ^= mask ;
468 		mask <<= 1 ;
469 	}
470 
471 	index_of[alpha_to[mm]] = mm ;
472 	mask >>= 1 ;
473 	for (i = mm + 1; i < nn; i++)
474 	{
475 		if (alpha_to[i-1] >= mask)
476 			alpha_to[i] = alpha_to[mm] ^ ((alpha_to[i-1] ^ mask) << 1) ;
477 		else
478 			alpha_to[i] = alpha_to[i-1] << 1 ;
479 
480 		index_of[alpha_to[i]] = i ;
481 	}
482 	index_of[0] = -1 ;
483 }
484