version 1.1, 2001/03/13 01:10:25 |
version 1.5, 2001/05/28 08:22:01 |
|
|
* DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE, |
* DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE, |
* PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE. |
* PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE. |
* |
* |
* $OpenXM$ |
* $OpenXM: OpenXM_contrib2/asir2000/engine/gfs.c,v 1.4 2001/03/29 09:49:58 noro Exp $ |
*/ |
*/ |
#include "ca.h" |
#include "ca.h" |
|
|
/* q = p^n */ |
/* q = p^n */ |
|
|
int current_gfs_ext; |
P current_gfs_ext; |
|
int current_gfs_p; |
int current_gfs_q; |
int current_gfs_q; |
int current_gfs_q1; |
int current_gfs_q1; |
int *current_gfs_plus1; |
int *current_gfs_plus1; |
Line 59 int *current_gfs_ntoi; |
|
Line 60 int *current_gfs_ntoi; |
|
int *current_gfs_iton; |
int *current_gfs_iton; |
|
|
void chsgngfs(); |
void chsgngfs(); |
|
void generate_defpoly_um(); |
|
|
|
void dec_um(p,a,u) |
|
int p,a; |
|
UM u; |
|
{ |
|
int i; |
|
|
|
for ( i = 0; a; i++, a /= p ) |
|
COEF(u)[i] = a%p; |
|
DEG(u) = i-1; |
|
} |
|
|
/* |
/* |
|
* an element of GF(p^n) f(x)=a(n-1)*x^(n-1)+...+a(0) |
|
* is encodeded to f(p). |
* current_gfs_iton[i] = r^i mod p (i=0,...,p-2) |
* current_gfs_iton[i] = r^i mod p (i=0,...,p-2) |
* current_gfs_iton[p-1] = 0 |
* current_gfs_iton[p-1] = 0 |
*/ |
*/ |
|
|
void setmod_sf(p,n) |
void setmod_sf(p,n) |
int p,n; |
int p,n; |
{ |
{ |
int r,i,p1; |
int r,i,q1,q,t,t1; |
|
UM dp; |
|
|
|
for ( i = 0, q = 1; i < n; i++ ) |
|
q *= p; |
|
dp = UMALLOC(n); |
|
generate_defpoly_um(p,n,dp); |
|
r = generate_primitive_root_enc(p,n,dp); |
|
current_gfs_p = p; |
|
current_gfs_q = q; |
|
current_gfs_q1 = q1 = q-1; |
if ( n > 1 ) |
if ( n > 1 ) |
error("setup_gfs : not implemented yet"); |
umtop(CO->v,dp,¤t_gfs_ext); |
else { |
else |
r = generate_primitive_root_p(p); |
current_gfs_ext = 0; |
current_gfs_q = p; |
current_gfs_iton = (int *)MALLOC(q1*sizeof(int)); |
current_gfs_ext = 1; |
current_gfs_iton[0] = 1; |
current_gfs_q1 = p1 = p-1; |
for ( i = 1; i < q1; i++ ) |
|
current_gfs_iton[i] = mulremum_enc(p,n,dp,current_gfs_iton[i-1],r); |
|
|
current_gfs_iton = (int *)MALLOC(p1*sizeof(int)); |
current_gfs_ntoi = (int *)MALLOC(q*sizeof(int)); |
current_gfs_iton[0] = 1; |
current_gfs_ntoi[0] = -1; |
for ( i = 1; i < p1; i++ ) |
for ( i = 0; i < q1; i++ ) |
current_gfs_iton[i] = (current_gfs_iton[i-1]*r)%p; |
current_gfs_ntoi[current_gfs_iton[i]] = i; |
|
|
|
current_gfs_plus1 = (int *)MALLOC(q*sizeof(int)); |
|
for ( i = 0; i < q1; i++ ) { |
|
t = current_gfs_iton[i]; |
|
/* add 1 to the constant part */ |
|
t1 = (t/p)*p+((t+1)%p); |
|
current_gfs_plus1[i] = current_gfs_ntoi[t1]; |
|
} |
|
} |
|
|
current_gfs_ntoi = (int *)MALLOC(p*sizeof(int)); |
void generate_defpoly_um(p,n,dp) |
current_gfs_ntoi[0] = -1; |
int p,n; |
for ( i = 0; i < p1; i++ ) |
UM dp; |
current_gfs_ntoi[current_gfs_iton[i]] = i; |
{ |
|
int i,j,a,c,q; |
current_gfs_plus1 = (int *)MALLOC(p*sizeof(int)); |
UM wf,wdf,wgcd; |
for ( i = 0; i < p1; i++ ) |
|
current_gfs_plus1[i] |
wf = W_UMALLOC(n); |
= current_gfs_ntoi[(current_gfs_iton[i]+1)%p]; |
wdf = W_UMALLOC(n); |
|
wgcd = W_UMALLOC(n); |
|
COEF(dp)[n] = 1; |
|
DEG(dp) = n; |
|
for ( i = 0, q = 1; i < n; i++ ) |
|
q *= p; |
|
for ( i = 0; i < q; i++ ) { |
|
for ( j = 0, a = i; a; j++, a /= p ) |
|
COEF(dp)[j] = a%p; |
|
for ( ; j < n; j++ ) |
|
COEF(dp)[j] = 0; |
|
cpyum(dp,wf); |
|
diffum(p,dp,wdf); |
|
gcdum(p,wf,wdf,wgcd); |
|
if ( DEG(wgcd) >= 1 ) |
|
continue; |
|
mini(p,dp,wf); |
|
if ( DEG(wf) <= 0 ) |
|
return; |
} |
} |
} |
} |
|
|
int generate_primitive_root_p(p) |
int generate_primitive_root_enc(p,n,dp) |
int p; |
int p,n; |
|
UM dp; |
{ |
{ |
int r,rj,j; |
int i,r,rj,j,q; |
|
|
for ( r = 2; r < p; r++ ) { |
if ( p == 2 && n == 1 ) |
|
return 1; |
|
|
|
for ( i = 0, q = 1; i < n; i++ ) |
|
q *= p; |
|
for ( r = n==1?2:p; r < q; r++ ) { |
rj = r; |
rj = r; |
for ( j = 1; j < p-1 && rj != 1; j++ ) |
for ( j = 1; j < q-1 && rj != 1; j++ ) |
rj = (rj*r) % p; |
rj = mulremum_enc(p,n,dp,rj,r); |
if ( j == p-1 ) |
if ( j == q-1 ) |
return r; |
return r; |
} |
} |
} |
} |
|
|
|
/* [a(p)]*[b(p)] in GF(p^n) -> [a(x)*b(x) mod dp(x)]_{x->p} */ |
|
|
|
int mulremum_enc(p,n,dp,a,b) |
|
int p,n; |
|
UM dp; |
|
int a,b; |
|
{ |
|
int i,dr,r; |
|
UM wa,wb,wc,wq; |
|
|
|
if ( n == 1 ) |
|
return (a*b)%p; |
|
if ( !a || !b ) |
|
return 0; |
|
|
|
wa = W_UMALLOC(n); |
|
dec_um(p,a,wa); |
|
|
|
wb = W_UMALLOC(n); |
|
dec_um(p,b,wb); |
|
|
|
wc = W_UMALLOC(2*n); |
|
wq = W_UMALLOC(2*n); |
|
mulum(p,wa,wb,wc); |
|
dr = divum(p,wc,dp,wq); |
|
for ( i = dr, r = 0; i >= 0; i-- ) |
|
r = r*p+COEF(wc)[i]; |
|
return r; |
|
} |
|
|
|
void gfs_galois_action(a,e,c) |
|
GFS a; |
|
Q e; |
|
GFS *c; |
|
{ |
|
Q p; |
|
int i,k; |
|
GFS t,s; |
|
|
|
t = a; |
|
k = QTOS(e); |
|
STOQ(current_gfs_p,p); |
|
for ( i = 0; i < k; i++ ) { |
|
pwrgfs(t,p,&s); t = s; |
|
} |
|
*c = t; |
|
} |
|
|
|
void qtogfs(a,c) |
|
Q a; |
|
GFS *c; |
|
{ |
|
int s; |
|
|
|
s = QTOS(a)%current_gfs_q; |
|
if ( s < 0 ) |
|
s += current_gfs_q; |
|
if ( !s ) |
|
*c = 0; |
|
else |
|
MKGFS(current_gfs_ntoi[s],*c); |
|
} |
|
|
void mqtogfs(a,c) |
void mqtogfs(a,c) |
MQ a; |
MQ a; |
GFS *c; |
GFS *c; |
|
|
else if ( OID(a) == O_N && NID(a) == N_M ) |
else if ( OID(a) == O_N && NID(a) == N_M ) |
mqtogfs(a,b); |
mqtogfs(a,b); |
else if ( OID(a) == O_N && NID(a) == N_Q ) { |
else if ( OID(a) == O_N && NID(a) == N_Q ) { |
ptomp(current_gfs_q,(P)a,&t); mqtogfs(t,b); |
ptomp(current_gfs_p,(P)a,&t); mqtogfs(t,b); |
} else |
} else |
error("ntogfs : invalid argument"); |
error("ntogfs : invalid argument"); |
} |
} |
|
|
else |
else |
return 0; |
return 0; |
} |
} |
|
} |
|
|
|
void randomgfs(r) |
|
GFS *r; |
|
{ |
|
unsigned int t; |
|
|
|
if ( !current_gfs_q1 ) |
|
error("addgfs : current_gfs_q is not set"); |
|
t = mt_genrand()%current_gfs_q; |
|
if ( !t ) |
|
*r = 0; |
|
else { |
|
if ( t == current_gfs_q1 ) |
|
t = 0; |
|
MKGFS(t,*r); |
|
} |
} |
} |