version 1.2, 2000/08/21 08:31:28 |
version 1.7, 2018/03/29 01:32:52 |
|
|
* shall be made on your publication or presentation in any form of the |
* shall be made on your publication or presentation in any form of the |
* results obtained by use of the SOFTWARE. |
* results obtained by use of the SOFTWARE. |
* (4) In the event that you modify the SOFTWARE, you shall notify FLL by |
* (4) In the event that you modify the SOFTWARE, you shall notify FLL by |
* e-mail at risa-admin@flab.fujitsu.co.jp of the detailed specification |
* e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification |
* for such modification or the source code of the modified part of the |
* for such modification or the source code of the modified part of the |
* SOFTWARE. |
* SOFTWARE. |
* |
* |
|
|
* 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/up_gf2n.c,v 1.1.1.1 1999/12/03 07:39:08 noro Exp $ |
* $OpenXM: OpenXM_contrib2/asir2000/engine/up_gf2n.c,v 1.6 2015/08/14 13:51:55 fujimoto Exp $ |
*/ |
*/ |
#include "ca.h" |
#include "ca.h" |
#include <math.h> |
#include <math.h> |
Line 54 extern int debug_up; |
|
Line 54 extern int debug_up; |
|
extern int up_lazy; |
extern int up_lazy; |
extern GEN_UP2 current_mod_gf2n; |
extern GEN_UP2 current_mod_gf2n; |
|
|
void squarep_gf2n(vl,n1,nr) |
void squarep_gf2n(VL vl,P n1,P *nr) |
VL vl; |
|
P n1; |
|
P *nr; |
|
{ |
{ |
UP b1,br; |
UP b1,br; |
|
|
if ( !n1 ) |
if ( !n1 ) |
*nr = 0; |
*nr = 0; |
else if ( OID(n1) == O_N ) |
else if ( OID(n1) == O_N ) |
mulp(vl,n1,n1,nr); |
mulp(vl,n1,n1,nr); |
else { |
else { |
ptoup(n1,&b1); |
ptoup(n1,&b1); |
squareup_gf2n(b1,&br); |
squareup_gf2n(b1,&br); |
uptop(br,nr); |
uptop(br,nr); |
} |
} |
} |
} |
|
|
void squareup_gf2n(n1,nr) |
void squareup_gf2n(UP n1,UP *nr) |
UP n1; |
|
UP *nr; |
|
{ |
{ |
UP r; |
UP r; |
GF2N *c1,*c; |
GF2N *c1,*c; |
int i,d1,d; |
int i,d1,d; |
|
|
if ( !n1 ) |
if ( !n1 ) |
*nr = 0; |
*nr = 0; |
else if ( !n1->d ) { |
else if ( !n1->d ) { |
*nr = r = UPALLOC(0); r->d = 0; |
*nr = r = UPALLOC(0); r->d = 0; |
squaregf2n((GF2N)n1->c[0],(GF2N *)(&r->c[0])); |
squaregf2n((GF2N)n1->c[0],(GF2N *)(&r->c[0])); |
} else { |
} else { |
d1 = n1->d; |
d1 = n1->d; |
d = 2*d1; |
d = 2*d1; |
*nr = r = UPALLOC(d); r->d = d; |
*nr = r = UPALLOC(d); r->d = d; |
c1 = (GF2N *)n1->c; c = (GF2N *)r->c; |
c1 = (GF2N *)n1->c; c = (GF2N *)r->c; |
bzero((char *)c,(d+1)*sizeof(GF2N *)); |
bzero((char *)c,(d+1)*sizeof(GF2N *)); |
for ( i = 0; i <= d1; i++ ) |
for ( i = 0; i <= d1; i++ ) |
squaregf2n(c1[i],&c[2*i]); |
squaregf2n(c1[i],&c[2*i]); |
} |
} |
} |
} |
|
|
/* x^(2^n) mod f */ |
/* x^(2^n) mod f */ |
|
|
void powermodup_gf2n(f,xp) |
void powermodup_gf2n(UP f,UP *xp) |
UP f; |
|
UP *xp; |
|
{ |
{ |
UP x,t,invf; |
UP x,t,invf; |
int k,n; |
int k,n; |
GF2N lm; |
GF2N lm; |
struct oEGT eg_sq,eg_rem,eg_mul,eg_inv,eg0,eg1,eg2; |
|
|
|
n = degup2(current_mod_gf2n->dense); |
n = degup2(current_mod_gf2n->dense); |
MKGF2N(ONEUP2,lm); |
MKGF2N(ONEUP2,lm); |
x = UPALLOC(1); x->d = 1; x->c[1] = (Num)lm; |
x = UPALLOC(1); x->d = 1; x->c[1] = (Num)lm; |
|
|
reverseup(f,f->d,&t); |
reverseup(f,f->d,&t); |
invmodup(t,f->d,&invf); |
invmodup(t,f->d,&invf); |
for ( k = 0; k < n; k++ ) { |
for ( k = 0; k < n; k++ ) { |
squareup_gf2n(x,&t); |
squareup_gf2n(x,&t); |
rembymulup_special(t,f,invf,&x); |
rembymulup_special(t,f,invf,&x); |
/* remup(t,f,&x); */ |
/* remup(t,f,&x); */ |
} |
} |
*xp = x; |
*xp = x; |
} |
} |
|
|
/* g^d mod f */ |
/* g^d mod f */ |
|
|
void generic_powermodup_gf2n(g,f,d,xp) |
void generic_powermodup_gf2n(UP g,UP f,Q d,UP *xp) |
UP g,f; |
|
Q d; |
|
UP *xp; |
|
{ |
{ |
N e; |
N e; |
UP x,y,t,invf,s; |
UP x,y,t,invf,s; |
int k; |
int k; |
GF2N lm; |
GF2N lm; |
|
|
e = NM(d); |
e = NM(d); |
MKGF2N(ONEUP2,lm); |
MKGF2N(ONEUP2,lm); |
y = UPALLOC(0); y->d = 0; y->c[0] = (Num)lm; |
y = UPALLOC(0); y->d = 0; y->c[0] = (Num)lm; |
remup(g,f,&x); |
remup(g,f,&x); |
if ( !x ) { |
if ( !x ) { |
*xp = !d ? y : 0; |
*xp = !d ? y : 0; |
return; |
return; |
} else if ( !x->d ) { |
} else if ( !x->d ) { |
pwrup(x,d,xp); |
pwrup(x,d,xp); |
return; |
return; |
} |
} |
reverseup(f,f->d,&t); |
reverseup(f,f->d,&t); |
invmodup(t,f->d,&invf); |
invmodup(t,f->d,&invf); |
for ( k = n_bits(e)-1; k >= 0; k-- ) { |
for ( k = n_bits(e)-1; k >= 0; k-- ) { |
squareup_gf2n(y,&t); |
squareup_gf2n(y,&t); |
rembymulup_special(t,f,invf,&s); |
rembymulup_special(t,f,invf,&s); |
y = s; |
y = s; |
if ( e->b[k/32] & (1<<(k%32)) ) { |
if ( e->b[k/32] & (1<<(k%32)) ) { |
mulup(y,x,&t); |
mulup(y,x,&t); |
remup(t,f,&s); |
remup(t,f,&s); |
y = s; |
y = s; |
} |
} |
} |
} |
*xp = y; |
*xp = y; |
} |
} |
|
|
/* g+g^2+...+g^(2^(nd-1)) mod f; where e = deg(mod) */ |
/* g+g^2+...+g^(2^(nd-1)) mod f; where e = deg(mod) */ |
|
|
void tracemodup_gf2n(g,f,d,xp) |
void tracemodup_gf2n(UP g,UP f,Q d,UP *xp) |
UP g,f; |
|
Q d; |
|
UP *xp; |
|
{ |
{ |
UP x,t,s,u,invf; |
UP x,t,s,u,invf; |
int en,i; |
int en,i; |
|
|
en = QTOS(d)*degup2(current_mod_gf2n->dense); |
en = QTOS(d)*degup2(current_mod_gf2n->dense); |
remup(g,f,&x); |
remup(g,f,&x); |
if ( !x ) { |
if ( !x ) { |
*xp = 0; |
*xp = 0; |
return; |
return; |
} |
} |
reverseup(f,f->d,&t); |
reverseup(f,f->d,&t); |
invmodup(t,f->d,&invf); |
invmodup(t,f->d,&invf); |
for ( i = 1, t = s = x; i < en; i++ ) { |
for ( i = 1, t = s = x; i < en; i++ ) { |
squareup_gf2n(t,&u); |
squareup_gf2n(t,&u); |
rembymulup_special(u,f,invf,&t); |
rembymulup_special(u,f,invf,&t); |
addup(s,t,&u); s = u; |
addup(s,t,&u); s = u; |
} |
} |
*xp = s; |
*xp = s; |
} |
} |
|
|
void tracemodup_gf2n_slow(g,f,d,xp) |
void tracemodup_gf2n_slow(UP g,UP f,Q d,UP *xp) |
UP g,f; |
|
Q d; |
|
UP *xp; |
|
{ |
{ |
UP x,t,s,u; |
UP x,t,s,u; |
int en,i; |
int en,i; |
|
|
en = QTOS(d)*degup2(current_mod_gf2n->dense); |
en = QTOS(d)*degup2(current_mod_gf2n->dense); |
remup(g,f,&x); |
remup(g,f,&x); |
if ( !x ) { |
if ( !x ) { |
*xp = 0; |
*xp = 0; |
return; |
return; |
} |
} |
for ( i = 1, t = s = x; i < en; i++ ) { |
for ( i = 1, t = s = x; i < en; i++ ) { |
squareup_gf2n(t,&u); |
squareup_gf2n(t,&u); |
remup(u,f,&t); |
remup(u,f,&t); |
addup(s,t,&u); s = u; |
addup(s,t,&u); s = u; |
} |
} |
*xp = s; |
*xp = s; |
} |
} |
|
|
static struct oEGT eg_trace_tab,eg_trace_mul; |
void tracemodup_gf2n_tab(UP g,UP f,Q d,UP *xp) |
|
|
void tracemodup_gf2n_tab(g,f,d,xp) |
|
UP g,f; |
|
Q d; |
|
UP *xp; |
|
{ |
{ |
UP x0,x2,t,s,u; |
UP x0,x2,t,s,u; |
int en,i; |
int en,i; |
UP *tab; |
UP *tab; |
GF2N one; |
GF2N one; |
struct oEGT eg1,eg2; |
|
|
|
en = QTOS(d)*degup2(current_mod_gf2n->dense); |
en = QTOS(d)*degup2(current_mod_gf2n->dense); |
remup(g,f,&t); g = t; |
remup(g,f,&t); g = t; |
if ( !g ) { |
if ( !g ) { |
*xp = 0; |
*xp = 0; |
return; |
return; |
} |
} |
|
|
MKGF2N(ONEUP2,one); |
MKGF2N(ONEUP2,one); |
x0 = UPALLOC(0); x0->d = 0; x0->c[0] = (Num)one; |
x0 = UPALLOC(0); x0->d = 0; x0->c[0] = (Num)one; |
x2 = UPALLOC(2); x2->d = 2; x2->c[2] = (Num)one; |
x2 = UPALLOC(2); x2->d = 2; x2->c[2] = (Num)one; |
|
|
tab = (UP *)ALLOCA(en*sizeof(UP)); |
tab = (UP *)ALLOCA(en*sizeof(UP)); |
tab[0] = x0; |
tab[0] = x0; |
remup(x2,f,&tab[1]); |
remup(x2,f,&tab[1]); |
|
|
for ( i = 2; i < en; i++ ) { |
for ( i = 2; i < en; i++ ) { |
mulup(tab[i-1],tab[1],&t); remup(t,f,&tab[i]); |
mulup(tab[i-1],tab[1],&t); remup(t,f,&tab[i]); |
} |
} |
|
|
for ( i = 1, t = s = g; i < en; i++ ) { |
for ( i = 1, t = s = g; i < en; i++ ) { |
square_rem_tab_up_gf2n(t,tab,&u); t = u; |
square_rem_tab_up_gf2n(t,tab,&u); t = u; |
addup(s,t,&u); s = u; |
addup(s,t,&u); s = u; |
} |
} |
*xp = s; |
*xp = s; |
} |
} |
|
|
void square_rem_tab_up_gf2n(f,tab,rp) |
void square_rem_tab_up_gf2n(UP f,UP *tab,UP *rp) |
UP f; |
|
UP *tab; |
|
UP *rp; |
|
{ |
{ |
UP s,t,u,n; |
UP s,t,u,n; |
Num *c; |
Num *c; |
int i,d; |
int i,d; |
|
|
n = UPALLOC(0); n->d = 0; |
n = UPALLOC(0); n->d = 0; |
if ( !f ) |
if ( !f ) |
*rp = 0; |
*rp = 0; |
else { |
else { |
d = f->d; c = f->c; |
d = f->d; c = f->c; |
up_lazy = 1; |
up_lazy = 1; |
for ( i = 0, s = 0; i <= d; i++ ) { |
for ( i = 0, s = 0; i <= d; i++ ) { |
squaregf2n((GF2N)c[i],(GF2N *)(&n->c[0])); |
squaregf2n((GF2N)c[i],(GF2N *)(&n->c[0])); |
mulup(tab[i],n,&t); addup(s,t,&u); s = u; |
mulup(tab[i],n,&t); addup(s,t,&u); s = u; |
} |
} |
up_lazy = 0; |
up_lazy = 0; |
simpup(s,rp); |
simpup(s,rp); |
} |
} |
} |
} |
|
|
void powertabup_gf2n(f,xp,tab) |
void powertabup_gf2n(UP f,UP xp,UP *tab) |
UP f; |
|
UP xp; |
|
UP *tab; |
|
{ |
{ |
UP y,t,invf; |
UP y,t,invf; |
int i,d; |
int i,d; |
GF2N lm; |
GF2N lm; |
|
|
d = f->d; |
d = f->d; |
MKGF2N(ONEUP2,lm); |
MKGF2N(ONEUP2,lm); |
y = UPALLOC(0); y->d = 0; y->c[0] = (Num)lm; |
y = UPALLOC(0); y->d = 0; y->c[0] = (Num)lm; |
tab[0] = y; |
tab[0] = y; |
tab[1] = xp; |
tab[1] = xp; |
|
|
reverseup(f,f->d,&t); |
reverseup(f,f->d,&t); |
invmodup(t,f->d,&invf); |
invmodup(t,f->d,&invf); |
|
|
for ( i = 2; i < d; i++ ) { |
for ( i = 2; i < d; i++ ) { |
if ( debug_up ) |
if ( debug_up ){ |
fprintf(stderr,"."); |
fprintf(stderr,"."); |
if ( !(i%2) ) |
} |
squareup_gf2n(tab[i/2],&t); |
if ( !(i%2) ) |
else |
squareup_gf2n(tab[i/2],&t); |
kmulup(tab[i-1],xp,&t); |
else |
rembymulup_special(t,f,invf,&tab[i]); |
kmulup(tab[i-1],xp,&t); |
/* remup(t,f,&tab[i]); */ |
rembymulup_special(t,f,invf,&tab[i]); |
} |
/* remup(t,f,&tab[i]); */ |
|
} |
} |
} |
|
|
void find_root_gf2n(f,r) |
void find_root_gf2n(UP f,GF2N *r) |
UP f; |
|
GF2N *r; |
|
{ |
{ |
UP g,ut,c,t,h,rem; |
UP g,ut,c,t,h,rem; |
int n; |
int n; |
GF2N rn; |
GF2N rn; |
struct oEGT eg0,eg1,eg_trace; |
|
|
|
n = degup2(current_mod_gf2n->dense); |
n = degup2(current_mod_gf2n->dense); |
g = f; |
g = f; |
while ( g->d > 1 ) { |
while ( g->d > 1 ) { |
ut = UPALLOC(1); ut->c[0] = 0; |
ut = UPALLOC(1); ut->c[0] = 0; |
randomgf2n(&rn); |
randomgf2n(&rn); |
if ( !rn ) |
if ( !rn ) |
continue; |
continue; |
ut->c[1] = (Num)rn; ut->d = 1; |
ut->c[1] = (Num)rn; ut->d = 1; |
tracemodup_gf2n_tab(ut,f,ONE,&c); |
tracemodup_gf2n_tab(ut,f,ONE,&c); |
gcdup(c,g,&h); |
gcdup(c,g,&h); |
if ( h->d && h->d < g->d ) { |
if ( h->d && h->d < g->d ) { |
if ( 2*h->d > g->d ) { |
if ( 2*h->d > g->d ) { |
qrup(g,h,&t,&rem); g = t; |
qrup(g,h,&t,&rem); g = t; |
if ( rem ) |
if ( rem ) |
error("find_root_gf2n : cannot happen"); |
error("find_root_gf2n : cannot happen"); |
} else |
} else |
g = h; |
g = h; |
} |
} |
monicup(g,&t); g = t; |
monicup(g,&t); g = t; |
printf("deg(g)=%d\n",g->d); |
printf("deg(g)=%d\n",g->d); |
} |
} |
divgf2n((GF2N)g->c[0],(GF2N)g->c[1],r); |
divgf2n((GF2N)g->c[0],(GF2N)g->c[1],r); |
} |
} |