Skip to content

fix: adopt upstream NUT-13 improvements (big.Int + collision detection) - #8

Merged
Amperstrand merged 1 commit into
mainfrom
fix/adopt-upstream-nut13-improvements
Jul 25, 2026
Merged

fix: adopt upstream NUT-13 improvements (big.Int + collision detection)#8
Amperstrand merged 1 commit into
mainfrom
fix/adopt-upstream-nut13-improvements

Conversation

@Amperstrand

Copy link
Copy Markdown

Summary

Adopts lescuer97's NUT-13 improvements from elnosh/gonuts upstream (PRs #146, #147) into our fork.

Changes

keysetIdToBigInt() replaces SHA-256 hash approach

  • Before: V2 keyset IDs (>8 bytes) were hashed with SHA-256, then first 8 bytes converted to uint64. Worked but was a workaround.
  • After: Uses math/big.Int to parse keyset IDs of any length, supports both hex and base64 formats, then applies modulo 2^31-1. Cleaner, no overflow risk, handles edge cases properly.

CheckCollidingKeysets() — new collision detection

Verifies that keyset IDs don't collide after modulo reduction. Two different keyset IDs that produce the same BIP32 derivation path would cause silent secret reuse — this function detects and prevents that.

Test Results

=== RUN   TestSecretDerivation           --- PASS (existing V1 test, confirms backward compat)
=== RUN   TestDeriveKeysetPath_V2KeyId   --- PASS (66-char V2 keyset ID)
=== RUN   TestKeysetIdToBigInt_HexInput  --- PASS
=== RUN   TestKeysetIdToBigInt_V2HexInput --- PASS
=== RUN   TestCheckCollidingKeysets_NoCollision --- PASS
=== RUN   TestCheckCollidingKeysets_ExactMatch   --- PASS
=== RUN   TestCheckCollidingKeysets_ModuloCollision --- PASS

Full suite: all 17 packages pass.

Why adopt from upstream?

elnosh/gonuts is the original repository. lescuer97 contributed these improvements in August 2025. Our fork (OpenTollGate/gonuts-tollgate) is the active fork for TollGate, but we should stay close to upstream where possible. This change is strictly better than our SHA-256 hash workaround.

Replaces SHA-256 hash approach for V2 keyset ID derivation with
math/big.Int based keysetIdToBigInt() from elnosh/gonuts upstream
(lescur97's PRs elnosh#146, elnosh#147). The big.Int approach is cleaner, handles
arbitrary-length IDs without overflow risk, and supports both hex and
base64 keyset ID formats.

Adds CheckCollidingKeysets() to detect keyset ID collisions after modulo
reduction — prevents two different keyset IDs from mapping to the same
BIP32 derivation path.

Adopted from: elnosh#146
             elnosh#147

6 new tests: V2 keyset derivation, hex/base64 parsing, collision detection.
@Amperstrand
Amperstrand merged commit 62313cc into main Jul 25, 2026
5 checks passed
@Amperstrand
Amperstrand deleted the fix/adopt-upstream-nut13-improvements branch July 25, 2026 12:23
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