/* Copyright 2002 Colin Percival and the University of Oxford Copyright in this software is held by the University of Oxford and Colin Percival. Both the University of Oxford and Colin Percival have agreed that this software may be distributed free of charge and in accordance with the attached licence. The above notwithstanding, in order that the University as a charitable foundation protects its assets for the benefit of its educational and research purposes, the University makes clear that no condition is made or to be implied, nor is any warranty given or to be implied, as to the proper functioning of this work, or that it will be suitable for any particular purpose or for use under any specific conditions. Furthermore, the University disclaims all responsibility for any use which is made of this work. For the terms under which this work may be distributed, please see the adjoining file "LICENSE". */ #ifdef RCSID static const char rcsid[] = "$Id: numt.c,v 1.4 2002/04/25 06:13:52 cperciva Exp $"; #endif #include "ptypes.h" #include "smpa.h" #define BIT(x,n) ((x[(n)/8]>>((n)%8))&0x01) void numt_powmod(uint8 * x,uint8 * n,uint8 * m,uint8 * y, double * T1,uint32 len,uint32 hibit,uint32 lobit) { uint32 j; smpa_init(T1,len); smpa_in(x,T1+len*2,len); for(j=1;jlobit;j--) { smpa_premul(T1+len*3,len,T1); smpa_mulmod(T1+len*3,T1+len*3,T1+len*3, T1+len*4,T1+len*5,T1+len*6, T1+len*7,len,T1); smpa_premul(T1+len*3,len,T1); smpa_mulmod(T1+len*(1+BIT(n,j-1)),T1+len*3,T1+len*3, T1+len*4,T1+len*5,T1+len*6, T1+len*7,len,T1); }; smpa_out(T1+len*3,y,len); } int numt_spsp(uint8 * a,uint8 * p,double * T1,uint8 * T2,uint32 len) { uint32 i,j; uint8 r1; int r; r=1;j=0; for(i=1;i T2 = 1 r=r1; for(;j>0;j--) { r1=T2[0]+1-p[0]; for(i=1;i T2+1 = p r=r*r1%257; smpa_premul(T1+len*3,len,T1); smpa_mulmod(T1+len*3,T1+len*3,T1+len*3, T1+len*4,T1+len*5,T1+len*6, T1+len*7,len,T1); smpa_out(T1+len*3,T2,len); }; return r; } uint8 prim32dat[] = {2,0,0,0,3,0,0,0,5,0,0,0,7,0,0,0,11,0,0,0}; void numt_prim32(uint8 * r,uint8 * p,double * T1) { uint32 i; int r1; for(i=0;i<4;i++) p[i]=r[i]; p[0]|=0x01;p[3]|=0x80; do { i=int32_little(*(uint32 *)(p))+2; *(uint32 *)(p)=int32_little(i|0x80000000); r1=0; for(i=0;i<5;i++) r1+=numt_spsp(prim32dat+4*i,p,T1,r,4); } while(r1); } void numt_primap(uint8 * p1,uint8 * m,uint8 * a,uint8 * b,uint8 * p,double * T1,uint8 * T2,uint32 len) { uint32 j; uint32 c; uint8 r1; do { smpa_init(T1,len/2); do { c=1; for(j=0;j>1)|(m[j+1]<<7); m[len/2-1]=m[len/2-1]>>1; }; } while(p[len-1]&0x80); for(j=len-1;j>0;j--) p[j]=(p[j]<<1)|(p[j-1]>>7); p[0]=(p[0]<<1)+1; for(j=0;j0;j--) x=(x*256+p[j-1])%65537; } while(x==1); }