33个重大版本

0.35.0 2022年5月9日
0.34.0 2022年2月9日
0.33.0 2022年1月31日
0.30.0 2021年12月14日
0.12.0 2021年7月29日

#2444 in 密码学

Download history 33/week @ 2024-03-27 33/week @ 2024-04-03 8/week @ 2024-06-26 188/week @ 2024-07-03

196 每月下载量

Apache-2.0

150KB
3.5K SLoC

signature_ps

crate docs license discuss

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

为了支持各种证明协议,这个包实现了PS签名方案,可用于生成关于已签名属性及其签名的零知识证明。

使用方法

将其添加到你的 Cargo.toml

[dependencies]
signature_ps = "0.35.0"

包特性

[dependencies]
signature_ps = { version = "0.35.0" , default-features = false }

请注意,Cargo特性在整个项目依赖图范围内是并集的。如果任何其他你依赖的crate没有选择退出 signature_ps 默认特性,Cargo将启用std特性构建 signature_ps,无论你的直接依赖 signature_ps 是否有 default-features = false

API

生成密钥

PS方案允许签名者和持有者是两个不同的实体。这种情况很常见,尤其是在可验证凭证的情况下。

要为签名生成一个新的密钥对,请调用 Issuer::new_keys API。短组签名允许使用单个密钥对一组消息进行签名。PS可以签任何数量的消息,代价是更大的公钥。此实现使用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, &mut messages[..], nonce)?;

解盲签名

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

let signature = blind_signature.to_unblinded(blinding);

验证

一旦签名被解盲,就可以使用公钥来验证消息。这是通过调用 Signature::verify 函数来完成的。对 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_ps::{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_secret_key(num_messages, &secret_key);
    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, &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, messages.as_ref());
    assert_eq!(res.unwrap_u8(), 1);
    Ok(())
}

许可证

此代码根据 Apache License 2.0 许可。

依赖

~4.5MB
~87K SLoC