13 篇文章 11 订阅

2021SC@SDUSC

# BGV原理分析

## 1 符号说明

v ∈ Z q n 表 示 一 个 n 维 向 量 ， 向 量 内 的 元 素 属 于 Z q v\in Z_q^n 表示一个n维向量，向量内的元素属于Z_q

[ . ] m 表 示 m o d m 的 操 作 {[.]_m}表示mod\quad m的操作

< a , b > = ∑ i n a i ⋅ b i ( m o d q ) <a,b>=\sum_i^na_i\cdot b_i(mod\quad q)

• 加法：

• 乘法

## 3 Learning With Error 与 Ring Learning With Error

LWE就是说根据(ai,bi)去恢复s很困难，因为存在误差。

Ring-LWE问题是LWE问题的变体，它也基于根据(ai,bi)恢复s的困难性，等式也基本相同，但是变量的取值空间从
Z q n Z_q^n

R q = Z q [ x ] / < x n + 1 > R_q=Z_q[x]/<x^n+1>

## 4 构建一个全同态体系

import numpy as np
from numpy.polynomial import polynomial as poly

def polymul(x, y, modulus, poly_mod):
Args:
x, y: 两个要相加的多项式.
modulus: 多项式系数的模 Zq中的q.
poly_mod: 多项式模x^n+1.
Returns:
A polynomial in Z_modulus[X]/(poly_mod).
多项式xy相乘后系数mod modulus，然后对多项式模 poly_mod（polydiv[0] 商，polydiv[1]余数，得到的余数多项式再mod modulus）
"""
return np.int64(
np.round(poly.polydiv(poly.polymul(x, y) % modulus, poly_mod)[1] % modulus)
)

"""Multiply two polynoms
Args:
x, y: two polynoms to be multiplied.
modulus: coefficient modulus.
poly_mod: polynomial modulus.
Returns:
A polynomial in Z_modulus[X]/(poly_mod).
"""
return np.int64(
np.round(poly.polydiv(poly.polyadd(x, y) % modulus, poly_mod)[1] % modulus)
)


### 4.1 Key Generation

def gen_binary_poly(size):
"""Generates a polynomial with coeffecients in [0, 1]——构造sk
Args:
size: number of coeffcients, size-1为这个多项式的度.
Returns:
array of coefficients with the coeff[i] being
the coeff of x ^ i.
"""
return np.random.randint(0, 2, size, dtype=np.int64)

def gen_uniform_poly(size, modulus):
"""Generates a polynomial with coeffecients being integers in Z_modulus——在Zq范围内随机采样
Args:
size: number of coeffcients, size-1 being the degree of the
polynomial.
Returns:
array of coefficients with the coeff[i] being
the coeff of x ^ i.
"""
return np.random.randint(0, modulus, size, dtype=np.int64)

def gen_normal_poly(size):
"""Generates a polynomial with coeffecients in a normal distribution——一个正态分布
of mean 0 and a standard deviation of 2, then discretize it.
Args:
size: number of coeffcients, size-1 being the degree of the
polynomial.
Returns:
array of coefficients with the coeff[i] being
the coeff of x ^ i.
"""
return np.int64(np.random.normal(0, 2, size=size))


def keygen(size, modulus, poly_mod):
"""生成pk与sk
Args:
size: size of the polynoms for the public and secret keys.
modulus: coefficient modulus.
poly_mod: polynomial modulus.
Returns:
Public and secret key.
"""
sk = gen_binary_poly(size)
a = gen_uniform_poly(size, modulus)
e = gen_normal_poly(size)
b = polyadd(polymul(-a, sk, modulus, poly_mod), -e, modulus, poly_mod)
return (b, a), sk


### 4.2 Encryption

• u：是R2的均匀分布（与sk相同）
• e1,e2：是Rq上的离散高斯分布采样（与KeyGen的error相同）
• δ：q整除t的商。
def encrypt(pk, size, q, t, poly_mod, pt):
"""Encrypt an integer.加密一个整数
Args:
pk: public-key.
size: size of polynomials.
q: ciphertext modulus.
t: plaintext modulus.
poly_mod: polynomial modulus.
pt: integer to be encrypted.
Returns:
Tuple representing a ciphertext.
"""
# encode the integer into a plaintext polynomial
m = np.array([pt] + [0] * (size - 1), dtype=np.int64) % t
delta = q // t
scaled_m = delta * m  % q
e1 = gen_normal_poly(size)
e2 = gen_normal_poly(size)
u = gen_binary_poly(size)
polymul(pk[0], u, q, poly_mod),
e1, q, poly_mod),
scaled_m, q, poly_mod
)
polymul(pk[1], u, q, poly_mod),
e2, q, poly_mod
)
return (ct0, ct1)


### 4.3 Decryption

def decrypt(sk, size, q, t, poly_mod, ct):
"""Decrypt a ciphertext——解密一个密文
Args:
sk: secret-key.
size: size of polynomials.
q: ciphertext modulus.
t: plaintext modulus.
poly_mod: polynomial modulus.
ct: ciphertext.
Returns:
Integer representing the plaintext.
"""
polymul(ct[1], sk, q, poly_mod),
ct[0], q, poly_mod
)
decrypted_poly = np.round(scaled_pt * t / q) % t
return int(decrypted_poly[0])


### 4.4 Evaluation

def add_plain(ct, pt, q, t, poly_mod):
"""Add a ciphertext and a plaintext.
Args:
ct: ciphertext.
q: ciphertext modulus.
t: plaintext modulus.
poly_mod: polynomial modulus.
Returns:
Tuple representing a ciphertext.
"""
size = len(poly_mod) - 1
# encode the integer into a plaintext polynomial
m = np.array([pt] + [0] * (size - 1), dtype=np.int64) % t
delta = q // t
scaled_m = delta * m  % q
new_ct0 = polyadd(ct[0], scaled_m, q, poly_mod)
return (new_ct0, ct[1])


#### 4.4.2 Multiplication

ct是密文，m1为原明文，我们想要乘上一个明文m2

−a⋅sk⋅u⋅m2 anda⋅sk⋅u无法抵消，正确的做法是对ct1也乘上m2

def mul_plain(ct, pt, q, t, poly_mod):
"""Multiply a ciphertext and a plaintext.
Args:
ct: ciphertext.
pt: integer to multiply.
q: ciphertext modulus.
t: plaintext modulus.
poly_mod: polynomial modulus.
Returns:
Tuple representing a ciphertext.
"""
size = len(poly_mod) - 1
# encode the integer into a plaintext polynomial
m = np.array([pt] + [0] * (size - 1), dtype=np.int64) % t
new_c0 = polymul(ct[0], m, q, poly_mod)
new_c1 = polymul(ct[1], m, q, poly_mod)
return (new_c0, new_c1)


## 5 测试代码

# Scheme's parameters
# polynomial modulus degree
n = 2**4
# ciphertext modulus
q = 2**15
# plaintext modulus
t = 2**8
# polynomial modulus
poly_mod = np.array([1] + [0] * (n - 1) + [1])
# Keygen
pk, sk = keygen(n, q, poly_mod)
# Encryption
pt1, pt2 = 73, 20
cst1, cst2 = 7, 5
ct1 = encrypt(pk, n, q, t, poly_mod, pt1)
ct2 = encrypt(pk, n, q, t, poly_mod, pt2)

print("[+] Ciphertext ct1({}):".format(pt1))
print("")
print("\t ct1_0:", ct1[0])
print("\t ct1_1:", ct1[1])
print("")
print("[+] Ciphertext ct2({}):".format(pt2))
print("")
print("\t ct1_0:", ct2[0])
print("\t ct1_1:", ct2[1])
print("")

# Evaluation
ct3 = add_plain(ct1, cst1, q, t, poly_mod)
ct4 = mul_plain(ct2, cst2, q, t, poly_mod)

# Decryption
decrypted_ct3 = decrypt(sk, n, q, t, poly_mod, ct3)
decrypted_ct4 = decrypt(sk, n, q, t, poly_mod, ct4)

print("[+] Decrypted ct3(ct1 + {}): {}".format(cst1, decrypted_ct3))
print("[+] Decrypted ct4(ct2 * {}): {}".format(cst2, decrypted_ct4))


• 2
点赞
• 12
收藏
• 打赏
• 1
评论
01-29 2876
08-22 1万+
07-21
07-24 49
06-15

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

Sunburst7

¥2 ¥4 ¥6 ¥10 ¥20

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