【以太坊基礎系列-003】環形簽名

前言

在密碼學中,環簽名是一種數字簽名,其可以由每個具有密鑰的一組用戶的任何成員完成。因此,使用環簽名簽名的消息由特定人羣中的某一人簽署。環簽名的一個安全屬性是若要確定哪個組成員的密鑰用於產生簽名在計算上是不可行的。環簽名與羣簽名類似,但在兩個關鍵方面有所不同:

1. 無法撤銷單個簽名的匿名性;

2. 任何用戶組都可以作爲一個組使用,無需額外設置。

環簽名技術由Ron Rivest, Adi Shamir, 和 Yael Tauman發明的,於2001發表出來的。環簽名得名於其環狀結構簽名算法。

定義

假設有一組用戶,每個人都有公鑰和私鑰對,(P1, S1), (P2, S2), …, (Pn, Sn)。用戶i可以基於消息m計算一個環簽名σ ,輸入參數爲(m, Si, P1, …, Pn)。如果給定參數σ, m以及所有的公鑰(P1, …, Pn),任何人都可以檢查該環簽名的合法性。如果環簽名是正確的,那麼它應該可以通過剛纔的驗證。另外,如果沒有當前用戶組中任何一個用戶的私鑰,任何人應該是不太可能基於任何組消息來創建一個合法的環簽名。

環簽名滿足的性質

無條件匿名性:攻-擊-者者無法確定簽名是由環中哪個成員生成,即使在獲得環成員私鑰的情況下,概率也不超過1/n。

正確性:簽名必需能被所有其他人驗證。

不可僞造性:環中其他成員不能僞造真實簽名者簽名,外部攻-擊-者者即使在獲得某個有效環簽名的基礎上,也不能爲消息m僞造一個簽名。

環簽名實現:

(1)密鑰生成。爲環中每個成員產生一個密鑰對(公鑰PKi,私鑰SKi)。

(2)簽名。簽名者用自己的私鑰和任意n個環成員(包括自己)的公鑰爲消息m生成簽名a。

(3)簽名驗證。驗證者根據環簽名和消息m,驗證簽名是否爲環中成員所籤,如果有效就接收,否則丟棄。

Python實現樣例

import os, hashlib, random, Crypto.PublicKey.RSA



class ring:

    def __init__(self, k, L=1024):

        self.k = k

        self.l = L

        self.n = len(k)

        self.q = 1 << (L - 1)



    def sign(self, m, z):

        self.permut(m)

        s = [None] * self.n

        u = random.randint(0, self.q)

        c = v = self.E(u)

        for i in (range(z+1, self.n) + range(z)):

            s[i] = random.randint(0, self.q)

            e = self.g(s[i], self.k[i].e, self.k[i].n)

            v = self.E(v^e)

            if (i+1) % self.n == 0:

                c = v

        s[z] = self.g(v^u, self.k[z].d, self.k[z].n)

        return [c] + s



    def verify(self, m, X):

        self.permut(m)

        def _f(i):

            return self.g(X[i+1], self.k[i].e, self.k[i].n)

        y = map(_f, range(len(X)-1))

        def _g(x, i):

            return self.E(x^y[i])

        r = reduce(_g, range(self.n), X[0])

        return r == X[0]



    def permut(self, m):

        self.p = int(hashlib.sha1('%s' % m).hexdigest(),16)



    def E(self, x):

        msg = '%s%s' % (x, self.p)

        return int(hashlib.sha1(msg).hexdigest(), 16)



    def g(self, x, e, n):

        q, r = divmod(x, n)

        if ((q + 1) * n) <= ((1 << self.l) - 1):

            rslt = q * n + pow(r, e, n)

        else:

            rslt = x

        return rslt

簽名並驗證兩個由4個用戶組成的環簽名消息:

size = 4

msg1, msg2 = 'hello', 'world!'

def _rn(_):

  return Crypto.PublicKey.RSA.generate(1024, os.urandom)

key = map(_rn, range(size))

r = ring(key)

for i in range(size):

    s1 = r.sign(msg1, i)

    s2 = r.sign(msg2, i)

    assert r.verify(msg1, s1) and r.verify(msg2, s2) and not r.verify(msg1, s2)

---------------------

原文:https://blog.csdn.net/iamhuihua/article/details/82391988

 

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