zkenc-core API 参考
zkenc-core 是提供见证加密密码学原语的 Rust 库。它作为基础层 - zkenc-cli 和 zkenc-js 都建构在这个核心库之上。
概览
zkenc-core 使用椭圆曲线密码学(BN254 曲线)实现 R1CS 电路的见证加密。它提供两个核心函数:
encap:生成见证加密的密钥decap:使用有效见证恢复密钥
安装
添加至您的 Cargo.toml:
[dependencies]
zkenc-core = { path = "../zkenc-core" }
ark-bn254 = "0.4"
ark-std = "0.4"
ark-serialize = "0.4"
核心类型
Ciphertext<E: Pairing>
代表见证加密密文。
pub struct Ciphertext<E: Pairing> {
// 内部字段为私有
}
属性:
- 可使用 arkworks 序列化进行序列化
- 大小:BN254 曲线约 1576 字节
- 可透过网络传送或存储至磁盘
Key
代表对称加密密钥。
pub struct Key {
// 内部:32 字节密钥
}
方法:
as_bytes() -> &[u8; 32]- 获取密钥的字节表示以进行 AES 加密
核心函数
encap
从电路生成见证加密的密文和密钥。
pub fn encap<E, C, R>(
circuit: C,
rng: &mut R,
) -> Result<(Ciphertext<E>, Key), EncapError>
where
E: Pairing,
C: ConstraintSynthesizer<E::ScalarField>,
R: RngCore + CryptoRng,
类型参数:
E- 椭圆曲线配对(通常为Bn254)C- 实现ConstraintSynthesizer的电路R- 随机数生成器
参数:
circuit- 已设置公开输入的电路实例rng- 密码学安全的随机数生成器
返回:
Ok((Ciphertext, Key))- 密文和生成的密钥Err(EncapError)- 如果电路合成失败
范例:
use zkenc_core::{encap, Ciphertext, Key};
use ark_bn254::Bn254;
use ark_std::rand::rngs::OsRng;
// 建立包含公开输入的电路
let mut circuit = MyCircuit::new();
circuit.set_public_input(42);
// 生成密文和密钥
let mut rng = OsRng;
let (ciphertext, key) = encap::<Bn254, _, _>(circuit, &mut rng)?;
// 序列化以供存储/传输
let mut ct_bytes = Vec::new();
ciphertext.serialize_compressed(&mut ct_bytes)?;
效能:
- 时间复杂度:O(n * log n),其中 n = 约束数量
- 内存:O(n) 用于约束系统
- 典型时间:50-500ms,取决于电路大小
decap
使用有效见证恢复加密密钥。
pub fn decap<E, C>(
circuit: C,
ciphertext: &Ciphertext<E>,
) -> Result<Key, DecapError>
where
E: Pairing,
C: ConstraintSynthesizer<E::ScalarField>,
类型参数:
E- 椭圆曲线配对(通常为Bn254)C- 实现ConstraintSynthesizer的电路
参数:
circuit- 已设置完整见证的电路实例ciphertext- 来自encap的密文
返回:
Ok(Key)- 恢复的加密密钥Err(DecapError)- 如果见证无效或不满足约束
范例:
use zkenc_core::{decap, Ciphertext, Key};
use ark_bn254::Bn254;
use ark_serialize::CanonicalDeserialize;
// 载入密文
let ct_bytes = std::fs::read("ciphertext.bin")?;
let ciphertext = Ciphertext::<Bn254>::deserialize_compressed(&ct_bytes[..])?;
// 建立包含完整见证的电路
let mut circuit = MyCircuit::new();
circuit.set_public_input(42);
circuit.set_private_input(123); // 见证
// 恢复密钥
let key = decap::<Bn254, _>(circuit, &ciphertext)?;
// 使用密钥进行解密
let key_bytes = key.as_bytes();
效能:
- 时间复杂度:O(n),其中 n = 约束数量
- 内存:O(n) 用于约束系统
- 典型时间:100-1000ms,取决于电路大小
错误类型
EncapError
封装期间可能发生的错误。
pub enum EncapError {
/// 电路合成失败
SynthesisError(SynthesisError),
/// 随机数生成失败
RngError,
}
DecapError
解封装期间可能发生的错误。
pub enum DecapError {
/// 电路合成失败
SynthesisError(SynthesisError),
/// 见证不满足约束
InvalidWitness,
/// 配对检查失败
PairingCheckFailed,
}
电路接口
要使用 zkenc-core,您的电路必须实现 ConstraintSynthesizer:
use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError};
pub struct MyCircuit<F: Field> {
pub public_input: Option<F>,
pub private_input: Option<F>,
}
impl<F: Field> ConstraintSynthesizer<F> for MyCircuit<F> {
fn generate_constraints(self, cs: ConstraintSystemRef<F>) -> Result<(), SynthesisError> {
// 配置公开输入
let pub_var = cs.new_input_variable(|| {
self.public_input.ok_or(SynthesisError::AssignmentMissing)
})?;
// 配置私密输入(见证)
let priv_var = cs.new_witness_variable(|| {
self.private_input.ok_or(SynthesisError::AssignmentMissing)
})?;
// 添加约束
// ... 您的电路逻辑
Ok(())
}
}
完整范例
这是一个完整的加密和解密范例:
use zkenc_core::{encap, decap};
use ark_bn254::Bn254;
use ark_ff::Field;
use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError};
use ark_r1cs_std::prelude::*;
use ark_serialize::{CanonicalSerialize, CanonicalDeserialize};
use ark_std::rand::rngs::OsRng;
// 定义电路
#[derive(Clone)]
struct SimpleCircuit {
pub_input: Option<u64>,
priv_input: Option<u64>,
}
impl ConstraintSynthesizer<ark_bn254::Fr> for SimpleCircuit {
fn generate_constraints(
self,
cs: ConstraintSystemRef<ark_bn254::Fr>,
) -> Result<(), SynthesisError> {
use ark_bn254::Fr;
// 公开输入
let pub_var = cs.new_input_variable(|| {
self.pub_input.map(Fr::from).ok_or(SynthesisError::AssignmentMissing)
})?;
// 私密见证
let priv_var = cs.new_witness_variable(|| {
self.priv_input.map(Fr::from).ok_or(SynthesisError::AssignmentMissing)
})?;
// 约束:pub + priv = 常数
cs.enforce_constraint(
lc!() + pub_var + priv_var,
lc!() + Variable::One,
lc!() + (165u64, Variable::One), // pub + priv = 165
)?;
Ok(())
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 加密
println!("加密中...");
// 建立仅包含公开输入的电路
let encrypt_circuit = SimpleCircuit {
pub_input: Some(42),
priv_input: None, // 加密不需要
};
// 封装
let mut rng = OsRng;
let (ciphertext, key) = encap::<Bn254, _, _>(encrypt_circuit, &mut rng)?;
println!("生成的密钥:{:?}", key.as_bytes());
// 序列化密文
let mut ct_bytes = Vec::new();
ciphertext.serialize_compressed(&mut ct_bytes)?;
std::fs::write("ciphertext.bin", &ct_bytes)?;
// 使用密钥进行 AES 加密
let message = b"秘密消息";
// ... 使用 key.as_bytes() 加密消息 ...
// 解密
println!("\n解密中...");
// 载入密文
let ct_bytes = std::fs::read("ciphertext.bin")?;
let ciphertext = Ciphertext::<Bn254>::deserialize_compressed(&ct_bytes[..])?;
// 建立包含完整见证的电路
let decrypt_circuit = SimpleCircuit {
pub_input: Some(42),
priv_input: Some(123), // 必须满足:42 + 123 = 165
};
// 解封装
let recovered_key = decap::<Bn254, _>(decrypt_circuit, &ciphertext)?;
println!("恢复的密钥:{:?}", recovered_key.as_bytes());
// 验证密钥是否相符
assert_eq!(key.as_bytes(), recovered_key.as_bytes());
println!("✅ 密钥相符!");
Ok(())
}
与其他工具整合
与 zkenc-cli 整合
zkenc-cli 内部使用 zkenc-core:
use zkenc_core::{encap, decap};
use zkenc_cli::circuit::CircomCircuit;
// 载入 R1CS 电路
let circuit = CircomCircuit::from_r1cs("circuit.r1cs")?;
// 封装
let (ciphertext, key) = encap::<Bn254, _, _>(circuit, &mut rng)?;
与自定义电路整合
// 您的自定义电路
impl ConstraintSynthesizer<Fr> for MyCircuit {
fn generate_constraints(/* ... */) -> Result<(), SynthesisError> {
// 您的约束
}
}
// 与 zkenc-core 一起使用
let circuit = MyCircuit::new(/* 参数 */);
let (ct, key) = encap::<Bn254, _, _>(circuit, &mut rng)?;
效能提示
- 电路最佳化:最小化约束以加快操作速度
- 批处理操作:尽可能重复使用电路编译
- 内存管理:使用压缩序列化以减少大小
- 平行处理:encap/decap 可在多个消息之间平行化
曲线选择
目前,zkenc-core 默认使用 BN254 曲线:
use ark_bn254::Bn254;
let (ct, key) = encap::<Bn254, _, _>(circuit, &mut rng)?;
未来版本可能支持额外的曲线(BLS12-381 等)。
安全性考量
- RNG 安全性:始终使用密码学安全的 RNG(
OsRng) - 见证隐私:永远不要暴露私密见证值
- 电路正确性:确保电路正确执行约束
- 密钥使用:使用适当的对称加密(AES-256-GCM)来使用密钥
下一步
- zkenc-cli API → - 命令行界面
- zkenc-js API → - JavaScript 绑定
- 快速入门 → - 快速入门指南