Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

563580 views
1
#include "typedef.h"
2
/**************************************************************************\
3
@---------------------------------------------------------------------------
4
@---------------------------------------------------------------------------
5
@ FILE: prime_tools.c
6
@---------------------------------------------------------------------------
7
@---------------------------------------------------------------------------
8
@
9
\**************************************************************************/
10
/*
11
@-------------------------------------------------------------------------
12
@ This file exports the global variables
13
@ int act_prime - This the actual used prime_number
14
@
15
@ int (*S)(int,int), (*P)(int,int)
16
@ S is the function for addition modulo act_prime and
17
@ P the function for multiplication
18
@
19
@ void cleanup_prime();
20
@ releases all memory that was allocated by init_prime(). Only
21
@ useful for debugging memory allocation.
22
@ void init_prime( int prime);
23
@ This function MUST be called before the functions S(a,b) and P(a,b)
24
@ can be used, since otherwise they are not defined.
25
@ The argument of init_prime is the new prime number, modulo which
26
@ the calculations shoud be done, i.e. act_prime is set to prime.
27
@
28
@-------------------------------------------------------------------------
29
| Dieses file export die globalen Variablen
30
|
31
| int act_prime;
32
| Dies ist die gerade benutzte Primzahl
33
|
34
| int (*S)(int, int), (*P)(int,int);
35
| Dies sind die Multiplikationsfunktionen fuer das Rechenen
36
| modulo act_prime;
37
|
38
| Es werden zwei Funktionen definiert, naemlich
39
|
40
| void init_prime( int prime );
41
| Diese Funktion \underline{MUSS} aufgerufen werden, bevor die
42
| Rechenfunktionen S(a,b) und P(a,b) benutzt werden koennen,
43
| da diese sonst nicht definiert sind. Argument von
44
| init_prime() ist die neue Primzahl, modulo derer gerechnet
45
| werden soll, das heisst, act_prime wird auf prime gesetzt
46
|
47
| void cleanup_prime();
48
| releases all memory that was allocated by init_prime(). Only
49
| useful for debugging memory allocation.
50
|
51
*/
52
#include "tools.h"
53
54
/*
55
* local variables
56
*/
57
#define SHORTPRIME_LIMIT 300 /* Grenze fuer Rechnen mit Tabelle */
58
59
typedef struct {
60
int s_number, *s_primes; /* Anzahl kleiner Pz; Liste der ... */
61
int l_number, *l_primes; /* Anzahl grosser Pz; Liste der ... */
62
int ***ADD, ***MUL; /* Rechen-Tabellen fuer kleine Pz. */
63
int **LOG, **EXP; /* p-Logarithmen fuer grosse Pz. */
64
} table;
65
66
static int dummy( int a, int b);
67
68
static int **P_ADD = NULL, **P_MUL = NULL; /* aktuelle Rechen_Tabelle */
69
static int *P_LOG = NULL, *P_EXP = NULL; /* aktuelle p-Logarithmen */
70
static table *prime_table = NULL;
71
72
/*
73
* global variables
74
*/
75
int (*S)(int, int)= dummy, (*P)(int, int)= dummy; /* aktuelle Funktion */
76
int act_prime= -1;
77
78
/*}}} */
79
/*{{{ dummy*/
80
static int dummy( a, b)
81
int a,b;
82
{
83
fprintf(stderr,"You tried to use GF(p)-Arithmetic without calling init_prime(act_prime).\n");
84
fprintf(stderr,"Currently, act_prime is set to %d, which is apparently not prime.\n", act_prime);
85
exit(3);
86
return 0;
87
}
88
89
/*}}} */
90
/*{{{ short_P*/
91
static
92
int short_P(i,j)
93
int i,j;
94
{
95
return(P_MUL[i][j]);
96
}
97
98
/*}}} */
99
/*{{{ short_S*/
100
static
101
int short_S(i,j)
102
int i,j;
103
{
104
int k;
105
return(P_ADD[i][j]);
106
}
107
108
/*}}} */
109
/*{{{ int_P*/
110
static
111
int int_P(i,j)
112
int i,j;
113
{
114
return((i*j ==0 ) ? 0 : P_EXP[(P_LOG[i] + P_LOG[j]) % (act_prime-1)]);
115
}
116
117
/*}}} */
118
/*{{{ int_S*/
119
static
120
int int_S(i,j)
121
int i,j;
122
{
123
/* die "5" ist nur ein Sicherheitsfaktor */
124
return((i+j+5*act_prime)%act_prime);
125
}
126
127
/*}}} */
128
/*{{{ init_short_prime*/
129
static
130
void init_short_prime()
131
{
132
int j,k;
133
134
P_ADD = (int **)malloc((unsigned)act_prime*sizeof(int *));
135
P_MUL = (int **)malloc((unsigned)act_prime*sizeof(int *));
136
for ( j = 0; j < act_prime; j ++) {
137
P_MUL[j] = (int *)malloc((unsigned)(2*act_prime-1)*sizeof(int));
138
P_ADD[j] = (int *)malloc((unsigned)(2*act_prime-1)*sizeof(int));
139
P_MUL[j] += act_prime-1;
140
P_ADD[j] += act_prime-1;
141
}
142
for ( j = 0; j < act_prime; j ++) {
143
for ( k = 0; k <= j; k++) {
144
P_MUL[j][k] = P_MUL[k][j] = (j * k) % act_prime;
145
if ( j != 0 ) {
146
P_MUL[P_MUL[j][k]][-j] = k;
147
}
148
if ( k != 0 ) {
149
P_MUL[P_MUL[j][k]][-k] = j;
150
}
151
if((k != 0) && (P_MUL[j][k] == 0)) {
152
fprintf(stderr,"init_short_prime: Error Non-prime (%d) in makefield occured\n", act_prime);
153
}
154
P_ADD[j][k] = P_ADD[k][j] = (j + k) % act_prime;
155
P_ADD[P_ADD[j][k]][-j] = k;
156
P_ADD[P_ADD[j][k]][-k] = j;
157
}
158
}
159
}
160
/*}}} */
161
/*{{{ init_int_prime*/
162
static
163
void init_int_prime()
164
{
165
int i,j,k,gt;
166
int *p_tmp;
167
int flag;
168
169
P_LOG = (int *)calloc(2*act_prime+1,sizeof(int));
170
P_EXP = (int *)calloc(act_prime,sizeof(int));
171
p_tmp = (int *)calloc(act_prime+1,sizeof(int));
172
P_LOG += act_prime;
173
174
/* find a generator of the cyclic multiplicative group of Fp */
175
176
for(i = 1; i <= act_prime; i++) {
177
p_tmp[i] = 1;
178
}
179
180
k = gt = (act_prime-1)/2;
181
p_tmp[k] = 0;
182
j = 1;
183
flag = TRUE;
184
while(flag) {
185
do {
186
if((k = (k * gt)%act_prime) == 0) {
187
fprintf(stderr,"Error: Nullteiler\n");
188
exit(3);
189
}
190
p_tmp[k] = 0;
191
j++;
192
} while(k != 1);
193
flag = (j == act_prime-1) ? FALSE : TRUE;
194
if(flag) {
195
j = 1;
196
for(i = 1; i <=act_prime; i++) {
197
if (p_tmp[i] == 1) {
198
gt = i;
199
break;
200
}
201
}
202
if(i > act_prime) {
203
fprintf(stderr,"No generator for multiplicative group found");
204
exit(3);
205
}
206
k = gt;
207
p_tmp[k] = 0;
208
}
209
}
210
211
k = j = 1;
212
do {
213
k = (k * gt)%act_prime;
214
P_LOG[k] = j;
215
P_EXP[j] = k;
216
P_LOG[-k] = act_prime-j-1;
217
j++;
218
} while(k != 1);
219
P_LOG[1] = 0;
220
P_EXP[0] = 1;
221
free(p_tmp);
222
}
223
/*}}} */
224
/*{{{ cleanup_prime*/
225
void cleanup_prime()
226
{
227
int i, j;
228
229
if ( prime_table != NULL ) {
230
for ( i=1; i < prime_table->s_number; i ++ ) {
231
act_prime = prime_table->s_primes[i];
232
for ( j = 0; j < act_prime; j ++) {
233
prime_table->ADD[i][j] -= act_prime - 1;
234
prime_table->MUL[i][j] -= act_prime - 1;
235
free( prime_table->ADD[i][j] );
236
free( prime_table->MUL[i][j] );
237
}
238
free( prime_table->ADD[i] );
239
free( prime_table->MUL[i] );
240
}
241
free( prime_table->s_primes );
242
free( prime_table->ADD );
243
free( prime_table->MUL );
244
245
for ( i=1; i < prime_table->l_number; i ++ ) {
246
act_prime = prime_table->l_primes[i];
247
prime_table->LOG[i] -= act_prime;
248
free( prime_table->LOG[i] );
249
free( prime_table->EXP[i] );
250
}
251
free( prime_table->l_primes );
252
free( prime_table->LOG );
253
free( prime_table->EXP );
254
free( prime_table );
255
}
256
act_prime = -1;
257
prime_table = NULL;
258
P_LOG = NULL;
259
P_EXP = NULL;
260
P_ADD = NULL;
261
P_MUL = NULL;
262
263
264
}
265
/*}}} */
266
/*{{{ init_prime*/
267
void init_prime (prime)
268
int prime;
269
{
270
int j, k, number;
271
272
number = 1;
273
if (act_prime == -1) {
274
prime_table = (table *)malloc(sizeof(table));
275
prime_table->s_number = 1;
276
prime_table->l_number = 1;
277
prime_table->s_primes= (int *)calloc(1,sizeof(int));
278
prime_table->l_primes= (int *)calloc(1,sizeof(int));
279
prime_table->ADD = (int ***)malloc(1*sizeof(int **));
280
prime_table->MUL = (int ***)malloc(1*sizeof(int **));
281
prime_table->LOG = (int **)malloc(1*sizeof(int *));
282
prime_table->EXP = (int **)malloc(1*sizeof(int *));
283
}
284
j = 0;
285
if (prime < SHORTPRIME_LIMIT) {
286
number = prime_table->s_number;
287
while (j < number) {
288
if (prime_table->s_primes[j] == prime) {
289
P_ADD = prime_table->ADD[j];
290
P_MUL = prime_table->MUL [j];
291
act_prime = prime;
292
return;
293
}
294
j++;
295
}
296
number++;
297
prime_table->s_primes= (int *)realloc(prime_table->s_primes,
298
number*sizeof(int));
299
prime_table->ADD = (int ***)realloc(prime_table->ADD,
300
number*sizeof(int **));
301
prime_table->MUL = (int ***)realloc(prime_table->MUL ,
302
number*sizeof(int **));
303
prime_table->s_primes[number-1] = act_prime = prime;
304
init_short_prime();
305
prime_table->ADD[number-1] = P_ADD;
306
prime_table->MUL[number-1] = P_MUL;
307
prime_table->s_number = number;
308
S = (int (*)(int, int))(short_S);
309
P = (int (*)(int, int))(short_P);
310
} else {
311
number = prime_table->l_number;
312
while (j < number) {
313
if (prime_table->l_primes[j] == prime) {
314
P_LOG = prime_table->LOG[j];
315
P_EXP = prime_table->EXP[j];
316
act_prime = prime;
317
return;
318
}
319
j++;
320
}
321
number++;
322
prime_table->l_primes= (int *)realloc(prime_table->l_primes,
323
number*sizeof(int));
324
prime_table->LOG = (int **)realloc(prime_table->LOG,
325
number*sizeof(int *));
326
prime_table->EXP = (int **)realloc(prime_table->EXP,
327
number*sizeof(int *));
328
prime_table->l_primes[number-1] = act_prime = prime;
329
init_int_prime();
330
prime_table->LOG[number-1] = P_LOG;
331
prime_table->EXP[number-1] = P_EXP;
332
prime_table->l_number = number;
333
S = (int (*)(int, int))(int_S);
334
P = (int (*)(int, int))(int_P);
335
}
336
337
338
return;
339
}
340
341
/*}}} */
342
343