/* InterFace to Lisp routines, using foreign-function interface. Comments in ../doc/LispWins2.txt */ #include #include #include //ZZX is NTL's name for polynomials in one variable (X) over //arbitrary precision integers (ZZ). //Make ZZX from array of LONG (signed-byte 32) extern "C" __declspec(dllexport) void* LMakePoly(long* coefs, long size) { ZZX *b=new ZZX(); long i; (*b).rep.SetLength(size+1); // implicitly set coefs to 0 for (i=0; i< size;i++) { SetCoeff((*b) ,i,coefs[i]); } return b ;} //The reverse transformation, ZZX to lisp array // is programmed in Lisp. We need to know the size of a polynomial, // and how to get coefficients extern "C" __declspec(dllexport) long LSizePoly(ZZX* poly) {return (*poly).rep.length();} // multiply two polynomials in ZZX. extern "C" __declspec(dllexport) void* LMul2(ZZX* poly1, ZZX* poly2) // multiply 2 args, return new result { ZZX *res=new ZZX(); mul(*res, *poly1,*poly2); return res ; } // multiply two polynomials in ZZX, overlaying target extern "C" __declspec(dllexport) void LMul3(ZZX* target,ZZX* poly1, ZZX* poly2) { mul(*target, *poly1,*poly2);} // Change a coefficient in a ZZX to a given long value extern "C" __declspec(dllexport) void LSetCoeffL(ZZX* target, long power, long val) { SetCoeff(*target,power,val); } // Change a coefficient in a ZZX to a given ZZ value extern "C" __declspec(dllexport) void LSetCoeffZ(ZZX* target, long power, ZZ* val) { SetCoeff(*target,power,*val); } // Return a ZZ coefficient of a given power in a ZZX. extern "C" __declspec(dllexport) void* LGetCoeffZ(ZZX* target, long power) { ZZ *rzz=new ZZ(); GetCoeff(*rzz,*target,power); return rzz; } // make an NTL integer from a Lisp long extern "C" __declspec(dllexport) void* LMakeZZL(long inputval) {ZZ *b=new ZZ(); conv(*b,inputval); return b;} // make a lisp long from a (presumably not very big) NTL ZZ extern "C" __declspec(dllexport) long LUnMakeZZL(ZZ* azz) {long q; conv(q,*azz); return q;} //SIGNUM of a ZZ extern "C" __declspec(dllexport) long LSignZZ(ZZ* azz) // azz is a bignum. { return sign(*azz); } // we should use NTL_ZZ_NBITS instead of 30. //Number of 32 bit bigits in a ZZ // A zzigit is between 0 and 2^(30)-1 on 32-bit pentium extern "C" __declspec(dllexport) long LSizeZZ32(ZZ* azz) // azz is a bignum. { return ( ((*azz).size()*30 +31)/ 32);} // returns number of 30-bit zzigits. extern "C" __declspec(dllexport) long LSizeZZ(ZZ* azz) // azz is a bignum. { return ((*azz).size()); } // make an array of 32-bit bigits from an NTL integer. // produced from Lisp. see file loadntl.cl // Given a ZZ, // results in an array of 32-bit zzigits. // It also destroys the ZZ number. If we do not // really want to do that, use LunMakeZZSafe, below. extern "C" __declspec(dllexport) long LUnMakeZZ( long* buf, ZZ* azz) // azz is a bignum. //buf is an array. It had better be long enough. { long i, res=0, signum=sign(*azz), size=LSizeZZ32(azz); ZZ q, m= *azz; for (i=0; i<= size; i++) { buf[i]= trunc_long((*azz),32); RightShift((*azz),(*azz),32); } // buf and size* sign are both the results. return size*signum; } extern "C" __declspec(dllexport) long LUnMakeZZSafe( long* buf, ZZ* azz) // azz is a bignum. //buf is an array. It had better be long enough. { long i, res=0, signum=sign(*azz), size=LSizeZZ32(azz); //depends on size being right, not off by 1 ZZ q, *m= new ZZ(*azz); for (i=0; i<= size; i++) { buf[i]= trunc_long((*m),32); RightShift((*m),(*m),32); } // buf and size* sign are both the results. return size*signum; } extern "C" __declspec(dllexport) void* LMulZZ2(ZZ* poly1, ZZ* poly2) // multiply 2 ZZ args, return new result { ZZ *res=new ZZ(); mul(*res, *poly1,*poly2); return res ; } extern "C" __declspec(dllexport) void LMulZZ3(ZZ* target, ZZ* poly1, ZZ* poly2) // multiply 2 ZZ args clobber target { mul(*target, *poly1,*poly2); } extern "C" __declspec(dllexport) void* LAddZZ2(ZZ* poly1, ZZ* poly2) // add 2 args, return new result { ZZ *res=new ZZ(); add(*res, *poly1,*poly2); return res ; } extern "C" __declspec(dllexport) void LAddZZ3(ZZ* target, ZZ* poly1, ZZ* poly2) // add 2 args clobber target { add(*target, *poly1,*poly2); } extern "C" __declspec(dllexport) void LeftShiftZZ3(ZZ* target, ZZ* zz1, long theshift) { LeftShift(*target, *zz1, theshift); } extern "C" __declspec(dllexport) void LNegateZZ(ZZ* target, ZZ* zz1) { negate(*target, *zz1); } // could add other one-line functions as needed. // see file loadntl.cl for further comments