JHILKE झिल्के

Just Hidden In-band Legitimate Key Exchange

Deterministic bootstrap key derivation and continuous friend-or-foe peer verification for the Yakmesh mesh.

v3.0

The 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 peer verification signals inside ordinary mesh entropy traffic. To an observer, it's noise. To nodes sharing the same codebase and build — 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 + per-build nonce. Same code, same build = same species = you understand the flash pattern. Different code or different build = 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 for the Yakmesh mesh:

Deterministic Bootstrap

Both nodes independently derive the same initial symmetric key from SHA3(codeHash + buildNonce) via HKDF. Traffic is encrypted from message #1 — ANNEX has a key before any wire traffic flows.

Friend-or-Foe Verification

Continuous 8-byte peer integrity chirps every 30 seconds, hidden in mesh_entropy messages. Only nodes with the same codebase AND build nonce can produce or verify chirps. JHILKE emits events; KARMA handles consequences.

ACT State Machine

AGUWA Coordinated Transition using TRIBHUJ trits: PREPARE (+1) → READY (0) → SWITCH (−1). Execution waits for AGUWA epoch boundary with order parameter r ≥ 0.2 before any transition fires.

SST Modulation

Every chirp's HKDF context includes a Fibonacci 24-cycle digital root (fibonacciRoot(tick % 24)), adding rotational variety that prevents pattern analysis across tick boundaries.

Initialization

JHILKE is initialized from mesh/network.js with four parameters:

import { JhilkeCoordinator } from './mesh/jhilke.js';

const jhilke = new JhilkeCoordinator({
  codeHash:   oracle.selfHash,    // Validation Oracle code hash (hex string)
  nodeId:     identity.nodeId,    // This node's identity
  mesh:       meshInstance,       // MeshNetwork (provides sendTo + peers Map)
  buildNonce: manifest.nonce,     // Per-build secret from manifest.json
});

jhilke.start();  // Begin 30-second chirp loop
Build Nonce: The buildNonce comes from manifest.json, generated at build time. It makes both the bootstrap key and the chirp dialect per-build secrets — an attacker with only the source code cannot derive them. They need the manifest from a specific build.

Deterministic Bootstrap

When two nodes connect, they both independently compute the same initial 256-bit symmetric key. No KEM exchange needed — traffic is encrypted from the very first message:

deriveBootstrapKey(peerId) {
  // Step 1: Input Key Material — per-build secret
  const ikm = sha3_256.create()
    .update(hexToBytes(this.codeHash))
    .update(utf8ToBytes(this.buildNonce || ''))
    .digest();

  // Step 2: Sort node IDs for order-independence
  const [first, second] = [this.nodeId, peerId].sort();

  // Step 3: HKDF derivation
  const salt = `YAKMESH-JHILKE-BOOTSTRAP-2026:${first}:${second}`;
  const info = 'yakmesh-jhilke-bootstrap-key-v1';
  const key  = hkdf(sha3_256, ikm, salt, info, 32);

  return Buffer.from(key);  // 32-byte (256-bit) symmetric key
}

Bootstrap Key Properties

  • Order-independent: Node IDs are sorted before hashing — A→B and B→A produce the same key.
  • Per-build secret: IKM = SHA3(codeHash + buildNonce) — not derivable from source code alone.
  • Deterministic: Same code hash + same build nonce + same node pair = identical key on both sides.
  • JHILKE's only key: This is the one key JHILKE derives. What ANNEX does with it after (KEM upgrade, rekey) is ANNEX's business — JHILKE doesn't know or care.

What JHILKE Provides

JHILKE touches exactly three things in the connection lifecycle. Everything else is ANNEX's job:

  1. 1
    Bootstrap Key (on connect) — JHILKE derives a deterministic 256-bit key from SHA3(codeHash + buildNonce) and hands it to ANNEX. This is the only key JHILKE ever produces. What ANNEX does with it — encrypt, KEM upgrade, whatever — is not JHILKE's concern.
  2. 2
    Continuous Chirps (every 30s) — Friend-or-foe verification via mesh_entropy messages. JHILKE emits chirp:verified or chirp:failed events. It does not act on failures — KARMA handles consequences.
  3. 3
    ACT Coordination (on demand) — When a coordinated transition is needed, JHILKE's ACT state machine coordinates timing across peers. Execution fires at an AGUWA epoch boundary with r ≥ 0.2. What happens at execution is up to the caller — JHILKE just emits act:execute.

Cricket Chirps — Friend-or-Foe

Every 30 seconds (matching the gossip HELLO cadence), each node sends a friend-or-foe chirp to every connected peer. Chirps are hidden inside normal mesh_entropy messages:

