#匿名凭证 #零知识证明 #凭证 #消息认证 #零知识 #匿名 #加密解密

nightly no-std aeonflux

使用代数消息认证码(aMACs)、对称可验证加密和非交互式零知识证明,实现可组合、轻量级、快速的无限(aeon)重随机(flux)属性匿名凭证。

2个不稳定版本

0.2.0 2020年11月24日
0.1.0 2020年6月18日
0.0.0 2018年9月22日

#2024 in 密码学

每月 23次下载

BSD-3-Clause

130KB
2K SLoC

aeonflux

使用代数消息认证码(aMACs)、对称可验证加密和非交互式零知识证明,实现可组合、轻量级、快速的无限(aeon)重随机(flux)属性匿名凭证。

这些主要基于2019/1416中的凭证。

特性

目前,我们只支持公开凭证发行;即,用户在请求新凭证时,向发行方公开其凭证上的所有属性。在之后出示该凭证时,属性可以是隐藏的或公开的。

凭证属性可以是标量(群阶的整数模,一个大素数)或群元素。此库提供了一种将任意字节数组编码为群元素的方法,这些元素可以被加密和解密——以可逆方式存储任意字符串作为属性。

在凭证出示时被隐藏的群元素属性是对称加密的,这样用户可以在零知识中向发行方证明其正确性,同时与其他第三方共享对称解密密钥。这允许发行方在用户请求新凭证时执行某些外部验证个人信息(如电子邮件地址或电话号码),而发行方在之后无法追踪这些数据;然而,用户仍然可以与其他用户共享这些数据。另一个用例是存储共享密钥,这样所有可以访问密钥的用户都可以在以后以零知识证明其对该密钥的了解,从而允许进行任意命名空间和/或访问控制列表。

警告

虽然这个库是由密码学家创建的,但它尚未被任何其他密码学家审查。此外,尽管我可能是一名密码学家,但我很可能不是您的密码学家。使用风险自担。

使用

extern crate aeonflux;
extern crate curve25519_dalek;
extern crate rand;

use aeonflux::issuer::Issuer;
use aeonflux::parameters::IssuerParameters;
use aeonflux::parameters::SystemParameters;
use aeonflux::symmetric::Plaintext;
use aeonflux::symmetric::Keypair as SymmetricKeypair;
use aeonflux::user::CredentialRequestConstructor;

use curve25519_dalek::ristretto::RistrettoPoint;
use curve25519_dalek::scalar::Scalar;

use rand::thread_rng;

// First we set up an anonymous credential issuer.  We have to specify
// the number of attributes the credentials will have (here, 4),
// but not their type.
let mut rng = thread_rng();
let system_parameters = SystemParameters::generate(&mut rng, 4).unwrap();
let issuer = Issuer::new(&system_parameters, &mut rng);

// The issuer then publishes the `system_parameters` and the
// `issuer.issuer_parameters` somewhere publicly where users may obtain them.
let issuer_parameters = issuer.issuer_parameters.clone();

// A user creates a request for a new credential with some revealed
// attributes and sends it to the issuer.
let mut request = CredentialRequestConstructor::new(&system_parameters);

// Revealed scalars and revealed points count for one attribute each.
request.append_revealed_scalar(Scalar::random(&mut rng));
request.append_revealed_scalar(Scalar::random(&mut rng));
request.append_revealed_point(RistrettoPoint::random(&mut rng));

// Every 30 bytes of message uses one plaintext attribute. This plaintext
// message is exactly 30 bytes, so it accounts for one attribute total on the
// credential.  If it were one byte longer, it would account for two attributes.
let plaintexts = request.append_plaintext(&String::from("This is a tsunami alert test..").into_bytes());

// Hence we have 4 total attributes, as specified in the generation of the
// `system_parameters` above.
let credential_request = request.finish();

// The user now sends `credential_request` to the issuer, who may issue the
// credential, if seen fit to do so.
let issuance = issuer.issue(credential_request, &mut rng).unwrap();

// The issuer sends the `credential_issuance` to the user, who verifies the
// contained proof of correct issuance.
let mut credential = issuance.verify(&system_parameters, &issuer_parameters).unwrap();

// Optionally, upon showing the credential, the user can create a
// keypair and encrypt some or all of the attributes.  The master secret
// can be stored to regenerate the full keypair later on.  Encryption
// keys can be rotated to rerandomise the encrypted attributes.
let (keypair, master_secret) = SymmetricKeypair::generate(&system_parameters, &mut rng);

// For this presentation, we're going to encrypt the plaintext (the fourth attribute)
// and also mark the first attribute, a scalar, as being hidden. Remember that
// indexing starts at 0.
credential.hide_attribute(0);
credential.hide_attribute(3);

// The user now creates a presentation of the credential to give to the issuer.
let presentation = credential.show(&system_parameters, &issuer_parameters, Some(&keypair), &mut rng).unwrap();

// The user then sends this presentation to the issuer, who verifies it.
let verification = issuer.verify(&presentation);

assert!(verification.is_ok());

待办事项

  • [] 在隐藏群属性和加密的对应证明之间添加DLEQ证明。

依赖项

~2.9–4MB
~83K SLoC