S3: GF(256) field + SLIP-39 Shamir split/recover#110
Draft
SachinMeier wants to merge 2 commits into
Draft
Conversation
SachinMeier
force-pushed
the
sachin--slip39-3-gf256-shamir
branch
from
July 2, 2026 04:22
595d728 to
6360071
Compare
Collaborator
Author
|
Independent adversarial review (subagent) complete: math verified clean — exhaustive 65,536-pair Addressed in the follow-up commit:
|
Add Bitcoinex.SLIP39.GF256: arithmetic over GF(2^8) with the Rijndael
polynomial 0x11B. exp/log tables are generated in the module body at
compile time from generator 3 (with compile-time assertions that the
exp cycle closes at 255 and covers every nonzero element), plus
add/2, mul/2, divide/2, pow/2, and byte-lane-wise Lagrange
interpolate/2 per the SLIP-0039 formula.
Add Bitcoinex.SLIP39.Shamir: split_secret/4 and recover_secret/2 with
the SLIP-0039 digest scheme (secret at index 255, digest share at 254,
digest = HMAC-SHA256(random_part, secret)[0..3] ++ random_part),
create_digest/2 / valid_digest?/2, {:error, :invalid_digest} on wrong,
corrupted, or under-threshold share sets, and the threshold == 1
verbatim-copy case. Randomness is injected via an rng function;
production callers must pass a CSPRNG.
Tests cover the FIPS-197 known answer (0x57 * 0x13 == 0xFE), a full-
field cross-check against an independent slow multiplication, division
by zero raising ArithmeticError, algebraic properties (commutativity,
distributivity, inverses, Fermat), interpolation of known polynomials
from any T-subset of points, Shamir round-trips for (2,3)/(3,5)/(2,2)/
(16,16) over every T-subset with 16- and 32-byte secrets, digest
rejection of corrupted or insufficient shares, and property tests with
a deterministic rng stub (no CSPRNG in tests).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- cap split_secret count at 16 in the clause guards (fail closed: an
uncapped count would emit the secret verbatim as the share at the
anchor index 255)
- recover_secret rejects duplicate share indices with
{:error, :duplicate_share_indices} instead of silently interpolating
a wrong value that only the digest would catch
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
SachinMeier
force-pushed
the
sachin--slip39-2-bip39
branch
from
July 2, 2026 04:27
9896406 to
6b4eeab
Compare
SachinMeier
force-pushed
the
sachin--slip39-3-gf256-shamir
branch
from
July 2, 2026 04:27
6360071 to
d77750f
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.
Stack: S0 → S1 → S2 → S3 → S4 → S5 → S6 (spec §3.4, §3.5)
Bitcoinex.SLIP39.GF256: Rijndael-poly (0x11B) field; exp/log tables generated in the module body at compile time with compile-time assertions that the generator-3 cycle is exactly 255;add/mul/divide/pow/interpolate(byte-lane Lagrange)Bitcoinex.SLIP39.Shamir:split_secret/4(digest share at 254, secret at 255, HMAC-SHA256 digest per SLIP-39),recover_secret/2rejecting bad share sets via:invalid_digest0x57·0x13=0xFEKAT verified against an independent slow multiply over the full 256×256 field; algebraic properties (commutativity, distributivity, Fermat); every-T-subset recovery for (2,3)/(3,5)/(2,2)/(16,16) on 16- and 32-byte secrets; corruption/under-threshold rejection. Deterministic rng stub in all tests.🤖 Generated with Claude Code