Files
zeekay 366c1d87a4 feat(rns): canonical DID computation + cross-language KAT fixture
Adds the minimum-viable PQ-RNS conformance test:

- did.go: ComputeDID(kemPubKey, sigPubKey) — base32 lowercase no-padding
  of SHA3-256(kemPubKey || sigPubKey), prefixed "did⚡"
- did_test.go: Go test that reads testdata/pqrns_kat.json and verifies
  the implementation reproduces the canonical DID
- testdata/pqrns_kat.json: language-neutral fixture — fixed input keys
  (1216 bytes of 0x01 for KEM, 1984 bytes of 0x02 for sig) → fixed
  SHA3-256 (72bea585...) and DID (did:zap:ok7klbkh...)

Every language SDK that implements PQ-RNS MUST reproduce the same DID
for the same inputs. The KAT catches any divergence on the hash, byte
order, base32 alphabet, or casing.

go test ./... passes locally.
2026-05-27 04:47:35 -07:00

28 lines
1.0 KiB
Go

// Package rns implements the canonical DID computation for the Resource Name
// Service. The DID is the lowercase RFC 4648 base32 encoding of the SHA3-256
// of (kemPubKey || sigPubKey), prefixed with "did:zap:".
//
// Every language SDK MUST reproduce the same DID for the same inputs.
// The KAT vector in testdata/pqrns_kat.json is the conformance fixture.
package rns
import (
"encoding/base32"
"strings"
"golang.org/x/crypto/sha3"
)
// ComputeDID returns the canonical did:zap identifier for an identity
// composed of a KEM public key and a signature public key.
//
// - kemPubKey: X-Wing static public key (1216 bytes)
// - sigPubKey: hybrid Ed25519 + ML-DSA-65 verification key (1984 bytes)
//
// DID = "did:zap:" + base32(SHA3-256(kemPubKey || sigPubKey)) lowercase, no padding.
func ComputeDID(kemPubKey, sigPubKey []byte) string {
h := sha3.Sum256(append(append([]byte{}, kemPubKey...), sigPubKey...))
enc := base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(h[:])
return "did:zap:" + strings.ToLower(enc)
}