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 密码学
196 每月下载量
150KB
3.5K SLoC
signature_ps
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