#bls-signatures #bls #bls12-381 #signature #ethereum #cryptography

no-std bls_on_arkworks

在Arkworks生态系统之上实现最新IETF草案的BLS签名的Rust crate

5个不稳定版本

0.3.0 2023年9月12日
0.2.2 2023年9月3日
0.2.1 2023年9月3日
0.2.0 2023年9月3日
0.1.0 2023年8月27日

#2830 in 神奇豆子

Download history 74/week @ 2024-03-13 115/week @ 2024-03-20 110/week @ 2024-03-27 45/week @ 2024-04-03 95/week @ 2024-04-10 21/week @ 2024-04-17 151/week @ 2024-04-24 120/week @ 2024-05-01 136/week @ 2024-05-08 276/week @ 2024-05-15 205/week @ 2024-05-22 279/week @ 2024-05-29 353/week @ 2024-06-05 361/week @ 2024-06-12 339/week @ 2024-06-19 401/week @ 2024-06-26

每月1,507次下载

MIT 许可证

59KB
695

BLS on Arkworks

MIT licensed crates.io Documentation

这个crate实现了最新IRTF草案的BLS签名: draft-irtf-cfrg-bls-signature-05,与Arkworks crates

目标

按重要性排序

  • 正确性:首先,这个库应该是正确的。这就是为什么它通过强大的单元测试套件进行测试。它还针对ethereum/bls12-381-tests中的案例进行了测试。请参阅tests/lib.rs
  • 规范遵从性:每个核心函数的文档都投入了大量精力,以便将其链接到相关的规范部分,并且代码引用了规范指令的步骤。类型、接口、函数名尽可能接近规范。与规范不符的地方用XXX标注。
  • 与Ethereum的兼容性:此crate生成的BLS签名应与Ethereum兼容(变体的选择请参见此处)。
  • 简洁性:虽然域分离标记不是硬编码的(我们需要灵活性来测试多种类型的测试向量),但我们硬编码了椭圆曲线(BLS12-381)、哈希函数(SHA-256)和变体(最小公钥大小)的选择。

用法

基本签名和验证

use bls_on_arkworks as bls;
use rand_core::{RngCore, OsRng};

// We start with 64 bytes of good randomness from the OS.
// ikm has to be at least 32 bytes long to be secure, but can be longer.
let mut ikm = [0u8; 64];
OsRng.fill_bytes(&mut ikm);

// Build a secret key from the random bytes.
// The secret key is a field element.
let secret_key = bls::keygen(&ikm.to_vec());

// Sign a message with the Ethereum Domain Separation Tag
let message = "message to sign".as_bytes().to_vec();
let dst = bls::DST_ETHEREUM.as_bytes().to_vec();

let signature = bls::sign(secret_key, &message, &dst).unwrap();


// Derive a public key from our secret key above...
let public_key = bls::sk_to_pk(secret_key);
// ...and verify the signature we just produced.
let verified = bls::verify(&public_key, &message, &signature, &dst);

聚合

此软件包支持聚合签名和验证

use bls_on_arkworks as bls;

// Load known hex bytes (instead of generating a new random secret key like in the previous example)
let sk1 = bls::os2ip(
    &vec![
        0x32, 0x83, 0x88, 0xaf, 0xf0, 0xd4, 0xa5, 0xb7,
        0xdc, 0x92, 0x05, 0xab, 0xd3, 0x74, 0xe7, 0xe9,
        0x8f, 0x3c, 0xd9, 0xf3, 0x41, 0x8e, 0xdb, 0x4e,
        0xaf, 0xda, 0x5f, 0xb1, 0x64, 0x73, 0xd2, 0x16,
    ]
);
let sk2 = bls::os2ip(
    &vec![
        0x47, 0xb8, 0x19, 0x2d, 0x77, 0xbf, 0x87, 0x1b,
        0x62, 0xe8, 0x78, 0x59, 0xd6, 0x53, 0x92, 0x27,
        0x25, 0x72, 0x4a, 0x5c, 0x03, 0x1a, 0xfe, 0xab,
        0xc6, 0x0b, 0xce, 0xf5, 0xff, 0x66, 0x51, 0x38,
    ]
);

// Sign a message with the Ethereum Domain Separation Tag
let dst = bls::DST_ETHEREUM.as_bytes().to_vec();
let message = "message to be signed by multiple parties".as_bytes().to_vec();

let first_signature = bls::sign(sk1, &message, &dst).unwrap();
let second_signature = bls::sign(sk2, &message, &dst).unwrap();

let aggregate = bls::aggregate(&vec![first_signature, second_signature]).unwrap();

// Derive a public key from our secret keys...
let pk1 = bls::sk_to_pk(sk1);
let pk2 = bls::sk_to_pk(sk2);
// ...and verify the aggregate signature we produced.
let verified = bls::aggregate_verify(
    vec![pk1, pk2],
    vec![message.clone(), message],
    &aggregate,
    &dst);

错误处理

所有错误都汇总在一个单一的 BLSError 枚举中。我们更倾向于基于 Result 的接口,而不是内部的 panic

测试

要运行测试

$ cargo test

tests/* 中的 JSON 测试用例定义是从 ethereum/[email protected] 中获取的。

代码风格检查(Clippy)

$ cargo clippy -- -D warnings

格式化

$ cargo fmt --

依赖关系

~7MB
~126K SLoC