#include <iostream>1#include <sstream>2using namespace std;34#include "ntl_wrap.h"5#include <NTL/mat_poly_ZZ.h>6#include <NTL/LLL.h>7#include <NTL/tools.h>89void del_charstar(char* a) {10delete[] a;11}121314void setup_NTL_error_callback(void (*function)(const char*, void*), void* context)15{16NTL::SetErrorCallbackFunction(function, context);17}181920//////// ZZ //////////2122/* Return value is only valid if the result should fit into an int.23AUTHOR: David Harvey (2008-06-08) */24int ZZ_to_int(const ZZ* x)25{26return to_int(*x);27}2829/* Returns a *new* ZZ object.30AUTHOR: David Harvey (2008-06-08) */31struct ZZ* int_to_ZZ(int value)32{33ZZ* output = new ZZ();34conv(*output, value);35return output;36}3738/* Copies the ZZ into the mpz_t39Assumes output has been mpz_init'd.40AUTHOR: David Harvey41Joel B. Mohler moved the ZZX_getitem_as_mpz code out to this function (2007-03-13) */42void ZZ_to_mpz(mpz_t* output, const struct ZZ* x)43{44unsigned char stack_bytes[4096];45int use_heap;46unsigned long size = NumBytes(*x);47use_heap = (size > sizeof(stack_bytes));48unsigned char* bytes = use_heap ? (unsigned char*) malloc(size) : stack_bytes;49BytesFromZZ(bytes, *x, size);50mpz_import(*output, size, -1, 1, 0, 0, bytes);51if (sign(*x) < 0)52mpz_neg(*output, *output);53if (use_heap)54free(bytes);55}5657// Ok, I know that this is obvious58// I just wanted to document the appearance of the magic number 8 in the code below59#define bits_in_byte 86061/* Copies the mpz_t into the ZZ62AUTHOR: Joel B. Mohler (2007-03-15) */63// This should be changed to an mpz_t not an mpz_t*64void mpz_to_ZZ(struct ZZ* output, const mpz_t *x)65{66unsigned char stack_bytes[4096];67int use_heap;68size_t size = (mpz_sizeinbase(*x, 2) + bits_in_byte-1) / bits_in_byte;69use_heap = (size > sizeof(stack_bytes));70void* bytes = use_heap ? malloc(size) : stack_bytes;71size_t words_written;72mpz_export(bytes, &words_written, -1, 1, 0, 0, *x);73clear(*output);74ZZFromBytes(*output, (unsigned char *)bytes, words_written);75if (mpz_sgn(*x) < 0)76NTL::negate(*output, *output);77if (use_heap)78free(bytes);79}8081/* Sets given ZZ to value82AUTHOR: David Harvey (2008-06-08) */83void ZZ_set_from_int(ZZ* x, int value)84{85conv(*x, value);86}8788long ZZ_remove(struct ZZ &dest, const struct ZZ &src, const struct ZZ &f)89{90// Based on the code for mpz_remove91ZZ fpow[40]; // inexaustible...until year 2020 or so92ZZ x, rem;93long pwr;94int p;9596if (compare(f, 1) <= 0 && compare(f, -1) >= 0)97Error("Division by zero");9899if (compare(src, 0) == 0)100{101if (src != dest)102dest = src;103return 0;104}105106if (compare(f, 2) == 0)107{108dest = src;109return MakeOdd(dest);110}111112/* We could perhaps compute mpz_scan1(src,0)/mpz_scan1(f,0). It is an113upper bound of the result we're seeking. We could also shift down the114operands so that they become odd, to make intermediate values smaller. */115116pwr = 0;117fpow[0] = ZZ(f);118dest = src;119rem = ZZ();120x = ZZ();121122/* Divide by f, f^2, ..., f^(2^k) until we get a remainder for f^(2^k). */123for (p = 0;;p++)124{125DivRem(x, rem, dest, fpow[p]);126if (compare(rem, 0) != 0)127break;128fpow[p+1] = ZZ();129mul(fpow[p+1], fpow[p], fpow[p]);130dest = x;131}132133pwr = (1 << p) - 1;134135/* Divide by f^(2^(k-1)), f^(2^(k-2)), ..., f for all divisors that give a136zero remainder. */137while (--p >= 0)138{139DivRem(x, rem, dest, fpow[p]);140if (compare(rem, 0) == 0)141{142pwr += 1 << p;143dest = x;144}145}146return pwr;147}148149//////// ZZ_p //////////150151/* Return value is only valid if the result should fit into an int.152AUTHOR: David Harvey (2008-06-08) */153int ZZ_p_to_int(const ZZ_p& x )154{155return ZZ_to_int(&rep(x));156}157158/* Returns a *new* ZZ_p object.159AUTHOR: David Harvey (2008-06-08) */160ZZ_p int_to_ZZ_p(int value)161{162ZZ_p r;163r = value;164return r;165}166167/* Sets given ZZ_p to value168AUTHOR: David Harvey (2008-06-08) */169void ZZ_p_set_from_int(ZZ_p* x, int value)170{171conv(*x, value);172}173174void ZZ_p_modulus(struct ZZ* mod, const struct ZZ_p* x)175{176(*mod) = x->modulus();177}178179struct ZZ_p* ZZ_p_pow(const struct ZZ_p* x, long e)180{181ZZ_p *z = new ZZ_p();182power(*z, *x, e);183return z;184}185186void ntl_ZZ_set_modulus(ZZ* x)187{188ZZ_p::init(*x);189}190191ZZ_p* ZZ_p_inv(ZZ_p* x)192{193ZZ_p *z = new ZZ_p();194inv(*z, *x);195return z;196}197198ZZ_p* ZZ_p_random(void)199{200ZZ_p *z = new ZZ_p();201random(*z);202return z;203}204205struct ZZ_p* ZZ_p_neg(struct ZZ_p* x)206{207return new ZZ_p(-(*x));208}209210211212///////////////////////////////////////////////213//////// ZZX //////////214///////////////////////////////////////////////215216char* ZZX_repr(struct ZZX* x)217{218ostringstream instore;219instore << (*x);220int n = strlen(instore.str().data());221char* buf = new char[n+1];222strcpy(buf, instore.str().data());223return buf;224}225226struct ZZX* ZZX_copy(struct ZZX* x) {227return new ZZX(*x);228}229230/* Sets ith coefficient of x to value.231AUTHOR: David Harvey (2006-06-08) */232void ZZX_setitem_from_int(struct ZZX* x, long i, int value)233{234SetCoeff(*x, i, value);235}236237/* Returns ith coefficient of x.238Return value is only valid if the result should fit into an int.239AUTHOR: David Harvey (2006-06-08) */240int ZZX_getitem_as_int(struct ZZX* x, long i)241{242return ZZ_to_int(&coeff(*x, i));243}244245/* Copies ith coefficient of x to output.246Assumes output has been mpz_init'd.247AUTHOR: David Harvey (2007-02) */248void ZZX_getitem_as_mpz(mpz_t* output, struct ZZX* x, long i)249{250const ZZ& z = coeff(*x, i);251ZZ_to_mpz(output, &z);252}253254struct ZZX* ZZX_div(struct ZZX* x, struct ZZX* y, int* divisible)255{256struct ZZX* z = new ZZX();257*divisible = divide(*z, *x, *y);258return z;259}260261262263void ZZX_quo_rem(struct ZZX* x, struct ZZX* other, struct ZZX** r, struct ZZX** q)264{265struct ZZX *qq = new ZZX(), *rr = new ZZX();266DivRem(*qq, *rr, *x, *other);267*r = rr; *q = qq;268}269270271struct ZZX* ZZX_square(struct ZZX* x)272{273struct ZZX* s = new ZZX();274sqr(*s, *x);275return s;276}277278279int ZZX_is_monic(struct ZZX* x)280{281return IsOne(LeadCoeff(*x));282}283284285struct ZZX* ZZX_neg(struct ZZX* x)286{287struct ZZX* y = new ZZX();288*y = -*x;289return y;290}291292293struct ZZX* ZZX_left_shift(struct ZZX* x, long n)294{295struct ZZX* y = new ZZX();296LeftShift(*y, *x, n);297return y;298}299300301struct ZZX* ZZX_right_shift(struct ZZX* x, long n)302{303struct ZZX* y = new ZZX();304RightShift(*y, *x, n);305return y;306}307308struct ZZX* ZZX_primitive_part(struct ZZX* x)309{310struct ZZX* p = new ZZX();311PrimitivePart(*p, *x);312return p;313}314315316void ZZX_pseudo_quo_rem(struct ZZX* x, struct ZZX* y, struct ZZX** r, struct ZZX** q)317{318*r = new ZZX();319*q = new ZZX();320PseudoDivRem(**q, **r, *x, *y);321}322323324struct ZZX* ZZX_gcd(struct ZZX* x, struct ZZX* y)325{326struct ZZX* g = new ZZX();327GCD(*g, *x, *y);328return g;329}330331332void ZZX_xgcd(struct ZZX* x, struct ZZX* y, struct ZZ** r, struct ZZX** s, \333struct ZZX** t, int proof)334{335*r = new ZZ();336*s = new ZZX();337*t = new ZZX();338XGCD(**r, **s, **t, *x, *y, proof);339}340341342long ZZX_degree(struct ZZX* x)343{344return deg(*x);345}346347void ZZX_set_x(struct ZZX* x)348{349SetX(*x);350}351352353int ZZX_is_x(struct ZZX* x)354{355return IsX(*x);356}357358359struct ZZX* ZZX_derivative(struct ZZX* x)360{361ZZX* d = new ZZX();362diff(*d, *x);363return d;364}365366367struct ZZX* ZZX_reverse(struct ZZX* x)368{369ZZX* r = new ZZX();370reverse(*r, *x);371return r;372}373374struct ZZX* ZZX_reverse_hi(struct ZZX* x, int hi)375{376ZZX* r = new ZZX();377reverse(*r, *x, hi);378return r;379}380381382struct ZZX* ZZX_truncate(struct ZZX* x, long m)383{384ZZX* t = new ZZX();385trunc(*t, *x, m);386return t;387}388389390struct ZZX* ZZX_multiply_and_truncate(struct ZZX* x, struct ZZX* y, long m)391{392ZZX* t = new ZZX();393MulTrunc(*t, *x, *y, m);394return t;395}396397398struct ZZX* ZZX_square_and_truncate(struct ZZX* x, long m)399{400ZZX* t = new ZZX();401SqrTrunc(*t, *x, m);402return t;403}404405406struct ZZX* ZZX_invert_and_truncate(struct ZZX* x, long m)407{408ZZX* t = new ZZX();409InvTrunc(*t, *x, m);410return t;411}412413414struct ZZX* ZZX_multiply_mod(struct ZZX* x, struct ZZX* y, struct ZZX* modulus)415{416ZZX* p = new ZZX();417MulMod(*p, *x, *y, *modulus);418return p;419}420421422struct ZZ* ZZX_trace_mod(struct ZZX* x, struct ZZX* y)423{424ZZ* p = new ZZ();425TraceMod(*p, *x, *y);426return p;427}428429430char* ZZX_trace_list(struct ZZX* x)431{432vec_ZZ v;433TraceVec(v, *x);434ostringstream instore;435instore << v;436int n = strlen(instore.str().data());437char* buf = new char[n+1];438strcpy(buf, instore.str().data());439return buf;440}441442443struct ZZ* ZZX_resultant(struct ZZX* x, struct ZZX* y, int proof)444{445ZZ* res = new ZZ();446resultant(*res, *x, *y, proof);447return res;448}449450451struct ZZ* ZZX_norm_mod(struct ZZX* x, struct ZZX* y, int proof)452{453ZZ* res = new ZZ();454NormMod(*res, *x, *y, proof);455return res;456}457458459struct ZZ* ZZX_discriminant(struct ZZX* x, int proof)460{461ZZ* d = new ZZ();462discriminant(*d, *x, proof);463return d;464}465466467struct ZZX* ZZX_charpoly_mod(struct ZZX* x, struct ZZX* y, int proof)468{469ZZX* f = new ZZX();470CharPolyMod(*f, *x, *y, proof);471return f;472}473474475struct ZZX* ZZX_minpoly_mod(struct ZZX* x, struct ZZX* y)476{477ZZX* f = new ZZX();478MinPolyMod(*f, *x, *y);479return f;480}481482483void ZZX_clear(struct ZZX* x)484{485clear(*x);486}487488489void ZZX_preallocate_space(struct ZZX* x, long n)490{491x->SetMaxLength(n);492}493494/*495EXTERN struct ZZ* ZZX_polyeval(struct ZZX* f, struct ZZ* a)496{497ZZ* b = new ZZ();498*b = PolyEval(*f, *a);499return b;500}501*/502503void ZZX_squarefree_decomposition(struct ZZX*** v, long** e, long* n, struct ZZX* x)504{505vec_pair_ZZX_long factors;506SquareFreeDecomp(factors, *x);507*n = factors.length();508*v = (ZZX**) malloc(sizeof(ZZX*) * (*n));509*e = (long*) malloc(sizeof(long) * (*n));510for (long i = 0; i < (*n); i++) {511(*v)[i] = new ZZX(factors[i].a);512(*e)[i] = factors[i].b;513}514}515516///////////////////////////////////////////////517//////// ZZ_pX //////////518///////////////////////////////////////////////519520// char* ZZ_pX_repr(struct ZZ_pX* x)521// {522// ostringstream instore;523// instore << (*x);524// int n = strlen(instore.str().data());525// char* buf = new char[n+1];526// strcpy(buf, instore.str().data());527// return buf;528// }529530// void ZZ_pX_dealloc(struct ZZ_pX* x) {531// delete x;532// }533534// struct ZZ_pX* ZZ_pX_copy(struct ZZ_pX* x) {535// return new ZZ_pX(*x);536// }537538// /* Sets ith coefficient of x to value.539// AUTHOR: David Harvey (2008-06-08) */540// void ZZ_pX_setitem_from_int(struct ZZ_pX* x, long i, int value)541// {542// SetCoeff(*x, i, value);543// }544545// /* Returns ith coefficient of x.546// Return value is only valid if the result should fit into an int.547// AUTHOR: David Harvey (2008-06-08) */548// int ZZ_pX_getitem_as_int(struct ZZ_pX* x, long i)549// {550// return ZZ_to_int(&rep(coeff(*x, i)));551// }552553// struct ZZ_pX* ZZ_pX_add(struct ZZ_pX* x, struct ZZ_pX* y)554// {555// ZZ_pX *z = new ZZ_pX();556// add(*z, *x, *y);557// return z;558// }559560// struct ZZ_pX* ZZ_pX_sub(struct ZZ_pX* x, struct ZZ_pX* y)561// {562// ZZ_pX *z = new ZZ_pX();563// sub(*z, *x, *y);564// return z;565// }566567// struct ZZ_pX* ZZ_pX_mul(struct ZZ_pX* x, struct ZZ_pX* y)568// {569// ZZ_pX *z = new ZZ_pX();570// mul(*z, *x, *y);571// return z;572// }573574575// struct ZZ_pX* ZZ_pX_div(struct ZZ_pX* x, struct ZZ_pX* y, int* divisible)576// {577// struct ZZ_pX* z = new ZZ_pX();578// *divisible = divide(*z, *x, *y);579// return z;580// }581582583// struct ZZ_pX* ZZ_pX_mod(struct ZZ_pX* x, struct ZZ_pX* y)584// {585// struct ZZ_pX* z = new ZZ_pX();586// rem(*z, *x, *y);587// return z;588// }589590591592// void ZZ_pX_quo_rem(struct ZZ_pX* x, struct ZZ_pX* y, struct ZZ_pX** r, struct ZZ_pX** q)593// {594// *r = new ZZ_pX();595// *q = new ZZ_pX();596// DivRem(**q, **r, *x, *y);597// }598599600// struct ZZ_pX* ZZ_pX_square(struct ZZ_pX* x)601// {602// struct ZZ_pX* s = new ZZ_pX();603// sqr(*s, *x);604// return s;605// }606607608609// int ZZ_pX_is_monic(struct ZZ_pX* x)610// {611// IsOne(LeadCoeff(*x));612// }613614615// struct ZZ_pX* ZZ_pX_neg(struct ZZ_pX* x)616// {617// struct ZZ_pX* y = new ZZ_pX();618// *y = -*x;619// return y;620// }621622623// struct ZZ_pX* ZZ_pX_left_shift(struct ZZ_pX* x, long n)624// {625// struct ZZ_pX* y = new ZZ_pX();626// LeftShift(*y, *x, n);627// return y;628// }629630631// struct ZZ_pX* ZZ_pX_right_shift(struct ZZ_pX* x, long n)632// {633// struct ZZ_pX* y = new ZZ_pX();634// RightShift(*y, *x, n);635// return y;636// }637638639640// struct ZZ_pX* ZZ_pX_gcd(struct ZZ_pX* x, struct ZZ_pX* y)641// {642// struct ZZ_pX* g = new ZZ_pX();643// GCD(*g, *x, *y);644// return g;645// }646647648// void ZZ_pX_xgcd(struct ZZ_pX** d, struct ZZ_pX** s, struct ZZ_pX** t, struct ZZ_pX* a, struct ZZ_pX* b)649// {650// *d = new ZZ_pX();651// *s = new ZZ_pX();652// *t = new ZZ_pX();653// XGCD(**d, **s, **t, *a, *b);654// }655656// void ZZ_pX_plain_xgcd(struct ZZ_pX** d, struct ZZ_pX** s, struct ZZ_pX** t, struct ZZ_pX* a, struct ZZ_pX* b)657// {658// *d = new ZZ_pX();659// *s = new ZZ_pX();660// *t = new ZZ_pX();661// PlainXGCD(**d, **s, **t, *a, *b);662// }663664// ZZ_p* ZZ_pX_leading_coefficient(struct ZZ_pX* x)665// {666// return new ZZ_p(LeadCoeff(*x));667// }668669670// void ZZ_pX_set_x(struct ZZ_pX* x)671// {672// SetX(*x);673// }674675676// int ZZ_pX_is_x(struct ZZ_pX* x)677// {678// return IsX(*x);679// }680681682// struct ZZ_pX* ZZ_pX_derivative(struct ZZ_pX* x)683// {684// ZZ_pX* d = new ZZ_pX();685// diff(*d, *x);686// return d;687// }688689690// struct ZZ_pX* ZZ_pX_reverse(struct ZZ_pX* x)691// {692// ZZ_pX* r = new ZZ_pX();693// reverse(*r, *x);694// return r;695// }696697// struct ZZ_pX* ZZ_pX_reverse_hi(struct ZZ_pX* x, int hi)698// {699// ZZ_pX* r = new ZZ_pX();700// reverse(*r, *x, hi);701// return r;702// }703704705// struct ZZ_pX* ZZ_pX_truncate(struct ZZ_pX* x, long m)706// {707// ZZ_pX* t = new ZZ_pX();708// trunc(*t, *x, m);709// return t;710// }711712713// struct ZZ_pX* ZZ_pX_multiply_and_truncate(struct ZZ_pX* x, struct ZZ_pX* y, long m)714// {715// ZZ_pX* t = new ZZ_pX();716// MulTrunc(*t, *x, *y, m);717// return t;718// }719720721// struct ZZ_pX* ZZ_pX_square_and_truncate(struct ZZ_pX* x, long m)722// {723// ZZ_pX* t = new ZZ_pX();724// SqrTrunc(*t, *x, m);725// return t;726// }727728729// struct ZZ_pX* ZZ_pX_invert_and_truncate(struct ZZ_pX* x, long m)730// {731// ZZ_pX* t = new ZZ_pX();732// InvTrunc(*t, *x, m);733// return t;734// }735736737// struct ZZ_pX* ZZ_pX_multiply_mod(struct ZZ_pX* x, struct ZZ_pX* y, struct ZZ_pX* modulus)738// {739// ZZ_pX* p = new ZZ_pX();740// MulMod(*p, *x, *y, *modulus);741// return p;742// }743744745// struct ZZ_p* ZZ_pX_trace_mod(struct ZZ_pX* x, struct ZZ_pX* y)746// {747// ZZ_p* p = new ZZ_p();748// TraceMod(*p, *x, *y);749// return p;750// }751752753char* ZZ_pX_trace_list(struct ZZ_pX* x)754{755vec_ZZ_p v;756TraceVec(v, *x);757ostringstream instore;758instore << v;759int n = strlen(instore.str().data());760char* buf = new char[n+1];761strcpy(buf, instore.str().data());762return buf;763}764765766// struct ZZ_p* ZZ_pX_resultant(struct ZZ_pX* x, struct ZZ_pX* y)767// {768// ZZ_p* res = new ZZ_p();769// resultant(*res, *x, *y);770// return res;771// }772773774// struct ZZ_p* ZZ_pX_norm_mod(struct ZZ_pX* x, struct ZZ_pX* y)775// {776// ZZ_p* res = new ZZ_p();777// NormMod(*res, *x, *y);778// return res;779// }780781782783// struct ZZ_pX* ZZ_pX_charpoly_mod(struct ZZ_pX* x, struct ZZ_pX* y)784// {785// ZZ_pX* f = new ZZ_pX();786// CharPolyMod(*f, *x, *y);787// return f;788// }789790791// struct ZZ_pX* ZZ_pX_minpoly_mod(struct ZZ_pX* x, struct ZZ_pX* y)792// {793// ZZ_pX* f = new ZZ_pX();794// MinPolyMod(*f, *x, *y);795// return f;796// }797798799// void ZZ_pX_clear(struct ZZ_pX* x)800// {801// clear(*x);802// }803804805// void ZZ_pX_preallocate_space(struct ZZ_pX* x, long n)806// {807// x->SetMaxLength(n);808// }809810void ZZ_pX_factor(struct ZZ_pX*** v, long** e, long* n, struct ZZ_pX* x, long verbose)811{812long i;813vec_pair_ZZ_pX_long factors;814berlekamp(factors, *x, verbose);815*n = factors.length();816*v = (ZZ_pX**) malloc(sizeof(ZZ_pX*) * (*n));817*e = (long*) malloc(sizeof(long)*(*n));818for (i=0; i<(*n); i++) {819(*v)[i] = new ZZ_pX(factors[i].a);820(*e)[i] = factors[i].b;821}822}823824void ZZ_pX_linear_roots(struct ZZ_p*** v, long* n, struct ZZ_pX* f)825{826long i;827// printf("1\n");828vec_ZZ_p w;829FindRoots(w, *f);830// printf("2\n");831*n = w.length();832// printf("3 %d\n",*n);833(*v) = (ZZ_p**) malloc(sizeof(ZZ_p*)*(*n));834for (i=0; i<(*n); i++) {835(*v)[i] = new ZZ_p(w[i]);836}837}838839/////////// ZZ_pE //////////////840841struct ZZ_pX ZZ_pE_to_ZZ_pX(struct ZZ_pE x)842{843return ZZ_pX(rep(x));844}845846847848//////// mat_ZZ //////////849850void mat_ZZ_SetDims(struct mat_ZZ* mZZ, long nrows, long ncols){851mZZ->SetDims(nrows, ncols);852}853854struct mat_ZZ* mat_ZZ_pow(const struct mat_ZZ* x, long e)855{856mat_ZZ *z = new mat_ZZ();857power(*z, *x, e);858return z;859}860861long mat_ZZ_nrows(const struct mat_ZZ* x)862{863return x->NumRows();864}865866867long mat_ZZ_ncols(const struct mat_ZZ* x)868{869return x->NumCols();870}871872void mat_ZZ_setitem(struct mat_ZZ* x, int i, int j, const struct ZZ* z)873{874(*x)[i][j] = *z;875876}877878struct ZZ* mat_ZZ_getitem(const struct mat_ZZ* x, int i, int j)879{880return new ZZ((*x)(i,j));881}882883struct ZZ* mat_ZZ_determinant(const struct mat_ZZ* x, long deterministic)884{885ZZ* d = new ZZ();886determinant(*d, *x, deterministic);887return d;888}889890struct mat_ZZ* mat_ZZ_HNF(const struct mat_ZZ* A, const struct ZZ* D)891{892struct mat_ZZ* W = new mat_ZZ();893HNF(*W, *A, *D);894return W;895}896897long mat_ZZ_LLL(struct ZZ **det, struct mat_ZZ *x, long a, long b, long verbose)898{899*det = new ZZ();900return LLL(**det,*x,a,b,verbose);901}902903long mat_ZZ_LLL_U(struct ZZ **det, struct mat_ZZ *x, struct mat_ZZ *U, long a, long b, long verbose)904{905*det = new ZZ();906return LLL(**det,*x,*U,a,b,verbose);907}908909910struct ZZX* mat_ZZ_charpoly(const struct mat_ZZ* A)911{912ZZX* f = new ZZX();913CharPoly(*f, *A);914return f;915}916917/**918* GF2EContext919*/920921GF2EContext* GF2EContext_construct(void *mem, const GF2X *p)922{923return new(mem) GF2EContext(*p);924}925926927GF2EContext* GF2EContext_new(const GF2X *p)928{929return new GF2EContext(*p);930}931932933void mat_GF2E_setitem(struct mat_GF2E* x, int i, int j, const struct GF2E* z)934{935(*x)[i][j] = *z;936}937938void mat_GF2_setitem(struct mat_GF2* x, int i, int j, const struct GF2* z)939{940(*x)[i][j] = *z;941}942943/**944* ZZ_pContext945*/946947ZZ_pContext* ZZ_pContext_new(ZZ *p)948{949return new ZZ_pContext(*p);950}951952ZZ_pContext* ZZ_pContext_construct(void *mem, ZZ *p)953{954return new(mem) ZZ_pContext(*p);955}956957void ZZ_pContext_restore(ZZ_pContext *ctx)958{959ctx->restore();960}961962// Functions for using ZZ_pX's for p-adic extensions963964void ZZ_pX_conv_modulus(ZZ_pX &fout, const ZZ_pX &fin, const ZZ_pContext &modout)965{966// Changes the modulus of fin to modout, and puts the result in fout.967long i, n;968969n = fin.rep.length();970fout.rep.SetLength(n);971972ZZ_p* xp = fout.rep.elts();973const ZZ_p* ap = fin.rep.elts();974975// I think it's enough to just restore modout once.976// This should be true as long as the function rep taking a ZZ_p as an argument977// and returning a ZZ works when the ZZ_p::modulus is incorrect.978modout.restore();979980for (i = 0; i < n; i++)981{982conv(xp[i], rep(ap[i]));983}984985// We may have set a leading coefficient to 0, so we have to normalize986fout.normalize();987}988989void ZZ_pEX_conv_modulus(ZZ_pEX &fout, const ZZ_pEX &fin, const ZZ_pContext &modout)990{991// Changes the modulus of fin to modout, and puts the result in fout.992long i, n, j, m;993994n = fin.rep.length();995fout.rep.SetLength(n);996997ZZ_pE* outpe = fout.rep.elts();998const ZZ_pE* inpe = fin.rep.elts();9991000ZZ_p* xp;1001const ZZ_p* ap;1002// I think it's enough to just restore modout once1003// This should be true as long as Loophole() offers access to1004// the underlying ZZ_pX representations of ZZ_pEs,1005// and rep of a ZZ_p (giving a ZZ) works even if the ZZ_p::modulus is1006// incorrect1007modout.restore();10081009for (i = 0; i < n; i++)1010{1011m = rep(inpe[i]).rep.length();1012outpe[i]._ZZ_pE__rep.rep.SetLength(m);10131014xp = outpe[i]._ZZ_pE__rep.rep.elts();1015ap = rep(inpe[i]).rep.elts();10161017for (j = 0; j < m; j++)1018conv(xp[j], rep(ap[j]));10191020// We may have set a leading coefficient to 0, so we have to normalize1021outpe[i]._ZZ_pE__rep.normalize();1022}1023// We may have set a leading coefficient to 0, so we have to normalize1024fout.normalize();1025}10261027void ZZ_pX_min_val_coeff(long & valuation, long &index, const struct ZZ_pX &f, const struct ZZ &p)1028{1029// Sets index, where the indexth coefficient of f has the minimum p-adic valuation.1030// Sets valuation to be this valuation.1031// If there are ties, index will be the lowest of the tied indices1032// This only makes mathematical sense when p divides the modulus of f.1033long i, n, v;10341035n = f.rep.length();1036if (n == 0)1037{1038index = -1;1039return;1040}10411042const ZZ_p* fp = f.rep.elts();1043ZZ *u = new ZZ();10441045valuation = -1;1046i = 0;10471048while (valuation == -1)1049{1050if (rep(fp[i]) != 0)1051{1052index = i;1053valuation = ZZ_remove(*u, rep(fp[i]), p);1054}1055i++;1056}1057for (; i < n; i++)1058{1059if (rep(fp[i]) != 0)1060{1061v = ZZ_remove(*u, rep(fp[i]), p);1062if (v < valuation)1063{1064valuation = v;1065index = i;1066}1067}1068}1069delete u;1070}10711072long ZZ_pX_get_val_coeff(const struct ZZ_pX &f, const struct ZZ &p, long i)1073{1074// Gets the p-adic valuation of the ith coefficient of f.1075ZZ *u = new ZZ();1076long ans = ZZ_remove(*u, rep(coeff(f, i)), p);1077delete u;1078return ans;1079}10801081void ZZ_pX_left_pshift(struct ZZ_pX &x, const struct ZZ_pX &a, const struct ZZ &pn, const struct ZZ_pContext &c)1082{1083// Multiplies each coefficient by pn, and sets the context of the answer to c.10841085long i, n;10861087n = a.rep.length();1088x.rep.SetLength(n);10891090ZZ_p* xp = x.rep.elts();1091const ZZ_p* ap = a.rep.elts();10921093// I think it's enough to just restore modout once.1094// This should be true as long as the function rep taking a ZZ_p as an argument1095// and returning a ZZ works when the ZZ_p::modulus is incorrect.1096c.restore();10971098for (i = 0; i < n; i++)1099{1100conv(xp[i], rep(ap[i]) * pn);1101}11021103// We may have set a leading coefficient to 0, so we have to normalize1104x.normalize();1105}11061107void ZZ_pX_right_pshift(struct ZZ_pX &x, const struct ZZ_pX &a, const struct ZZ &pn, const struct ZZ_pContext &c)1108{1109// Divides each coefficient by pn, and sets the context of the answer to c.11101111long i, n;11121113n = a.rep.length();1114x.rep.SetLength(n);11151116ZZ_p* xp = x.rep.elts();1117const ZZ_p* ap = a.rep.elts();11181119// I think it's enough to just restore modout once.1120// This should be true as long as the function rep taking a ZZ_p as an argument1121// and returning a ZZ works when the ZZ_p::modulus is incorrect.1122c.restore();11231124for (i = 0; i < n; i++)1125{1126conv(xp[i], rep(ap[i]) / pn);1127}11281129// We may have set a leading coefficient to 0, so we have to normalize1130x.normalize();1131}11321133void ZZ_pX_InvMod_newton_unram(struct ZZ_pX &x, const struct ZZ_pX &a, const struct ZZ_pXModulus &F, const struct ZZ_pContext &cpn, const struct ZZ_pContext &cp)1134{1135//int j;1136cp.restore();1137ZZ_pX *amodp = new ZZ_pX();1138ZZ_pX *xmodp = new ZZ_pX();1139ZZ_pX *fmodp = new ZZ_pX();1140ZZ_pX_conv_modulus(*amodp, a, cp);1141ZZ_pX_conv_modulus(*fmodp, F.val(), cp);1142InvMod(*xmodp, *amodp, *fmodp);1143//cout << "xmodp: " << *xmodp << "\namodp: " << *amodp << "\nfmodp: " << *fmodp << "\n";1144cpn.restore();1145ZZ_pX *minusa = new ZZ_pX();1146ZZ_pX *xn = new ZZ_pX();1147ZZ_pX_conv_modulus(*xn, *xmodp, cpn);1148NTL::negate(*minusa, a);1149while (1 > 0)1150{1151// x_n = 2*x_{n-1} - a*x_{n-1}^2 = (2 - a*x_{n-1})*x_{n-1}1152MulMod(x, *minusa, *xn, F);1153SetCoeff(x, 0, ConstTerm(x) + 2);1154MulMod(x, x, *xn, F);1155if (x == *xn)1156break;1157*xn = x;1158//cout << "x: " << x << "\nxn: " << *xn << "\n";1159//cin >> j;1160}1161delete amodp;1162delete xmodp;1163delete fmodp;1164delete minusa;1165delete xn;1166}11671168void ZZ_pX_InvMod_newton_ram(struct ZZ_pX &x, const struct ZZ_pX &a, const struct ZZ_pXModulus &F, const struct ZZ_pContext &cpn)1169{1170//int j;1171cpn.restore();1172ZZ_pX *minusa = new ZZ_pX();1173ZZ_pX *xn = new ZZ_pX();1174SetCoeff(*xn, 0, inv(ConstTerm(a)));1175NTL::negate(*minusa, a);1176while (1 > 0)1177{1178// x_n = 2*x_{n-1} - a*x_{n-1}^2 = (2 - a*x_{n-1})*x_{n-1}1179MulMod(x, *minusa, *xn, F);1180SetCoeff(x, 0, ConstTerm(x) + 2);1181MulMod(x, x, *xn, F);1182//cout << "x: " << x << "\nxn: " << *xn << "\n";1183if (x == *xn)1184break;1185*xn = x;1186//cin >> j;1187}1188delete minusa;1189delete xn;1190}11911192/**1193* ZZ_pEContext1194*/11951196ZZ_pEContext* ZZ_pEContext_new(ZZ_pX *f)1197{1198return new ZZ_pEContext(*f);1199}12001201ZZ_pEContext* ZZ_pEContext_construct(void *mem, ZZ_pX *f)1202{1203return new(mem) ZZ_pEContext(*f);1204}12051206void ZZ_pEContext_restore(ZZ_pEContext *ctx)1207{1208ctx->restore();1209}12101211/**1212* zz_pContext1213*/12141215zz_pContext* zz_pContext_new(long p)1216{1217return new zz_pContext(p);1218}12191220zz_pContext* zz_pContext_construct(void *mem, long p)1221{1222return new(mem) zz_pContext(p);1223}12241225void zz_pContext_restore(zz_pContext *ctx)1226{1227ctx->restore();1228}122912301231