// What an observer sees on the wire:
{
  type: 'mesh_entropy',
  entropy: 'a7f3b2c1...',   // 32 bytes genuine PRAHARI sponge entropy
  jhilke: '8e4d1f2a...',    // 8-byte friend-or-foe chirp
  pad:    'c3d2e1f0...',    // 16–64 bytes PRAHARI random padding
  t:      1741564800000     // AGUWA-synchronized timestamp
}
// To an observer: routine entropy exchange. Nothing unusual.
// To nodes sharing the dialect: continuous peer verification.

Dialect Derivation

The "dialect" is the shared secret that makes chirp encoding/verification possible. It's derived from the same SHA3(codeHash + buildNonce) IKM as the bootstrap key, but with different salt and info strings — producing a completely independent seed:

_deriveDialectSeed() {
  const ikm = sha3_256.create()
    .update(hexToBytes(this.codeHash))
    .update(utf8ToBytes(this.buildNonce || ''))
    .digest();

  return hkdf(sha3_256, ikm,
    'jhilke-cricket-salt-2026',    // Salt (different from bootstrap)
    'yakmesh-jhilke-dialect-v1',   // Info (different from bootstrap)
    32);                           // 256-bit dialect seed
}

Chirp Generation

Each chirp is an 8-byte HKDF output encoding both node IDs, the current AGUWA tick, and the SST Fibonacci 24-cycle position for rotational variety:

_generateChirp(peerId, tick) {
  const [first, second] = [this.nodeId, peerId].sort();

  // SST modulation — Fibonacci digital root at this tick position
  const fibPos  = tick % 24;
  const fibRoot = fibonacciRoot(fibPos);

  const context = `${first}:${second}:${tick}:${fibPos}:${fibRoot}`;

  return hkdf(sha3_256, this.dialectSeed, context,
    'jhilke-signal-v1', 8);  // 8-byte chirp
}

Chirp Verification

Verification uses dynamic tick tolerance computed from three sources. This accounts for GPS precision differences AND actual system clock drift:

_verifyChirp(peerId, signalBytes, currentTick) {
  // Source 1: MANI trust-level tolerance (peer's time source precision)
  const maniToleranceMs = aguwa.getToleranceForPeer(peerId);

  // Source 2: Clock drift — our correctionMs + peer margin + propagation
  const driftToleranceMs = Math.abs(aguwa._correctionMs) + 2000;

  // Use the larger of MANI precision vs actual drift
  const toleranceMs  = Math.max(maniToleranceMs, driftToleranceMs);
  const dynamicTicks = Math.ceil(toleranceMs / 1000);
  const tolerance    = Math.max(1, dynamicTicks); // ±1 tick floor

  for (let offset = -tolerance; offset <= tolerance; offset++) {
    const testTick = currentTick + offset;
    if (testTick < 0) continue;
    const expected = this._generateChirp(peerId, testTick);
    if (bytesToHex(expected) === bytesToHex(signalBytes)) {
      return { valid: true, tick: testTick, offset };
    }
  }
  return { valid: false };
}
Why three tolerance sources? MANI tolerance alone is insufficient: two GPS nodes (each ±500ms precision) can still have system clocks seconds apart if Kuramoto hasn't fully converged. The correctionMs-based drift term accounts for the actual clock offset that the oscillator is still correcting. The ±1 static floor provides a minimum safety margin.

Wire Format

Chirps are transmitted via _sendChirp(), which constructs a complete mesh_entropy message with genuine entropy, the hidden chirp, and variable camouflage padding:

_sendChirp(peerId) {
  const chirp = this._generateChirp(peerId, this._sharedTick());

  // Variable padding from PRAHARI sponge (16–64 bytes)
  const paddingSize = 16 + (seedStore.squeeze(4, 'JHILKE-PADDING-SIZE')
    .readUInt32BE(0) % 48);
  const padding = seedStore.squeeze(paddingSize, 'JHILKE-PADDING');

  this.mesh.sendTo(peerId, {
    type:    'mesh_entropy',
    entropy: bytesToHex(seedStore.squeeze(32, 'JHILKE-ENTROPY')),
    jhilke:  bytesToHex(chirp),
    pad:     bytesToHex(padding),
    t:       aguwa.now(),
  });
}
Field Size Source Purpose
entropy 32 bytes PRAHARI sponge Genuine entropy contribution to mesh pool
jhilke 8 bytes HKDF(dialect + context) Friend-or-foe verification chirp
pad 16–64 bytes PRAHARI sponge Variable camouflage (prevents size fingerprinting)
t number AGUWA GPS-synchronized timestamp

