Exemplo n.º 1
0
Arquivo: Ctxt.cpp Projeto: 2080/HElib
void Ctxt::multiplyBy2(const Ctxt& other1, const Ctxt& other2)
{
  // Special case: if *this is empty then do nothing
  if (this->isEmpty()) return;

  long lvl = findBaseLevel();
  long lvl1 = other1.findBaseLevel();
  long lvl2 = other2.findBaseLevel();

  if (lvl<lvl1 && lvl<lvl2){ // if both others at higher levels than this,
    Ctxt tmp = other1;       // multiply others by each other, then by this
    if (&other1 == &other2) tmp *= tmp; // squaring rather than multiplication
    else                    tmp *= other2;

    *this *= tmp;
  }
  else if (lvl<lvl2) { // lvl1<=lvl<lvl2, multiply by other2, then by other1
    *this *= other2;
    *this *= other1;    
  }
  else { // multiply first by other1, then by other2
    *this *= other1;
    *this *= other2;
  }
  reLinearize(); // re-linearize after all the multiplications
}
Exemplo n.º 2
0
Ctxt& Ctxt::operator*=(const Ctxt& other)
{
  FHE_TIMER_START;
  // Special case: if *this is empty then do nothing
  if (this->isEmpty()) return  *this;

  // Sanity check: plaintext spaces are compatible
  long g = GCD(ptxtSpace, other.ptxtSpace);
  assert (g>1);
  this->ptxtSpace = g;
  Ctxt tmpCtxt(this->pubKey, this->ptxtSpace); // a scratch ciphertext

  if (this == &other) { // a squaring operation
    modDownToLevel(findBaseLevel());      // mod-down if needed
    tmpCtxt.tensorProduct(*this, other);  // compute the actual product
    tmpCtxt.noiseVar *= 2;     // a correction factor due to dependency
  }
  else {                // standard multiplication between two ciphertexts
    // Sanity check: same context and public key
    assert (&context==&other.context && &pubKey==&other.pubKey);

    // Match the levels, mod-DOWN the arguments if needed
    long lvl = findBaseLevel();
    long otherLvl = other.findBaseLevel();
    if (lvl > otherLvl) lvl = otherLvl; // the smallest of the two

    // mod-DOWN *this, if needed (also removes special primes, if any)
    modDownToLevel(lvl);

    // mod-DOWN other, if needed
    if (primeSet!=other.primeSet){ // use temporary copy to mod-DOWN other
      Ctxt tmpCtxt1 = other;
      tmpCtxt1.modDownToLevel(lvl);
      tmpCtxt.tensorProduct(*this,tmpCtxt1); // compute the actual product
    }
    else 
      tmpCtxt.tensorProduct(*this, other);   // compute the actual product
  }
  *this = tmpCtxt; // copy the result into *this

  FHE_TIMER_STOP;
  return *this;
}
Exemplo n.º 3
0
void Ctxt::multiplyBy2(const Ctxt& other1, const Ctxt& other2)
{
  FHE_TIMER_START;
  // Special case: if *this is empty then do nothing
  if (this->isEmpty()) return;

  long lvl = findBaseLevel();
  long lvl1 = other1.findBaseLevel();
  long lvl2 = other2.findBaseLevel();

  if (lvl<lvl1 && lvl<lvl2){ // if both others at higher levels than this,
    Ctxt tmp = other1;       // multiply others by each other, then by this
    if (&other1 == &other2) tmp *= tmp; // squaring rather than multiplication
    else                    tmp *= other2;

    *this *= tmp;
    reLinearize(); // re-linearize after all the multiplications
    return;
  }

  const Ctxt *first, *second;
  if (lvl<lvl2) { // lvl1<=lvl<lvl2, multiply by other2, then by other1
    first = &other2;
    second = &other1;
  }
  else { // multiply first by other1, then by other2
    first = &other1;
    second = &other2;
  }

  if (this == second) { // handle pointer collision
    Ctxt tmp = *second;
    *this *= *first;
    *this *= tmp;
    if (this == first) // cubing operation
      noiseVar *= 3;   // a correction factor due to dependency
    else
      noiseVar *= 2;   // a correction factor due to dependency
  } else {
    *this *= *first;
    *this *= *second;
  }
  reLinearize(); // re-linearize after all the multiplications
}