本文整理汇总了C++中Ctxt::getPubKey方法的典型用法代码示例。如果您正苦于以下问题:C++ Ctxt::getPubKey方法的具体用法?C++ Ctxt::getPubKey怎么用?C++ Ctxt::getPubKey使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Ctxt
的用法示例。
在下文中一共展示了Ctxt::getPubKey方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: assert
// Constructor
Ctxt::Ctxt(ZeroCtxtLike_type, const Ctxt& ctxt):
context(ctxt.getPubKey().getContext()), pubKey(ctxt.getPubKey()),
ptxtSpace(ctxt.getPtxtSpace()),
noiseVar(to_xdouble(0.0))
{
// same body as previous constructor
if (ptxtSpace<=0) ptxtSpace = pubKey.getPtxtSpace();
else assert (GCD(ptxtSpace, pubKey.getPtxtSpace()) > 1); // sanity check
primeSet=context.ctxtPrimes;
}
示例2: tmp
// This procedure assumes that k*(2^e +1) > deg(poly) > k*(2^e -1),
// and that babyStep contains >= k + (deg(poly) mod k) powers
static void
degPowerOfTwo(Ctxt& ret, const ZZX& poly, long k,
DynamicCtxtPowers& babyStep, DynamicCtxtPowers& giantStep)
{
if (deg(poly)<=babyStep.size()) { // Edge condition, use simple eval
simplePolyEval(ret, poly, babyStep);
return;
}
long n = deg(poly)/k; // We assume n=2^e or n=2^e -1
n = 1L << NextPowerOfTwo(n); // round up to n=2^e
ZZX r = trunc(poly, (n-1)*k); // degree <= k(2^e-1)-1
ZZX q = RightShift(poly, (n-1)*k); // 0 < degree < 2k
SetCoeff(r, (n-1)*k); // monic, degree == k(2^e-1)
q -= 1;
PatersonStockmeyer(ret, r, k, n/2, 0, babyStep, giantStep);
Ctxt tmp(ret.getPubKey(), ret.getPtxtSpace());
simplePolyEval(tmp, q, babyStep); // evaluate q
// multiply by X^{k(n-1)} with minimum depth
for (long i=1; i<n; i*=2) {
tmp.multiplyBy(giantStep.getPower(i));
}
ret += tmp;
}
示例3: extractDigits
void extractDigits(vector<Ctxt>& digits, const Ctxt& c, long r)
{
const FHEcontext& context = c.getContext();
long rr = c.effectiveR();
if (r<=0 || r>rr) r = rr; // how many digits to extract
long p = context.zMStar.getP();
ZZX x2p;
if (p>3) {
buildDigitPolynomial(x2p, p, r);
}
Ctxt tmp(c.getPubKey(), c.getPtxtSpace());
digits.resize(r, tmp); // allocate space
#ifdef DEBUG_PRINTOUT
fprintf(stderr, "***\n");
#endif
for (long i=0; i<r; i++) {
tmp = c;
for (long j=0; j<i; j++) {
if (p==2) digits[j].square();
else if (p==3) digits[j].cube();
else polyEval(digits[j], x2p, digits[j]);
// "in spirit" digits[j] = digits[j]^p
#ifdef DEBUG_PRINTOUT
fprintf(stderr, "%5ld", digits[j].bitCapacity());
#endif
tmp -= digits[j];
tmp.divideByP();
}
digits[i] = tmp; // needed in the next round
#ifdef DEBUG_PRINTOUT
if (dbgKey) {
double ratio =
log(embeddingLargestCoeff(digits[i], *dbgKey)/digits[i].getNoiseBound())/log(2.0);
fprintf(stderr, "%5ld [%f]", digits[i].bitCapacity(), ratio);
if (ratio > 0) fprintf(stderr, " BAD-BOUND");
fprintf(stderr, "\n");
}
else {
fprintf(stderr, "%5ld\n", digits[i].bitCapacity());
}
#endif
}
#ifdef DEBUG_PRINTOUT
fprintf(stderr, "***\n");
#endif
}
示例4: applyToCtxt
// Apply a permutation network to a ciphertext
// FIXME: Do we need to also give an EncryptedArray object as paramter?
void PermNetwork::applyToCtxt(Ctxt& c) const
{
const PAlgebra& al = c.getContext().zMStar;
EncryptedArray ea(c.getContext());
// Use G(X)=X for this ea object, this works since we only have 0/1 entries
// Apply the layers, one at a time
for (long i=0; i<layers.length(); i++) {
const PermNetLayer& lyr = layers[i];
if (lyr.isID) continue; // this layer is the identity permutation
// This layer is shifted via powers of g^e mod m
long g2e = PowerMod(al.ZmStarGen(lyr.genIdx), lyr.e, al.getM());
Vec<long> unused = lyr.shifts; // copy to a new vector
vector<long> mask(lyr.shifts.length()); // buffer to hold masks
Ctxt sum(c.getPubKey(), c.getPtxtSpace()); // an empty ciphertext
long shamt = 0;
bool frst = true;
while (true) {
pair<long,bool> ret=makeMask(mask, unused, shamt); // compute mask
if (ret.second) { // non-empty mask
Ctxt tmp = c;
ZZX maskPoly;
ea.encode(maskPoly, mask); // encode mask as polynomial
tmp.multByConstant(maskPoly); // multiply by mask
if (shamt!=0) // rotate if the shift amount is nonzero
tmp.smartAutomorph(PowerMod(g2e, shamt, al.getM()));
if (frst) {
sum = tmp;
frst = false;
}
else
sum += tmp;
}
if (ret.first >= 0)
shamt = unused[ret.first]; // next shift amount to use
else break; // unused is all-zero, done with this layer
}
c = sum; // update the cipehrtext c before the next layer
}
}
示例5: apply
static void apply(const EncryptedArrayDerived<type>& ea,
Ctxt& ctxt, const PlaintextMatrixBaseInterface& mat)
{
assert(&ea == &mat.getEA().getDerived(type()));
assert(&ea.getContext() == &ctxt.getContext());
RBak bak; bak.save(); ea.getTab().restoreContext();
// Get the derived type
const PlaintextMatrixInterface<type>& mat1 =
dynamic_cast< const PlaintextMatrixInterface<type>& >( mat );
ctxt.cleanUp(); // not sure, but this may be a good idea
Ctxt res(ctxt.getPubKey(), ctxt.getPtxtSpace()); // fresh encryption of zero
long nslots = ea.size();
long d = ea.getDegree();
RX entry;
vector<RX> diag;
diag.resize(nslots);
// Process the diagonals one at a time
for (long i = 0; i < nslots; i++) { // process diagonal i
bool zDiag = true; // is this a zero diagonal?
long nzLast = -1; // index of last non-zero entry on this diagonal
// Compute constants for each entry on this diagonal
for (long j = 0; j < nslots; j++) { // process entry j
bool zEntry = mat1.get(entry, mcMod(j-i, nslots), j); // callback
assert(zEntry || deg(entry) < d);
if (!zEntry && IsZero(entry)) zEntry = true; // check for zero
if (!zEntry) { // non-zero diagonal entry
zDiag = false; // diagonal is non-zero
// clear entries between last nonzero entry and this one
for (long jj = nzLast+1; jj < j; jj++) clear(diag[jj]);
nzLast = j;
diag[j] = entry;
}
}
if (zDiag) continue; // zero diagonal, continue
// clear trailing zero entries
for (long jj = nzLast+1; jj < nslots; jj++) clear(diag[jj]);
// Now we have the constants for all the diagonal entries, encode the
// diagonal as a single polynomial with these constants in the slots
ZZX cpoly;
ea.encode(cpoly, diag);
// rotate by i, multiply by the polynomial, then add to the result
Ctxt shCtxt = ctxt;
ea.rotate(shCtxt, i); // rotate by i
shCtxt.multByConstant(cpoly);
res += shCtxt;
}
ctxt = res;
}
示例6: extendExtractDigits
void extendExtractDigits(vector<Ctxt>& digits, const Ctxt& c, long r, long e)
{
const FHEcontext& context = c.getContext();
long p = context.zMStar.getP();
ZZX x2p;
if (p>3) {
buildDigitPolynomial(x2p, p, r);
}
// we should pre-compute this table
// for i = 0..r-1, entry i is G_{e+r-i} in Chen and Han
Vec<ZZX> G;
G.SetLength(r);
for (long i: range(r)) {
compute_magic_poly(G[i], p, e+r-i);
}
vector<Ctxt> digits0;
Ctxt tmp(c.getPubKey(), c.getPtxtSpace());
digits.resize(r, tmp); // allocate space
digits0.resize(r, tmp);
#ifdef DEBUG_PRINTOUT
fprintf(stderr, "***\n");
#endif
for (long i: range(r)) {
tmp = c;
for (long j: range(i)) {
if (digits[j].capacity() >= digits0[j].capacity()) {
// optimization: digits[j] is better than digits0[j],
// so just use it
tmp -= digits[j];
#ifdef DEBUG_PRINTOUT
fprintf(stderr, "%5ld*", digits[j].bitCapacity());
#endif
}
else {
if (p==2) digits0[j].square();
else if (p==3) digits0[j].cube();
else polyEval(digits0[j], x2p, digits0[j]); // "in spirit" digits0[j] = digits0[j]^p
tmp -= digits0[j];
#ifdef DEBUG_PRINTOUT
fprintf(stderr, "%5ld ", digits0[j].bitCapacity());
#endif
}
tmp.divideByP();
}
digits0[i] = tmp; // needed in the next round
polyEval(digits[i], G[i], tmp);
#ifdef DEBUG_PRINTOUT
if (dbgKey) {
double ratio =
log(embeddingLargestCoeff(digits[i], *dbgKey)/digits[i].getNoiseBound())/log(2.0);
fprintf(stderr, "%5ld --- %5ld", digits0[i].bitCapacity(), digits[i].bitCapacity());
fprintf(stderr, " [%f]", ratio);
if (ratio > 0) fprintf(stderr, " BAD-BOUND");
fprintf(stderr, "\n");
}
else {
fprintf(stderr, "%5ld --- %5ld\n", digits0[i].bitCapacity(), digits[i].bitCapacity());
}
#endif
}
}
示例7: res
void EncryptedArrayDerived<type>::mat_mul(Ctxt& ctxt, const PlaintextBlockMatrixBaseInterface& mat) const
{
FHE_TIMER_START;
assert(this == &mat.getEA().getDerived(type()));
assert(&context == &ctxt.getContext());
RBak bak; bak.save(); tab.restoreContext();
const PlaintextBlockMatrixInterface<type>& mat1 =
dynamic_cast< const PlaintextBlockMatrixInterface<type>& >( mat );
ctxt.cleanUp(); // not sure, but this may be a good idea
Ctxt res(ctxt.getPubKey(), ctxt.getPtxtSpace());
// a new ciphertext, encrypting zero
long nslots = size();
long d = getDegree();
mat_R entry;
entry.SetDims(d, d);
vector<RX> entry1;
entry1.resize(d);
vector< vector<RX> > diag;
diag.resize(nslots);
for (long j = 0; j < nslots; j++) diag[j].resize(d);
for (long i = 0; i < nslots; i++) {
// process diagonal i
bool zDiag = true;
long nzLast = -1;
for (long j = 0; j < nslots; j++) {
bool zEntry = mat1.get(entry, mcMod(j-i, nslots), j);
assert(zEntry || (entry.NumRows() == d && entry.NumCols() == d));
// get(...) returns true if the entry is empty, false otherwise
if (!zEntry && IsZero(entry)) zEntry=true; // zero is an empty entry too
if (!zEntry) { // non-empty entry
zDiag = false; // mark diagonal as non-empty
// clear entries between last nonzero entry and this one
for (long jj = nzLast+1; jj < j; jj++) {
for (long k = 0; k < d; k++)
clear(diag[jj][k]);
}
nzLast = j;
// recode entry as a vector of polynomials
for (long k = 0; k < d; k++) conv(entry1[k], entry[k]);
// compute the lin poly coeffs
buildLinPolyCoeffs(diag[j], entry1);
}
}
if (zDiag) continue; // zero diagonal, continue
// clear trailing zero entries
for (long jj = nzLast+1; jj < nslots; jj++) {
for (long k = 0; k < d; k++)
clear(diag[jj][k]);
}
// now diag[j] contains the lin poly coeffs
Ctxt shCtxt = ctxt;
rotate(shCtxt, i);
// apply the linearlized polynomial
for (long k = 0; k < d; k++) {
// compute the constant
bool zConst = true;
vector<RX> cvec;
cvec.resize(nslots);
for (long j = 0; j < nslots; j++) {
cvec[j] = diag[j][k];
if (!IsZero(cvec[j])) zConst = false;
}
if (zConst) continue;
ZZX cpoly;
encode(cpoly, cvec);
// FIXME: record the encoded polynomial for future use
Ctxt shCtxt1 = shCtxt;
shCtxt1.frobeniusAutomorph(k);
shCtxt1.multByConstant(cpoly);
res += shCtxt1;
//.........这里部分代码省略.........
示例8: tmp
void EncryptedArrayDerived<type>::shift(Ctxt& ctxt, long k) const
{
FHE_TIMER_START;
const PAlgebra& al = context.zMStar;
const vector< vector< RX > >& maskTable = tab.getMaskTable();
RBak bak; bak.save(); tab.restoreContext();
assert(&context == &ctxt.getContext());
// Simple case: just one generator
if (al.numOfGens()==1) {
shift1D(ctxt, 0, k);
return;
}
long nSlots = al.getNSlots();
// Shifting by more than the number of slots gives an all-zero cipehrtext
if (k <= -nSlots || k >= nSlots) {
ctxt.multByConstant(to_ZZX(0));
return;
}
// Make sure that amt is in [1,nslots-1]
long amt = k % nSlots;
if (amt == 0) return;
if (amt < 0) amt += nSlots;
// rotate the ciphertext, one dimension at a time
long i = al.numOfGens()-1;
long v = al.coordinate(i, amt);
RX mask = maskTable[i][v];
Ctxt tmp(ctxt.getPubKey());
const RXModulus& PhimXmod = tab.getPhimXMod();
rotate1D(ctxt, i, v);
for (i--; i >= 0; i--) {
v = al.coordinate(i, amt);
DoubleCRT m1(conv<ZZX>(mask), context, ctxt.getPrimeSet());
tmp = ctxt;
tmp.multByConstant(m1); // only the slots in which mask=1
ctxt -= tmp; // only the slots in which mask=0
if (i>0) {
rotate1D(ctxt, i, v+1);
rotate1D(tmp, i, v);
ctxt += tmp; // combine the two parts
mask = ((mask * (maskTable[i][v] - maskTable[i][v+1])) % PhimXmod)
+ maskTable[i][v+1]; // update the mask before next iteration
}
else { // i == 0
if (k < 0) v -= al.OrderOf(0);
shift1D(tmp, 0, v);
shift1D(ctxt, 0, v+1);
ctxt += tmp;
}
}
FHE_TIMER_STOP;
}