Skip to content

Commit

Permalink
Use #[serde(rename)] to reduce the size taken by serialized data
Browse files Browse the repository at this point in the history
  • Loading branch information
sosthene-nitrokey committed Mar 25, 2024
1 parent becc5a3 commit 2295ebc
Show file tree
Hide file tree
Showing 2 changed files with 202 additions and 6 deletions.
9 changes: 7 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ trussed = { version = "0.1.0", features = ["serde-extensions"] }
[dev-dependencies]
quickcheck = { version = "1.0.3", default-features = false }
rand_core = { version = "0.6.4", default-features = false, features = ["getrandom"] }
serde_test = "1.0.176"
trussed = { version = "0.1.0", features = ["serde-extensions", "virt"] }
serde_cbor = { version = "0.11.2", features = ["std"] }
hex-literal = "0.4.1"

[patch.crates-io]
littlefs2 = { git = "https://github.com/Nitrokey/littlefs2", tag = "v0.3.2-nitrokey-2" }
trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "df720980888e3e0d5487250bd14a28db02a5f13b" }
littlefs2 = { git = "https://github.com/trussed-dev/littlefs2", rev = "ebd27e49ca321089d01d8c9b169c4aeb58ceeeca" }
trussed = { git = "https://github.com/Nitrokey/trussed.git", tag = "v0.1.0-nitrokey.17" }
serde-indexed = { git = "https://github.com/nitrokey/serde-indexed.git", rev = "37ba220526961fb8ba067d3fa18ee620337bb73b" }
cbor-smol = { git = "https://github.com/sosthene-nitrokey/cbor-smol.git", rev = "327f723d53263d4ac1da368660de4fe4aa8ebef8" }
199 changes: 195 additions & 4 deletions src/backend/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,24 +106,30 @@ pub(crate) type Key = ByteArray<KEY_LEN>;
/// to_presistent_storage(salt, wrapped_key);
/// }
/// ````
#[derive(Debug, Deserialize, Serialize)]
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
struct WrappedKeyData {
#[serde(rename = "w", alias = "wrapped_key")]
wrapped_key: Key,
#[serde(rename = "t", alias = "tag")]
tag: ChaChaTag,
}

#[derive(Debug, Deserialize, Serialize)]
// No need for using SerializeIndexed, cbor_smol already does it for enums
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
enum KeyOrHash {
Key(WrappedKeyData),
Hash(Hash),
}

#[derive(Debug, Deserialize, Serialize)]
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
pub(crate) struct PinData {
#[serde(skip)]
id: PinId,
#[serde(rename = "r", alias = "retries")]
retries: Option<Retries>,
#[serde(rename = "s", alias = "salt")]
salt: Salt,
#[serde(rename = "d", alias = "data")]
data: KeyOrHash,
}

Expand Down Expand Up @@ -438,9 +444,11 @@ impl Deref for PinDataMut<'_> {
}
}

#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq)]
struct Retries {
#[serde(rename = "m", alias = "max")]
max: u8,
#[serde(rename = "l", alias = "left")]
left: u8,
}

Expand Down Expand Up @@ -580,4 +588,187 @@ mod tests {
let serialized = trussed::cbor_serialize_bytes::<_, 1024>(&salt).unwrap();
assert!(serialized.len() <= SALT_LEN + 1, "{}", serialized.len());
}

