Goldwasser-Micali 公鑰加密系統

曼哈頓距離的保密計算

1、二次剩餘問題

對於整數n ,定義Zn={aZn,gcd(a,n)=1}Z^*_n=\{ a∈Z_n,gcd(a,n) =1\} 。當存在dZnd \in Z_n ,使得 d2amodnd^2 \equiv a \, mod \,n ,稱 a 爲模 n 的二次剩餘;否則稱 a 爲模 n的二次非剩餘。判斷 a 是否爲模 n 的二次剩餘的問題稱爲模n 的二次剩餘問題。

\rule[-10pt]{14.3cm}{0.05em}

2、Goldwasser-Micali 公鑰加密系統

密鑰產生:

  1. 大素數 pqp,q,求出 N=pqN=p*q
  2. 任取R,滿足J(Rp)=J(Rq)=1J(\frac{R}{p})=J(\frac{R}{q})=-1
  3. PK(R,N),SK(p,q)PK(R, N), SK(p, q)

加密:

  1. BB 將明文轉化爲二進制數字 M=(m1,m2,m3mk)0,1M=(m_1,m_2,m_3… m_k) ∈{0,1}
  2. 對於每一個mim_i,都對應選取一個rZnr ∈Z^*_n
    mi=1,ci=R1r2modNm_i=1, c_i=R^1*r^2modN
    mi=0,ci=R0r2modNm_i=0, c_i=R^0*r^2modN
  3. C={c1,c2,c3ck}C =\lbrace c_1,c_2,c_3…c_k\rbrace 將這個CC發給AA

解密:
J(cp)J(cq)      mi={0=11=1 計算J(\frac{c}{p}) 和 J(\frac{c}{q}) \;\;\; m_i=\left\{ \begin{aligned} 0 & & 若都=1 \\ 1 & & 若都=-1 \\ \end{aligned} \right.
性質
a)異或同態性。設明文x1x_1x2x_2的密文爲E(x1)E(x_1)E(x1)E(x_1) , 則E(x1)E(x1)E(x_1)*E(x_1)x1x2x_1 \oplus x_2的密文,即 ;

這裏密文相乘之後,需要模p*q,要不然只能實現或同態

b)非運算同態性。即 E(x)z=E(x1)=E(xˉ)E(x) \cdot z = E(x \oplus 1) = E(\bar x)
c)重複加密隨機性。即D(E(x)E(0))=D(E(x))D(E(x) \cdot 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中存放就是抑或之後的密文

本人才疏學淺,如有紕漏,歡迎指正,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章