2021SC@SDUSC-PALISADE(五)加密Encrypt

2021SC@SDUSC
本节主要分析BGV的加密过程,加密过程的具体实现主要在bgvrns-impl.cpp内。大致从700行开始。开始前我们需要先了解PALISADE的元素格式

一 PALISADE元素类型

从palisade_manual.pdf的7.1节与7.13节中,我们了解到:

7.1 Typeing

All PALISADE operations are strongly typed. A Plaintext that is passed to encrypt will create a Ciphertext that is aware of the underlying format of the Plaintext, as well as the particular key that was used to encrypt the Plaintext. The decrypt operation will fail in cases where an improper key is used. A successful decrypt will produce a new Plaintext whose underlying format matches the initial Plaintext that was passed to encrypt. Homomorphic operations between Ciphertexts, and mixed-mode operations between a Ciphertext and a Plaintext will only be permitted for operands with formats and keys that match.

7.13 Element

The math layer performs operations on different kinds of Element. This is a representation of a vector in lattice space.

7.13.1 Poly

A Poly is a vector of polynomial coefficients. The coefficients are whatever the BigInteger type is for the selected math back-end, and the vector is simply a vector of these BigInteger, and an associated modulus. All operations on a Poly are done modulo this modulus.

7.13.2 NativePoly

A NativePoly is a vector of polynomial coefficients where each of the coefficients is of type 64-bit unsigned integer. The NativePoly also has a modulus of at most 64 bits (though our math implementations are most efficient for moduli of 60 bits or less). Again,all operations are done modulo the modulus.

7.13.3 DCRTPoly

A DCRTPoly implements a large Poly decomposed via residue arithmetic into a tower (set) of NativePoly element

翻译一下就是:所有的PALISADE开源库内的操作都是强类型的,要加密的明文会创造一个知道明文格式的密文(Ciphertext)以及用来加密的特定的密钥,如果使用不正确的密文,解密操作将会失败。一次成功的解密将产生一个新的,其基本格式与传递给的初始明文相匹配的明文加密。密文之间的同态操作和混合模式操作在密文和明文之间只允许在相同格式之间进行。

PALISADE中有三种元素的类型:

  • Poly:

    Poly是多项式系数的向量,系数的取值是后端选择的BigInteger。向量包括一个BigInteger类型的向量以及一个模数(modulus),所有在Poly类型上的操作都要模上这个模数。

  • NativePoly

    NativePloy与Poly唯一不同的一点就是,多项式的系数的取值是64-bits位的无符号整数。

  • DCRTPoly

    DCRTPoly,它将编码的明文表示为使用双中国余数定理的分解的堆栈NativePoly多项式。

二 加密Encrypt

bgvrns-impl.cpp的开头定义了两个string类型的错误信息。

#define NOPOLY                                                                \
  std::string errMsg = "BGVrns does not support Poly. Use DCRTPoly instead."; \
  PALISADE_THROW(not_implemented_error, errMsg);

#define NONATIVEPOLY                                               \
  std::string errMsg =                                             \
      "BGVrns does not support NativePoly. Use DCRTPoly instead."; \
  PALISADE_THROW(not_implemented_error, errMsg);

从错误信息中,我们了解了BGVrns的加密方案不支持PALISADE元素格式中的Poly格式与NativePoly格式,当我们想要加密这两种格式的元素时需要使用DCRTPoly替代。因此接下来我们主要分析对DCRTPoly的加密方式。加密函数的定义如下:

template <>
Ciphertext<DCRTPoly> LPAlgorithmBGVrns<DCRTPoly>::Encrypt(
    const LPPrivateKey<DCRTPoly> privateKey, DCRTPoly ptxt) const {

该泛型的加密函数Encrypt(LPPrivateKey DCRTPoly)传入两个参数,分别是密钥与明文,明文的格式时DCRTPoly类型的明文。返回一个加密的密文Ciphertext

const auto cryptoParams =
      std::static_pointer_cast<LPCryptoParametersBGVrns<DCRTPoly>>(
          privateKey->GetCryptoParameters());

const auto t = cryptoParams->GetPlaintextModulus();

接着声明一个参数对象cryptoParams,与KeyGen函数中的cryptoParams类似,这步主要是获取BGV方案的加密的参数。第二行从这个对象中取出模数t

接着声明一些变量:

//这一步是声明一个密文对象,封装我们加密后的密文。
Ciphertext<DCRTPoly> ciphertext(
      std::make_shared<CiphertextImpl<DCRTPoly>>(privateKey));

//声明一个离散高斯分布的采样生成器
const DggType &dgg = cryptoParams->GetDiscreteGaussianGenerator();
//声明一个离散均匀分布生成器 (discrete uniform generator)
DugType dug;

//创建一个向量,用于保存密文。
std::vector<DCRTPoly> cv;

//根据离散高斯分布生成一个类型DCRTPoly为噪声e
DCRTPoly e(dgg, ptxtParams, Format::EVALUATION);
//根据离散均匀分布生成一个类型为DCRTPoly参数a
DCRTPoly a(dug, ptxtParams, Format::EVALUATION);

//取出私钥元素
const DCRTPoly &s = privateKey->GetPrivateElement();

//声明密文的两个组成部分:co与c1
DCRTPoly c0, c1;

参考【2】的BGV加密原理的加密过程:

if (sizeQl != sizeQ) {
    uint32_t diffQl = sizeQ - sizeQl;
    DCRTPoly scopy(s);
    scopy.DropLastElements(diffQl);

    c0 = a * scopy + t * e + ptxt;
    c1 = -a;
  } else {
    // Use secret key as is
    c0 = a * s + t * e + ptxt;
    c1 = -a;
  }

//添加到密文向量(ciphertext vector-cv)中 
cv.push_back(std::move(c0));
cv.push_back(std::move(c1));

在加密方法的开头我们初始化了一个密文对象,里面保存了关于密文的信息:密文深度、等级、密文向量…

  ciphertext->SetElements(std::move(cv));

  // Ciphertext depth, level, and scaling factor should be
  // equal to that of the plaintext. However, Encrypt does
  // not take Plaintext as input (only DCRTPoly), so we
  // don't have access to these here, and we set them in
  // the crypto context Encrypt method.
  ciphertext->SetDepth(1);
  ciphertext->SetLevel(1);

加密方法的末尾,返回设置好的密文封装对象。

return ciphertext;

参考

【1】PALISADE Lattice Cryptography Library User Manual (v1.11.5)
【2】https://eprint.iacr.org/2021/204

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Sunburst7

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

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

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

打赏作者

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

抵扣说明:

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

余额充值