Skip to content

eth: preserve signed integer encodings - #135

Open
benma-agent wants to merge 1 commit into
BitBoxSwiss:masterfrom
benma-agent:benma-agent/eip712-signed-integers
Open

benma-agent wants to merge 1 commit into
BitBoxSwiss:masterfrom
benma-agent:benma-agent/eip712-signed-integers

Conversation

@benma-agent

@benma-agent benma-agent commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

EIP-712 intN values are sent as signed big-endian two's-complement bytes.
The JSON-number path strips the leading zero supplied by the signed BigInt
serializer, so e.g. int16(128) becomes -128 on the device. The string path
already preserves the sign correctly.

Use to_signed_bytes_be directly for JSON numbers as well, without stripping
its sign byte. Add boundary cases for positive values, negative values and
zero, checking that numeric and string inputs produce the same encoding.

Unsigned integer encoding and the firmware protocol are unchanged. No
firmware version gate is needed.

Related PRs:

EIP-712 intN values are sent as signed big-endian two's-complement bytes.
The JSON-number path strips the leading zero supplied by the signed BigInt
serializer, so e.g. int16(128) becomes -128 on the device. The string path
already preserves the sign correctly.

Use to_signed_bytes_be directly for JSON numbers as well, without stripping
its sign byte. Add boundary cases for positive values, negative values and
zero, checking that numeric and string inputs produce the same encoding.

Unsigned integer encoding and the firmware protocol are unchanged. No
firmware version gate is needed.

Related PRs:

- Go: BitBoxSwiss/bitbox02-api-go#189
- TypeScript: BitBoxSwiss/bitbox-api-ts#14
benma-agent added a commit to benma-agent/bitbox02-api-go that referenced this pull request Oct 2, 2026
EIP-712 intN values are sent as signed big-endian two's-complement bytes.
Using big.Int.Bytes for a positive value loses its sign when the most
significant bit is set, so e.g. int16(128) is interpreted as -128.

Serialize the shortest representation including a sign bit for both signs,
with one byte for zero. This also avoids redundant sign extension for
negative boundary values such as -128. Unsigned integer encoding is unchanged.

Add sign-boundary and width tests, plus a simulator regression that verifies
the signature against an independently computed EIP-712 digest. The encoding
uses the existing firmware protocol and needs no firmware version gate.

Related PRs:

- Rust: BitBoxSwiss/bitbox-api-rs#135
- TypeScript: BitBoxSwiss/bitbox-api-ts#14
benma-agent added a commit to benma-agent/bitbox-api-ts that referenced this pull request Oct 2, 2026
EIP-712 intN values are sent as signed big-endian two's-complement bytes.
The JavaScript-number path strips the leading zero supplied by the signed
serializer, so e.g. int16(128) becomes -128 on the device. String and bigint
inputs already preserve the sign correctly.

Use bigIntToSignedBytesBE directly for all accepted input types, without
stripping its sign byte. Add positive, negative and zero boundary cases that
check identical encodings for number, string and bigint inputs.

Unsigned integer encoding and the firmware protocol are unchanged. No
firmware version gate is needed.

Related PRs:

- Go: BitBoxSwiss/bitbox02-api-go#189
- Rust: BitBoxSwiss/bitbox-api-rs#135
@benma-agent
benma-agent force-pushed the benma-agent/eip712-signed-integers branch from 27a1a29 to b301470 Compare October 2, 2026 10:39
@benma
benma requested a review from Tomasvrba October 2, 2026 10:47
@benma
benma marked this pull request as ready for review October 2, 2026 10:47
benma-agent added a commit to benma-agent/bitbox02-api-go that referenced this pull request Oct 2, 2026
EIP-712 intN values are sent as signed big-endian two's-complement bytes.
Using big.Int.Bytes for a positive value loses its sign when the most
significant bit is set, so e.g. int16(128) is interpreted as -128.

Keep the existing two's-complement conversion. Prepend 0x00 to nonnegative
values when a sign byte is needed, and represent zero with one byte. Trim
redundant 0xff sign extension for negative values such as -128. Unsigned
integer encoding is unchanged.

Add sign-boundary and width tests, plus a simulator regression that verifies
the signature against an independently computed EIP-712 digest. The encoding
uses the existing firmware protocol and needs no firmware version gate.

Related PRs:

- Rust: BitBoxSwiss/bitbox-api-rs#135
- TypeScript: BitBoxSwiss/bitbox-api-ts#14

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant