2017-08-25 70 views
1

氧化鈉defines PublicKey爲:爲什麼Rust/sodiumdioxide PublicKeys在序列化時會以前綴長度爲前綴?

new_type! { 
    /// `PublicKey` for signatures 
    public PublicKey(PUBLICKEYBYTES); 
} 

The new_type macro擴展爲:

pub struct $name(pub [u8; $bytes]); 

因此,PublicKey被定義爲32個字節的簡單包裝。

當我定義自己的32字節封裝(MyPubKey)時,它將二進制序列化爲32個字節。

當我bincode serialise 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] 

是什麼PublicKey型,具有氧化鈉的new_type!宏和MyPublicKey類型創建區別?

如何從PublicKey中獲得32個字節,以便我可以有效地將其串行化?

+0

這可能是值得與氧化鈉開發商檢查,看看是否轉換爲片是故意的或他們是否可以代替連載數組直接。 – Shepmaster

回答

2

這取決於implementation of the serialization。氧化鈉已經選擇通過轉換類型的切片,然後序列化實現所有序列:

#[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)