3个版本 (重大更改)

0.4.0 2020年2月1日
0.3.0 2020年2月1日
0.2.0 2020年1月31日

#2203密码学

Apache-2.0

97KB
2K SLoC

Pixel: 前向安全的多重签名

  1. 基于论文 Pixel: 用于共识的多重签名
  2. 使用MIRACL的AMCL库
  3. 使用BLS12-381曲线。
  4. 可以通过编译时特性交换签名密钥和验证密钥之间的组(G1或G2)。
  5. 提供简单的密钥更新(下一个时间段的密钥)和快速前向密钥更新(未来任意时间的密钥)机制。
  6. 提供阈值签名机制。这虽然在论文中没有提到,但其思想与BLS签名相同。

概述

通过将时间划分为时间段并为每个时间段关联一个签名密钥来实现前向安全性。只保留当前时间段和任何必要的未来时间段的签名密钥。
签名密钥被组织成一棵完全二叉树的节点(内部和叶子),树的高度是对最大时间段的对数。因此,为了支持T时间段,创建了一个深度为d的树,因为此树中的节点总数将是2d+1 - 1。在论文和代码中,d+1被表示为l。然后以先序(根节点然后左子树然后右子树)的方式遍历树,并将节点分配与时间段相对应的编号。最初,为根节点生成签名密钥,但随着时间的推移,通过父节点(即时或外祖父母)生成子节点的签名密钥,并删除早于当前时间节点的密钥。

Binary tree with 7 nodes

以上是一个支持7个时间段的示例,因此T = 7。每个节点都有一个数字,用斜体表示的t表示。加粗的t表示从根节点到节点的路径,如果节点在父节点的左侧,则路径中添加1,否则添加2。最初,为t = 1(根)生成密钥。当时间推移到t = 2时,使用t=1(根)的密钥生成节点t = 2的密钥。现在需要删除t=1的密钥。但是不能删除它,因为只有它可以生成节点t=5的密钥,因为t=5只有一个父节点t=1。因此,先生成t=5的密钥,然后删除t=1的节点。在代码中,t=2和t=5被称为t=1节点的后继节点。当t=3时,生成节点t=3和t=4的密钥,并删除节点t=2。依此类推。

Binary tree with 15 nodes

另一个支持15个时间段的示例,所以T = 15。每个节点都有一个与时间段相对应的数字。最初为节点1(根)生成密钥。然后当t=2时,为节点2和9生成密钥,并删除节点1的密钥。当t=3时,删除节点2的密钥,但必须在为节点3和6生成密钥之后。当t=4时,由于需要删除父节点3,因此生成节点4和5的密钥。依此类推。
在快速前进的情况下,即签名人想要前进到不是立即下一个的时间段。比如说,签名人有t=1的签名密钥。现在他想要前进到t=3。他将推导出节点3、6和9的密钥(不需要推导节点2的密钥),然后删除节点1的密钥。

API

  1. 验证密钥可以使用VerkeyG1VerkeyG2功能分别保存在组G1或G2中。
  2. 存在一个表示一个时间段的签名密钥的Sigkey对象。签名人需要维护一组签名密钥。
  3. 这通过SigkeyManager对象来完成。SigkeyManager与实现SigKeyDb接口的数据库对象一起使用。SigkeyManager保存当前时间段,而SigKeyDb保存签名密钥。为了测试,提供了InMemorySigKeyDb,它实现了SigKeyDb并将密钥保存在内存哈希表中。SigkeyManager有方法可以增加1或快速前进更新到未来的任意时间。
    • 要前进到下一个时间段,请调用simple_update
    • 要前进到未来的任意时间,请调用fast_forward_update
    • 要获取当前密钥,请调用get_current_key
  4. 调用GeneratorSet::new函数以创建所需数量的生成器。
  5. 生成器创建后,调用Keypair::new来创建一个新的验证密钥,带有t=1的密钥和占有证明的SigkeyManager
  6. 调用Keypair::verify_pop来验证占有证明。
  7. 调用Signature::new在消息上生成一个非确定性的签名。这将导致每次调用此方法时,给定相同的密钥和相同的时间段会产生不同的签名。
  8. 调用Signature::new_deterministic在消息上生成一个确定性的签名。这将导致每次调用此方法时,给定相同的密钥和相同的时间段会产生相同的签名。
  9. 调用 Signature::verify 验证签名。
  10. 调用 Verkey::aggregate 聚合公钥。
  11. 调用 Signature::aggregate 聚合签名。
  12. 调用 Signature::verify_aggregated 通过传递所有公钥来验证聚合签名。
  13. 如果公钥已经聚合(调用 Verkey::aggregate),则调用 Signature::verify 验证聚合签名。
  14. 对于门限签名,使用 ThresholdScheme::aggregate_sigs 组合签名者的签名。要创建门限验证密钥,使用 ThresholdScheme::aggregate_vk

基准测试

有一些测试测量签名和密钥更新(简单和快速前进)的时间。这些测试的名称以 timing 开头。这些测试使用 15 或 19 的高度(l=16 或 l=20),因此它们分别支持 65535 和 1048575 个密钥。要运行所有这些测试,请执行

RUST_TEST_THREADS=1 cargo test --no-default-features --features VerkeyG2 -- --nocapture timing

或者保持验证密钥在 G1 组

RUST_TEST_THREADS=1 cargo test --no-default-features --features VerkeyG1 -- --nocapture timing

这将计算各种操作所需的时间。

依赖项

~6MB
~114K SLoC