#[test]
fn index_serialization() {
use serde_test::{assert_de_tokens, assert_tokens, Token};

let data = PinData {
id: PinId::from(0),
retries: None,
salt: [0xFE; SALT_LEN].into(),
data: KeyOrHash::Hash([0xED; HASH_LEN].into()),
};

assert_tokens(
&data,
&[
Token::Struct {
name: "PinData",
len: 3,
},
Token::Str("r"),
Token::None,
Token::Str("s"),
Token::Bytes(&[0xFE; SALT_LEN]),
Token::Str("d"),
Token::NewtypeVariant {
name: "KeyOrHash",
variant: "Hash",
},
Token::Bytes(&[0xED; HASH_LEN]),
Token::StructEnd,
],
);

assert_de_tokens(
&data,
&[
Token::Map { len: Some(3) },
Token::Str("retries"),
Token::None,
Token::Str("salt"),
Token::Bytes(&[0xFE; SALT_LEN]),
Token::Str("data"),
Token::Enum { name: "KeyOrHash" },
Token::U64(1),
Token::Bytes(&[0xED; HASH_LEN]),
Token::MapEnd,
],
);

let data = PinData {
id: PinId::from(0),
retries: Some(Retries { max: 3, left: 2 }),
salt: [0xFE; SALT_LEN].into(),
data: KeyOrHash::Hash([0xDE; HASH_LEN].into()),
};

assert_tokens(
&data,
&[
Token::Struct {
name: "PinData",
len: 3,
},
Token::Str("r"),
Token::Some,
Token::Struct {
name: "Retries",
len: 2,
},
Token::Str("m"),
Token::U8(3),
Token::Str("l"),
Token::U8(2),
Token::StructEnd,
Token::Str("s"),
Token::Bytes(&[0xFE; SALT_LEN]),
Token::Str("d"),
Token::NewtypeVariant {
name: "KeyOrHash",
variant: "Hash",
},
Token::Bytes(&[0xDE; HASH_LEN]),
Token::StructEnd,
],
);

assert_de_tokens(
&data,
&[
Token::Map { len: Some(3) },
Token::Str("retries"),
Token::Some,
Token::Map { len: Some(2) },
Token::Str("left"),
Token::U8(2),
Token::Str("max"),
Token::U8(3),
Token::MapEnd,
Token::Str("salt"),
Token::Bytes(&[0xFE; SALT_LEN]),
Token::Str("data"),
Token::Enum { name: "KeyOrHash" },
Token::U64(1),
Token::Bytes(&[0xDE; HASH_LEN]),
Token::MapEnd,
],
);

let data = PinData {
id: PinId::from(0),
retries: Some(Retries { max: 3, left: 2 }),
salt: [0xFE; SALT_LEN].into(),
data: KeyOrHash::Key(WrappedKeyData {
wrapped_key: [0xED; KEY_LEN].into(),
tag: [0xDC; CHACHA_TAG_LEN].into(),
}),
};

assert_tokens(
&data,
&[
Token::Struct {
name: "PinData",
len: 3,
},
Token::Str("r"),
Token::Some,
Token::Struct {
name: "Retries",
len: 2,
},
Token::Str("m"),
Token::U8(3),
Token::Str("l"),
Token::U8(2),
Token::StructEnd,
Token::Str("s"),
Token::Bytes(&[0xFE; SALT_LEN]),
Token::Str("d"),
Token::NewtypeVariant {
name: "KeyOrHash",
variant: "Key",
},
Token::Struct {
name: "WrappedKeyData",
len: 2,
},
Token::Str("w"),
Token::Bytes(&[0xED; KEY_LEN]),
Token::Str("t"),
Token::Bytes(&[0xDC; CHACHA_TAG_LEN]),
Token::StructEnd,
Token::StructEnd,
],
);

assert_de_tokens(
&data,
&[
Token::Map { len: Some(3) },
Token::Str("retries"),
Token::Some,
Token::Map { len: Some(2) },
Token::Str("left"),
Token::U8(2),
Token::Str("max"),
Token::U8(3),
Token::MapEnd,
Token::Str("salt"),
Token::Bytes(&[0xFE; SALT_LEN]),
Token::Str("data"),
Token::Enum { name: "KeyOrHash" },
Token::U64(0),
Token::Map { len: Some(2) },
Token::Str("wrapped_key"),
Token::Bytes(&[0xED; KEY_LEN]),
Token::Str("tag"),
Token::Bytes(&[0xDC; CHACHA_TAG_LEN]),
Token::MapEnd,
Token::MapEnd,
],
);
}
}

0 comments on commit 2295ebc

Please sign in to comment.