JHILKE झिल्के
Just Hidden In-band Legitimate Key Exchange
Steganographic key lifecycle management for the Yakmesh mesh.
v1.0.0The Sound of Crickets
In Nepali, झिल्के (jhilke) describes the chirping of crickets in the Himalayan night — a chorus only those who belong can hear. Outsiders perceive noise; insiders hear signals.
Like the D-Day cricket clickers, where Allied paratroopers used a simple click-clack pattern to identify friend from foe in darkness. Like the Navajo codetalkers whose language was unbreakable because it was meaningful only to those who grew up with it.
JHILKE hides its key management signals inside ordinary mesh entropy traffic. To an observer, it's noise. To nodes sharing the same codebase — it's a conversation.
Why Fireflies?
Fireflies (Lampyridae) are nature's original steganographers. Each species flashes a unique pattern — a species-specific dialect that only potential mates of the same species can decode. To every other creature in the meadow, it's just random light. Sound familiar?
JHILKE nodes do exactly what fireflies do: they embed signals in the noise of the night. The "dialect" is derived from the shared codebase hash. Same code = same species = you understand the flash pattern. Different code = different species = it's just entropy.
Real fireflies are disappearing worldwide due to light pollution, habitat loss, and pesticides. At least 2,000 species exist, with some already critically endangered. If you see fireflies near your home, consider yourself lucky — and keep the lights low for them.
Overview
JHILKE provides two critical functions that together eliminate all plaintext cryptographic exchange on the Yakmesh network:
Deterministic Bootstrap
Both nodes independently derive the same initial encryption key from the shared code hash. Traffic is encrypted from message #1 — no plaintext KEM exchange ever occurs.
Steganographic Rekey
Ongoing key rotations are coordinated via hidden signals embedded in mesh_entropy messages. No explicit REKEY messages — an observer sees only noise.
Ternary State Machine
Three-phase coordination using TRIBHUJ trits: PREPARE (+1), READY (0), SWITCH (-1). Both sides must agree before any key change occurs.
SST Modulation
Signal encoding is modulated by the Fibonacci 24-cycle (Sacred Sequence Theory), adding rotational variety that makes pattern analysis impossible.
The Problem JHILKE Solves
Traditional key exchange protocols expose critical metadata to passive observers:
| Leaked Information | Before JHILKE | After JHILKE |
|---|---|---|
| KEM public keys | Plaintext on wire | Encrypted (bootstrap channel) |
| KEM ciphertext | Plaintext on wire | Encrypted (bootstrap channel) |
| Rekey timing | Visible REKEY messages | Hidden in entropy traffic |
| Key rotation frequency | Countable | Indistinguishable from noise |
| First message encryption | Delayed until KEM completes | Immediate (deterministic key) |
Deterministic Bootstrap
When two nodes connect, they both independently compute the same initial symmetric key:
// Both nodes independently derive the same bootstrap key
// Key = HKDF(SHA3-256, codeHash, sortedNodeIds, bootstrapInfo, 32)
import { JhilkeCoordinator } from './mesh/jhilke.js';
const jhilke = new JhilkeCoordinator({
codeHash: oracle.selfHash, // Validation Oracle code hash
nodeId: myNodeId,
annex: annexInstance,
mesh: meshInstance,
});
// Derive bootstrap key for a peer (deterministic — both nodes get same key)
const bootstrapKey = jhilke.deriveBootstrapKey(peerNodeId);
// Create ANNEX session using bootstrap key (no KEM exchange needed!)
annex.bootstrapSession(peerNodeId, bootstrapKey);
// Traffic is now encrypted from the very first message.
// KEM upgrade happens automatically through the encrypted channel.
Key Derivation
// Salt includes both node IDs (sorted for order-independence)
const [first, second] = [nodeA, nodeB].sort();
const salt = `YAKMESH-JHILKE-BOOTSTRAP-2026:${first}:${second}`;
// HKDF derivation
const key = HKDF(
SHA3-256, // Hash function
codeHash, // Input key material (oracle hash)
salt, // Salt (sorted node IDs)
'yakmesh-jhilke-bootstrap-key-v1', // Info string (versioned)
32 // Output: 256-bit key
);
Encryption Lifecycle
JHILKE manages the complete ANNEX encryption lifecycle:
-
1
Bootstrap — Both nodes derive deterministic key from shared code hash. ANNEX session created with immediate encryption capability.
-
2
KEM Upgrade — ML-KEM-768 key exchange happens inside the bootstrap-encrypted channel. KEM public key + ciphertext never appear in plaintext.
-
3
Steady State — ANNEX uses the KEM-derived key. JHILKE tick loop monitors for rekey needs (every 5 minutes or 10,000 messages).
-
4
Cricket Rekey — When rekey is needed, JHILKE coordinates both sides via steganographic signals. Only after mutual confirmation does the actual KEM rekey occur.
Steganographic Signals
The Firefly Flash Pattern: Just as Photinus pyralis uses a specific J-shaped flash lasting exactly 0.5 seconds followed by a 2-second pause, JHILKE nodes embed precisely-timed signals in the constant stream of mesh entropy. The pattern is meaningful only to nodes sharing the same "species" — the same codebase hash. Every other observer sees random light in the darkness.
JHILKE signals are hidden inside mesh_entropy messages —
a normal part of mesh communication used for entropy exchange between peers:
// What an observer sees on the wire:
{
type: 'mesh_entropy',
entropy: 'a7f3b2c1...', // 32 bytes of genuine entropy
jhilke: '8e4d1f2a...', // 8 bytes — cricket signal or random noise?
pad: 'c3d2e1f0...', // 16-64 bytes random padding (varying size)
t: 1740100000000 // Timestamp
}
// To an observer: just entropy exchange, nothing unusual.
// To nodes sharing the dialect: a coordinated key rotation.
Dialect Derivation
The "dialect" is the shared secret that allows signal encoding/decoding. It's derived from the code hash — only nodes running identical code share the dialect:
// Dialect seed — same for all nodes with identical codebase
const dialectSeed = HKDF(
SHA3-256,
codeHash, // Input key material
'jhilke-cricket-salt-2026', // Salt
'yakmesh-jhilke-dialect-v1', // Info
32 // 256-bit seed
);
// Signal generation — encodes intent + context
const signal = HKDF(
SHA3-256,
dialectSeed, // Key = dialect
`${nodeA}:${nodeB}:${tick}:${fibPos}:${fibRoot}:${intent}`,
'jhilke-signal-v1',
8 // 8-byte signal
);
Signal Decoding
Decoding is brute-force over a tiny search space — trivial for nodes sharing the dialect, impossible without it:
// 3 intents × 3 tick offsets (±1 tolerance) = 9 attempts
const intents = [PREPARE, READY, SWITCH]; // +1, 0, -1
const offsets = [-1, 0, +1]; // tick tolerance
for (const offset of offsets) {
for (const intent of intents) {
const expected = generateSignal(peerId, tick + offset, intent);
if (expected === receivedSignal) {
// Decoded! We know the intent and approximate timing.
return { intent, tick: tick + offset };
}
}
}
// No match → genuine entropy, not a cricket signal
Ternary State Machine
The rekey coordination uses a ternary state machine with TRIBHUJ trits:
| Signal | Trit | Meaning | Duration |
|---|---|---|---|
| PREPARE | +1 (POSITIVE) | "I'm preparing new key material" | 3 ticks |
| READY | 0 (NEUTRAL) | "My new key is ready, waiting for you" | Until peer ready |
| SWITCH | -1 (NEGATIVE) | "Switching to new key NOW" | 2 ticks then execute |
State Flow
Initiator Responder
───────── ─────────
idle idle
│ │
├── needsRekey() ─────────────────┤
│ │
prepare ──── PREPARE (+1) ────▶ prepare
│ │
│ (3 ticks generating keys) │
│ │
ready ──── READY (0) ──────▶ ready
│ ◀──── READY (0) ────── │
│ │
│ (both confirmed ready) │
│ │
switch ──── SWITCH (-1) ────▶ switch
│ ◀──── SWITCH (-1) ──── │
│ │
exchanging ── KEM rekey ──────▶ exchanging
│ ◀── KEM response ───── │
│ │
idle (new KEM key active) idle
Timing & Retry
Tick Loop
- • 1-second heartbeat interval
- • Sends cricket chirps to active peers
- • Drives state machine transitions
- • Scans ANNEX sessions every 30 ticks
Retry Logic
- • Retry after 24 ticks (24 seconds)
- • Maximum 3 retry cycles per rekey
- • Abort after 72 ticks total (72 seconds)
- • ±1 tick tolerance for network jitter
API Reference
jhilke.deriveBootstrapKey(peerId)
Derives a deterministic bootstrap encryption key for a peer. Both nodes compute the same key independently.
Parameters
| peerId | string | The remote peer's node ID |
Returns
Buffer // 32-byte (256-bit) symmetric key
jhilke.initiateRekey(peerId)
Begins a steganographic rekey coordination for a peer.
Called by ANNEX when needsRekey() returns true. Starts the cricket chirp sequence.
Parameters
| peerId | string | The peer to coordinate rekey with |
jhilke.handleIncoming(fromPeerId, message)
Processes incoming mesh_entropy messages, checking
for hidden cricket signals. Genuine entropy passes through unchanged.
Parameters
| fromPeerId | string | Sender's node ID |
| message | object | The mesh_entropy message (may contain jhilke field) |
jhilke.start() / jhilke.stop()
Starts or stops the 1-second tick loop. The tick loop drives state machine transitions and sends cricket chirps to peers in active rekey coordination.
jhilke.getStats()
Returns operational statistics.
{
bootstrapKeysDerived: 3, // Bootstrap keys computed
signalsSent: 142, // Cricket chirps sent
signalsReceived: 138, // Chirps received
signalsDecoded: 47, // Successfully decoded (rest were genuine entropy)
rekeyCoordinations: 12, // Rekey coordinations started
rekeySuccesses: 11, // Successful key rotations
rekeyAborts: 1, // Timed-out coordinations
activeSessions: 2, // Peers tracked
activeCoordinations: 1, // Rekeys in progress
globalTick: 3847 // Ticks since start
}
Security Properties
- • Zero plaintext key exchange — Bootstrap key encrypts the KEM exchange. All subsequent rekeys flow through the encrypted channel.
- • Perfect Forward Secrecy — No old key material is stored. Bootstrap keys are ephemeral (replaced by KEM within seconds). Rekeys generate fresh ML-KEM-768 keypairs.
- • Codebase-bound dialect — Only nodes with identical code (verified by the Validation Oracle) can encode or decode cricket signals. Fork the code → different dialect.
- • Race condition elimination — The ternary state machine ensures both sides agree before any key switch. No more "Unsupported state" errors during rekey.
- • Traffic analysis resistance — Cricket chirps are indistinguishable from regular mesh_entropy messages. Variable padding adds further camouflage.
Relationship to ANNEX
JHILKE is ANNEX's companion protocol — it manages the cryptographic lifecycle while ANNEX handles the actual encryption/decryption:
| Responsibility | ANNEX | JHILKE |
|---|---|---|
| Symmetric encryption | AES-256-GCM encrypt/decrypt | — |
| Initial key | Receives from JHILKE | Derives deterministic bootstrap |
| KEM exchange | ML-KEM-768 encapsulate/decapsulate | Routes through encrypted channel |
| Rekey trigger | Detects needsRekey() | Coordinates timing via chirps |
| Message signing | ML-DSA-65 sign/verify | — |