Skip to main content

Module primitive

Module primitive 

Source
Expand description

Canonical, order-preserving fixed-length byte encodings for the primitives bool, char, u8, i8, i16, i32, i64, u128, i128, the IEEE 754 floats f32 and f64, and byte arrays [u8; N].

Each impl emits the type’s native byte width — no padding:

  • bool, u8, i8 → [u8; 1]
  • i16, u16 → [u8; 2]
  • i32, u32, char, f32 → [u8; 4]
  • i64, u64, f64 → [u8; 8]
  • u128, i128 → [u8; 16]
  • [u8; N] → itself

Consumers that need a fixed wider encoding (e.g. an ORE construction whose plaintext block size is [u8; 8]) should zero-extend the orderable bytes upstream of the encrypter; widening is monotonic on lex order so it preserves the encoding’s guarantees.

§bool

Encoded as false → 0x00, true → 0x01. Already in lex order.

§Unsigned integers (u8, u16, u32, u64, u128)

Already in lex order — no sign-flip needed. Native big-endian.

§Signed integers (i8, i16, i32, i64, i128)

Each two’s-complement input is mapped to its unsigned equivalent by flipping the sign bit at its native width (x ^ (1 << (N-1))), then serialised big-endian. Sign-flipping moves negatives below positives (the sign bit 1 for negatives clears to 0, vice versa for positives) and preserves order within each sign class.

§char

Encoded as the big-endian bytes of the underlying u32 Unicode scalar value (*self as u32). Rust’s Ord impl for char compares by code point, and surrogate code points (U+D800..=U+DFFF) are not representable as char, so the native u32 lex order is exactly the order we need.

§IEEE 754 floats (f32, f64)

Each float is mapped to a lex-orderable unsigned integer of the same width (u32 for f32, u64 for f64) using the standard monotonic encoding:

  • Negatives flip every bit (their bit pattern’s lex order is the reverse of magnitude order, so flipping inverts it).
  • Positives (and +0.0) flip only the sign bit (bringing them above negatives in lex order).

-0.0 is canonicalised to +0.0 before encoding so the two compare byte-equal — matching -0.0 == 0.0 for IEEE 754.

NaN handling is unspecified. Floats implement PartialOrd rather than Ord (NaN compares unordered against every value, including itself), so the trait’s order/equality guarantees only apply to non-NaN inputs. Different NaN bit patterns will produce different bytes; consumers that need a canonical NaN must canonicalise upstream.