1 个不稳定版本
0.4.2 | 2024 年 5 月 26 日 |
---|
#887 in 加密学
54KB
1.5K SLoC
ark-serialize
ark-serialize
定义了用于将 Rust 数据结构序列化和反序列化为字节的 CanonicalSerialize
和 CanonicalDeserialize
特性。这些特性提供的接口专门针对加密对象进行序列化。特别是,它们为椭圆曲线元素的压缩表示提供特殊支持。大多数 arkworks-rs
中的类型都实现了这些特性。
用法
要使用 ark-serialize
,请将以下内容添加到您的 Cargo.toml
ark-serialize = "0.4"
如果您还希望为您的类型推导 CanonicalSerialize
和 CanonicalDeserialize
特性的实现,可以启用 derive
功能
ark-serialize = { version = "0.4", features = ["derive"] }
示例
让我们首先看看如何使用 ark-serialize
对现有类型进行操作
// We'll use the BLS12-381 pairing-friendly group for this example.
use ark_test_curves::bls12_381::{G1Projective as G1, G2Projective as G2, G1Affine, G2Affine};
use ark_serialize::{CanonicalSerialize, CanonicalDeserialize};
use ark_std::UniformRand;
let mut rng = ark_std::test_rng();
// Let's sample uniformly random group elements:
let a: G1Affine = G1::rand(&mut rng).into();
let b: G2Affine = G2::rand(&mut rng).into();
// We can serialize with compression...
let mut compressed_bytes = Vec::new();
a.serialize_compressed(&mut compressed_bytes).unwrap();
// ...and without:
let mut uncompressed_bytes = Vec::new();
a.serialize_uncompressed(&mut uncompressed_bytes).unwrap();
// We can reconstruct our points from the compressed serialization...
let a_compressed = G1Affine::deserialize_compressed(&*compressed_bytes).unwrap();
// ... and from the uncompressed one:
let a_uncompressed = G1Affine::deserialize_uncompressed(&*uncompressed_bytes).unwrap();
assert_eq!(a_compressed, a);
assert_eq!(a_uncompressed, a);
// If we trust the origin of the serialization
// (eg: if the serialization was stored on authenticated storage),
// then we can skip some validation checks, which can greatly reduce deserialization time.
let a_uncompressed_unchecked = G1Affine::deserialize_uncompressed_unchecked(&*uncompressed_bytes).unwrap();
let a_compressed_unchecked = G1Affine::deserialize_compressed_unchecked(&*compressed_bytes).unwrap();
assert_eq!(a_uncompressed_unchecked, a);
assert_eq!(a_compressed_unchecked, a);
如果我们想序列化自己的结构体,如果所有字段都实现了这些特性,我们可以为 CanonicalSerialize
和 CanonicalDeserialize
特性推导实现。例如
use ark_test_curves::bls12_381::{G1Affine, G2Affine};
use ark_serialize::{CanonicalSerialize, CanonicalDeserialize};
#[derive(CanonicalSerialize, CanonicalDeserialize)]
pub struct MyStruct {
a: G1Affine,
b: G2Affine,
}
我们也可以手动实现这些特性。例如
use ark_test_curves::bls12_381::{G1Affine, G2Affine};
use ark_serialize::{CanonicalSerialize, CanonicalDeserialize, Compress, SerializationError, Valid, Validate};
use ark_std::io::{Read, Write};
pub struct MyStruct {
a: G1Affine,
b: G2Affine,
}
impl CanonicalSerialize for MyStruct {
// We only have to implement the `serialize_with_mode` method; the other methods
// have default implementations that call the latter.
//
// Notice that `serialize_with_mode` takes `mode: Compress` as an argument. This
// is used to indicate whether we want to serialize with or without compression.
fn serialize_with_mode<W: Write>(&self, mut writer: W, mode: Compress) -> Result<(), SerializationError> {
self.a.serialize_with_mode(&mut writer, mode)?;
self.b.serialize_with_mode(&mut writer, mode)?;
Ok(())
}
fn serialized_size(&self, mode: Compress) -> usize {
self.a.serialized_size(mode) + self.b.serialized_size(mode)
}
}
impl CanonicalDeserialize for MyStruct {
// We only have to implement the `deserialize_with_mode` method; the other methods
// have default implementations that call the latter.
fn deserialize_with_mode<R: Read>(mut reader: R, compress: Compress, validate: Validate) -> Result<Self, SerializationError> {
let a = G1Affine::deserialize_with_mode(&mut reader, compress, validate)?;
let b = G2Affine::deserialize_with_mode(&mut reader, compress, validate)?;
Ok(Self { a, b })
}
}
// We additionally have to implement the `Valid` trait for our struct.
// This trait specifies how to perform certain validation checks on deserialized types.
// For example, we can check that the deserialized group elements are in the prime-order subgroup.
impl Valid for MyStruct {
fn check(&self) -> Result<(), SerializationError> {
self.a.check()?;
self.b.check()?;
Ok(())
}
}
依赖关系
~2–2.8MB
~54K SLoC