36 个重大版本

0.37.0 2022年5月9日
0.36.0 2022年2月9日
0.35.0 2022年1月31日
0.32.0 2021年12月14日
0.14.0 2021年7月29日

#2435 in 加密学


用于 ockam_entity

Apache-2.0

145KB
3K SLoC

signature_bbs_plus

crate docs license discuss

Ockam 是一个用于构建与云服务和其它设备安全、私密且可信赖通信的库。

为了支持各种证明协议,这个库实现了 BBS+ 签名方案,可以用来生成关于签名属性和签名的零知识证明。

主要的 Ockam 库对这个库有可选依赖。

用法

将以下内容添加到你的 Cargo.toml

[dependencies]
signature_bbs_plus = "0.37.0"

库功能

[dependencies]
signature_bbs_plus = { version = "0.37.0" , default-features = false }

请注意,Cargo 功能在整个项目依赖图中是联合的。如果你依赖的其他库没有选择退出 signature_bbs_plus 的默认功能,即使你的直接依赖没有 default-features = false,Cargo 也会构建 signature_bbs_plus 并启用 std 功能。

API

生成密钥

BBS+ 方案允许签名者和持有者是两个不同的实体。这在 可验证凭证 情况中尤为常见。

要生成用于签名的新的密钥对,请调用 Issuer::new_keys API。短组签名允许使用单个密钥对一组消息进行签名。BBS+ 可以以更大的公钥为代价签任何数量的消息。此实现使用曲线 BLS12-381 和 Blake2b-512 作为哈希函数。

let (public_key, secret_key) = Issuer::new_keys(&mut rand::thread_rng())?;

消息生成器

消息生成器是 BBS+ 算法中输入的每个消息的加密信息。它们是从公钥派生出来的,并且键将用于签名的消息数量。

签名

要签名消息,请调用 Issuer::sign API。

let (public_key, secret_key) = Issuer::new_keys(&mut rand::thread_rng())?;
let num_messages = 4;
let generators = MessageGenerators::from_public_key(public_key, num_messages);
let messages = [
    Message::hash(b"message 1"),
    Message::hash(b"message 2"),
    Message::hash(b"message 3"),
    Message::hash(b"message 4"),
];

let signature = Issuer::sign(&secret_key, &generators, &messages)?;

盲签名

要创建盲签名,我们首先需要建立一个盲签名上下文。这是通过调用 Prover::new_blind_signature_context API 来完成的。此函数接受一个可选的预提交消息的切片。在这个例子中,使用了一个空的切片,表示没有预提交的消息。生成器、随机nonce和RNG也被使用。

有了上下文和密钥,通过调用 Issuer::blind_sign 来创建盲签名。

let nonce = Nonce::random(&mut rng);

let (context, blinding) =
    Prover::new_blind_signature_context(&mut [][..], &generators, nonce, &mut rng)?;
let mut messages = [
    (0, Message::hash(b"firstname")),
    (1, Message::hash(b"lastname")),
    (2, Message::hash(b"age")),
    (3, Message::hash(b"allowed")),
];

let blind_signature =
    Issuer::blind_sign(&context, &secret_key, &generators, &mut messages[..], nonce)?;

解盲签名

解盲签名使用盲签名上下文提供的 blinding 信息。函数 to_unblinded 接收 blinding 并返回一个 Signature

let signature = blind_signature.to_unblinded(blinding);

验证

签名解盲后,可以使用公钥来验证消息。这是通过调用 Signature::verify 函数来完成的。当验证成功时,调用 Choice::unwrap_u8 会返回 1。

let signature = blind_signature.to_unblinded(blinding);

let messages = [
    Message::hash(b"message 1"),
    Message::hash(b"message 2"),
    Message::hash(b"message 3"),
    Message::hash(b"message 4"),
];
let res = signature.verify(&public_key, &generators, messages.as_ref());
assert_eq!(res.unwrap_u8(), 1);

完整示例 - 盲签、解盲、验证

use short_group_signatures_core::{error::Error, lib::*};
use signature_bbs_plus::{Issuer, MessageGenerators, Prover};

fn main() -> Result<(), Error> {
    let mut rng = rand::thread_rng();
    let (public_key, secret_key) = Issuer::new_keys(&mut rng)?;
    let num_messages = 4;
    let generators = MessageGenerators::from_public_key(public_key, num_messages);
    let nonce = Nonce::random(&mut rng);

    let (context, blinding) =
        Prover::new_blind_signature_context(&mut [][..], &generators, nonce, &mut rng)?;
    let mut messages = [
        (0, Message::hash(b"firstname")),
        (1, Message::hash(b"lastname")),
        (2, Message::hash(b"age")),
        (3, Message::hash(b"allowed")),
    ];

    let blind_signature =
        Issuer::blind_sign(&context, &secret_key, &generators, &mut messages[..], nonce)?;

    let signature = blind_signature.to_unblinded(blinding);

    // Remove index
    let messages = [messages[0].1, messages[1].1, messages[2].1, messages[3].1];

    let res = signature.verify(&public_key, &generators, messages.as_ref());
    assert_eq!(res.unwrap_u8(), 1);
    Ok(())
}

许可证

此代码根据 Apache License 2.0 许可条款授权。

依赖关系

~5.5MB
~96K SLoC