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

发布于 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_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_1、v_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代码:(基于维基百科文章代码的更容易阅读的版本)
# 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))https://crypto.stackexchange.com/questions/101270
复制相似问题