Security › hash-21 · Constant-time review · Performance: x86_1 · arm_1
Neulaser (hash-21)
| Candidate | Neulaser |
|---|---|
| Family | Symmetric (PRNG-based iterated hash) |
| Archive | Neulaser.zip (SHA-256: ffa76faaf6ae1c939ef6b1a726d6bcef19f0f0df63daddfe74a82e2831c4c6b3) |
| Specification | hash-21-spec.pdf PDF |
| Performance | x86_1 · arm_1 |
hash-21-1: A local feedback collision merges complete Neulaser states
| Severity | Critical |
|---|---|
| Scope | design |
| Status | Confirmed |
| Affected | Neulaser-512, Neulaser-768, and Neulaser-1024 |
| Discovery | Moderate |
| Exploitation | Trivial after a 175,493-input local search |
| Credit | Cryptanalysts001 (ISCAS) yufei2021@iscas.ac.cn |
| Date | 2026-09-22 |
Original source: CryptHashForum report
For a register module whose only nonzero word is its discarded first stage, the feedback map sends both 00002743 and 0002ad84 to 8c41db68. The global mixing function does not read that stage, so states differing only by these words become identical after one initialization round. All later rounds and the final digests are then identical.
The reporters give equal-length fixed-IV messages 00^d || BE32(x) || 00^60, with d=56,88,120 bytes for the three instances and x chosen from the colliding pair. The submitted Neulaser-512 implementation maps both 120-byte messages to f899bf50663e6e04fa5374baf28886153ea332bf25443817eb2abbca88072458dbd7a077712aae99fb112b7672c85a705700e027b348516cc45f8fff537713d3; full-round collisions reproduce for all three instances.
Further analysis: Yufei Yuan et al., Structural Analysis of Seven Hash Functions Submitted to the NGCC, Section 4 (2026-09-23), derives this local-feedback collision and its fixed-IV message pairs. This finding concerns the feedback merger rather than the separate modular-reduction mechanism described below.
Reproducing
Commands below run in a checkout of the ngcc-harness repository with the candidate built (see its README).
The same candidate-local witness checks both collision families against all three submitted libraries:
make -C hash-21 reproduce
hash-21-2: Reduction modulo 2^32-5 creates reachable state mergers
| Severity | Critical |
|---|---|
| Scope | design |
| Status | Confirmed |
| Affected | Neulaser-512, Neulaser-768, and Neulaser-1024 |
| Discovery | Moderate |
| Exploitation | Trivial |
| Credit | Tsinghua Hash Lab cuihr26@mails.tsinghua.edu.cn |
| Date | 2026-09-22 |
Original source: CryptHashForum report
Neulaser loads unrestricted 32-bit message words but overwrites stages 8, 12, and 15 after reduction modulo p=2^32-5. Each value y from 0 through 4 therefore has two encodings, y and y+p. Stages 8 and 12 do not enter any other tap feeding that round, so choosing the two pre-reduction values makes the entire state merge after one round.
The public comment supplies deterministic one-block collisions for every parameter set. For Neulaser-512, two otherwise-zero 888-bit messages place 45d27672 and ba2d8989 at bytes 24–27; both produce the published digest beginning a4cfaefc283b5d78. Four independently mergeable words give 16-message multicollisions. This modular-reduction merger is independent of the local-feedback collision described above.
Reproducing
Commands below run in a checkout of the ngcc-harness repository with the candidate built (see its README).
The witness verifies both published collision families, including the exact full digests, against all three submitted libraries:
make -C hash-21 reproduce
hash-21-3: Secret state indexes a 256-byte S-box
| Severity | Low |
|---|---|
| Scope | side-channel |
| Status | Confirmed |
| Affected | Reference Neulaser-512/768/1024 |
| Discovery | Trivial |
| Exploitation | Cache side-channel dependent |
| Credit | Markku-Juhani O. Saarinen markku-juhani.saarinen@tuni.fi, with AI assistance |
| Date | 2026-09-23 |
nl_sbox_word reads NL_SBOX at four indices derived from an evolving 32-bit state word (CryptHash_AlgorithmInstance.c:85-90). The 256-byte table spans cache lines, so the lookup address depends on secret message content. The source also computes state-derived x % (2^32-5) (:60-63), whose timing requires target-specific code inspection; the report does not rely on it. No preimage-recovery exploit is claimed. See constant_time.md.
Constant-time fix (easy, hence Low): the S-box is field inversion followed by an affine map, hence affine-equivalent to the AES S-box. It can be computed with aesenclast between two pshufb bit-matrix transforms (the technique used for SM4 on AES-NI), with GFNI gf2p8affineinvqb, or with a bitsliced inversion circuit. The modular reduction also needs a branch-free form.
Reproducing
Commands below run in a checkout of the ngcc-harness repository with the candidate built (see its README).
Inspect the four NL_SBOX accesses in any reference variant and compare indices for unequal state words; they select different table lines.
hash-21-4: Long random messages admit second preimages in one scan
| Severity | Critical |
|---|---|
| Scope | design |
| Status | Confirmed |
| Affected | Neulaser-512, Neulaser-768, and Neulaser-1024 |
| Discovery | Moderate |
| Exploitation | The reporter's one-pass scans of 12 GB random targets had approximately 60% success |
| Credit | Sun Shuzhou, with GLM-5.3 assistance |
| Date | 2026-10-04 |
Original source: Sun Shuzhou's CryptHash Forum post
The modular reduction used at state positions 8 and 12 has five double fibers: for p=2^32-5, each y in {0,...,4} has the two 32-bit representatives y and y+p. The round value XORed into either position is independent of that position's current word (CryptHash_AlgorithmInstance.c:140–172; the specified tap update is on physical p. 8). For a random message word, the pre-reduction value therefore lands in one of the ten fiber inputs with probability 10/2^32; replacing it by the other representative makes the complete states merge after that round.
Each full message block exposes 4, 5, or 6 such independently loaded words in Neulaser-512/768/1024. A 12,000,000,111-byte random target therefore contains about 400, 395, or 391 million eligible positions, giving exact success probabilities 1-(1-10/2^32)^T of 60.60%, 60.11%, and 59.79%. The replacement changes four bytes, preserves the message length, and leaves the remaining chaining path and full digest unchanged. The post reports end-to-end same-length second preimages for 4/4, 1/4, and 2/4 preregistered targets, with independent rehash controls.
These messages are far below the required maximum length, and Table 1 claims 512-, 768-, and 1024-bit second-preimage security (physical p. 5). The attack is one linear scan of the target. Treating each eligible word as an independent opportunity gives geometric expected positions equivalent to about 2^26.7, 2^26.4, or 2^26.1 message blocks before the first merger; these are not the cost of scanning the complete 12 GB target used for the reported success rates. Either accounting violates every claimed and required second-preimage target.
Reproducing
Commands below run in a checkout of the ngcc-harness repository with the candidate built (see its README).
make -C hash-21 reproduce
python3 hash-21/reproduce_long_second_preimage.py
The submitted-library witness confirms planted modular-reduction mergers at every tier and rejects byte-flipped controls. The second command checks the source dependencies, counts the message-loaded merge positions, and recomputes the long-target probabilities and work factors. It does not allocate or rehash a 12 GB message.