Skip to content

Commit 397e7cc

Browse files
authored
core: implement ssz for all objects with tests (#14)
* core: implement ssz for all objects with tests * clippy * wip serializable objects * fix visibility * simplify by rm macro * simplify testing
1 parent 3f1117f commit 397e7cc

File tree

12 files changed

+1410
-174
lines changed

12 files changed

+1410
-174
lines changed

src/array.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use ssz::{Decode, DecodeError, Encode};
33
use std::ops::{Deref, DerefMut};
44

55
use crate::F;
6+
use crate::serialization::Serializable;
67
use p3_field::{PrimeCharacteristicRing, PrimeField32, RawDataSerializable};
78

89
/// A wrapper around an array of field elements that implements SSZ Encode/Decode.
@@ -86,6 +87,8 @@ impl<const N: usize> Decode for FieldArray<N> {
8687
}
8788
}
8889

90+
impl<const N: usize> Serializable for FieldArray<N> {}
91+
8992
impl<const N: usize> Serialize for FieldArray<N> {
9093
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
9194
where

src/inc_encoding.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use rand::Rng;
2-
use serde::{Serialize, de::DeserializeOwned};
32
use std::fmt::Debug;
43

54
use crate::MESSAGE_LENGTH;
5+
use crate::serialization::Serializable;
66

77
/// Trait to model incomparable encoding schemes.
88
/// These schemes allow to encode a message into a codeword.
@@ -17,8 +17,8 @@ use crate::MESSAGE_LENGTH;
1717
/// x = (x_1,..,x_k) and x' = (x'_1,..,x'_k) we have
1818
/// x_i > x'_i for all i = 1,...,k.
1919
pub trait IncomparableEncoding {
20-
type Parameter: Serialize + DeserializeOwned;
21-
type Randomness: Serialize + DeserializeOwned;
20+
type Parameter: Serializable;
21+
type Randomness: Serializable;
2222
type Error: Debug;
2323

2424
/// number of entries in a codeword

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub(crate) type PackedF = <F as Field>::Packing;
1717
pub(crate) mod array;
1818
pub(crate) mod hypercube;
1919
pub(crate) mod inc_encoding;
20+
pub mod serialization;
2021
pub mod signature;
2122
pub(crate) mod simd_utils;
2223
pub(crate) mod symmetric;

src/serialization.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//! A unified serialization implementation
2+
3+
use serde::{Serialize, de::DeserializeOwned};
4+
use ssz::{Decode, DecodeError, Encode};
5+
6+
/// A supertrait combining all serialization capabilities needed for leanSig types.
7+
pub trait Serializable: Serialize + DeserializeOwned + Encode + Decode + Sized {
8+
/// Converts this object to a canonical byte representation.
9+
///
10+
/// # Canonical Format
11+
///
12+
/// - All field elements are converted to canonical `u32` form (not Montgomery)
13+
/// - All `u32` values are encoded as 4 bytes in little-endian order
14+
///
15+
/// # Returns
16+
///
17+
/// A `Vec<u8>` containing the canonical byte representation of this object.
18+
fn to_bytes(&self) -> Vec<u8> {
19+
// TODO: Update this to not use SSZ internally.
20+
self.as_ssz_bytes()
21+
}
22+
23+
/// Parses an object from its canonical byte representation.
24+
///
25+
/// # Canonical Format
26+
///
27+
/// The input bytes must follow the same canonical format as `to_bytes()`:
28+
/// - Field elements as canonical `u32` values (4 bytes, little-endian)
29+
/// - Composite structures following SSZ layout rules
30+
///
31+
/// # Arguments
32+
///
33+
/// * `bytes` - The canonical binary data to parse
34+
///
35+
/// # Returns
36+
///
37+
/// - `Ok(Self)` if the bytes represent a valid object
38+
/// - `Err(DecodeError)` if the bytes are malformed or invalid
39+
fn from_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
40+
// TODO: Update this to not use SSZ internally.
41+
Self::from_ssz_bytes(bytes)
42+
}
43+
}
44+
45+
impl Serializable for [u8; 32] {}

src/signature.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
use std::ops::Range;
22

33
use crate::MESSAGE_LENGTH;
4+
use crate::serialization::Serializable;
45
use rand::Rng;
5-
use serde::{Serialize, de::DeserializeOwned};
6-
use ssz::{Decode, Encode};
76
use thiserror::Error;
87

98
/// Error enum for the signing process.
@@ -99,17 +98,21 @@ pub trait SignatureScheme {
9998
/// The key must be serializable to allow for network transmission and storage.
10099
///
101100
/// We must support SSZ encoding for Ethereum consensus layer compatibility.
102-
type PublicKey: Serialize + DeserializeOwned + Encode + Decode;
101+
type PublicKey: Serializable;
103102

104103
/// The secret key used for signing.
105104
///
106105
/// The key must be serializable for persistence and secure backup.
107-
type SecretKey: SignatureSchemeSecretKey + Serialize + DeserializeOwned;
106+
///
107+
/// We must support SSZ encoding for Ethereum consensus layer compatibility.
108+
type SecretKey: SignatureSchemeSecretKey + Serializable;
108109

109110
/// The signature object produced by the signing algorithm.
110111
///
111112
/// The signature must be serializable to allow for network transmission and storage.
112-
type Signature: Serialize + DeserializeOwned;
113+
///
114+
/// We must support SSZ encoding for Ethereum consensus layer compatibility.
115+
type Signature: Serializable;
113116

114117
/// The maximum number of epochs supported by this signature scheme configuration,
115118
/// denoted as $L$ in the literature [DKKW25a, DKKW25b].

0 commit comments

Comments
 (0)