Skip to content

add mode: cmiyc ($cmiyc$2026$) - #35

Merged
cyclone-github merged 1 commit into
mainfrom
$cmiyc$2026$
Aug 18, 2026
Merged

add mode: cmiyc ($cmiyc$2026$)#35
cyclone-github merged 1 commit into
mainfrom
$cmiyc$2026$

Conversation

@cyclone-github

Copy link
Copy Markdown
Owner

Adds support for the custom memory-hard KDF hash algo used in CMIYC 2026. This algo was created by KoreLogic for CMIYC 2026 and at this time has no other practical purpose outside of the contest.

Parameters

mode:      cmiyc
rounds:    4
memlog:    16
memory:    4 MiB per KDF candidate
salt:      random 16 bytes
format:    $cmiyc$2026$4$16$<salt>$<digest>

Example

$ echo "hashgen" | hashgen -m cmiyc
2026/08/18 10:36:38 Starting...
2026/08/18 10:36:38 Reading from stdin...
2026/08/18 10:36:38 Hash function: cmiyc
2026/08/18 10:36:38 CPU Threads: 16
$cmiyc$2026$4$16$3MUwyBLiyd3IzNKjtbKfCg$ZWfuY36nvFHp3IJ9ohVuipJhjJI_G-PHCaMwnq0ef4E
2026/08/18 10:36:38 Finished processing 1 lines in 0.230 sec (4.353 lines/sec)

Algorithm overview from reverse engineered CMIYC 2026 Challenge 3 binary: cmiyc_2026_challenge_3

CMIYC 2026 Memory-Hard SHA-512 KDF

$cmiyc$2026$<rounds>$<memlog>$<salt_b64url>$<digest_b64url>

Parameters and encoding:

  • rounds: decimal integer, valid range 1..32.
  • memlog: decimal integer, valid range 10..24.
  • salt: exactly 16 bytes, unpadded RFC 4648 Base64URL.
  • digest: exactly 32 bytes, unpadded RFC 4648 Base64URL.
  • Number of memory blocks: N = 1 << memlog.
  • Each memory block is 64 bytes, so memory per candidate is 64 * 2^memlog bytes.
  • All integer values injected into the KDF are little-endian.
  • The literal 2026 is part of the modular hash format/version check, but it is not hashed by the KDF.

KDF

N = 1 << memlog

seed = HMAC-SHA512(
    key = salt,
    msg = password || LE32(rounds) || LE32(memlog)
)

M[0] = SHA512(seed || "cmiyc-fill" || LE64(0))

for i = 1 .. N-1:
    M[i] = SHA512(M[i-1] || "cmiyc-fill" || LE64(i))

for r = 1 .. rounds:

    # Forward pass, in place
    for i = 0 .. N-1:
        current = M[i]
        j = LE64(current[0:8]) & (N - 1)
        M[i] = SHA512(
            current || M[j] || LE64(r) || LE64(i) || "A"
        )

    # Reverse pass, in place
    for i = N-1 .. 0:
        current = M[i]
        j = LE64(current[8:16]) & (N - 1)
        M[i] = SHA512(
            current || M[j] || LE64(r) || LE64(i) || "B"
        )

X = 64 zero bytes
for i = 0 .. N-1:
    X = X XOR M[i]

full = SHA512(X)
digest = full[0:32]

Important implementation details:

  • HMAC key is the 16-byte salt. The password is in the HMAC message.
  • The fill tag is exactly the 10 ASCII bytes cmiyc-fill, with no NUL terminator.
  • Fill begins at index 0.
  • Mixing round numbers begin at 1.
  • Forward indexing uses bytes 0..7 of the current block.
  • Reverse indexing uses bytes 8..15 of the current block.
  • Both mixing passes mutate the memory array in place. M[j] therefore observes whatever value is currently in that slot at that point in the pass.
  • Forward domain separator is one byte A; reverse separator is one byte B.
  • The final reduction XORs every byte of all 64-byte blocks into one 64-byte accumulator.
  • The final SHA-512 is truncated to its first 32 bytes.

Default-cost example

For rounds=4, memlog=16:

  • N = 65,536 blocks.
  • Memory per candidate = 4 MiB.
  • Fill performs 65,536 SHA-512 hashes.
  • Mixing performs 2 * 4 * 65,536 = 524,288 SHA-512 hashes.
  • Each 145-byte mixing message spans two SHA-512 compression blocks.

Known test vectors

Password Always, salt hex 000102030405060708090a0b0c0d0e0f:

$cmiyc$2026$1$10$AAECAwQFBgcICQoLDA0ODw$PeDdIxtm9EBCX5W2QI9GTX9UVM4Vp-iPT-ntbNzcd_Q

Using the same password/salt with rounds=4, memlog=16:

$cmiyc$2026$4$16$AAECAwQFBgcICQoLDA0ODw$bPFnwgOl8XRYP3vMkEOl9fpebKwF8GFpMAAWCJR4Ptg

@cyclone-github cyclone-github self-assigned this Aug 18, 2026
@cyclone-github cyclone-github added the enhancement New feature or request label Aug 18, 2026
@cyclone-github
cyclone-github merged commit 9539f8c into main Aug 18, 2026
4 checks passed
@cyclone-github
cyclone-github deleted the $cmiyc$2026$ branch August 18, 2026 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant