Skip to content

fix(crypto): correct Keccak digest API behavior - #7018

Open
Federico2014 wants to merge 3 commits into
tronprotocol:release_v4.8.3from
Federico2014:fix/keccak-digest-api
Open

Federico2014 wants to merge 3 commits into
tronprotocol:release_v4.8.3from
Federico2014:fix/keccak-digest-api

Conversation

@Federico2014

@Federico2014 Federico2014 commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

What does this PR do?

Fixes Keccak-256/512 Java digest handling. update(ByteBuffer) now hashes the remaining bytes and advances the buffer position to its limit. The SPI update and digest methods delegate to the existing hash implementation.

Output-buffer digests now require space for the complete 32/64-byte result. Short output raises DigestException before finalization, invalid output ranges raise IllegalArgumentException, and successful calls reset the digest. Removes the temporary buffer used only for truncated output.

Why are these changes required?

The empty SPI update methods consumed ByteBuffer input without hashing it. The output-buffer overload also returned truncated hashes instead of requiring a complete digest.

This PR has been tested by:

  • Isolated JDK 8 compilation and JUnit execution on commit 76337caedb: 28 tests passed against Bouncy Castle 1.84's KeccakDigest, covering buffer variants, mixed updates, output boundaries, reset, SPI methods, and copied state.
  • Isolated JDK 8 base/head comparison: 1,488 full-digest records matched base 1ff2aae94b, head 76337caedb, and Bouncy Castle 1.84; see the consensus analysis below.
  • git diff --check passed.
  • Gradle's targeted crypto test was attempted offline but blocked by uncached dependencies; it did not execute tests. Full-node manual testing was not performed.

Follow up

Run the targeted Gradle tests and full CI suite before merging.

Extra details

Consensus impact

The Keccak permutation and padding are unchanged. The inspected TVM SHA3, address derivation, storage-key, and code-hash paths use Hash.sha3 with byte-array input and full-length output. All 1,488 base/head digest records matched Bouncy Castle 1.84.

No consensus-result change or coordinated fork activation is expected for these paths.

Compatibility impact

  • Source: output-buffer calls through Digest, DigestEngine, or concrete Keccak classes now require handling or declaring DigestException. MessageDigest callers already have this requirement.
  • Binary: the exception declaration preserves the JVM method descriptor, so it does not itself break binary linkage.
  • Behavior: ByteBuffer bytes now contribute to the hash. Short output throws DigestException without resetting state or modifying the output buffer; obtain the full digest and truncate explicitly if needed. Invalid output ranges raise IllegalArgumentException.
  • Unchanged: successful calls return the complete 32/64-byte digest and reset state. Algorithm/provider names, database schema, configuration, and RPC formats are unchanged; no data migration is required.

Related: #6996.

@Federico2014
Federico2014 force-pushed the fix/keccak-digest-api branch from 76337ca to 43742b5 Compare October 12, 2026 07:58
@0xbigapple

Copy link
Copy Markdown
Collaborator

Finished a review pass. The issues I found match @3for two open comments. I'll approve once those are addressed.

@3for 3for left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM.

Please document the branch-wide Digest API compatibility changes in the release notes:

  1. Source compatibility: Digest.digest(byte[], int, int) now declares the checked DigestException. External callers may need to catch or declare it to compile, while existing compiled binaries remain compatible.

  2. Insufficient output buffer: Instead of returning truncated output, the method now throws DigestException.

  3. Input validation: update() now rejects negative lengths instead of silently ignoring them. Out-of-bounds arguments and null input now consistently throw IllegalArgumentException.

  4. Subclass contract: Subclasses of DigestEngine that override engineReset() must call super.engineReset() to ensure the buffered state is fully reset.

@0xbigapple

Copy link
Copy Markdown
Collaborator

Both SPI issues are fixed in 301b22e. The reset and short-buffer regression tests pass for Keccak256 and Keccak512, and the crypto tests are green on my side. LGTM.

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.

5 participants