1、二次剩余问题
对于整数n ,定义 Z n ∗ = { a ∈ Z n , g c d ( a , n ) = 1 } Z^*_n=\{ a∈Z_n,gcd(a,n) =1\} Zn∗={a∈Zn,gcd(a,n)=1} 。当存在 d ∈ Z n d \in Z_n d∈Zn ,使得 d 2 ≡ a m o d n d^2 \equiv a \, mod \,n d2≡amodn ,称 a 为模 n 的二次剩余;否则称 a 为模 n的二次非剩余。判断 a 是否为模 n 的二次剩余的问题称为模n 的二次剩余问题。
\rule[-10pt]{14.3cm}{0.05em}
2、Goldwasser-Micali 公钥加密系统
密钥产生:
- 大素数 p , q p,q p,q,求出 N = p ∗ q N=p*q N=p∗q
- 任取R,满足 J ( R p ) = J ( R q ) = − 1 J(\frac{R}{p})=J(\frac{R}{q})=-1 J(pR)=J(qR)=−1
- P K ( R , N ) , S K ( p , q ) PK(R, N), SK(p, q) PK(R,N),SK(p,q)
加密:
- B B B 将明文转化为二进制数字 M = ( m 1 , m 2 , m 3 … m k ) ∈ 0 , 1 M=(m_1,m_2,m_3… m_k) ∈{0,1} M=(m1,m2,m3…mk)∈0,1
- 对于每一个
m
i
m_i
mi,都对应选取一个
r
∈
Z
n
∗
r ∈Z^*_n
r∈Zn∗
若 m i = 1 , c i = R 1 ∗ r 2 m o d N m_i=1, c_i=R^1*r^2modN mi=1,ci=R1∗r2modN
若 m i = 0 , c i = R 0 ∗ r 2 m o d N m_i=0, c_i=R^0*r^2modN mi=0,ci=R0∗r2modN - C = { c 1 , c 2 , c 3 … c k } C =\lbrace c_1,c_2,c_3…c_k\rbrace C={c1,c2,c3…ck} 将这个 C C C发给 A A A
解密:
计
算
J
(
c
p
)
和
J
(
c
q
)
m
i
=
{
0
若
都
=
1
1
若
都
=
−
1
计算J(\frac{c}{p}) 和 J(\frac{c}{q}) \;\;\; m_i=\left\{ \begin{aligned} 0 & & 若都=1 \\ 1 & & 若都=-1 \\ \end{aligned} \right.
计算J(pc)和J(qc)mi={01若都=1若都=−1
性质:
a)异或同态性。设明文
x
1
x_1
x1和
x
2
x_2
x2的密文为
E
(
x
1
)
E(x_1)
E(x1)和
E
(
x
1
)
E(x_1)
E(x1) , 则
E
(
x
1
)
∗
E
(
x
1
)
E(x_1)*E(x_1)
E(x1)∗E(x1)是
x
1
⊕
x
2
x_1 \oplus x_2
x1⊕x2的密文,即 ;
这里密文相乘之后,需要模p*q,要不然只能实现或同态
b)非运算同态性。即
E
(
x
)
⋅
z
=
E
(
x
⊕
1
)
=
E
(
x
ˉ
)
E(x) \cdot z = E(x \oplus 1) = E(\bar x)
E(x)⋅z=E(x⊕1)=E(xˉ);
c)重复加密随机性。即
D
(
E
(
x
)
⋅
E
(
0
)
)
=
D
(
E
(
x
)
)
D(E(x) \cdot E(0)) = D(E(x))
D(E(x)⋅E(0))=D(E(x)) 。
\rule[-10pt]{14.3cm}{0.05em}
3、仿真实验
# GM(Goldwasser - Micali)概率公钥加密算法,
# 其基于二次剩余难以复合困难性问题
# 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, n):
result = []
for i in range(len(a)):
result.append((a[i] * b[i]) % n)
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, p * q)
print("temp: "+ str(temp))
print("Dc(temp): "+ str(alice.Dc(temp)))
aa: [1332385353, 316626436, 130910625, 3285042617, 28761769, 2155772057, 1336602713, 16999129, 251381025, 25553025, 1390189433, 88128, 1025018825, 2584072097, 2034621200, 123298816, 712336, 128074489, 301925376, 90321425, 3037049252, 215355625]
bb: [86899684, 48011041, 6395481872, 3666536132, 213861376, 3628548, 4747377857, 110229001, 136282276, 38675961, 352512, 125821089, 105486377, 2007928208, 110282553, 101787921, 52243984, 8543929, 27071209, 4034338425, 864954713, 677517473]
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: [115783866141928452, 15201564800479876, 837236529039690000, 12044727450390337444, 6151031494534144, 7822322385883236, 6345358123302326041, 1873797007540129, 34258778230212900, 988287798332025, 490058457405696, 11088360931392, 108125522206047025, 5188631255072012176, 224383220323923600, 12550330142401536, 37215270586624, 1094259340727281, 8173484956099584, 364387195478255625, 2626910064130524676, 145907198846335625]
Dc(temp): ['1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1']
最后的结果加解密能够正常运行,同时此加密算法的异或同态也正确,temp中存放就是抑或之后的密文
本人才疏学浅,如有纰漏,欢迎指正,谢谢!