文章目录
一、预备知识
1、二次剩余
同余理论中,一个整数 x 对另一个整数 p 的二次剩余指 : 当 成立,则称d 是模 p 的二次剩余;否则称非二次剩余
2、雅可比符号
雅可比符号是勒让德符号的推广,但是根据雅可比符号的值不能判断同余式是否有解。
3、曼哈顿距离
图中红线代表曼哈顿距离,绿色代表欧氏距离,也就是直线距离,而蓝色和黄色代表等价的曼哈顿距离。曼哈顿距离——两点在南北方向上的距离加上在东西方向上的距离,即
二、加密算法
1、Paillier同态加密算法
密钥生成 选取两个大素数
, 计算
定义函数
, 随机选择一个生成元
, 使得
. 则加密方案的公钥为
, 私钥为 λ.
加密过程 对于明文 m < N, 选取随机数 r < N, 计算得密文
解密过程 对密文 c, 计算得明文
加法同态性: 由于下面性质成立:
2、Goldwasser-Micali 公钥加密系统
密钥产生:
- 大素数 ,求出
- 任取R,满足
加密:
- 将明文转化为二进制数字
- 对于每一个
,都对应选取一个
若
若 - 将这个 发给
解密:
可参考上一篇博客:Goldwasser-Micali公钥加密系统
三、基于Goldwasser-Micali 公钥加密系统的曼哈顿距离的保密计算
编码方式1 假设全集为 U = {−3, −2, · · · , 4, 5}, 对于点 P(5, 3), 根据编码方法 1, 将横坐标 5 编码为A1 = (1, 1, 1, 1, 1, 1, 1, 1, 1). 将纵坐标 3 编码为 A2= (1, 1, 1, 1, 1, 1, 1, 0, 0),
P(5, 3), A(P ) = (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0)
Q(−3, −2), A(Q) = (1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0)
计算原理 1: 在下面计算中, 假设全集为
Alice 和 Bob 分别拥有点
和
, 满足
, 在全集 U 之下, 点 P (或 Q) 按照编码方式 1 对应的向量记为
关于两点 P 和 Q 之间的曼哈顿距离, 有下面的结论.
命题 1 点 P 和 Q 间的曼哈顿距离可由下式计算:
协议 1 半诚实模型下安全计算两点间的曼哈顿距离
输入 Alice 输入私密点
, Bob 输入私密点
.
输出
准备工作 Alice 根据编码方法 1 构造 P 对应的向量
Bob 根据编码方法 1 得到 Q 对应的向量
Alice 运行 Goldwasser-Micali 加密方案, 生成公钥/私钥对
, 将公钥 pk 发送给 Bob.
(1) Alice 用公钥加密向量 A (分别对每个分量加密), 得到 并将 发送给 Bob.
(2) Bob 加密向量 B 的每个分量, 并计算 再将 R 的 n 个分量进行随机置换, 得到新的向量, 记为 R`, 并将 R` 发送给 Alice.
(3) Alice 解密 ˆR (分别对每个分量解密), 得到 计算 , 并将 y 发给 Bob.
(4) Alice 和 Bob 输出 y.
四、增强的曼哈顿距离协议
编码方式2假设全集为 U = {−3, −2, · · · , 4, 5}, 对于点 P(−3, −2), 应用编码方式 2, 将 x1= −3 编码为V1 = (0, 1, 1, 1, 1, 1, 1, 1, 1), 将 y1= −2 编码为 V2= (0, 0, 1, 1, 1, 1, 1, 1, 1), 并得到 P (−3, −2) 应用编码方法 2 对应的向量 V § = (0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1).
计算原理 2: 在下面计算中, 总假设全集为 U = {u_1, · · · , u_n}, Alice 和 Bob 分别拥有点P (x_1, y_1), Q(x_2, y_2), 满足 x_1, y_1, x_2, y_2 ∈ U, 在全集 U 之下, 对点 P (或 Q) 先按照编码方式 1 (或编码方式 2) 进行编码, 再按照编码方式 2 (或编码方式 1) 进行编码, 对应的向量记为 (或 关于两点 P 和 Q 间的曼哈顿距离, 下面结论成立.
解读上面计算原理2:
对Q(-3, -2)编码:
编码方式1:
编码方式1:
结合在一起:
根据上面所述的计算原理, 并结合应用 Paillier 加密方案和数字承诺思想可设计构造防欺骗场景下计算两点间曼哈顿距离的安全计算
协议2 防欺骗场景下安全计算两点间的曼哈顿距离输入 Alice
输入 Alice私密点
, Bob 输入私密点
.
输出
准备工作 Alice 和 Bob 根据上例分别按照编码方法 1 以及编码方法 2 对点 P 和 Q 进行编码, 得到 4n 维向量
以及
, 双方再商定一个哈希函数. 在下面, 将Paillier 加密及解密算法分别记为 E` 以及 D`.
(1) Alice 加密向量 A(P)(逐分量加密), 得到
并将 R` 发送给 Bob.
(2) Bob 选择随机数 s, 计算 v=hash(s), 利用 Paillier 加密算法加密得到 E`(s), 进一步计算
Bob 将 v 以及 T 发送给 Alice.
(3) Alice 解密 T 得到 t` = D`(T), 并将 t` 发送给 Bob.
(4) Bob 计算 d = t` − s, 并将 d 发给 Alice.
(5) Alice 验证 hash(t`− d) = v 是否成立. 若成立, 则输出 d; 否则, 不接受 d.
解读协议2
因为Paillier同态加密:
由 Paillier 加密算法的加法同态性, 协议第 (3) 步 Alice 解密可得到 再由 Bob 在第 (4) 步中计算可知,
这里使用s的目的,就是给Alice一个验证的步骤,以验证Bob是否欺骗自己
五、仿真实验
1、Paillier同态加密算法
from paillierlib import paillier
from gmpy2 import mpz
key_pair = paillier.keygen()# Optional param.: bit size (default = 2048)
m1 = mpz(50)
m2 = mpz(21)
c1 = paillier.encrypt(m1, key_pair.public_key)
c2 = paillier.encrypt(m2, key_pair.public_key)
print(paillier.decrypt(c1 + c2, key_pair.private_key))# => 71
print(paillier.decrypt(c1 - c2, key_pair.private_key))# => 29
print(paillier.decrypt(c1 + c1 + c2, key_pair.private_key))# => 121
# Multiplication (ciphertext with plaintext)
m3 = mpz(2)
print(paillier.decrypt(c1 * m3, key_pair.private_key))# => 100
2、GM加密系统代码模拟与同态性质验证
这里因为还不是特别了解这个加密算法,在参数选择上比较随意,知识仿真实验一下。
# GM(Goldwasser - Micali)概率公钥加密算法,
# 其基于二次剩余难以复合困难性问题
import math
import random
class Alice:
p = 0
q = 0
N = 0
R = 0
M = []
def __init__(self, p, q, R):
self.p = p
self.q = q
self.N = p * q
self.R = R
# 解密
def Dc(self, eM):
self.M = []
for i,em in enumerate(eM):
temp = '0'
c = int(math.sqrt(em % self.N))
# a = int(math.sqrt(em % self.q))
# 判断加密后的数组元素a, (a mod p) and (a mod q)是否是二次剩余
if c ** 2 == em:
temp = '0'
# if c ** 2 != em and a ** 2 != em:
else:
temp = '1'
self.M.append(temp)
return self.M
class Bob:
M = ''
PK = {
"R" : 0,
"N" : 0
}
C = []
def __init__(self, R, N):
self.PK['R'] = R
self.PK['N'] = N
# 加密
def Ec(self, M):
C = []
for i,m in enumerate(M):
c = 0
# 产生一个随机数,要满足randomnum是mod N的二次剩余
randomnum = random.randint(1,20000)
if m == '1':
c = (self.PK['R'] * (randomnum ** 2) ) % self.PK["N"]
else:
c = (randomnum ** 2) % self.PK["N"]
C.append(c)
return C
# 验证同态性质
def testTong(a, b):
result = []
for i in range(len(a)):
result.append(a[i] * b[i])
return result
if __name__ == '__main__':
p, q, R = 232312311797, 971179711797, 17
a = "1011011000111110000110" #
b = "0011011000101110000111" #
alice = Alice(p, q, R)
bob = Bob(R, p * q)
aa = bob.Ec(a)
alice.Dc(aa)
bb = bob.Ec(b)
print("aa: "+ str(aa))
print("bb: "+ str(bb))
print("Dc(aa): "+ str(alice.Dc(aa)))
print("Dc(bb): "+ str(alice.Dc(bb)))
#验证加密后的数据是否具有异或同态性质
temp = testTong(aa, bb)
print("temp: "+ str(temp))
print("Dc(temp): "+ str(alice.Dc(temp)))
结果:
aa: [2018287872, 81703521, 3249220625, 6064861248, 270898681, 169433033, 5980388112, 180284329, 3873024, 251001, 1537158377, 3446735057, 498293732, 305186873, 3109735625, 98565184, 132342016, 265103524, 20976400, 2332702532, 966733577, 279057025]
bb: [211033729, 15912121, 313599425, 1603820273, 316412944, 9948825, 1455506153, 294225409, 327392836, 41757444, 135094937, 289748484, 1749312512, 668106137, 3614294537, 200307409, 2515396, 26471025, 167598916, 708778433, 694362977, 1091811332]
Dc(aa): [‘1’, ‘0’, ‘1’, ‘1’, ‘0’, ‘1’, ‘1’, ‘0’, ‘0’, ‘0’, ‘1’, ‘1’, ‘1’, ‘1’, ‘1’, ‘0’, ‘0’, ‘0’, ‘0’, ‘1’, ‘1’, ‘0’]
Dc(bb): [‘0’, ‘0’, ‘1’, ‘1’, ‘0’, ‘1’, ‘1’, ‘0’, ‘0’, ‘0’, ‘1’, ‘0’, ‘1’, ‘1’, ‘1’, ‘0’, ‘0’, ‘0’, ‘0’, ‘1’, ‘1’, ‘1’]
temp: [425926815823634688, 1300076312278041, 1018953719698140625, 9726947422474480704, 85715849180926864, 1685659594536225, 8704491694344053136, 53044230436315561, 1268000311256064, 10481160201444, 207662314099837249, 998686257515403588, 871671460038774784, 203897222783139601, 11239500480951780625, 19743336624648256, 332892577678336, 7017562011392100, 3515621901582400, 1653369245286092356, 671264004491578729, 304677622169207300]
Dc(temp): [‘1’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘1’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘1’]
六、参考文献
[1] 方乐笛,李顺东,窦家维.曼哈顿距离的保密计算[J].密码学报,2019,6(04):512-525.
[2] https://blog.csdn.net/qq_26816591/article/details/82957481
本人才疏学浅,如有纰漏,欢迎指正,谢谢!