axelarnetwork / tofn

A threshold cryptography library in Rust
Apache License 2.0
110 stars 23 forks source link

feat: serde for Scalar in only 32 bytes #178

Closed ggutoski closed 2 years ago

ggutoski commented 2 years ago

Currently our serde implementation for k256::Scalar prepends length information to the serialized scalar. All scalars are known to be 32 bytes so this length information is a waste of space. This PR modifies the serde implementation to achieve a 32-byte encoding.

I did not do the same thing for curve points because

  1. Curve point encodings can have different byte lengths (1 for point at infinity, 33 for compressed, 65 for uncompressed). We could enforce a compressed-only policy (and disallow the point at infinity), but...
  2. serde implements Serialize and Deserialize for arrays of length 32 or less. To support larger lengths we'd need to implement these traits ourselves or use something like https://github.com/est31/serde-big-array . Arrays of larger length will be supported when Rust finally stabilizes const generics but for now it's not worth the hassle.

Unfortunately, the space savings in GG20 is only a few bytes each round. :/

tarcieri commented 2 years ago

I'd like to get something to address this upstream into elliptic-curve, but it's proven to be a particularly tricky problem.

Notably optimizing for compact representations in bincode has resulted in larger representations in other binary formats like CBOR. See:

https://github.com/RustCrypto/signatures/issues/336

We ended up optionally adopting the serde_bytes crate to handle the serialization, although ideally I think it would be nice if it could be addressed without an additional dependency.

ggutoski commented 2 years ago

Notably optimizing for compact representations in bincode has resulted in larger representations in other binary formats like CBOR.

Wow, that's frustrating. My first reaction is that this is a fault of CBOR (or perhaps of the serde model?). It seems outrageous that two binary formats can disagree so wildly on how to encode... binary data. 🤦