Python Winternitz 一次性签名(+)实现
项目描述
Winternitz 一次性签名
Winternitz 一次性签名方案的 Python 实现
描述
Winternitz 一次性签名是 Lamport 一次性签名的扩展。这个python包可以用来执行WOTS操作,包括密钥生成、签名生成和签名验证。目前已实施 WOTS 和 WOTS+。
介绍
Lamport 在 1979 年发明了一种算法,该算法允许人们使用加密安全的单向函数创建一次性签名。它是 Winternitz 一次性签名算法的基础。Winternitz 增加了调整时间复杂度和空间复杂度之间权衡的可能性。
Lamport一次性签名方案
Lamport 建议为将要签名的消息的每一位创建两个密钥。该位可以采用的每个值一个。为了派生验证密钥,每个密钥都被散列一次。现在您有一个密钥和一个验证密钥,它由m个 2 元组值组成,其中m是消息的位数。验证密钥已发布。签名由m价值观。对于消息的每一位,您从相应的密钥中释放一个密钥,具体取决于该位的值。所有这些密钥构成了消息的签名。验证器对您的每个密钥进行一次哈希处理,并将其与该位置的一个验证密钥进行比较,具体取决于该位的值。当且仅当所有派生的验证密钥与您在 2 元组的正确位置(由该位的值确定)处发布的验证密钥匹配时,签名才有效。该算法非常快(与现有的 PQC 算法相比),但签名大小很大。
温特尼茨扩展
Winternitz 扩展了 lamports 算法,提供了决定将有多少位一起签名的可能性。这些位可以表示的数字量称为 Winternitz 参数 ( w = 2^{bits} )。这种方法提供了巨大的优势,即该算法的用户可以选择时间和空间的权衡(速度或存储容量是否更相关)。将要签名的消息的指纹被分成ceil(log_2(w))位组。这些组中的每一个都获得一个密钥。每个验证密钥是通过将每个组的密钥散列2^{w-1}次得出的。所有的验证密钥都会被公开,代表一个统一的验证密钥。签名消息时,消息的指纹被分成几组ceil(log2(w))位。为了创建签名,每个位组的私钥被哈希bitgroup_value次,其中bitgroup_value是位组的值。此外,附加了一个(逆和)校验和,它拒绝了中间人攻击。校验和根据签名计算,分成ceil(log2(w))位的位组,并签名。为了验证签名,首先将消息的指纹分成ceil(log2(w) 个比特的比特组。基本思想是取每个比特组的签名,从中计算验证密钥,最后比较已发布的验证密钥。由于签名是经过哈希 处理的bitgroup_value时间,从签名计算验证密钥所需要做的就是将签名散列2^{w-1} - bitgroup_value - 1次。除了验证消息之外,验证者还必须计算校验和并进行验证。
设置
要求:Python >= 3.4
测试
生成文档
python setup.py 文档
用法
包Winternitz包含一个名为signatures的模块。在这个包中,您可以找到 WOTS 和 WOTSPLUS 类。这些类可以开箱即用地签署或验证消息
WOTS
import winternitz.signatures
# Create signature and verify it with the same object
wots = winternitz.signatures.WOTS()
message = "My message in bytes format".encode("utf-8")
sig = wots.sign(message)
success = wots.verify(message=message, signature=sig["signature"])
print("Verification success: " + str(success))
# Output: Verification success: True
如果您在 WOTS 的构造函数中没有指定任何值,它将使用 Winternitz 参数 16 和哈希函数sha512作为默认参数。私钥将由熵生成。在通过wots.pubkey或在 wots.sign(message)函数调用返回的 dict 中收到公钥后,您将其发布。确认它没有被修改。在最好的情况下,通过应用程序的设计,修改您的公钥的中间人攻击是不可能的。最后一步是发布您的消息以及wots.sign(message)返回的字典中的所有信息,除了公钥(因为它已经发布)。发布指纹是可选的,因为它对于签名验证不是必需的。签名字典包含以下值:
{
"w": winternitz parameter (Type: int),
"fingerprint": message hash (Type: bytes),
"hashalgo": hash algorithm (Type: str),
"digestsize": hash byte count (Type: int),
"pubkey": public key (Type: List[bytes]),
"signature": signature (Type: List[bytes])
}
使用该数据,其他人可以验证您的消息的真实性:
# Another person or machine wants to verify your signature:
# get required hash function by comparing the name
# published with local implementaitons
if sig["hashalgo"] == "openssl_sha512":
hashfunc = winternitz.signatures.openssl_sha512
elif sig["hashalgo"] == "openssl_sha256":
hashfunc = winternitz.signautres.openssl_sha256
else:
raise NotImplementedError("Hash function not implemented")
wots_other = winternitz.signatures.WOTS(w=sig["w"], hashfunction=hashfunc,
digestsize=sig["digestsize"], pubkey=sig["pubkey"])
success = wots_other.verify(message=message, signature=sig["signature"])
print("Verification success: " + str(success))
# Output: Verification success: True
在某些情况下,可能不希望使用正在执行的 WOTS 对象中的公钥来验证派生的公钥。例如,当验证发生在包装结构(如 XMSS 树)中时,可能就是这种情况。在这种情况下,可以使用函数 wots.getPubkeyFromSignature(message=message, signature=signature)从消息和签名中派生公钥
WOTSPLUS
import winternitz.signatures
wotsplus = winternitz.signatures.WOTSPLUS()
message = "My message in bytes format".encode("utf-8")
sig = wotsplus.sign(message)
success = wotsplus.verify(message=message, signature=sig["signature"])
print("Verification success: " + str(success))
# Output: Verification success: True
如果您在 WOTSPLUS 的构造函数中没有指定任何值,它将使用 Winternitz 参数 16 并且哈希函数默认为sha256。它还需要一个伪随机函数,默认为HMAC-sha256,以及一个同样由熵生成的种子。有关函数及其参数的更多信息,请访问本文档中的模块参考。由于 WOTS+ 使用伪随机函数和种子来派生签名和公钥,因此它们也必须被发布。除了 WOTS 的签名之外,返回的 dict 还包含以下值:
{
# ...
"prf": pseudo random function (Type: str),
"seed": Seed used in prf (Type: bytes)
}
除了在 WOTS 中指定的参数之外,这些参数还必须在 WOTSPLUS 的构造函数中指定。
杂项
WOTS 类具有一些将在以下部分中解释的特性。
完全可配置
WOTS 类是完全可参数化的。您可以指定描述算法的论文中指定的任何内容,包括 Winternitz 参数、散列函数、伪随机函数 (WOTSPLUS)、种子 (WOTSPLUS)、私钥和公钥。同时指定私钥和公钥会导致公钥被丢弃。
按需生成密钥
如果未指定私钥或未指定公钥,则它们将设置为 None。wots+ 中的种子也是如此。只有在需要它们时,才会生成或派生它们。这意味着只要您不执行repr(obj)、str(obj)、obj1 == obj2、 obj1 != obj2、obj.pubkey、obj.privkey、obj.sign(...)或obj。 verify(...),其中 obj 是 WOTS 对象,键将保持为无。
WOTS 对象的代码表示
您可以调用repr(obj),其中 obj 是 WOTS 对象,以获取包含初始化另一个对象的所有信息的代码行,以便它等于 obj。执行obj2 = eval(repr(obj)) 会执行 repr(obj) 返回的代码,并最终将其副本存储在obj2中。
人类可读的字符串表示
您可以调用str(obj)来获取包含该对象的人类可读表示的字符串。
对象比较
您可以比较此类obj1 == obj2和obj1 != obj2中的两个对象
优化
代码经过精心编写以减少执行时间。它肯定不是完美的并且仍然可以优化,进一步的时间关键部分可以编码为 C 扩展,但是在当前状态下它应该提供相当有效的实现。它定义了__slots__以减少类内的执行时间和存储要求。并行化的实现是有计划的,但它只在使用巨大的 Winternitz 参数时才有用,因为如果你生成一个新进程,python 只能并行执行代码,并且派生一个新的 python 解释器的开销是不可忽略的。
笔记
这个项目是使用 PyScaffold 3.1 建立的。有关 PyScaffold 的详细信息和使用信息,请参阅https://pyscaffold.org/。
项目详情
下载文件
下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。
源分布
内置分布
Winternitz-1.0.2- py2.py3 -none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 2e54d88a96619a828170019ecd1fd226af4162a531f8852282b1b7e32db15893 |
|
MD5 | 051362623d498332b80a35c6d60d571f |
|
布莱克2-256 | 2f3d636adf5d3822d05d60c3a8a8e56dd1a99421270b4ddf2154444b25f785a8 |