Skip to content

BN254 G2 msgpack serialization bug in barretenberg-rs #1669

Description

@johnathan79717

Summary

Bn254G2Point in barretenberg-rs is missing serde_bytes annotations on its [Vec<u8>; 2] fields, causing msgpack serialization to produce arrays of integers instead of bin32 blobs. The C++ bbapi expects bin32 (via uint256_t::msgpack_unpack), so bn254_g2_mul calls fail with a deserialization abort.

Reported by Porco from Obsidion.

Details

Bn254G1Point works correctly because its Vec<u8> fields use #[serde(with = "serde_bytes")]:

pub struct Bn254G1Point {
    #[serde(with = "serde_bytes")]
    pub x: Vec<u8>,
    #[serde(with = "serde_bytes")]
    pub y: Vec<u8>,
}

Bn254G2Point is missing the equivalent annotation:

pub struct Bn254G2Point {
    pub x: [Vec<u8>; 2],  // no serde annotation
    pub y: [Vec<u8>; 2],  // no serde annotation
}

Without the annotation, rmp-serde serializes each Vec<u8> element as a msgpack array of integers rather than a bin32 blob.

Root cause

The Rust code generator (rust_codegen.ts) handles serde_bytes for bytes primitives and serde_array4_bytes for [Vec<u8>; 4] arrays, but has no handling for the field2 primitive type which maps to [Vec<u8>; 2].

Fix

  1. Add a serde_array2_bytes module (same pattern as existing serde_array4_bytes)
  2. Add needsSerdeArray2Bytes() detection for field2 primitive types in rust_codegen.ts
  3. Annotate Bn254G2Point fields with #[serde(with = "serde_array2_bytes")]

Affected versions

Every published version from 4.1.0-rc.2 through 5.0.0-private.20260319. There are no tests for bn254_g2_mul which is why this was never caught.

Metadata

Metadata

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