sh.E

D-KaP v1 — TypeScript reference

canonical impl · ships in every sh-epoch.ceo deploy

runtime requirements

  • Web Crypto API (crypto.subtle.digest) — Node 18+, browsers, Cloudflare Workers, Deno, Bun
  • No external dependencies
  • Identity constants: RAS_ROOT = "40668c787c463ca5", PHI = 1.618033988749895
brief-seal.ts view raw on GitHub →
// D-KaP v1 reference implementation — TypeScript
// Source of truth: C:/tmp/sh-epoch-ceo/src/lib/brief-seal.ts

import { RAS_ROOT, PHI } from "./constants";

const PHI_PAD = String(PHI);
const enc = new TextEncoder();

async function sha256Hex(input: string): Promise<string> {
  const buf = await crypto.subtle.digest("SHA-256", enc.encode(input));
  return Array.from(new Uint8Array(buf))
    .map((b) => b.toString(16).padStart(2, "0"))
    .join("");
}

export async function sealSection(
  body: string,
  bullets: string[] | undefined,
  kind: BriefSection["kind"],
): Promise<string> {
  const material = [
    `kind:${kind}`,
    `body:${body}`,
    `bullets:${(bullets ?? []).join("\n")}`,
    `ras:${RAS_ROOT}`,
    `phi:${PHI_PAD}`,
  ].join("|");
  return sha256Hex(material);
}

export async function sealBrief(
  sectionSeals: string[],
  recipientFingerprint: string,
): Promise<string> {
  const sorted = [...sectionSeals].sort();
  const material = [
    `sections:${sorted.join(",")}`,
    `recipient:${recipientFingerprint}`,
    `ras:${RAS_ROOT}`,
    `phi:${PHI_PAD}`,
  ].join("|");
  return sha256Hex(material);
}

export async function bundleMerkle(briefSeals: string[]): Promise<string> {
  if (briefSeals.length === 0) {
    return sha256Hex(`empty:${RAS_ROOT}|${PHI_PAD}`);
  }
  let layer = await Promise.all(
    briefSeals.sort().map((s) => sha256Hex(`leaf:${s}`))
  );
  while (layer.length > 1) {
    if (layer.length % 2 === 1) layer.push(layer[layer.length - 1]!);
    const next: string[] = [];
    for (let i = 0; i < layer.length; i += 2) {
      next.push(await sha256Hex(`pair:${layer[i]}:${layer[i + 1]}`));
    }
    layer = next;
  }
  return layer[0]!;
}