为什么 Rust/sodiumoxide PublicKeys 在序列化时以长度为前缀?
Why do Rust/sodiumoxide PublicKeys get prefixed with a length when serialised?
氧化钠 defines PublicKey
为:
new_type! {
/// `PublicKey` for signatures
public PublicKey(PUBLICKEYBYTES);
}
The new_type
macro 扩展为:
pub struct $name(pub [u8; $bytes]);
因此,PublicKey
被定义为 32 字节的简单包装器。
当我定义自己的 32 字节包装器 (MyPubKey
) 时,它会将 bincode 序列化为 32 字节。
当我对序列化 PublicKey
进行二进制编码时,它是 40 个字节 - 32 个字节以包含长度的小端 u64
为前缀。
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate bincode;
extern crate sodiumoxide;
use sodiumoxide::crypto::{sign, box_};
use bincode::{serialize, deserialize, Infinite};
#[derive(Serialize, Deserialize, PartialEq, Debug)]
pub struct MyPubKey(pub [u8; 32]);
fn main() {
let (pk, sk) = sign::gen_keypair();
let arr: [u8; 32] = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31];
let mpk = MyPubKey(arr);
let encoded_pk: Vec<u8> = serialize(&pk, Infinite).unwrap();
let encoded_arr: Vec<u8> = serialize(&arr, Infinite).unwrap();
let encoded_mpk: Vec<u8> = serialize(&mpk, Infinite).unwrap();
println!("encoded_pk len:{:?} {:?}", encoded_pk.len(), encoded_pk);
println!("encoded_arr len:{:?} {:?}", encoded_arr.len(), encoded_arr);
println!("encoded_mpk len:{:?} {:?}", encoded_mpk.len(), encoded_mpk);
}
结果:
encoded_pk len:40 [32, 0, 0, 0, 0, 0, 0, 0, 7, 199, 134, 217, 109, 46, 34, 155, 89, 232, 171, 185, 199, 190, 253, 88, 15, 202, 58, 211, 198, 49, 46, 225, 213, 233, 114, 253, 61, 182, 123, 181]
encoded_arr len:32 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
encoded_mpk len:32 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
用氧化钠的 new_type!
宏创建的 PublicKey
类型和 MyPublicKey
类型有什么区别?
如何从 PublicKey
中取出 32 个字节以便我可以有效地序列化它们?
这取决于 implementation of the serialization。 sodiumoxide 已选择通过将类型转换为切片然后序列化来实现 all 序列化:
#[cfg(feature = "serde")]
impl ::serde::Serialize for $newtype {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: ::serde::Serializer
{
serializer.serialize_bytes(&self[..])
}
}
由于切片在编译时没有已知的大小,序列化 必须 包括长度以便反序列化可以发生。
您或许可以实现自己的 serialization for a remote type 甚至直接序列化内部字段:
serialize(&pk.0, Infinite)
氧化钠 defines PublicKey
为:
new_type! {
/// `PublicKey` for signatures
public PublicKey(PUBLICKEYBYTES);
}
The new_type
macro 扩展为:
pub struct $name(pub [u8; $bytes]);
因此,PublicKey
被定义为 32 字节的简单包装器。
当我定义自己的 32 字节包装器 (MyPubKey
) 时,它会将 bincode 序列化为 32 字节。
当我对序列化 PublicKey
进行二进制编码时,它是 40 个字节 - 32 个字节以包含长度的小端 u64
为前缀。
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate bincode;
extern crate sodiumoxide;
use sodiumoxide::crypto::{sign, box_};
use bincode::{serialize, deserialize, Infinite};
#[derive(Serialize, Deserialize, PartialEq, Debug)]
pub struct MyPubKey(pub [u8; 32]);
fn main() {
let (pk, sk) = sign::gen_keypair();
let arr: [u8; 32] = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31];
let mpk = MyPubKey(arr);
let encoded_pk: Vec<u8> = serialize(&pk, Infinite).unwrap();
let encoded_arr: Vec<u8> = serialize(&arr, Infinite).unwrap();
let encoded_mpk: Vec<u8> = serialize(&mpk, Infinite).unwrap();
println!("encoded_pk len:{:?} {:?}", encoded_pk.len(), encoded_pk);
println!("encoded_arr len:{:?} {:?}", encoded_arr.len(), encoded_arr);
println!("encoded_mpk len:{:?} {:?}", encoded_mpk.len(), encoded_mpk);
}
结果:
encoded_pk len:40 [32, 0, 0, 0, 0, 0, 0, 0, 7, 199, 134, 217, 109, 46, 34, 155, 89, 232, 171, 185, 199, 190, 253, 88, 15, 202, 58, 211, 198, 49, 46, 225, 213, 233, 114, 253, 61, 182, 123, 181]
encoded_arr len:32 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
encoded_mpk len:32 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
用氧化钠的 new_type!
宏创建的 PublicKey
类型和 MyPublicKey
类型有什么区别?
如何从 PublicKey
中取出 32 个字节以便我可以有效地序列化它们?
这取决于 implementation of the serialization。 sodiumoxide 已选择通过将类型转换为切片然后序列化来实现 all 序列化:
#[cfg(feature = "serde")]
impl ::serde::Serialize for $newtype {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: ::serde::Serializer
{
serializer.serialize_bytes(&self[..])
}
}
由于切片在编译时没有已知的大小,序列化 必须 包括长度以便反序列化可以发生。
您或许可以实现自己的 serialization for a remote type 甚至直接序列化内部字段:
serialize(&pk.0, Infinite)