本文整理汇总了C++中ZZX类的典型用法代码示例。如果您正苦于以下问题:C++ ZZX类的具体用法?C++ ZZX怎么用?C++ ZZX使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了ZZX类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: sub
void sub(ZZX& x, const ZZ& b, const ZZX& a)
{
long n = a.rep.length();
if (n == 0) {
conv(x, b);
}
else if (x.rep.MaxLength() == 0) {
negate(x, a);
add(x.rep[0], a.rep[0], b);
x.normalize();
}
else {
// ugly...b could alias a coeff of x
ZZ *xp = x.rep.elts();
sub(xp[0], b, a.rep[0]);
x.rep.SetLength(n);
xp = x.rep.elts();
const ZZ *ap = a.rep.elts();
long i;
for (i = 1; i < n; i++)
negate(xp[i], ap[i]);
x.normalize();
}
}
开发者ID:Macaulay2,项目名称:Singular,代码行数:25,代码来源:ZZX.c
示例2: sampleGaussian
void sampleGaussian(ZZX &poly, long n, double stdev)
{
static double const Pi=4.0*atan(1.0); // Pi=3.1415..
static long const bignum = 0xfffffff;
// THREADS: C++11 guarantees these are initialized only once
if (n<=0) n=deg(poly)+1; if (n<=0) return;
poly.SetMaxLength(n); // allocate space for degree-(n-1) polynomial
for (long i=0; i<n; i++) SetCoeff(poly, i, ZZ::zero());
// Uses the Box-Muller method to get two Normal(0,stdev^2) variables
for (long i=0; i<n; i+=2) {
double r1 = (1+RandomBnd(bignum))/((double)bignum+1);
double r2 = (1+RandomBnd(bignum))/((double)bignum+1);
double theta=2*Pi*r1;
double rr= sqrt(-2.0*log(r2))*stdev;
assert(rr < 8*stdev); // sanity-check, no more than 8 standard deviations
// Generate two Gaussians RV's, rounded to integers
long x = (long) floor(rr*cos(theta) +0.5);
SetCoeff(poly, i, x);
if (i+1 < n) {
x = (long) floor(rr*sin(theta) +0.5);
SetCoeff(poly, i+1, x);
}
}
poly.normalize(); // need to call this after we work on the coeffs
}
开发者ID:deepinit-arek,项目名称:HElib,代码行数:29,代码来源:NumbTh.cpp
示例3: RandPoly
ZZX RandPoly(long n,const ZZ& p)
{
ZZX F; F.SetMaxLength(n);
ZZ p2; p2=p>>1;
for (long i=0; i<n; i++)
{ SetCoeff(F,i,RandomBnd(p)-p2); }
return F;
}
开发者ID:deepinit-arek,项目名称:HElib,代码行数:8,代码来源:NumbTh.cpp
示例4: sampleSmall
void sampleSmall(ZZX &poly, long n)
{
if (n<=0) n=deg(poly)+1; if (n<=0) return;
poly.SetMaxLength(n); // allocate space for degree-(n-1) polynomial
for (long i=0; i<n; i++) { // Chosse coefficients, one by one
long u = lrand48();
if (u&1) { // with prob. 1/2 choose between -1 and +1
u = (u & 2) -1;
SetCoeff(poly, i, u);
}
else SetCoeff(poly, i, 0); // with ptob. 1/2 set to 0
}
poly.normalize(); // need to call this after we work on the coeffs
}
开发者ID:deepinit-arek,项目名称:HElib,代码行数:15,代码来源:NumbTh.cpp
示例5: toPoly
void SingleCRT::toPoly(ZZX& poly, const IndexSet& s) const
{
IndexSet s1 = map.getIndexSet() & s;
if (card(s1) == 0) {
clear(poly);
return;
}
ZZ p = to_ZZ(context.ithPrime(s1.first())); // the first modulus
poly = map[s1.first()]; // Get poly modulo the first prime
vec_ZZ& vp = poly.rep;
// ensure that coeficient vector is of size phi(m) with entries in [-p/2,p/2]
long phim = context.zMstar.phiM();
long vpLength = vp.length();
if (vpLength<phim) { // just in case of leading zeros in poly
vp.SetLength(phim);
for (long j=vpLength; j<phim; j++) vp[j]=0;
}
ZZ p_over_2 = p/2;
for (long j=0; j<phim; j++) if (vp[j] > p_over_2) vp[j] -= p;
// do incremental integer CRT for other levels
for (long i = s1.next(s1.first()); i <= s1.last(); i = s1.next(i)) {
long q = context.ithPrime(i); // the next modulus
// CRT the coefficient vectors of poly and current
intVecCRT(vp, p, map[i].rep, q); // defined in the module NumbTh
p *= q; // update the modulus
}
poly.normalize(); // need to call this after we work on the coeffs
}
开发者ID:dwu4,项目名称:fhe-si,代码行数:35,代码来源:SingleCRT.cpp
示例6: PlainMul
void PlainMul(ZZX& x, const ZZX& a, const ZZX& b)
{
if (&a == &b) {
PlainSqr(x, a);
return;
}
long da = deg(a);
long db = deg(b);
if (da < 0 || db < 0) {
clear(x);
return;
}
long d = da+db;
const ZZ *ap, *bp;
ZZ *xp;
ZZX la, lb;
if (&x == &a) {
la = a;
ap = la.rep.elts();
}
else
ap = a.rep.elts();
if (&x == &b) {
lb = b;
bp = lb.rep.elts();
}
else
bp = b.rep.elts();
x.rep.SetLength(d+1);
xp = x.rep.elts();
long i, j, jmin, jmax;
ZZ t, accum;
for (i = 0; i <= d; i++) {
jmin = max(0, i-db);
jmax = min(da, i);
clear(accum);
for (j = jmin; j <= jmax; j++) {
mul(t, ap[j], bp[i-j]);
add(accum, accum, t);
}
xp[i] = accum;
}
x.normalize();
}
开发者ID:Macaulay2,项目名称:Singular,代码行数:57,代码来源:ZZX.c
示例7: KarSqr
void KarSqr(ZZX& c, const ZZX& a)
{
if (IsZero(a)) {
clear(c);
return;
}
vec_ZZ mem;
const ZZ *ap;
ZZ *cp;
long sa = a.rep.length();
if (&a == &c) {
mem = a.rep;
ap = mem.elts();
}
else
ap = a.rep.elts();
c.rep.SetLength(sa+sa-1);
cp = c.rep.elts();
long maxa, xover;
maxa = MaxBits(a);
xover = 2;
if (sa < xover)
PlainSqr(cp, ap, sa);
else {
/* karatsuba */
long n, hn, sp, depth;
n = sa;
sp = 0;
depth = 0;
do {
hn = (n+1) >> 1;
sp += hn+hn+hn - 1;
n = hn;
depth++;
} while (n >= xover);
ZZVec stk;
stk.SetSize(sp,
((2*maxa + NumBits(sa) + 2*depth + 10)
+ NTL_ZZ_NBITS-1)/NTL_ZZ_NBITS);
KarSqr(cp, ap, sa, stk.elts());
}
c.normalize();
}
开发者ID:Macaulay2,项目名称:Singular,代码行数:57,代码来源:ZZX.c
示例8: add
void add(ZZX& x, const ZZX& a, long b)
{
if (a.rep.length() == 0) {
conv(x, b);
}
else {
if (&x != &a) x = a;
add(x.rep[0], x.rep[0], b);
x.normalize();
}
}
开发者ID:Macaulay2,项目名称:Singular,代码行数:11,代码来源:ZZX.c
示例9: PlainSqr
void PlainSqr(ZZX& x, const ZZX& a)
{
long da = deg(a);
if (da < 0) {
clear(x);
return;
}
long d = 2*da;
const ZZ *ap;
ZZ *xp;
ZZX la;
if (&x == &a) {
la = a;
ap = la.rep.elts();
}
else
ap = a.rep.elts();
x.rep.SetLength(d+1);
xp = x.rep.elts();
long i, j, jmin, jmax;
long m, m2;
ZZ t, accum;
for (i = 0; i <= d; i++) {
jmin = max(0, i-da);
jmax = min(da, i);
m = jmax - jmin + 1;
m2 = m >> 1;
jmax = jmin + m2 - 1;
clear(accum);
for (j = jmin; j <= jmax; j++) {
mul(t, ap[j], ap[i-j]);
add(accum, accum, t);
}
add(accum, accum, accum);
if (m & 1) {
sqr(t, ap[jmax + 1]);
add(accum, accum, t);
}
xp[i] = accum;
}
x.normalize();
}
开发者ID:Macaulay2,项目名称:Singular,代码行数:54,代码来源:ZZX.c
示例10: sampleHWt
void sampleHWt(ZZX &poly, long Hwt, long n)
{
if (n<=0) n=deg(poly)+1; if (n<=0) return;
clear(poly); // initialize to zero
poly.SetMaxLength(n); // allocate space for degree-(n-1) polynomial
long b,u,i=0;
if (Hwt>n) Hwt=n;
while (i<Hwt) { // continue until exactly Hwt nonzero coefficients
u=lrand48()%n; // The next coefficient to choose
if (IsZero(coeff(poly,u))) { // if we didn't choose it already
b = lrand48()&2; // b random in {0,2}
b--; // random in {-1,1}
SetCoeff(poly,u,b);
i++; // count another nonzero coefficient
}
}
poly.normalize(); // need to call this after we work on the coeffs
}
开发者ID:deepinit-arek,项目名称:HElib,代码行数:20,代码来源:NumbTh.cpp
示例11: sampleUniform
void sampleUniform(ZZX& poly, const ZZ& B, long n)
{
if (n<=0) n=deg(poly)+1; if (n<=0) return;
if (B <= 0) {
clear(poly);
return;
}
poly.SetMaxLength(n); // allocate space for degree-(n-1) polynomial
ZZ UB, tmp;
UB = 2*B + 1;
for (long i = 0; i < n; i++) {
RandomBnd(tmp, UB);
tmp -= B;
poly.rep[i] = tmp;
}
poly.normalize();
}
开发者ID:deepinit-arek,项目名称:HElib,代码行数:21,代码来源:NumbTh.cpp
示例12: MulMod
// multiply the polynomial f by the integer a modulo q
void MulMod(ZZX& out, const ZZX& f, long a, long q, bool abs/*default=true*/)
{
// ensure that out has the same degree as f
out.SetMaxLength(deg(f)+1); // allocate space if needed
if (deg(out)>deg(f)) trunc(out,out,deg(f)+1); // remove high degrees
for (int i=0; i<=deg(f); i++) {
int c = rem(coeff(f,i), q);
c = MulMod(c, a, q); // returns c \in [0,q-1]
if (!abs && c >= q/2)
c -= q;
SetCoeff(out,i,c);
}
}
开发者ID:guillermo,项目名称:HElib,代码行数:15,代码来源:NumbTh.cpp
示例13: SetCoeff
void SetCoeff(ZZX& x, long i)
{
long j, m;
if (i < 0)
Error("coefficient index out of range");
if (NTL_OVERFLOW(i, 1, 0))
Error("overflow in SetCoeff");
m = deg(x);
if (i > m) {
x.rep.SetLength(i+1);
for (j = m+1; j < i; j++)
clear(x.rep[j]);
}
set(x.rep[i]);
x.normalize();
}
开发者ID:Macaulay2,项目名称:Singular,代码行数:20,代码来源:ZZX.c
示例14: PolyRed
void PolyRed(ZZX& out, const ZZX& in, long q, bool abs)
{
// ensure that out has the same degree as in
out.SetMaxLength(deg(in)+1); // allocate space if needed
if (deg(out)>deg(in)) trunc(out,out,deg(in)+1); // remove high degrees
long q2; q2=q>>1;
for (long i=0; i<=deg(in); i++)
{ long c=coeff(in,i)%q;
if (abs)
{ if (c<0) { c=c+q; } }
else if (q==2)
{ if (coeff(in,i)<0) { c=-c; } }
else
{ if (c>=q2) { c=c-q; }
else if (c<-q2) { c=c+q; }
}
SetCoeff(out,i,c);
}
}
开发者ID:deepinit-arek,项目名称:HElib,代码行数:20,代码来源:NumbTh.cpp
示例15: powerfulToZZX
//FIXME: both the reduction from powerful to the individual primes and
// the CRT back to poly can be made more efficient
void PowerfulDCRT::powerfulToZZX(ZZX& poly, const Vec<ZZ>& powerful,
IndexSet set) const
{
zz_pBak bak; bak.save(); // backup NTL's current modulus
if (empty(set)) set = IndexSet(0, pConvVec.length()-1);
clear(poly);
// poly.SetLength(powerful.length());
ZZ product = conv<ZZ>(1L);
for (long i = set.first(); i <= set.last(); i = set.next(i)) {
pConvVec[i].restoreModulus();
// long newPrime = zz_p::modulus();
HyperCube<zz_p> oneRowPwrfl(indexes.shortSig);
conv(oneRowPwrfl.getData(), powerful); // reduce and convert to Vec<zz_p>
zz_pX oneRowPoly;
pConvVec[i].powerfulToPoly(oneRowPoly, oneRowPwrfl);
CRT(poly, product, oneRowPoly); // NTL :-)
}
poly.normalize();
}
开发者ID:shaih,项目名称:HElib,代码行数:25,代码来源:powerful.cpp
示例16: evalPolyTopLevel
// Note: poly is passed by value, not by reference, so the calling routine
// keeps its original polynomial
long evalPolyTopLevel(ZZX poly, long x, long p, long k=0)
{
if (verbose)
cerr << "\n* evalPolyTopLevel: p="<<p<<", x="<<x<<", poly="<<poly;
if (deg(poly)<=2) { // nothing to optimize here
if (deg(poly)<1) return to_long(coeff(poly, 0));
DynamicPtxtPowers babyStep(x, p, deg(poly));
long ret = simplePolyEval(poly, babyStep, p);
totalDepth = babyStep.getDepth(deg(poly));
return ret;
}
// How many baby steps: set k~sqrt(n/2), rounded up/down to a power of two
// FIXME: There may be some room for optimization here: it may be possible
// to choose k as something other than a power of two and still maintain
// optimal depth, in principle we can try all possible values of k between
// the two powers of two and choose the one that goves the least number
// of multiplies, conditioned on minimum depth.
if (k<=0) {
long kk = (long) sqrt(deg(poly)/2.0);
k = 1L << NextPowerOfTwo(kk);
// heuristic: if k>>kk then use a smaler power of two
if ((k==16 && deg(poly)>167) || (k>16 && k>(1.44*kk)))
k /= 2;
}
cerr << ", k="<<k;
long n = divc(deg(poly),k); // deg(p) = k*n +delta
if (verbose) cerr << ", n="<<n<<endl;
DynamicPtxtPowers babyStep(x, p, k);
long x2k = babyStep.getPower(k);
// Special case when deg(p)>k*(2^e -1)
if (n==(1L << NextPowerOfTwo(n))) { // n is a power of two
DynamicPtxtPowers giantStep(x2k, p, n/2, babyStep.getDepth(k));
if (verbose)
cerr << "babyStep="<<babyStep<<", giantStep="<<giantStep<<endl;
long ret = degPowerOfTwo(poly, k, babyStep, giantStep, p, totalDepth);
if (verbose) {
cerr << " degPowerOfTwo("<<poly<<") returns "<<ret<<", depth="<<totalDepth<<endl;
if (ret != polyEvalMod(poly,babyStep[0], p)) {
cerr << " ## recursive call failed, ret="<<ret<<"!="
<< polyEvalMod(poly,babyStep[0], p)<<endl;
exit(0);
}
// cerr << " babyStep depth=[";
// for (long i=0; i<babyStep.size(); i++)
// cerr << babyStep.getDepth(i+1)<<" ";
// cerr << "]\n";
// cerr << " giantStep depth=[";
// for (long i=0; i<giantStep.size(); i++)
// cerr<<giantStep.getDepth(i+1)<<" ";
// cerr << "]\n";
}
return ret;
}
// If n is not a power of two, ensure that poly is monic and that
// its degree is divisible by k, then call the recursive procedure
ZZ topInv; // the inverse mod p of the top coefficient of poly (if any)
bool divisible = (n*k == deg(poly)); // is the degree divisible by k?
long nonInvertibe = InvModStatus(topInv, LeadCoeff(poly), to_ZZ(p));
// 0 if invertible, 1 if not
// FIXME: There may be some room for optimization below: instead of
// adding a term X^{n*k} we can add X^{n'*k} for some n'>n, so long
// as n' is smaller than the next power of two. We could save a few
// multiplications since giantStep[n'] may be easier to compute than
// giantStep[n] when n' has fewer 1's than n in its binary expansion.
long extra = 0; // extra!=0 denotes an added term extra*X^{n*k}
if (!divisible || nonInvertibe) { // need to add a term
// set extra = 1 - current-coeff-of-X^{n*k}
extra = SubMod(1, to_long(coeff(poly,n*k)), p);
SetCoeff(poly, n*k); // set the top coefficient of X^{n*k} to one
topInv = to_ZZ(1); // inverse of new top coefficient is one
}
long t = (extra==0)? divc(n,2) : n;
DynamicPtxtPowers giantStep(x2k, p, t, babyStep.getDepth(k));
if (verbose)
cerr << "babyStep="<<babyStep<<", giantStep="<<giantStep<<endl;
long y; // the value to return
long subDepth1 =0;
if (!IsOne(topInv)) {
long top = to_long(poly[n*k]); // record the current top coefficient
// cerr << ", top-coeff="<<top;
// Multiply by topInv modulo p to make into a monic polynomial
//.........这里部分代码省略.........
开发者ID:alexandredantas,项目名称:HElib,代码行数:101,代码来源:polyEval.cpp
示例17: to_ZZX
// bootstrap a ciphertext to reduce noise
void FHEPubKey::reCrypt(Ctxt &ctxt)
{
FHE_TIMER_START;
// Some sanity checks for dummy ciphertext
long ptxtSpace = ctxt.getPtxtSpace();
if (ctxt.isEmpty()) return;
if (ctxt.parts.size()==1 && ctxt.parts[0].skHandle.isOne()) {
// Dummy encryption, just ensure that it is reduced mod p
ZZX poly = to_ZZX(ctxt.parts[0]);
for (long i=0; i<poly.rep.length(); i++)
poly[i] = to_ZZ( rem(poly[i],ptxtSpace) );
poly.normalize();
ctxt.DummyEncrypt(poly);
return;
}
assert(recryptKeyID>=0); // check that we have bootstrapping data
long p = getContext().zMStar.getP();
long r = getContext().alMod.getR();
long p2r = getContext().alMod.getPPowR();
// the bootstrapping key is encrypted relative to plaintext space p^{e-e'+r}.
long e = getContext().rcData.e;
long ePrime = getContext().rcData.ePrime;
long p2ePrime = power_long(p,ePrime);
long q = power_long(p,e)+1;
assert(e>=r);
#ifdef DEBUG_PRINTOUT
cerr << "reCrypt: p="<<p<<", r="<<r<<", e="<<e<<" ePrime="<<ePrime
<< ", q="<<q<<endl;
#endif
// can only bootstrap ciphertext with plaintext-space dividing p^r
assert(p2r % ptxtSpace == 0);
FHE_NTIMER_START(preProcess);
// Make sure that this ciphertxt is in canonical form
if (!ctxt.inCanonicalForm()) ctxt.reLinearize();
// Mod-switch down if needed
IndexSet s = ctxt.getPrimeSet() / getContext().specialPrimes; // set minus
if (s.card()>2) { // leave only bottom two primes
long frst = s.first();
long scnd = s.next(frst);
IndexSet s2(frst,scnd);
s.retain(s2); // retain only first two primes
}
ctxt.modDownToSet(s);
// key-switch to the bootstrapping key
ctxt.reLinearize(recryptKeyID);
// "raw mod-switch" to the bootstrapping mosulus q=p^e+1.
vector<ZZX> zzParts; // the mod-switched parts, in ZZX format
double noise = ctxt.rawModSwitch(zzParts, q);
noise = sqrt(noise);
// Add multiples of p2r and q to make the zzParts divisible by p^{e'}
long maxU=0;
for (long i=0; i<(long)zzParts.size(); i++) {
// make divisible by p^{e'}
long newMax = makeDivisible(zzParts[i].rep, p2ePrime, p2r, q,
getContext().rcData.alpha);
zzParts[i].normalize(); // normalize after working directly on the rep
if (maxU < newMax) maxU = newMax;
}
// Check that the estimated noise is still low
if (noise + maxU*p2r*(skHwts[recryptKeyID]+1) > q/2)
cerr << " * noise/q after makeDivisible = "
<< ((noise + maxU*p2r*(skHwts[recryptKeyID]+1))/q) << endl;
for (long i=0; i<(long)zzParts.size(); i++)
zzParts[i] /= p2ePrime; // divide by p^{e'}
// Multiply the post-processed cipehrtext by the encrypted sKey
#ifdef DEBUG_PRINTOUT
cerr << "+ Before recryption ";
decryptAndPrint(cerr, recryptEkey, *dbgKey, *dbgEa, printFlag);
#endif
double p0size = to_double(coeffsL2Norm(zzParts[0]));
double p1size = to_double(coeffsL2Norm(zzParts[1]));
ctxt = recryptEkey;
ctxt.multByConstant(zzParts[1], p1size*p1size);
ctxt.addConstant(zzParts[0], p0size*p0size);
#ifdef DEBUG_PRINTOUT
cerr << "+ Before linearTrans1 ";
decryptAndPrint(cerr, ctxt, *dbgKey, *dbgEa, printFlag);
#endif
FHE_NTIMER_STOP(preProcess);
// Move the powerful-basis coefficients to the plaintext slots
FHE_NTIMER_START(LinearTransform1);
//.........这里部分代码省略.........
开发者ID:fionser,项目名称:HElib,代码行数:101,代码来源:recryption.cpp
示例18: KarMul
void KarMul(ZZX& c, const ZZX& a, const ZZX& b)
{
if (IsZero(a) || IsZero(b)) {
clear(c);
return;
}
if (&a == &b) {
KarSqr(c, a);
return;
}
vec_ZZ mem;
const ZZ *ap, *bp;
ZZ *cp;
long sa = a.rep.length();
long sb = b.rep.length();
if (&a == &c) {
mem = a.rep;
ap = mem.elts();
}
else
ap = a.rep.elts();
if (&b == &c) {
mem = b.rep;
bp = mem.elts();
}
else
bp = b.rep.elts();
c.rep.SetLength(sa+sb-1);
cp = c.rep.elts();
long maxa, maxb, xover;
maxa = MaxBits(a);
maxb = MaxBits(b);
xover = 2;
if (sa < xover || sb < xover)
PlainMul(cp, ap, sa, bp, sb);
else {
/* karatsuba */
long n, hn, sp, depth;
n = max(sa, sb);
sp = 0;
depth = 0;
do {
hn = (n+1) >> 1;
sp += (hn << 2) - 1;
n = hn;
depth++;
} while (n >= xover);
ZZVec stk;
stk.SetSize(sp,
((maxa + maxb + NumBits(min(sa, sb)) + 2*depth + 10)
+ NTL_ZZ_NBITS-1)/NTL_ZZ_NBITS);
KarMul(cp, ap, sa, bp, sb, stk.elts());
}
c.normalize();
}
开发者ID:Macaulay2,项目名称:Singular,代码行数:70,代码来源:ZZX.c
示例19: conv
void conv(ZZX& x, const vec_ZZ& a)
{
x.rep = a;
x.normalize();
}
开发者ID:Macaulay2,项目名称:Singular,代码行数:5,代码来源:ZZX.c
示例20: polyEval
// Main entry point: Evaluate a cleartext polynomial on an encrypted input
void polyEval(Ctxt& ret, ZZX poly, const Ctxt& x, long k)
// Note: poly is passed by value, so caller keeps the original
{
if (deg(poly)<=2) { // nothing to optimize here
if (deg(poly)<1) { // A constant
ret.clear();
ret.addConstant(coeff(poly, 0));
} else { // A linear or quadratic polynomial
DynamicCtxtPowers babyStep(x, deg(poly));
simplePolyEval(ret, poly, babyStep);
}
return;
}
// How many baby steps: set k~sqrt(n/2), rounded up/down to a power of two
// FIXME: There may be some room for optimization here: it may be possible
// to choose k as something other than a power of two and still maintain
// optimal depth, in principle we can try all possible values of k between
// two consecutive powers of two and choose the one that gives the least
// number of multiplies, conditioned on minimum depth.
if (k<=0) {
long kk = (long) sqrt(deg(poly)/2.0);
k = 1L << NextPowerOfTwo(kk);
// heuristic: if k>>kk then use a smaler power of two
if ((k==16 && deg(poly)>167) || (k>16 && k>(1.44*kk)))
k /= 2;
}
#ifdef DEBUG_PRINTOUT
cerr << " k="<<k;
#endif
long n = divc(deg(poly),k); // n = ceil(deg(p)/k), deg(p) >= k*n
DynamicCtxtPowers babyStep(x, k);
const Ctxt& x2k = babyStep.getPower(k);
// Special case when deg(p)>k*(2^e -1)
if (n==(1L << NextPowerOfTwo(n))) { // n is a power of two
DynamicCtxtPowers giantStep(x2k, n/2);
degPowerOfTwo(ret, poly, k, babyStep, giantStep);
return;
}
// If n is not a power of two, ensure that poly is monic and that
// its degree is divisible by k, then call the recursive procedure
const ZZ p = to_ZZ(x.getPtxtSpace());
ZZ top = LeadCoeff(poly);
ZZ topInv; // the inverse mod p of the top coefficient of poly (if any)
bool divisible = (n*k == deg(poly)); // is the degree divisible by k?
long nonInvertibe = InvModStatus(topInv, top, p);
// 0 if invertible, 1 if not
// FIXME: There may be some room for optimization below: instead of
// adding a term X^{n*k} we can add X^{n'*k} for some n'>n, so long
// as n' is smaller than the next power of two. We could save a few
// multiplications since giantStep[n'] may be easier to compute than
// giantStep[n] when n' has fewer 1's than n in its binary expansion.
ZZ extra = ZZ::zero(); // extra!=0 denotes an added term extra*X^{n*k}
if (!divisible || nonInvertibe) { // need to add a term
top = to_ZZ(1); // new top coefficient is one
topInv = top; // also the new inverse is one
// set extra = 1 - current-coeff-of-X^{n*k}
extra = SubMod(top, coeff(poly,n*k), p);
SetCoeff(poly, n*k); // set the top coefficient of X^{n*k} to one
}
long t = IsZero(extra)? divc(n,2) : n;
DynamicCtxtPowers giantStep(x2k, t);
if (!IsOne(top)) {
poly *= topInv; // Multiply by topInv to make into a monic polynomial
for (long i=0; i<=n*k; i++) rem(poly[i], poly[i], p);
poly.normalize();
}
recursivePolyEval(ret, poly, k, babyStep, giantStep);
if (!IsOne(top)) {
ret.multByConstant(top);
}
if (!IsZero(extra)) { // if we added a term, now is the time to subtract back
Ctxt topTerm = giantStep.getPower(n);
topTerm.multByConstant(extra);
ret -= topTerm;
}
}
开发者ID:alexandredantas,项目名称:HElib,代码行数:91,代码来源:polyEval.cpp
注:本文中的ZZX类示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论