ACT — AGUWA Coordinated Transition

When a coordinated transition is needed, JHILKE runs the ACT state machine. ACT uses TRIBHUJ trits and is driven on the same 30-second chirp cadence. All transitions are driven by internal state only — never external signals.

State Trit Meaning Duration
PREPARE +1 (POSITIVE) Node has consented. Waiting for actPrepareMinTicks. ≥ 3 ticks (≥ 90s)
READY 0 (NEUTRAL) Minimum prepare elapsed. Waiting for all peers to reach READY. Until all peers READY
SWITCH −1 (NEGATIVE) All peers ready. Counting down to epoch boundary execution. ≥ 2 ticks (≥ 60s), then r ≥ 0.2
EXECUTING terminal Epoch boundary reached. act:execute event emitted. Instant (cleanup follows)

ACT State Flow (30-second cadence)

  Node A                              Node B
  ──────                              ──────
  idle                                idle
    │                                   │
    ├── beginACT(targetEpoch) ──────── ┤
    │                                   │
  PREPARE (+1)                        PREPARE (+1)
    │       (broadcast via gossip)      │
    │   ≥ 3 ticks (≥ 90 seconds)        │
    │                                   │
  READY (0)                           READY (0)
    │   ◀── peer state check ──▶        │
    │                                   │
    │       (all peers in READY)        │
    │                                   │
  SWITCH (−1)                         SWITCH (−1)
    │   ≥ 2 ticks, AGUWA r ≥ 0.2       │
    │   wait for epoch boundary         │
    │                                   │
  EXECUTING ── act:execute ──────▶    EXECUTING
    │                                   │
  idle   (transition complete)        idle
AGUWA Gate: The SWITCH → EXECUTING transition checks two conditions: (1) AGUWA order parameter r ≥ 0.2 — meaning nodes are sufficiently phase-synchronized, and (2) getCurrentEpoch() >= targetEpoch — the target epoch boundary has arrived. If either condition fails, execution is deferred to the next 30-second tick.

Dependencies

AGUWA

aguwa.tick() provides the GPS-synchronized wall-clock second used for chirp encoding. aguwa.orderParameter() gates ACT execution. aguwa.getToleranceForPeer() provides MANI precision for dynamic verification tolerance.

PRAHARI

seedStore.squeeze() provides genuine sponge entropy for the entropy field (32 bytes), variable padding (16–64 bytes), and padding size selection. All entropy is real, not filler.

SST

fibonacciRoot(tick % 24) from oracle/sst.js provides the 24-cycle digital root that modulates chirp context, preventing pattern repetition across tick boundaries.

KARMA

JHILKE emits chirp:verified and chirp:failed events but takes no punitive action. KARMA evaluates consecutiveFailures and manages peer reputation consequences.

Configuration Constants

All constants live in JHILKE_CONFIG (exported for testing):

Constant Value Purpose
bootstrapSalt 'YAKMESH-JHILKE-BOOTSTRAP-2026' HKDF salt prefix for bootstrap key derivation
bootstrapInfo 'yakmesh-jhilke-bootstrap-key-v1' HKDF info for bootstrap key derivation
dialectSalt 'jhilke-cricket-salt-2026' HKDF salt for dialect seed derivation
dialectInfo 'yakmesh-jhilke-dialect-v1' HKDF info for dialect seed derivation
signalInfo 'jhilke-signal-v1' HKDF info for individual chirp generation
signalSize 8 bytes HKDF output length per chirp
paddingMin / paddingMax 16 / 64 bytes Variable camouflage padding range
chirpInterval 30,000 ms Chirp transmission cadence (matches gossip HELLO)
tickTolerance ±1 tick Static floor for chirp verification tolerance
actPrepareMinTicks 3 (≥ 90s) Minimum ticks in PREPARE before advancing to READY
actSwitchDelayTicks 2 (≥ 60s) Minimum ticks in SWITCH before executing

API Reference

jhilke.deriveBootstrapKey(peerId) → Buffer

Derives a deterministic 32-byte bootstrap encryption key for a peer. Both nodes compute the same key independently from SHA3(codeHash + buildNonce).

peerId string The remote peer's node ID
jhilke.start() / jhilke.stop()

start() begins the 30-second chirp loop, sending friend-or-foe verification chirps to all connected peers. stop() halts the loop, cleans up ACT timers, and clears all peer state.

jhilke.handleIncoming(fromPeerId, message)

Processes an incoming mesh_entropy message. If the message contains a jhilke field, it verifies the chirp and emits chirp:verified or chirp:failed. Messages without chirps are ignored.

