Fix GrindKey() key derivation in Go implementation#106
Open
Ehsan-saradar wants to merge 1 commit into
Open
Conversation
GrindKey() diverged from the reference grind_key (paradex-py / paradex.js) in several ways, producing keys that did not match other SDKs: 1. Inverted range check (issue tradeparadex#102): the loop used `< 0`, looping while the key was already in range and accepting out-of-range keys. Rejection sampling requires grinding *while* the key is out of range, so the condition is now `>= 0`. 2. SHA256_EC_MAX_DIGEST was built from a string literal containing spaces, which big.Int.SetString rejects (ok=false) while the unchecked return left the value at 0. That 0 silently masked bug tradeparadex#1 (a hash is never < 0, so the loop never ran) and would have caused an infinite loop once the condition was flipped. Compute 2^256 directly instead. 3. The index was hex-encoded with `%02x`, which stops keeping the length even past 255 (e.g. 256 -> "100" vs the reference "0100"). Pad to an even number of hex digits, matching padded_hex. 4. The seed was not padded to even length, so an odd-length seed panicked in hex.DecodeString. Pad it the same way. Add utils_test.go pinning GrindKey output to golden values generated from the paradex-py reference, plus range and hex-prefix checks. Fixes tradeparadex#102
Ehsan-saradar
force-pushed
the
fix/grindkey-range-check-102
branch
from
June 16, 2026 09:33
f48d912 to
1b0c4cb
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
GrindKey()in the Go sample diverged from the referencegrind_key(paradex-py / paradex.js), so it produced Stark private keys that did not match the other SDKs for the same Ethereum signature. This fixes the divergence (closes #102) and adds tests pinning the output to reference values.Bugs fixed
Inverted range check ([BUG] - GrindKey() in Go Implementation #102). The grind loop used
key.Cmp(maxAllowedVal) < 0, looping while the key was already in range and accepting out-of-range keys. Rejection sampling requires grinding while the key is out of range, so the condition is now>= 0.SHA256_EC_MAX_DIGESTwas silently zero. It was parsed from a string literal containing spaces, whichbig.Int.SetStringrejects (ok=false); the unchecked return left the value at0. That0masked bug Add example for Paradex onboarding and authentication #1 (a hash is never< 0, so the buggy loop never ran) and would have turned into an infinite loop once the condition was flipped. It is now computed directly as2^256viaLsh.Index hex padding. The index was encoded with
%02x, which only guarantees even length up to 255 (e.g.256 -> "100"vs the reference"0100"). It is now padded to an even number of hex digits, matchingpadded_hex.Seed hex padding. The seed was not padded to even length, so an odd-length seed panicked in
hex.DecodeString. It is padded the same way.Tests
Adds
go/utils_test.gowith golden values generated from the paradex-py reference (grind_key), plus range and0x-prefix checks. Verified the tests fail against the previous behavior and pass with this fix.Fixes #102