2021SC@SDUSC-PALISADE(七)Evaluation中的加法评估

2021SC@SDUSC
照例先分析PALISADE库的特性,再讨论BVG方法。


PlainText

PALISADE中使用明文(PlainText)表示未加密的内容。它实际上是PALISADE中支持的每种可能的纯文本编码的基类:【1】

• PackedEncoding

• CKKSPackedEncoding

• CoefPackedEncoding

• StringEncoding

明文的用途:

  • 创建明文PlainText是通过调用适当的CryptoContext类的方法,方法的参数是未加密的信息

  • 一旦创建,明文PlainText可以使用CryptoContextEncrypt方法加密为密文Ciphertext

  • PlainText还可以用作多个CryptoContext同态操作的参数,

  • 当密文Ciphertext被解密时,解密方法创建一个新的Plaintext来包含解密

明文有几个方法提供对明文中的信息的访问,在/core/include/encoding/plaintext.h中的319行:

  virtual const std::string& GetStringValue() const {
    PALISADE_THROW(type_error, "not a string");
  }
  virtual const vector<int64_t>& GetCoefPackedValue() const {
    PALISADE_THROW(type_error, "not a packed coefficient vector");
  }
  virtual const vector<int64_t>& GetPackedValue() const {
    PALISADE_THROW(type_error, "not a packed coefficient vector");
  }
  virtual const std::vector<std::complex<double>>& GetCKKSPackedValue() const {
    PALISADE_THROW(type_error, "not a packed vector of complex numbers");
  }
  virtual const std::vector<double> GetRealPackedValue() const {
    PALISADE_THROW(type_error, "not a packed vector of real numbers");
  }
  virtual void SetStringValue(const std::string&) {
    PALISADE_THROW(type_error, "does not support a string");
  }
  virtual void SetIntVectorValue(const vector<int64_t>&) {
    PALISADE_THROW(type_error, "does not support an int vector");
  }

明文PlainText类中对明文的编码类型(PlaintextEncodings)、明文的元素类型都有定义:

enum PlaintextEncodings {
  Unknown = 0,
  CoefPacked,
  Packed,
  String,
  CKKSPacked,
};

enum PtxtPolyType { IsPoly, IsDCRTPoly, IsNativePoly };

class PlaintextImpl {
 protected:
  //是否被编码
  bool isEncoded;
  //元素类型
  PtxtPolyType typeFlag;
  //编码参数  
  EncodingParams encodingParams;
}

Evaluation中的加法评估

当我们手上有密文时,我们可以对该密文进行加法或乘法,运算的对象可以是其他的密文或明文,这是全同态加密算法的关键。PALISADE中关于评估函数的内容在bgvrns.cppbgvrns-impl.cpp中都有涉及,但是bgvrns-imp.cpp中的评估函数调用的是bgvrns.cpp内的,BVGRNS只支持DCRTPoly类的加密,自然评估函数也只支持DCRTPoly类,以加法为例:

//Poly类型没有加密方法
template <>
void LPAlgorithmSHEBGVrns<Poly>::EvalAddInPlace(
    Ciphertext<Poly>& ciphertext1,
    ConstCiphertext<Poly> ciphertext2) const {
  NOPOLY
}
//NativePoly类型没有加密方法
template <>
void LPAlgorithmSHEBGVrns<NativePoly>::EvalAddInPlace(
    Ciphertext<NativePoly>& ciphertext1,
    ConstCiphertext<NativePoly> ciphertext2) const {
  NONATIVEPOLY
}

template <>
void LPAlgorithmSHEBGVrns<DCRTPoly>::EvalAddInPlace(
    Ciphertext<DCRTPoly>& ciphertext1,
    ConstCiphertext<DCRTPoly> ciphertext2) const {

  auto ciphertext2_clone = ciphertext2->Clone();
  AdjustLevelsEq(ciphertext1, ciphertext2_clone);
  // 将两个密文作为参数执行EvalAddCoreInPlace方法
  EvalAddCoreInPlace(ciphertext1, ciphertext2_clone);
}

template <>
Ciphertext<DCRTPoly> LPAlgorithmSHEBGVrns<DCRTPoly>::EvalAdd(
    ConstCiphertext<DCRTPoly> ciphertext, ConstPlaintext plaintext) const {
  auto inPair = AdjustLevels(ciphertext, plaintext);
  // 执行一个明文与一个密文的评估函数
  return EvalAddCore(*(inPair.first), inPair.second);
}

转回到bgvrns.cpp,重点分析EvalAddCoreInPlaceEvalAddCore方法。先从简单的EvalAddCore分析:

//返回一个密文,输入一个明文与一个密文
template <class Element>
Ciphertext<Element> LPAlgorithmSHEBGVrns<Element>::EvalAddCore(
    ConstCiphertext<Element> ciphertext, Element ptxt) const {
    //创建要返回的密文,赋初值为空
  Ciphertext<Element> result = ciphertext->CloneEmpty();

    //获取密文向量
  const std::vector<Element> &cv = ciphertext->GetElements();

    //设置明文的格式为Format::EVALUATION
  ptxt.SetFormat(Format::EVALUATION);

  std::vector<Element> cvAdd(cv);
    //明文向量与密文向量相加
  cvAdd[0] += ptxt;

    //设置返回密文为相加的值
  result->SetElements(std::move(cvAdd));

  result->SetDepth(ciphertext->GetDepth());
  result->SetLevel(ciphertext->GetLevel());

    //返回加法同态的结果
  return result;
}

当进行加法同态的元素是两个密文时,需要考虑密文的维数不同的印象,具体的EvalAddCoreInPlace方法如下:

template <class Element>
void LPAlgorithmSHEBGVrns<Element>::EvalAddCoreInPlace(
    Ciphertext<Element> &ciphertext1,
    ConstCiphertext<Element> ciphertext2) const {

函数声明传入两个密文对象,同时与EvalAddCore不同的是,该函数并不返回结果,而是将加法同态的运算结果赋给第一个密文(后面会涉及)。

if (ciphertext1->GetLevel() != ciphertext2->GetLevel()) {
    PALISADE_THROW(config_error,
                   "EvalAddCore cannot add ciphertexts with different number "
                   "of CRT components.");
  }

首先判断两个密文的Level,不同则报错

  std::vector<Element> &cv1 = ciphertext1->GetElements();
  const std::vector<Element> &cv2 = ciphertext2->GetElements();

取出两个密文的密文向量

  size_t c1Size = cv1.size();
  size_t c2Size = cv2.size();
  size_t cSmallSize = std::min(c1Size, c2Size);

获取两个密文向量的维数与最小维数

for (size_t i = 0; i < cSmallSize; i++) {
    cv1[i] += cv2[i];
  }
if (c1Size < c2Size) {
    cv1.reserve(c2Size);
    for (size_t i = c1Size; i < c2Size; i++) {
      cv1.emplace_back(cv2[i]);
    }
}
 

将共有的维数范围内的向量值相加,if代码块的目的是保证cv1密文向量是有最大的维数,如果不是则将cv2多的部分填充给cv1

  ciphertext1->SetDepth(
      std::max(ciphertext1->GetDepth(), ciphertext2->GetDepth()));

最后设置Depth,完成了密文的加法同态,ciphertext1密文保存了结果。

参考

【1】PALISADE Lattice Cryptography Library User Manual (v1.11.5)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sunburst7

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值