fromPeerId string Sender's node ID
message object The mesh_entropy message object
jhilke.beginACT(targetEpoch, epochBufferN = 2)

Initiates the ACT state machine for a coordinated transition. Enters PREPARE phase with a 30-second tick cadence. Ignored if ACT is already in progress.

targetEpoch number The AGUWA epoch at which to execute
epochBufferN number Dynamic epoch buffer from propagation model (default: 2)
jhilke.handleACTState(peerId, data)

Receives a peer's ACT state announcement (broadcast via gossip). Ignored if this node is not participating in ACT or if targetEpoch doesn't match. Triggers _checkAllReady() when in READY state.

peerId string Sender's node ID
data object { state: 'PREPARE'|'READY'|'SWITCH', targetEpoch }
jhilke.getACTState() → Object | null

Returns current ACT state machine status for diagnostics. Returns null if no ACT is in progress.

{
  state: 'READY',               // Current phase
  targetEpoch: 42,              // Target epoch
  prepareTicks: 3,              // Ticks spent in PREPARE
  switchTicks: 0,               // Ticks spent in SWITCH
  peerStates: {                 // Tracked peer states
    'abc123...': 'READY',
    'def456...': 'PREPARE'
  }
}
jhilke.getStats() → Object

Returns operational statistics.

{
  bootstrapKeysDerived: 3,
  chirpsSent: 142,
  chirpsReceived: 138,
  chirpsVerified: 135,
  chirpsFailed: 3,
  peerCount: 2
}
jhilke.cleanupPeer(peerId)

Removes all tracked state for a disconnected peer. Called by the mesh when a peer connection is lost.

Event Emissions

JhilkeCoordinator extends EventEmitter. It emits soft intelligence signals — it does NOT take punitive action. KARMA handles consequences:

Event Trigger Payload
chirp:verified Incoming chirp validates (friend) { peerId, tick, offset }
chirp:failed Incoming chirp fails verification (foe?) { peerId, consecutiveFailures }
act:state ACT state transition or broadcast tick { state, targetEpoch }
act:execute Epoch boundary reached + r ≥ 0.2 { targetEpoch }

Security Properties

  • Zero plaintext first message — The bootstrap key (derived from code hash + build nonce) gives ANNEX a symmetric key before any traffic flows. The very first message on the wire is encrypted.
  • Build isolation — The buildNonce from manifest.json makes both the bootstrap key and the chirp dialect per-build secrets. Source code alone is insufficient to derive either one.
  • Codebase-bound dialect — Only nodes with identical code hash + identical build nonce (verified by the Validation Oracle) can produce or verify chirps. Fork the code → different dialect.
  • Internal-state-driven transitions — ACT state transitions are driven purely by internal state and timers; never by external signals. This prevents remote reset attacks.
  • Traffic analysis resistance — Chirps blend into normal mesh_entropy traffic at the same 30-second gossip cadence. PRAHARI-sourced variable padding (16–64 bytes) prevents size fingerprinting.
  • AGUWA epoch synchronization — ACT executes only at GPS-synchronized epoch boundaries with order parameter r ≥ 0.2. No node acts unilaterally.

Relationship to ANNEX

JHILKE and ANNEX are deliberately separate modules with clean separation of concerns:

Responsibility ANNEX JHILKE
Symmetric encryption AES-256-GCM encrypt/decrypt
Initial key derivation Uses key from JHILKE HKDF(SHA3(codeHash + buildNonce))
KEM exchange ML-KEM-768 encap/decap
Transition coordination ACT state machine (AGUWA-gated)
Peer verification Friend-or-foe chirps (30s)
Message signing ML-DSA-65 sign/verify
Design Philosophy: ANNEX doesn't know how its initial key is derived or when transitions should happen — it just encrypts and decrypts. JHILKE doesn't know how encryption works — it derives keys, verifies peers, and coordinates transition timing. Separation of concerns, Himalayan style.

What JHILKE Is NOT

  • Not a key exchange protocol. It's deterministic bootstrap + coordination. ANNEX handles actual ML-KEM-768 key exchange.
  • Not a trust model. KARMA evaluates chirp failures and manages peer reputation. JHILKE just emits events.
  • Not an encryption cipher. ANNEX handles AES-256-GCM encryption. JHILKE coordinates transition timing and verifies peer identity — KARMA handles trust.
  • Not a failover handler. Lost or failed chirps increment consecutiveFailures — KARMA decides the consequences.

JHILKE is the cricket chorus conductor — it orchestrates when and how all nodes synchronize to the same cryptographic state, continuously verifies that peers belong to the same swarm, and provides ANNEX with the foundation for encrypted communication from the very first message.