首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >请求环形签名数字示例或简单python代码

请求环形签名数字示例或简单python代码
EN

Cryptography用户
提问于 2022-07-29 18:13:02
回答 1查看 259关注 0票数 3

我在读关于魔戒的签名。但是,我不理解这项签字的核查过程。你能给我一个完整的数字例子来说明签名的创建和验证过程吗?在RSA的情况下,有许多数字例子可用,但我发现没有环签名。我相信这是很有帮助的。

EN

回答 1

Cryptography用户

发布于 2022-07-30 20:36:48

k=\texttt{sha256}(msg),其中msg是我们想要签名的消息,例如文本\texttt{"hello world!"}

然后将键控散列H_k(input)定义为\texttt{hmac-sha256}(k,\ input)。键控散列的目的是确保环签名只验证指定的消息。

我们将首先验证一个签名,该签名将包含整数v_0和公钥指数\{e_i\}和对应的模\{n_i\},用于环中的每个可能的签名者。签名还列出了一组整数值\{s_i\}

如果环大小为4,则从指定的v_0值开始,并按以下方式计算其他v_i值:

v_1 = H_k(s_1^{e_1} \oplus v_0)
v_2 = H_k(s_2^{e_2} \oplus v_1)
v_3 = H_k(s_3^{e_3} \oplus v_2)
v_0' = H_k(s_0^{e_0} \oplus v_3)

如果是v_0' \overset{?}{=}v_0,签名是有效的。

为了简洁起见,我省略了每个指数所需的(mod\ n_i)。我还简化为标准RSA加密。如下面的python代码所示,需要额外的步骤才能“将陷阱门排列扩展到公共域”,如如何泄露秘密论文中所描述的。

注意,每个键控散列都依赖于环中前一步的v_i值。这意味着,如果我们试图创建这样一个环,而不知道任何私钥,并且不知道工作的v_0值,我们就会陷入困境。

在知道v_3值之前,我们如何在环签名中创建最后一行?了解v_3需要我们计算v_2,这需要我们计算v_1,这需要我们计算v_0。但是,我们不能计算v_0,直到我们知道v_3

如果我们知道与公钥d_0相对应的私钥e_0,就可以按以下方式创建该环:

v_0=H_k(u),其中u是一致随机整数。我们将选择每个s_i值(其中i\ge1)作为一致随机整数,并按照上述验证过程中描述的步骤计算值v_1v_2和最终v_3

现在,我们需要使它以某种方式使v_0=H_k(u)=H_k(s_0^{e_0} \oplus v_3),以便我们的戒指将验证。

这很简单。如果我们设置s_0=(u \oplus v_3)^{d_0},那么H_k(s_0^{e_0} \oplus v_3) = H_k({(u \oplus v_3)^{d_0}}^{e_0} \oplus v_3)=H_k(u \oplus v_3 \oplus v_3) = H_k(u)

我们现在有了一个环签名,它只能通过了解与列表中的一个公钥对应的一个私钥才能创建。

我在下面包含了Python代码:(基于维基百科文章代码的更容易阅读的版本)

代码语言:javascript
复制
# needs: pip install PyCryptodome
import hmac
import os
import random
import Crypto.PublicKey.RSA
from hashlib import sha256


def gen_key_pair():
    r = Crypto.PublicKey.RSA.generate(1024, os.urandom)
    return {'e': r.e, 'd': r.d, 'n': r.n}


def gen_public_key():
    r = Crypto.PublicKey.RSA.generate(1024, os.urandom)
    return {'e': r.e, 'n': r.n}


def crypto_hash(msg):
    return int(sha256(msg.encode("utf-8")).hexdigest(), 16)


def keyed_hash(key, msg):
    return int(hmac.new(bytes(str(key), 'UTF-8'), str(msg).encode("utf-8"), sha256).hexdigest(), 16)


def rsa_encrypt_or_decrypt(msg, e_or_d, n):
    q, r = divmod(msg, n)
    if ((q + 1) * n) <= (pow(2, 1024) - 1):
        result = q * n + pow(r, e_or_d, n)
    else:
        result = msg
    return result


def xor(a, b):
    return a ^ b


def sign(msg, signer_key_pair, other_public_keys):
    ring_size = len(other_public_keys) + 1
    key = crypto_hash(msg)
    u = random.randint(0, pow(2, 1023))
    v = [0] * ring_size
    v[0] = keyed_hash(key, u)

    s = [0] + [random.randint(0, pow(2, 1023)) for i in range(1, ring_size)]
    for i in range(1, ring_size):
        v[i] = keyed_hash(key, xor(v[i - 1], rsa_encrypt_or_decrypt(s[i], other_public_keys[i - 1]['e'], other_public_keys[i - 1]['n'])))
    s[0] = rsa_encrypt_or_decrypt(xor(v[ring_size - 1], u), signer_key_pair['d'], signer_key_pair['n'])

    signature = {
        'msg': msg,
        'rows':
            [{'e': signer_key_pair['e'], 'n': signer_key_pair['n'], 's': s[0]}] +
            [{'e': other_public_keys[i - 1]['e'], 'n': other_public_keys[i - 1]['n'], 's': s[i]} for i in range(1, ring_size)]
    }

    # rotate signature randomly to conceal position of true signer
    rotation = random.randint(0, ring_size - 1)
    signature['v'] = rotate(v, rotation)[ring_size - 1]
    signature['rows'] = rotate(signature['rows'], rotation)

    return signature


def rotate(list, n):
    return list[-n:] + list[:-n]


def verify(signature):
    ring_size = len(signature['rows'])
    key = crypto_hash(signature['msg'])
    v = signature['v']
    for i in range(0, ring_size):
        row = signature['rows'][i]
        v = keyed_hash(key, xor(v, rsa_encrypt_or_decrypt(row['s'], row['e'], row['n'])))
    return v == signature['v']


ring_size = 10

signer_key_pair = gen_key_pair()
other_public_keys = [gen_public_key() for i in range(ring_size - 1)]

signature = sign("hello world!", signer_key_pair, other_public_keys)
print(signature)
print("Verifies?", verify(signature))
票数 3
EN
页面原文内容由Cryptography提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://crypto.stackexchange.com/questions/101270

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档