Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
db3fca8
Integrate BNB tss-lib hardening
mswilkison May 17, 2026
4758b79
Address hardening review findings
mswilkison May 17, 2026
f2e1b3f
Address Gemini review cleanup
mswilkison May 17, 2026
78ca61d
Add session nonce helper and docs
mswilkison May 19, 2026
93e3cb4
Reject empty session nonce IDs
mswilkison May 19, 2026
a71b1cd
Extend session-tagged ModChallenge to full N-bit challenges
piotr-roslaniec May 19, 2026
92320a8
Validate signing constructor fullBytesLen at call site
piotr-roslaniec May 19, 2026
21efbe2
Fail closed when signing without SessionNonce
piotr-roslaniec May 19, 2026
762507e
Restore wire-format SSID broadcast in ECDSA resharing
piotr-roslaniec May 19, 2026
b6b48b2
Fail closed when keygen/resharing without SessionNonce
piotr-roslaniec May 19, 2026
78c9528
Pin party-context separation for AppendUint64ToBytesSlice
piotr-roslaniec May 19, 2026
c541bda
Validate resharing SSIDs before acceptance
mswilkison May 19, 2026
0835914
Address resharing and CI review findings
mswilkison May 19, 2026
7bf584b
Run Go CI on hardening branch pushes
mswilkison May 19, 2026
d0d3aed
Merge remote-tracking branch 'origin/master' into pr-2
mswilkison May 20, 2026
d2fe895
Address proof hardening review comments
mswilkison May 20, 2026
c62bf90
Stabilize tss-lib CI test setup
mswilkison May 20, 2026
ae7075f
Tighten hardening integration contracts
mswilkison May 20, 2026
caa64fc
Expand FactorProof invalid-base coverage
mswilkison May 20, 2026
d4555c8
Validate resharing modulus widths
mswilkison May 21, 2026
f2a959a
Stabilize malformed factor proof fixture
mswilkison May 21, 2026
8c235ef
Stabilize EdDSA keygen scalar test encoding
mswilkison May 21, 2026
56e25da
Document SetSessionNonceBytes entropy requirement
piotr-roslaniec May 23, 2026
16d848b
Document range proof acceptance of zero contribution
piotr-roslaniec May 23, 2026
630a7e5
Drop misleading legacy framing from ModChallenge docs
piotr-roslaniec May 23, 2026
5196025
docs: add CHANGELOG.md for BNB hardening integration
piotr-roslaniec Jun 15, 2026
11aa064
docs: remove BNB_HARDENING_INTEGRATION.md
piotr-roslaniec Jun 15, 2026
25ffef4
docs(changelog): trace entries to fork PRs
piotr-roslaniec Jun 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/gofmt.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
name: Go-fmt
on:
push:
branches:
- master
- release/*
pull_request:
branches:
- master
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
name: Go Test
on:
push:
branches:
- master
- release/*
pull_request:
branches:
- master
Expand Down
240 changes: 240 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
# Changelog

All notable changes to this fork (`threshold-network/tss-lib`) are documented here.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
This fork follows the upstream [`bnb-chain/tss-lib`](https://github.com/bnb-chain/tss-lib)
SemVer line for provenance but has not yet published its own tagged release; all changes
below are therefore listed under `[Unreleased]`.

Provenance notation. Each entry carries two kinds of reference:
- **Upstream source** — `BNB #NNN` / `BNB <sha>` is the upstream pull request or commit the
change was adapted from. Most were **manually adapted**, not cherry-picked, so behavior may
differ from upstream. `threshold-original` means there is no direct upstream counterpart.
- **Fork PR** — `PR #N` is the `threshold-network/tss-lib` pull request that introduced the
change into this fork, for traceability.

---

## [Unreleased] — BNB hardening integration

Security and correctness hardening ported or manually adapted from `bnb-chain/tss-lib`,
without replacing Threshold's existing Paillier/NTilde `ModProof`/`FactorProof` remediation.

- Threshold base: `2e712689cfbeefede15f95a0ec7112227d86f702`
- BNB upstream head compared: `3f677ff761fcf692edb0243a5d812930844d879a`

This unreleased set is delivered through a stack of fork pull requests. **Every entry below
belongs to PR #2 (the base BNB hardening integration) unless it is tagged with another
`PR #N`.** Composing PRs:
- **PR #2** — base BNB hardening integration.

### ⚠️ Compatibility — read before upgrading

**This release is a protocol/wire compatibility break and must be rolled out as a
coordinated protocol upgrade.** Fiat-Shamir proof challenges now use tagged hashing,
session context, and fixed-width message encoding. Parties running pre-upgrade code
**cannot** interoperate with upgraded parties in the same keygen, signing, or resharing
ceremony, even though the Go API remains source-compatible for nearly all call sites.

Do not mix pre- and post-upgrade parties in one ceremony. All participants (and, for
resharing, **both** committees) must run the upgraded build simultaneously.

Two new caller obligations are enforced at runtime (see Breaking Changes 1 and 2):
1. Set a per-ceremony session nonce before `Start()`.
2. Pass a positive `fullBytesLen` to every signing constructor.

### Breaking changes

#### 1. Session nonce is now mandatory and fails closed
- **What:** ECDSA keygen, ECDSA signing, ECDSA resharing, EdDSA keygen, and EdDSA signing
now require a positive session nonce. Each protocol's `Start()` (round 1) returns an
error if `Parameters.SetSessionNonce` / `SetSessionNonceBytes` was not called, e.g.
`"keygen requires tss.Parameters.SetSessionNonce(...) before Start"`
(`ecdsa/keygen/round_1.go`, `ecdsa/signing/round_1.go`,
`ecdsa/resharing/round_1_old_step_1.go`, `eddsa/keygen/round_1.go`,
`eddsa/signing/round_1.go`). The nonce is folded into the SSID that binds every proof
transcript. **EdDSA resharing is intentionally excluded** — it has no SSID-bound
transcript in this port (see Residual risks).
- **Break type:** Runtime (previously-succeeding honest callers now error) **and** wire
(proofs are now SSID-bound, so transcripts differ from pre-upgrade peers).
- **Motivation:** Without a unique per-ceremony SSID folded into every Fiat-Shamir
challenge, two ceremonies over otherwise-identical inputs derive the same SSID, enabling
cross-run transcript splicing / proof replay. Fail-closed prevents silently running
without session binding.
- **Provenance:** `BNB fc38979` (SSID uniqueness, `Parameters.SessionNonce`), with the
fail-closed-with-no-fallback decision being `threshold-original`. (Note: the threshold
base had no SSID machinery at all; the "previous zero / `SHA512_256(messageBytes)`
fallback" described in upstream history never shipped in this fork's base.)
- **Migration:** Before `Start()`, on the constructing goroutine, call
`params.SetSessionNonce(<unique positive *big.Int>)` or
`params.SetSessionNonceBytes(<>=16-byte high-entropy session ID>)`. All parties in a run
must agree on the same value.

#### 2. `fullBytesLen` is required at runtime for signing
- **What:** ECDSA and EdDSA signing constructors (`NewLocalParty`, `NewLocalPartyWithKDD`)
accept `fullBytesLen` as a **variadic** argument for source compatibility, but exactly
one **positive** value is now required at construction time and is bounded to
`[ceil(msg.BitLen()/8), curveOrderBytes]`. Passing none, zero, multiple, or an
out-of-range value panics in the constructor (`ecdsa/signing/local_party.go`,
`eddsa/signing/local_party.go`).
- **Break type:** Runtime (the variadic signature still compiles unchanged, but unupdated
callers panic at runtime).
- **Motivation:** Pins a fixed, ceremony-wide message byte width so leading zero bytes are
preserved. The previous minimal `big.Int.Bytes()` encoding silently dropped high-order
zero bytes, so distinct parties could hash different preimages for the "same" message.
- **Provenance:** `BNB #284` (`9acd90b`, `2f294cf`, `6b92e7d`, `c0de534`).
- **Migration:** Pass a positive `fullBytesLen` (the fixed message/hash width, e.g. `32`)
to every signing constructor call. The value must be identical across all signers.

#### 3. EdDSA round-3 hashes the full-length message
- **What:** EdDSA signing round 3 now hashes the message left-padded to `fullBytesLen`
(`m.FillBytes`) instead of the minimal `m.Bytes()` when deriving `lambda`
(`eddsa/signing/round_3.go`). This changes each signer's `s` share, hence the final
signature scalar, whenever `fullBytesLen` exceeds the message's minimal byte length.
- **Break type:** Wire/protocol (cross-version EdDSA signers compute incompatible shares
and produce an invalid aggregate signature).
- **Motivation:** Canonical fixed-width message encoding; removes the leading-zero
ambiguity of minimal encoding.
- **Provenance:** `BNB #284`.
- **Migration:** Upgrade all EdDSA signers in lockstep with an identical `fullBytesLen`.

#### 4. Tagged-hash / session-bound Fiat-Shamir challenges (DLN, Schnorr, MtA, range proof)
- **What:** Challenge derivation for DLN (`crypto/dlnproof`), Schnorr
(`crypto/schnorr`), MtA `ProofBob`/`ProofBobWC` (`crypto/mta/proofs.go`), and
`RangeProofAlice` (`crypto/mta/range_proof.go`) now uses length-delimited tagged hashing
(`common.SHA512_256i_TAGGED`) plus optional session context. **The challenge bytes change
unconditionally** — even on the default/nil-session path — because the underlying hash
construction itself changed. Per-party proof contexts also append a fixed-width `uint64`
party index so party 0 no longer collapses to the bare SSID.
- **Break type:** Wire/protocol (old and new proofs do not cross-verify).
- **Motivation:** Domain separation binds each proof to its session/sub-protocol context,
defeating cross-protocol and cross-session proof replay. The MtA path additionally binds
`NTilde, h1, h2` into the transcript so a malicious verifier cannot swap ring-Pedersen
parameters.
- **Provenance:** `BNB #252` (`3d95e54`), `BNB #256` (`1a14f3a`), `BNB #257` (`ff989bf`,
tagged hashing), `BNB b59ed36` (DLN/MtA session context); party-index append is
`threshold-original`.
- **Migration:** Coordinated network-wide upgrade; no mixed old/new parties. Any persisted
pre-upgrade proofs are not re-verifiable.

#### 5. Tagged Fiat-Shamir for Paillier ModProof / FactorProof (active on the protocol path)
- **What:** `ModProof`/`ModVerify` and `FactorProof`/`FactorVerify`
(`crypto/paillier/mod_proof.go`, `factor_proof.go`) gain an optional session tag. When a
session tag **is** supplied they use tagged hashing (`common.HashToNTagged`, sized to the
modulus to avoid challenge bias) and are **not** wire-compatible with pre-upgrade peers.
With **no** session tag the challenge bytes are unchanged (backward-compatible default).
- **Break type:** Wire/protocol **only when a session tag is supplied**.
- **Motivation:** Domain separation for the Paillier proofs without weakening Threshold's
existing `N`/`NTilde` `ModProof`/`FactorProof` remediation. Threshold's stronger coverage
was retained; no BNB no-proof escape hatches were introduced.
- **Provenance:** `BNB #252`, `BNB #257`; the in-tree round code now passes session tags,
so in practice this is active on the protocol path.
- **Migration:** Covered by the coordinated upgrade in Breaking Change 1/4.

#### 6. ECDSA resharing broadcasts and validates an SSID (`DGRound1Message`)
- **What:** `DGRound1Message` gains a new wire field `bytes ssid = 4`
(`protob/ecdsa-resharing.proto`). The new committee rejects any DGRound1 broadcast whose
SSID does not equal its locally-derived SSID, with culprit attribution
(`ecdsa/resharing/round_1_old_step_1.go`), and `ValidateBasic` now requires a 32-byte
SSID (`ecdsa/resharing/messages.go`). The exported constructor `NewDGRound1Message` gains
a required `ssid []byte` parameter.
- **Break type:** Wire/protocol (old and new resharing parties cannot interoperate) **and
source/compile** — this is the **only** exported signature in the whole integration that
changed in a source-breaking way; external callers constructing `DGRound1Message`
directly must update.
- **Motivation:** Lets the new committee detect a corrupted old-committee party that
broadcasts an inconsistent SSID (committee-substitution / context-disagreement
detection).
- **Provenance:** `threshold-original`, derived from the `BNB fc38979` session work.
- **Migration:** Upgrade both committees in lockstep; set a session nonce (Breaking Change
1); update any direct `NewDGRound1Message` callers to pass `ssid`.

> Aside from `NewDGRound1Message` (Breaking Change 6), every session / `fullBytesLen`
> parameter was added as a trailing variadic argument, so all other existing call sites
> compile unchanged. The breaks above are runtime/wire, not compile-time. This was verified
> by diffing every exported signature between the base and HEAD.

### Security & correctness hardening (non-breaking)

These tighten validation against malformed or malicious input, or fix latent bugs, without
rejecting input that an honest caller would previously have produced.

- **MtA / range / factor / mod proof boundary checks:** GCD, interval, lower/upper-bound,
non-one/non-zero, ciphertext-coprimality, and curve-mismatch checks now reject malformed
or adversarial proofs (returning errors instead of panicking on, e.g., a nil `U` or a
cross-curve point). Honest proofs are unaffected. The MtA `betaPrm` sampling range was
narrowed (`q^5` instead of `N`) to match the new verifier bounds; this changes
intermediate ciphertext/proof wire values but preserves the `alpha + beta ≡ a·b mod q`
MtA output. _Provenance: `BNB #252`, `BNB #289` (`5d01446`)._
- **VSS commitment-vector length check:** `feldman_vss.Verify` now requires
`len(vs) == threshold+1`, turning a potential out-of-range panic on a short/long
adversarial commitment vector into a clean `false`. _Provenance: `BNB #291` (`843de68`)._
- **VSS reconstruction off-by-one fix:** `feldman_vss.ReConstruct` now requires
`threshold+1` shares (was `threshold`) and guards the empty-slice case. The previous
behavior silently reconstructed an **incorrect** secret from `threshold` shares.
Behavior change: a caller passing exactly `threshold` shares now receives
`ErrNumSharesBelowThreshold` instead of a wrong value. No in-tree non-test caller is
affected. _Provenance: `BNB #324` (`4878da5`)._
- **ECDSA `SignatureData.M` is now full-length-padded:** ECDSA signing finalize emits the
message and computes the verify preimage with `FillBytes(fullBytesLen)` instead of minimal
`m.Bytes()` (`ecdsa/signing/finalize.go`). This is an output-format change only — ECDSA
scalar math uses `m` as an integer, so it is not an interop break — but an operator
diffing the emitted `data.M` across the upgrade will see padded bytes. _Provenance:
`BNB #284`._
- **Canonical EC coordinate rejection:** EC point construction/deserialization
(`crypto/ecpoint.go`, backing `NewECPoint`, `GobDecode`, `UnmarshalJSON`) now rejects
coordinates outside `[0, P)`. Honest callers never produce out-of-range coordinates;
this hardens against malicious peer input. _Provenance: `BNB 685c2af`._
- **`round.ok` accumulation fix:** all non-terminal ECDSA/EdDSA keygen, signing, and
resharing rounds now accumulate per-party readiness across the whole message set instead
of bailing on the first not-ready party, fixing inconsistent bookkeeping under
out-of-order message delivery. Internal only; no wire or API change. _Provenance:
`BNB #282` (`409542e`)._
- **Nil-guards:** `BaseParty.String()` returns `"No more rounds"` instead of panicking
after completion (`BNB #276`, `f3aad28`); the EdDSA resharing round-1 party-0 broadcast
and EdDSA keygen `NewECPoint`-error path are guarded against nil dereference
(`BNB #282`, `BNB 5d0d0f3`).

### Added

- `common.SHA512_256i_TAGGED` and `common.HashToNTagged` — length-delimited, domain-
separated tagged hashing primitives. _Provenance: `BNB #257`._
- `tss.Parameters.SessionNonce`, `SetSessionNonce`, `SetSessionNonceBytes` — session-nonce
API. `SetSessionNonce` rejects non-positive nonces; `SetSessionNonceBytes` requires a
session ID of at least 16 bytes. _Provenance: `BNB fc38979`._
- `common.IsInInterval`, `common.AppendUint64ToBytesSlice`,
`common.AppendBigIntToBytesSlice` (the last currently unused), and `tss.SameCurve` —
helpers backing the hardened range checks and session/transcript context construction.
- `schnorr.NewZKProofWithSession`, `NewZKVProofWithSession`, `VerifyWithSession` — session-
aware Schnorr proof overloads (the original signatures are retained and delegate with a
nil session).

### Notes

- `common.RejectionSample` keeps the upstream name for porting clarity but is a modular
reduction, not a looping rejection sampler.
- Threshold's Paillier/NTilde `ModProof` and `FactorProof` remediation
(GHSA-h24c-6p6p-m3vx) was retained; the upstream modproof checker (`BNB #323`) was
already covered.

### Not ported / deferred

- Module path bumps to `/v2`, `/v3` (`BNB faf1884`, `c23246e`) — skipped to preserve
Threshold compatibility; the module path remains `github.com/bnb-chain/tss-lib`.
- `SignatureData` channel-to-pointer change (`BNB fbb0ef7`) — public API churn not needed
for hardening.
- Optional constant-time framework (`BNB #328`) — adds a dependency and broad
Paillier/MtA rewrites, default-disabled upstream; deferred to a separate follow-up with
benchmarking and side-channel review.
- Dependency / random-source API churn and repository/CI/metadata housekeeping
(`BNB b8d526d`, `8abf1d5`, `6c233c6`, `87f7e12`, `7113b68`, `d0325a1`, `dca2ac4`).

### Residual risks

- Applications **must** call `SetSessionNonce`/`SetSessionNonceBytes` before keygen,
signing, and ECDSA resharing; those protocols fail closed without it.
- EdDSA resharing has no SSID-bound proof transcript in this port.
- The optional constant-time work is not integrated.

[Unreleased]: https://github.com/threshold-network/tss-lib/compare/2e712689...HEAD
13 changes: 11 additions & 2 deletions README.md

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loose idea for follow-up work: Maybe a good move would be to remove all the code that is not used by keep-core, i.e. the whole eddsa and ecdsa/resharing packages? There are at least several issues in those packages that are inherited from upstream, for example:

  1. Resharing round 4 omits Paillier N and NTilde bit-length checks present in keygen, allowing weak-modulus key substitution -> ecdsa/keygen/round_2.go:53-61 rejects any peer-broadcast Paillier modulus or NTilde whose BitLen is not exactly paillierBitsLen (2048). The analogous loop in ecdsa/resharing/round_4_new_step_2.go performs DLN and mod-proof checks, h1!=h2, h1/h2 uniqueness — but NO BitLen validation of paiPK.N or NTildej. A malicious new-committee party can therefore broadcast a 1024-bit factorable N / a smooth-factor NTildej, generate valid DLN/Mod proofs over it (the proofs do not certify size), and have honest new-committee verifiers persist that weak key. This may open the door for a class of attacks that could lead to secret recovery given 1024-bit keys are considered vulnerable nowadays.
  2. EdDSA resharing has no SSID-bound proof transcript in this port as the "Residual Risks" section of BNB_HARDENING_INTEGRATION.md mentions.

... and probably more. Getting rid of those packages greatly limits the potential attack surface, and will make the threshold-network/tss-lib far easier to maintain. Moreover, we avoid dead code with known problems to bite us one day or bite another protocols that will leverage the affected packages of this fork.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in #5

Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ Use the `signing.LocalParty` for signing and provide it with a `message` to sign
Please note that `t+1` signers are required to sign a message and for optimal usage no more than this should be involved. Each signer should have the same view of who the `t+1` signers are.

```go
party := signing.NewLocalParty(message, params, ourKeyData, outCh, endCh)
fullBytesLen := (params.EC().Params().N.BitLen() + 7) / 8
party := signing.NewLocalParty(message, params, ourKeyData, outCh, endCh, fullBytesLen)
go func() {
err := party.Start()
// handle err ...
Expand Down Expand Up @@ -146,6 +147,15 @@ When you build a transport, it should offer a broadcast channel as well as point

Within your transport, each message should be wrapped with a **session ID** that is unique to a single run of the keygen, signing or re-sharing rounds. This session ID should be agreed upon out-of-band and known only by the participating parties before the rounds begin. Upon receiving any message, your program should make sure that the received session ID matches the one that was agreed upon at the start.

The same session ID should be bound into the protocol parameters before constructing local parties:

```go
params := tss.NewParameters(curve, ctx, thisParty, len(parties), threshold)
params.SetSessionNonceBytes([]byte(sessionID))
```

All parties in the run must use the same high-entropy session ID of at least 16 bytes, and it must be unique to the ceremony. Keygen, signing, and ECDSA re-sharing fail closed if no session nonce is set; reusing a session ID across otherwise identical ceremonies reintroduces transcript-splicing risk.

Additionally, there should be a mechanism in your transport to allow for "reliable broadcasts", meaning parties can broadcast a message to other parties such that it's guaranteed that each one receives the same message. There are several examples of algorithms online that do this by sharing and comparing hashes of received messages.

Timeouts and errors should be handled by your application. The method `WaitingFor` may be called on a `Party` to get the set of other parties that it is still waiting for messages from. You may also get the set of culprit parties that caused an error from a `*tss.Error`.
Expand All @@ -155,4 +165,3 @@ A full review of this library was carried out by Kudelski Security and their fin

## References
\[1\] https://eprint.iacr.org/2019/114.pdf

42 changes: 42 additions & 0 deletions common/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,48 @@ func SHA512_256i(in ...*big.Int) *big.Int {
return new(big.Int).SetBytes(state.Sum(nil))
}

// SHA512_256i_TAGGED is a domain-separated variant of SHA512_256i. The tag is
// hashed and prepended twice.
func SHA512_256i_TAGGED(tag []byte, in ...*big.Int) *big.Int {
tagBz := SHA512_256(tag)
state := crypto.SHA512_256.New()
if _, err := state.Write(tagBz); err != nil {
panic("SHA512_256i_TAGGED Write(tag) failed: " + err.Error())
}
if _, err := state.Write(tagBz); err != nil {
panic("SHA512_256i_TAGGED Write(tag) failed: " + err.Error())
}
Comment on lines +101 to +106

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a bug, but a potential code robustness issue - state.Write should never return an error, so conditions inside the two ifs here are unreachable code. We do, however, suggest with them that SHA512_256i_TAGGED may return a nil value, and this path is never handled in the code using this function - in the DLN proof path, a direct .Bit() call would panic, and in the rejection sample path, the .Mod() call would panic.

That said, instead of suggesting SHA512_256i_TAGGED may return nil, I would panic here if state.Write returns an error which, by the Go spec, is not possible. Even if this somehow magically happens, we will panic in the right place, not later when doing .Bit() or .Mod().


inLen := len(in)
bzSize := 0
inLenBz := make([]byte, 64/8)
binary.LittleEndian.PutUint64(inLenBz, uint64(inLen))
ptrs := make([][]byte, inLen)
for i, n := range in {
if n == nil {
ptrs[i] = zero.Bytes()
} else {
ptrs[i] = n.Bytes()
}
bzSize += len(ptrs[i])
}

dataCap := len(inLenBz) + bzSize + inLen + (inLen * 8)
data := make([]byte, 0, dataCap)
data = append(data, inLenBz...)
for i := range in {
data = append(data, ptrs[i]...)
data = append(data, hashInputDelimiter)
dataLen := make([]byte, 8)
binary.LittleEndian.PutUint64(dataLen, uint64(len(ptrs[i])))
data = append(data, dataLen...)
}
if _, err := state.Write(data); err != nil {
panic("SHA512_256i_TAGGED Write(data) failed: " + err.Error())
}
Comment on lines +132 to +134

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar comment here - state is a hash.Hash and state.Write should never return an error. I would panic here if that happens instead of having the downstream code panic because of a nil value returned.

return new(big.Int).SetBytes(state.Sum(nil))
}

func SHA512_256iOne(in *big.Int) *big.Int {
var data []byte
state := crypto.SHA512_256.New()
Expand Down
Loading
Loading