GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#include "typedef.h"1/**************************************************************************\2@---------------------------------------------------------------------------3@---------------------------------------------------------------------------4@ FILE: prime_tools.c5@---------------------------------------------------------------------------6@---------------------------------------------------------------------------7@8\**************************************************************************/9/*10@-------------------------------------------------------------------------11@ This file exports the global variables12@ int act_prime - This the actual used prime_number13@14@ int (*S)(int,int), (*P)(int,int)15@ S is the function for addition modulo act_prime and16@ P the function for multiplication17@18@ void cleanup_prime();19@ releases all memory that was allocated by init_prime(). Only20@ useful for debugging memory allocation.21@ void init_prime( int prime);22@ This function MUST be called before the functions S(a,b) and P(a,b)23@ can be used, since otherwise they are not defined.24@ The argument of init_prime is the new prime number, modulo which25@ the calculations shoud be done, i.e. act_prime is set to prime.26@27@-------------------------------------------------------------------------28| Dieses file export die globalen Variablen29|30| int act_prime;31| Dies ist die gerade benutzte Primzahl32|33| int (*S)(int, int), (*P)(int,int);34| Dies sind die Multiplikationsfunktionen fuer das Rechenen35| modulo act_prime;36|37| Es werden zwei Funktionen definiert, naemlich38|39| void init_prime( int prime );40| Diese Funktion \underline{MUSS} aufgerufen werden, bevor die41| Rechenfunktionen S(a,b) und P(a,b) benutzt werden koennen,42| da diese sonst nicht definiert sind. Argument von43| init_prime() ist die neue Primzahl, modulo derer gerechnet44| werden soll, das heisst, act_prime wird auf prime gesetzt45|46| void cleanup_prime();47| releases all memory that was allocated by init_prime(). Only48| useful for debugging memory allocation.49|50*/51#include "tools.h"5253/*54* local variables55*/56#define SHORTPRIME_LIMIT 300 /* Grenze fuer Rechnen mit Tabelle */5758typedef struct {59int s_number, *s_primes; /* Anzahl kleiner Pz; Liste der ... */60int l_number, *l_primes; /* Anzahl grosser Pz; Liste der ... */61int ***ADD, ***MUL; /* Rechen-Tabellen fuer kleine Pz. */62int **LOG, **EXP; /* p-Logarithmen fuer grosse Pz. */63} table;6465static int dummy( int a, int b);6667static int **P_ADD = NULL, **P_MUL = NULL; /* aktuelle Rechen_Tabelle */68static int *P_LOG = NULL, *P_EXP = NULL; /* aktuelle p-Logarithmen */69static table *prime_table = NULL;7071/*72* global variables73*/74int (*S)(int, int)= dummy, (*P)(int, int)= dummy; /* aktuelle Funktion */75int act_prime= -1;7677/*}}} */78/*{{{ dummy*/79static int dummy( a, b)80int a,b;81{82fprintf(stderr,"You tried to use GF(p)-Arithmetic without calling init_prime(act_prime).\n");83fprintf(stderr,"Currently, act_prime is set to %d, which is apparently not prime.\n", act_prime);84exit(3);85return 0;86}8788/*}}} */89/*{{{ short_P*/90static91int short_P(i,j)92int i,j;93{94return(P_MUL[i][j]);95}9697/*}}} */98/*{{{ short_S*/99static100int short_S(i,j)101int i,j;102{103int k;104return(P_ADD[i][j]);105}106107/*}}} */108/*{{{ int_P*/109static110int int_P(i,j)111int i,j;112{113return((i*j ==0 ) ? 0 : P_EXP[(P_LOG[i] + P_LOG[j]) % (act_prime-1)]);114}115116/*}}} */117/*{{{ int_S*/118static119int int_S(i,j)120int i,j;121{122/* die "5" ist nur ein Sicherheitsfaktor */123return((i+j+5*act_prime)%act_prime);124}125126/*}}} */127/*{{{ init_short_prime*/128static129void init_short_prime()130{131int j,k;132133P_ADD = (int **)malloc((unsigned)act_prime*sizeof(int *));134P_MUL = (int **)malloc((unsigned)act_prime*sizeof(int *));135for ( j = 0; j < act_prime; j ++) {136P_MUL[j] = (int *)malloc((unsigned)(2*act_prime-1)*sizeof(int));137P_ADD[j] = (int *)malloc((unsigned)(2*act_prime-1)*sizeof(int));138P_MUL[j] += act_prime-1;139P_ADD[j] += act_prime-1;140}141for ( j = 0; j < act_prime; j ++) {142for ( k = 0; k <= j; k++) {143P_MUL[j][k] = P_MUL[k][j] = (j * k) % act_prime;144if ( j != 0 ) {145P_MUL[P_MUL[j][k]][-j] = k;146}147if ( k != 0 ) {148P_MUL[P_MUL[j][k]][-k] = j;149}150if((k != 0) && (P_MUL[j][k] == 0)) {151fprintf(stderr,"init_short_prime: Error Non-prime (%d) in makefield occured\n", act_prime);152}153P_ADD[j][k] = P_ADD[k][j] = (j + k) % act_prime;154P_ADD[P_ADD[j][k]][-j] = k;155P_ADD[P_ADD[j][k]][-k] = j;156}157}158}159/*}}} */160/*{{{ init_int_prime*/161static162void init_int_prime()163{164int i,j,k,gt;165int *p_tmp;166int flag;167168P_LOG = (int *)calloc(2*act_prime+1,sizeof(int));169P_EXP = (int *)calloc(act_prime,sizeof(int));170p_tmp = (int *)calloc(act_prime+1,sizeof(int));171P_LOG += act_prime;172173/* find a generator of the cyclic multiplicative group of Fp */174175for(i = 1; i <= act_prime; i++) {176p_tmp[i] = 1;177}178179k = gt = (act_prime-1)/2;180p_tmp[k] = 0;181j = 1;182flag = TRUE;183while(flag) {184do {185if((k = (k * gt)%act_prime) == 0) {186fprintf(stderr,"Error: Nullteiler\n");187exit(3);188}189p_tmp[k] = 0;190j++;191} while(k != 1);192flag = (j == act_prime-1) ? FALSE : TRUE;193if(flag) {194j = 1;195for(i = 1; i <=act_prime; i++) {196if (p_tmp[i] == 1) {197gt = i;198break;199}200}201if(i > act_prime) {202fprintf(stderr,"No generator for multiplicative group found");203exit(3);204}205k = gt;206p_tmp[k] = 0;207}208}209210k = j = 1;211do {212k = (k * gt)%act_prime;213P_LOG[k] = j;214P_EXP[j] = k;215P_LOG[-k] = act_prime-j-1;216j++;217} while(k != 1);218P_LOG[1] = 0;219P_EXP[0] = 1;220free(p_tmp);221}222/*}}} */223/*{{{ cleanup_prime*/224void cleanup_prime()225{226int i, j;227228if ( prime_table != NULL ) {229for ( i=1; i < prime_table->s_number; i ++ ) {230act_prime = prime_table->s_primes[i];231for ( j = 0; j < act_prime; j ++) {232prime_table->ADD[i][j] -= act_prime - 1;233prime_table->MUL[i][j] -= act_prime - 1;234free( prime_table->ADD[i][j] );235free( prime_table->MUL[i][j] );236}237free( prime_table->ADD[i] );238free( prime_table->MUL[i] );239}240free( prime_table->s_primes );241free( prime_table->ADD );242free( prime_table->MUL );243244for ( i=1; i < prime_table->l_number; i ++ ) {245act_prime = prime_table->l_primes[i];246prime_table->LOG[i] -= act_prime;247free( prime_table->LOG[i] );248free( prime_table->EXP[i] );249}250free( prime_table->l_primes );251free( prime_table->LOG );252free( prime_table->EXP );253free( prime_table );254}255act_prime = -1;256prime_table = NULL;257P_LOG = NULL;258P_EXP = NULL;259P_ADD = NULL;260P_MUL = NULL;261262263}264/*}}} */265/*{{{ init_prime*/266void init_prime (prime)267int prime;268{269int j, k, number;270271number = 1;272if (act_prime == -1) {273prime_table = (table *)malloc(sizeof(table));274prime_table->s_number = 1;275prime_table->l_number = 1;276prime_table->s_primes= (int *)calloc(1,sizeof(int));277prime_table->l_primes= (int *)calloc(1,sizeof(int));278prime_table->ADD = (int ***)malloc(1*sizeof(int **));279prime_table->MUL = (int ***)malloc(1*sizeof(int **));280prime_table->LOG = (int **)malloc(1*sizeof(int *));281prime_table->EXP = (int **)malloc(1*sizeof(int *));282}283j = 0;284if (prime < SHORTPRIME_LIMIT) {285number = prime_table->s_number;286while (j < number) {287if (prime_table->s_primes[j] == prime) {288P_ADD = prime_table->ADD[j];289P_MUL = prime_table->MUL [j];290act_prime = prime;291return;292}293j++;294}295number++;296prime_table->s_primes= (int *)realloc(prime_table->s_primes,297number*sizeof(int));298prime_table->ADD = (int ***)realloc(prime_table->ADD,299number*sizeof(int **));300prime_table->MUL = (int ***)realloc(prime_table->MUL ,301number*sizeof(int **));302prime_table->s_primes[number-1] = act_prime = prime;303init_short_prime();304prime_table->ADD[number-1] = P_ADD;305prime_table->MUL[number-1] = P_MUL;306prime_table->s_number = number;307S = (int (*)(int, int))(short_S);308P = (int (*)(int, int))(short_P);309} else {310number = prime_table->l_number;311while (j < number) {312if (prime_table->l_primes[j] == prime) {313P_LOG = prime_table->LOG[j];314P_EXP = prime_table->EXP[j];315act_prime = prime;316return;317}318j++;319}320number++;321prime_table->l_primes= (int *)realloc(prime_table->l_primes,322number*sizeof(int));323prime_table->LOG = (int **)realloc(prime_table->LOG,324number*sizeof(int *));325prime_table->EXP = (int **)realloc(prime_table->EXP,326number*sizeof(int *));327prime_table->l_primes[number-1] = act_prime = prime;328init_int_prime();329prime_table->LOG[number-1] = P_LOG;330prime_table->EXP[number-1] = P_EXP;331prime_table->l_number = number;332S = (int (*)(int, int))(int_S);333P = (int (*)(int, int))(int_P);334}335336337return;338}339340/*}}} */341342343