version 1.9, 2001/10/09 01:36:12 |
version 1.11, 2002/09/27 04:24:04 |
|
|
* 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_contrib2/asir2000/engine/gfs.c,v 1.8 2001/06/29 09:08:53 noro Exp $ |
* $OpenXM: OpenXM_contrib2/asir2000/engine/gfs.c,v 1.10 2001/11/06 09:40:36 noro Exp $ |
*/ |
*/ |
#include "ca.h" |
#include "ca.h" |
|
#include "inline.h" |
|
|
/* q = p^n */ |
/* q = p^n */ |
|
|
Line 66 struct prim_root_info { |
|
Line 67 struct prim_root_info { |
|
int prim_root; |
int prim_root; |
}; |
}; |
|
|
|
/* if p >= SF_THRESHOLD, usual representation is used */ |
|
|
|
#define SF_THRESHOLD 16384 |
|
|
struct prim_root_info prim_root_info_tab[] = { |
struct prim_root_info prim_root_info_tab[] = { |
{2,1,0,0}, {2,2,7,2}, {2,3,11,2}, {2,4,19,2}, {2,5,37,2}, {2,6,67,2}, |
{2,1,0,0}, {2,2,7,2}, {2,3,11,2}, {2,4,19,2}, {2,5,37,2}, {2,6,67,2}, |
{2,7,131,2}, {2,8,283,3}, {2,9,515,7}, {2,10,1033,2}, {2,11,2053,2}, |
{2,7,131,2}, {2,8,283,3}, {2,9,515,7}, {2,10,1033,2}, {2,11,2053,2}, |
Line 491 void setmod_sf(int p,int n) |
|
Line 496 void setmod_sf(int p,int n) |
|
int r,i,q1,q,t,t1; |
int r,i,q1,q,t,t1; |
UM dp; |
UM dp; |
|
|
|
if ( p >= SF_THRESHOLD ) { |
|
if ( n > 1 ) |
|
error("setmod_ff : p^n is too large"); |
|
current_gfs_p = p; |
|
current_gfs_q = p; |
|
current_gfs_q1 = p-1; |
|
current_gfs_ext = 0; |
|
current_gfs_ntoi = 0; |
|
current_gfs_iton = 0; |
|
current_gfs_plus1 = 0; |
|
return; |
|
} |
|
|
for ( i = 0, q = 1; i < n; i++ ) |
for ( i = 0, q = 1; i < n; i++ ) |
q *= p; |
q *= p; |
dp = UMALLOC(n); |
dp = UMALLOC(n); |
Line 639 int mulremum_enc(int p,int n,UM dp,int a,int b) |
|
Line 657 int mulremum_enc(int p,int n,UM dp,int a,int b) |
|
return r; |
return r; |
} |
} |
|
|
|
/* sigma : alpha -> alpha^q */ |
|
|
void gfs_galois_action(GFS a,Q e,GFS *c) |
void gfs_galois_action(GFS a,Q e,GFS *c) |
{ |
{ |
Q p; |
Q q; |
int i,k; |
int i,k; |
GFS t,s; |
GFS t,s; |
|
|
t = a; |
t = a; |
k = QTOS(e); |
k = QTOS(e); |
STOQ(current_gfs_p,p); |
STOQ(current_gfs_q,q); |
for ( i = 0; i < k; i++ ) { |
for ( i = 0; i < k; i++ ) { |
pwrgfs(t,p,&s); t = s; |
pwrgfs(t,q,&s); t = s; |
} |
} |
*c = t; |
*c = t; |
} |
} |
Line 677 void qtogfs(Q a,GFS *c) |
|
Line 697 void qtogfs(Q a,GFS *c) |
|
s += current_gfs_q; |
s += current_gfs_q; |
if ( !s ) |
if ( !s ) |
*c = 0; |
*c = 0; |
else |
else if ( !current_gfs_ntoi ) { |
|
MKGFS(s,*c); |
|
} else { |
MKGFS(current_gfs_ntoi[s],*c); |
MKGFS(current_gfs_ntoi[s],*c); |
|
} |
} |
} |
|
|
void mqtogfs(MQ a,GFS *c) |
void mqtogfs(MQ a,GFS *c) |
{ |
{ |
if ( !a ) |
if ( !a ) |
*c = 0; |
*c = 0; |
else { |
else if ( !current_gfs_ntoi ) { |
|
MKGFS(CONT(a),*c); |
|
} else { |
MKGFS(current_gfs_ntoi[CONT(a)],*c); |
MKGFS(current_gfs_ntoi[CONT(a)],*c); |
} |
} |
} |
} |
Line 694 void gfstomq(GFS a,MQ *c) |
|
Line 719 void gfstomq(GFS a,MQ *c) |
|
{ |
{ |
if ( !a ) |
if ( !a ) |
*c = 0; |
*c = 0; |
else { |
else if ( !current_gfs_ntoi ) { |
|
UTOMQ(CONT(a),*c); |
|
} else { |
UTOMQ(current_gfs_iton[CONT(a)],*c); |
UTOMQ(current_gfs_iton[CONT(a)],*c); |
} |
} |
} |
} |
Line 726 void addgfs(GFS a,GFS b,GFS *c) |
|
Line 753 void addgfs(GFS a,GFS b,GFS *c) |
|
*c = b; |
*c = b; |
else if ( !b ) |
else if ( !b ) |
*c = a; |
*c = a; |
else { |
else if ( !current_gfs_ntoi ) { |
ai = CONT(a); bi = CONT(b); |
ai = CONT(a); bi = CONT(b); |
|
ci = ai+bi-current_gfs_q; |
|
if ( ci == 0 ) |
|
*c = 0; |
|
else { |
|
if ( ci < 0 ) |
|
ci += current_gfs_q; |
|
MKGFS(ci,*c); |
|
} |
|
} else { |
|
ai = CONT(a); bi = CONT(b); |
if ( ai > bi ) { |
if ( ai > bi ) { |
/* tab[ai]+tab[bi] = tab[bi](tab[ai-bi]+1) */ |
/* tab[ai]+tab[bi] = tab[bi](tab[ai-bi]+1) */ |
ci = current_gfs_plus1[ai-bi]; |
ci = current_gfs_plus1[ai-bi]; |
Line 770 void subgfs(GFS a,GFS b,GFS *c) |
|
Line 807 void subgfs(GFS a,GFS b,GFS *c) |
|
|
|
void mulgfs(GFS a,GFS b,GFS *c) |
void mulgfs(GFS a,GFS b,GFS *c) |
{ |
{ |
int ai; |
int ai,bi,ci; |
GFS z; |
GFS z; |
|
|
ntogfs((Obj)a,&z); a = z; |
ntogfs((Obj)a,&z); a = z; |
ntogfs((Obj)b,&z); b = z; |
ntogfs((Obj)b,&z); b = z; |
if ( !a || !b ) |
if ( !a || !b ) |
*c = 0; |
*c = 0; |
else { |
else if ( !current_gfs_ntoi ) { |
|
ai = CONT(a); bi = CONT(b); |
|
DMAR(ai,bi,0,current_gfs_q,ci); |
|
MKGFS(ci,*c); |
|
} else { |
ai = CONT(a) + CONT(b); |
ai = CONT(a) + CONT(b); |
if ( ai >= current_gfs_q1 ) |
if ( ai >= current_gfs_q1 ) |
ai -= current_gfs_q1; |
ai -= current_gfs_q1; |
Line 787 void mulgfs(GFS a,GFS b,GFS *c) |
|
Line 828 void mulgfs(GFS a,GFS b,GFS *c) |
|
|
|
void divgfs(GFS a,GFS b,GFS *c) |
void divgfs(GFS a,GFS b,GFS *c) |
{ |
{ |
int ai; |
int ai,bi,ci; |
GFS z; |
GFS z; |
|
|
ntogfs((Obj)a,&z); a = z; |
ntogfs((Obj)a,&z); a = z; |
Line 796 void divgfs(GFS a,GFS b,GFS *c) |
|
Line 837 void divgfs(GFS a,GFS b,GFS *c) |
|
error("divgfs : division by 0"); |
error("divgfs : division by 0"); |
else if ( !a ) |
else if ( !a ) |
*c = 0; |
*c = 0; |
else { |
else if ( !current_gfs_ntoi ) { |
|
ai = CONT(a); bi = invm(CONT(b),current_gfs_q); |
|
DMAR(ai,bi,0,current_gfs_q,ci); |
|
MKGFS(ci,*c); |
|
} else { |
ai = CONT(a) - CONT(b); |
ai = CONT(a) - CONT(b); |
if ( ai < 0 ) |
if ( ai < 0 ) |
ai += current_gfs_q1; |
ai += current_gfs_q1; |
Line 812 void chsgngfs(GFS a,GFS *c) |
|
Line 857 void chsgngfs(GFS a,GFS *c) |
|
ntogfs((Obj)a,&z); a = z; |
ntogfs((Obj)a,&z); a = z; |
if ( !a ) |
if ( !a ) |
*c = 0; |
*c = 0; |
else if ( current_gfs_q1&1 ) |
else if ( !current_gfs_ntoi ) { |
|
ai = current_gfs_q - CONT(a); |
|
MKGFS(ai,*c); |
|
} else if ( current_gfs_q1&1 ) |
*c = a; |
*c = a; |
else { |
else { |
/* r^((q-1)/2) = -1 */ |
/* r^((q-1)/2) = -1 */ |
Line 827 void pwrgfs(GFS a,Q b,GFS *c) |
|
Line 875 void pwrgfs(GFS a,Q b,GFS *c) |
|
{ |
{ |
N an,tn,rn; |
N an,tn,rn; |
GFS t,s,z; |
GFS t,s,z; |
|
int ai; |
|
|
ntogfs((Obj)a,&z); a = z; |
ntogfs((Obj)a,&z); a = z; |
if ( !b ) |
if ( !b ) |
MKGFS(0,*c); |
MKGFS(0,*c); |
else if ( !a ) |
else if ( !a ) |
*c = 0; |
*c = 0; |
else { |
else if ( !current_gfs_ntoi ) { |
|
ai = pwrm(current_gfs_q,CONT(a),QTOS(b)); |
|
MKGFS(ai,*c); |
|
} else { |
STON(CONT(a),an); muln(an,NM(b),&tn); |
STON(CONT(a),an); muln(an,NM(b),&tn); |
STON(current_gfs_q1,an); remn(tn,an,&rn); |
STON(current_gfs_q1,an); remn(tn,an,&rn); |
if ( !rn ) |
if ( !rn ) |
Line 878 void randomgfs(GFS *r) |
|
Line 930 void randomgfs(GFS *r) |
|
if ( !t ) |
if ( !t ) |
*r = 0; |
*r = 0; |
else { |
else { |
if ( t == (unsigned int)current_gfs_q1 ) |
if ( current_gfs_ntoi && t == (unsigned int)current_gfs_q1 ) |
t = 0; |
t = 0; |
MKGFS(t,*r); |
MKGFS(t,*r); |
} |
} |
Line 894 int _addsf(int a,int b) |
|
Line 946 int _addsf(int a,int b) |
|
return a; |
return a; |
|
|
a = IFTOF(a); b = IFTOF(b); |
a = IFTOF(a); b = IFTOF(b); |
|
|
|
if ( !current_gfs_ntoi ) { |
|
a = a+b-current_gfs_q; |
|
if ( a == 0 ) |
|
return 0; |
|
else { |
|
if ( a < 0 ) |
|
a += current_gfs_q; |
|
return FTOIF(a); |
|
} |
|
} |
|
|
if ( a > b ) { |
if ( a > b ) { |
/* tab[a]+tab[b] = tab[b](tab[a-b]+1) */ |
/* tab[a]+tab[b] = tab[b](tab[a-b]+1) */ |
a = current_gfs_plus1[a-b]; |
a = current_gfs_plus1[a-b]; |
Line 923 int _chsgnsf(int a) |
|
Line 987 int _chsgnsf(int a) |
|
{ |
{ |
if ( !a ) |
if ( !a ) |
return 0; |
return 0; |
else if ( current_gfs_q1&1 ) |
else if ( !current_gfs_ntoi ) { |
|
a = current_gfs_q-IFTOF(a); |
|
return FTOIF(a); |
|
} else if ( current_gfs_q1&1 ) |
return a; |
return a; |
else { |
else { |
/* r^((q-1)/2) = -1 */ |
/* r^((q-1)/2) = -1 */ |
Line 947 int _subsf(int a,int b) |
|
Line 1014 int _subsf(int a,int b) |
|
|
|
int _mulsf(int a,int b) |
int _mulsf(int a,int b) |
{ |
{ |
|
int c; |
|
|
if ( !a || !b ) |
if ( !a || !b ) |
return 0; |
return 0; |
else { |
else if ( !current_gfs_ntoi ) { |
|
a = IFTOF(a); b = IFTOF(b); |
|
DMAR(a,b,0,current_gfs_q,c); |
|
return FTOIF(c); |
|
} else { |
a = IFTOF(a) + IFTOF(b); |
a = IFTOF(a) + IFTOF(b); |
if ( a >= current_gfs_q1 ) |
if ( a >= current_gfs_q1 ) |
a -= current_gfs_q1; |
a -= current_gfs_q1; |
Line 963 int _invsf(int a) |
|
Line 1036 int _invsf(int a) |
|
error("_invsf : division by 0"); |
error("_invsf : division by 0"); |
/* NOTREACHED */ |
/* NOTREACHED */ |
return -1; |
return -1; |
|
} else if ( !current_gfs_ntoi ) { |
|
a = invm(IFTOF(a),current_gfs_q); |
|
return FTOIF(a); |
} else { |
} else { |
a = current_gfs_q1 - IFTOF(a); |
a = current_gfs_q1 - IFTOF(a); |
return FTOIF(a); |
return FTOIF(a); |
Line 971 int _invsf(int a) |
|
Line 1047 int _invsf(int a) |
|
|
|
int _divsf(int a,int b) |
int _divsf(int a,int b) |
{ |
{ |
|
int c; |
|
|
if ( !b ) { |
if ( !b ) { |
error("_divsf : division by 0"); |
error("_divsf : division by 0"); |
/* NOTREACHED */ |
/* NOTREACHED */ |
return -1; |
return -1; |
|
} else if ( !current_gfs_ntoi ) { |
|
b = invm(IFTOF(b),current_gfs_q); |
|
a = IFTOF(a); |
|
DMAR(a,b,0,current_gfs_q,c); |
|
return FTOIF(c); |
} else if ( !a ) |
} else if ( !a ) |
return 0; |
return 0; |
else { |
else { |
Line 995 int _pwrsf(int a,int b) |
|
Line 1078 int _pwrsf(int a,int b) |
|
return _onesf(); |
return _onesf(); |
else if ( !a ) |
else if ( !a ) |
return 0; |
return 0; |
else { |
if ( !current_gfs_ntoi ) { |
|
a = pwrm(current_gfs_q,IFTOF(a),b); |
|
return FTOIF(a); |
|
} else { |
a = IFTOF(a); |
a = IFTOF(a); |
MKGFS(a,at); |
MKGFS(a,at); |
STOQ(b,bt); |
STOQ(b,bt); |
Line 1007 int _pwrsf(int a,int b) |
|
Line 1093 int _pwrsf(int a,int b) |
|
|
|
int _onesf() |
int _onesf() |
{ |
{ |
return FTOIF(0); |
return !current_gfs_ntoi ? FTOIF(1) : FTOIF(0); |
} |
} |
|
|
int _itosf(int n) |
int _itosf(int n) |
Line 1017 int _itosf(int n) |
|
Line 1103 int _itosf(int n) |
|
n %= current_gfs_p; |
n %= current_gfs_p; |
if ( !n ) |
if ( !n ) |
return 0; |
return 0; |
i = current_gfs_ntoi[n]; |
i = !current_gfs_ntoi ? n : current_gfs_ntoi[n]; |
i = FTOIF(i); |
i = FTOIF(i); |
if ( n < 0 ) |
if ( n < 0 ) |
i = _chsgnsf(i); |
i = _chsgnsf(i); |
Line 1026 int _itosf(int n) |
|
Line 1112 int _itosf(int n) |
|
|
|
int _isonesf(int a) |
int _isonesf(int a) |
{ |
{ |
return a == FTOIF(0); |
return a == (!current_gfs_ntoi ? FTOIF(1) : FTOIF(0)); |
} |
} |
|
|
int _randomsf() |
int _randomsf() |
{ |
{ |
int t; |
int t; |
|
|
t = (int) (mt_genrand() % current_gfs_q1); |
t = (int) (mt_genrand() % current_gfs_q); |
if ( !t ) |
if ( !current_gfs_ntoi ) |
return 0; |
return t ? FTOIF(t) : 0; |
else |
else |
return FTOIF(t); |
return t!=current_gfs_q1 ? FTOIF(t) : 0; |
} |
} |
|
|
int field_order_sf() |
int field_order_sf() |
Line 1052 int characteristic_sf() |
|
Line 1138 int characteristic_sf() |
|
|
|
int extdeg_sf() |
int extdeg_sf() |
{ |
{ |
return UDEG(current_gfs_ext); |
if ( !current_gfs_ext ) |
|
return 1; |
|
else |
|
return UDEG(current_gfs_ext); |
} |
} |