Appendix B: Baseline Canonical Encoding (BCE) Specification

B.1 Type Encoding Table

Type Encoding Byte Size
bool 0x00 (false) or 0x01 (true) 1
u8 unsigned 8-bit integer 1
u16 unsigned 16-bit little-endian 2
u32 unsigned 32-bit little-endian 4
u64 unsigned 64-bit little-endian 8
u128 unsigned 128-bit little-endian 16
u256 unsigned 256-bit little-endian 32
bytes20 fixed 20-byte array (EVM address) 20
bytes32 fixed 32-byte array (Solana address) 32
string u32(length) + UTF-8 bytes 4 + length
option<T> 0x00 (None) \ 0x01 + T (Some) 1 + sizeof(T)
array<T> u32(length) + T[] (elements) 4 + length * sizeof(T)
map<K,V> u32(length) + sorted (K,V)[] pairs 4 + length * (sizeof(K) + sizeof(V))
fixedpoint64 signed 64-bit little-endian, implicit scale factor 8
null 0xFF 1

B.2 Fixed-Point Representation

BCE does not support IEEE 754 floating-point types. All real-valued quantities MUST be represented as fixedpoint64: a signed 64-bit integer with an implicit scale factor defined per field.

Why: IEEE 754 float64 introduces cross-implementation non-determinism — NaN bit patterns, rounding mode differences, denormalized number handling, and operation ordering all produce divergent byte representations for mathematically equivalent computations. Since voId = Keccak-256(BCE_ENCODE(...)), even a single bit difference causes replay failure.

Scale factor convention:

Domain Scale Factor Precision Range
SOL amounts 10^9 (lamports) 9 decimals ±9.2 × 10^9 SOL
Token counts / integers 10^0 (identity) exact ±9.2 × 10^18
Ratios and percentages 10^8 8 decimals ±92,233,720,368
Time (seconds) 10^0 (identity) exact ±9.2 × 10^18 s
Rates (per second) 10^12 12 decimals ±9,223,372
Standard deviation / scores 10^8 8 decimals ±92,233,720,368

Arithmetic rules for deterministic computation:

  1. All intermediate values MUST be computed in integer arithmetic (i64 or i128 for intermediates that may overflow i64).
  2. Division MUST use truncating integer division (round toward zero), not rounding.
  3. std_dev MUST be computed as: isqrt(sum((x_i - mean)^2 * SCALE^2) / n) where isqrt is integer square root (floor).
  4. If a denominator is zero, the result MUST be 0 (not NaN or Infinity).
  5. Scale factors are not stored in the encoding — they are defined by this specification per feature field.

Encoding: fixedpoint64 is encoded identically to a signed i64 little-endian (8 bytes). Decoders MUST apply the field's defined scale factor to recover the real value.

B.3 Object Encoding

Objects are encoded as sorted maps. Field keys are sorted lexicographically by UTF-8 byte order.

Example: ACCOUNT_BALANCE canonical form

Fields sorted: ["account", "balance", "mint", "slot"]

Encoding: map(4)
  + string("account") + bytes32(...)
  + string("balance") + u64(...)
  + string("mint")    + bytes32(...)
  + string("slot")    + u64(...)

B.4 Hash Computation

evidenceId = Keccak-256(canonicalForm)
voId       = Keccak-256(BCE_ENCODE(VerificationObject_content_fields))

results matching ""

    No results matching ""