Skip to content

BoxedUint serialization portability issue across architectures #986

@elichai

Description

@elichai

When using BoxedUint with a precision that isn't a multiple of 64 (or closer to that than a multiple of 32) then serializing on a 64 bit machines will fail deserializing on 32 bit machine, and if used in a hashing scenario they'll have incompatible hashing,

Issue 1, using to_*bytes()
On 64 bit machines:

let one = BoxedUint::one_with_precision(32);
assert_eq!(&*one.to_le_bytes(), &[1, 0, 0, 0, 0, 0, 0, 0]);

on 32 bit machines:

let buf = [1, 0, 0, 0, 0, 0, 0, 0];
let back = BoxedUint::from_le_slice(&buf, 32);
assert_eq!(back, Err(DecodeError::InputSize));

When using serde, the problem is increasing the bit precision.

On 64 bit machines:

let one: BoxedUint = BoxedUint::one_with_precision(32);
let bincoded = bincode::serde::encode_to_vec(&one, bincode::config::standard()).unwrap();
assert_eq!(bincoded, vec![8, 1, 0, 0, 0, 0, 0, 0, 0]);

On 32 bit machines:

let one = BoxedUint::one_with_precision(32);
let from_network = [8, 1, 0, 0, 0, 0, 0, 0, 0]; // bincode of `1` in 64 bit machines.
let (one_network, _) = bincode::serde::decode_from_slice::<BoxedUint, _>(&from_network,bincode::config::standard()).unwrap();
assert_eq!(one.bits_precision(), 32);
assert_eq!(one_network.bits_precision(), 64);

You can see that now they have incompatible bits precision even though they were both initialized with BoxedUint::one_with_precision(32) and things like BoxedUint::add_mod will fail

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions