RustCrypto / RustCrypto/crypto-bigint

BoxedUint serialization portability issue across architectures

Open
#986 1 comment 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
309
Forks
95
Avg merge
1d 14h
Merged PRs (30d)
3

Description

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

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with BoxedUint::to_le_bytes(), from_le_slice(), and the serde encoding and decoding shown in the examples; inspect the linked src/uint/boxed/add_mod.rs path for the precision assumptions. Reproduce the cases on 32-bit and 64-bit targets, then add regression coverage showing portable byte and serde representations with matching precision and compatible arithmetic.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cryptography
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.