Skip to content

feat(session)!: migrate DID resolver to dig-identity v0.4 BLS-G1 (resolve_bls_public_key, 48B)#62

Merged
MichaelTaylor3d merged 4 commits into
mainfrom
feat/dig-identity-v0.4-bls
Jul 19, 2026
Merged

feat(session)!: migrate DID resolver to dig-identity v0.4 BLS-G1 (resolve_bls_public_key, 48B)#62
MichaelTaylor3d merged 4 commits into
mainfrom
feat/dig-identity-v0.4-bls

Conversation

@MichaelTaylor3d

Copy link
Copy Markdown
Contributor

C2 of epic #1169 (issue #1171)

Migrates dig-node's engine DID signing-key resolver (ChainDidSigningKeyResolver, #778/#1080) to dig-identity v0.4.0 (BLS-G1-only key model): resolve_signing_key -> [u8;32] becomes resolve_bls_public_key -> [u8;48], slot 0x0010 is now a 48-byte BLS12-381 G1 key (Ed25519 slot + X25519 0x0011 retired), and ResolveError::NoSigningKey becomes NoIdentityKey.

Authority semantics preserved (#778/#1080): chain-authenticated lineage-membership resolution, fail-closed on every ambiguity/staleness/mismatch, no key echo, engine holds no user key. Only the KEY TYPE changes (32B Ed25519 -> 48B BLS G1); the authority logic is unchanged.

BLOCKED on C5b (#1173) — release-first ordering

The resolver implements dig_ipc_protocol::DidSigningKeyResolver, whose resolve_signing_key -> SigningPublicKey([u8;32]) type is owned by dig-ipc-protocol (crates.io, latest v0.1.2, still Ed25519 32B). A 48-byte G1 key cannot be returned through that seam until dig-ipc-protocol widens SigningPublicKey to 48B G1 (+ Signature to 96B G2, verify to BLS) and republishes — that is C5b (#1173, in-progress). So the decider's C2 ∥ C5b must be C5b -> C2. This PR stays DRAFT until the new dig-ipc-protocol version ships; then it is a version-bump-and-merge.

Version: workspace 0.45.0 -> 0.46.0, dig-node-core 0.11.0 -> 0.12.0.

Refs #1171, #1169, #1173, #778, #1080

Co-Authored-By: Claude noreply@anthropic.com

MichaelTaylor3d and others added 3 commits July 18, 2026 23:12
…2 #1171)

WIP stub for the C2 resolver migration (epic #1169). Bumps the
dig-identity git-dep tag to v0.4.0 (BLS-G1-only) and the versions;
resolver migration follows.

Refs #1171
Co-Authored-By: Claude <noreply@anthropic.com>
…olve_bls_public_key, 48B)

Migrate the engine's production DID signing-key resolver
(ChainDidSigningKeyResolver, #778/#1080) to dig-identity v0.4.0's
BLS-only key model (epic #1169):

- resolve_signing_key([u8;32]) -> resolve_bls_public_key([u8;48])
  (slot 0x0010 is now a 48-byte BLS12-381 G1 identity key; the v1
  Ed25519 slot + X25519 0x0011 are retired)
- ResolveError::NoSigningKey -> NoIdentityKey (describe() + tests)
- resolver-only tests: with_schema_v2, BLS_G1_PUBLIC_KEY, 48B key

Authority semantics preserved (#778/#1080): chain-authenticated
lineage-membership resolution, fail-closed, no key echo, engine holds
no user key. Only the key TYPE changes (32B Ed25519 -> 48B BLS G1).

The DidSigningKeyResolver trait + SigningPublicKey/Signature/verify are
owned by dig-ipc-protocol; the 48B key can only be returned through that
seam once C5b (#1173) widens SigningPublicKey to 48B G1 + BLS G2 verify
and republishes. The end-to-end attach tests (still Ed25519) are marked
TODO(#1173) accordingly. BLOCKED on C5b -> stays draft.

Refs #1171, #1169, #1173, #778, #1080
Co-Authored-By: Claude <noreply@anthropic.com>
…ocol 0.2.0

Bumps dig-ipc-protocol 0.1 -> 0.2.0 (crates.io), whose SigningPublicKey
widened to 48-byte BLS12-381 G1 and Signature to 96-byte G2 AugScheme.
This unblocks the resolver's 48-byte return type at session.rs:85 (the
one remaining production error under dig-identity v0.4) and lets the two
end-to-end attach tests exercise real BLS G2 signing.

- Migrate honest_attach + attach_is_refused (and key_from/profile_with_key)
  from ring Ed25519 to chia-bls G2 signing; drop the TODO(#1173) block.
- Add chia-bls dev-dep; profiles publish the slot-0x0010 BLS G1 key via
  schema v2 (standard::BLS_G1_PUBLIC_KEY).
- Pin dig-ipc-protocol 0.2.0 in the lock without disturbing the frozen
  bare-git peer-stack revs (dig-constants/dig-nat HEADs have drifted ahead
  of dig-gossip's <0.5/<0.4 bounds; a full re-resolve would break them).

Authority semantics unchanged (#778/#1080 lineage-membership): only the
key TYPE changed 32->48B; the engine still resolves the chain-authorized
pubkey and holds no user key. Fail-closed + KeyMismatch paths intact.

Refs #1171, #1169, #1173
Co-Authored-By: Claude <noreply@anthropic.com>
@MichaelTaylor3d
MichaelTaylor3d marked this pull request as ready for review July 19, 2026 06:52

@MichaelTaylor3d MichaelTaylor3d left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

loop-reviewer verdict: CHANGES-REQUIRED

The code migration itself is clean, correct, and fully gated (all CI green: Rustfmt, Clippy -D warnings, Test+coverage, CodeQL/Analyze, version-increment, commitlint, per-OS builds). Verified independently against a fresh clone of feat/dig-identity-v0.4-bls @ e5b8170:

What is correct (PASS on these):

  • Resolver correctly swaps dig_identity::resolve_signing_key -> resolve_bls_public_key returning the 48-byte slot-0x0010 BLS G1 identity key; SigningPublicKey::new([u8;48]) now type-checks against dig-ipc-protocol 0.2.0.
  • Error mapping complete: NoSigningKey/no-signing-key fully replaced by NoIdentityKey/no-identity-key; describe_covers_every_resolve_error_variant exercises every arm.
  • No stale 32B/Ed25519 session path remains reachable (grep clean): the only remaining resolve_signing_key is the dig-ipc-protocol TRAIT method (out of scope, owned there); the only remaining Ed25519 is peer.rs mTLS transport identity (unrelated to session auth).
  • Tests exercise REAL BLS keys, verify-success AND refusal: honest_attach_binds_the_session_to_the_chain_resolved_key signs with a real chia_bls::SecretKey via the G2 AugScheme and requires a genuine verify (open_sessions==1); attach_is_refused_when_the_did_advertises_a_key_it_did_not_publish proves the resolved!=presented KeyMismatch fail-closed (open_sessions==0). KAT lengths updated to 48/96.
  • Custody boundary preserved: engine resolves PUBLIC key only, requires resolved==presented, fails closed on every ambiguity. Adversarial lenses (custody / key-substitution / scheme-confusion / replay-domain-separation / length-confusion) all clear.
  • dig-constants check: (1) nothing shared-canonical is defined LOCALLY here — key lengths/domain tags/SIGNING_KEY_LEN/SIGNATURE_LEN come from the correct SSOT (dig-ipc-protocol, the byte-identical session contract crate), not hardcoded; (2) nothing here hardcodes a value dig-constants already publishes. Clears.
  • Version bump 0.11->0.12 / 0.45->0.46 is a correct pre-1.0 minor-for-breaking bump.

BLOCKING finding (see inline): the repo's own normative SPEC.md §7.15 was NOT updated in this unit of work and now contradicts the shipped code for a security-critical auth path. §4.2 makes a SPEC-describing-old-behavior change INCOMPLETE. Fix the stale 32B/Ed25519 language, then this is a clean PASS.

Comment thread crates/dig-node-core/src/session.rs

@MichaelTaylor3d MichaelTaylor3d left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CHANGES-REQUIRED (loop-reviewer, fresh independent context — custody-adjacent key-type migration).

The code migration itself is CORRECT and I verified the security-critical properties are preserved:

  • Key-type migration correct. resolve_signing_key([u8;32])resolve_bls_public_key([u8;48]) at session.rs:84; the seam returns SigningPublicKey::new(key) over the 48B G1 pubkey; SIGNING_KEY_LEN 48 / SIGNATURE_LEN 96 KATs asserted; NoSigningKeyNoIdentityKey in describe. dig-ipc-protocol 0.2.0 (widened SigningPublicKey 48B / Signature 96B G2) consumed correctly; Cargo.lock shows it published from registry.
  • Authority PRESERVED (#778/#1080). The resolver body only swaps the delegated fn; the lineage-membership walk, fail-closed-on-every-error mapping, no-key-echo, and KeyMismatch-on-substitution logic are byte-unchanged. Every authority test survives — invalid DID, melted singleton, chain-source error, no-key, honest_attach, attach_is_refused_when_the_did_advertises_a_key_it_did_not_publish (KeyMismatch), describe-covers-every-variant.
  • Attach tests migrated genuinely. key_from now derives a chia_bls::SecretKey::from_seed (hashed seed, no literal); profiles publish slot-0x0010 via with_schema_v2 + BLS_G1_PUBLIC_KEY; challenges signed with chia_bls::sign (96B G2), pub is to_bytes() (48B). Real BLS attach/verify exercised end-to-end.
  • Deps / version. dig-ipc-protocol 0.2, dig-identity v0.4.0 tag, chia-bls 0.26 dev-dep; ed25519-dalek/curve25519 removed from the lock. 0.45.0→0.46.0 / 0.11.0→0.12.0 feat! breaking bump correct. dig-node is modules/apps (nightlies) → git dep on dig-identity OK.
  • Gates green (clippy -D, fmt, tests incl. 2 BLS attach, coverage). Beautiful-code: doc-comments updated to the BLS model, reads cleanly.

The one blocker is the already-open coherence thread at session.rs:84 (§4.2): the repo's own normative SPEC.md still describes the OLD auth path and now contradicts the shipped code —

  • SPEC.md:1340 "delegating to dig_identity::resolve_signing_key" → now resolve_bls_public_key
  • SPEC.md:1364 "the engine validates the DID + 32-byte hex key" → now 48-byte BLS G1
  • SPEC.md:1369 "Ed25519-verifies the challenge signature" → now BLS12-381 G2 AugScheme

I re-verified against branch head feat/dig-identity-v0.4-bls: these lines are still stale. An independent reimplementer reading the current spec would build an incompatible 32B-Ed25519 verifier for the session-attach custody boundary — exactly the §4.2 half-migration this gate forbids. Update §7.15 (+ confirm top-level vs crates/dig-node-core/SPEC.md agree) in this same unit of work, then re-request. No authority weakening beyond the type change was found — no adversarial escalation needed; this is purely the spec-coherence gap.

…2 AugScheme verify)

Co-Authored-By: Claude <noreply@anthropic.com>
@MichaelTaylor3d

Copy link
Copy Markdown
Contributor Author

SPEC.md §7.15 is now aligned with BLS-G1 auth migration:

  • Line 1340: resolve_signing_keyresolve_bls_public_key (commit d64d134)
  • Line 1364: 32-byte → 48-byte hex key
  • Line 1369: Ed25519-verifies → BLS12-381 G2 AugScheme-verifies

No other stale Ed25519 or resolve_signing_key references found in session-auth context (dig-node-core/SPEC.md clean). Spec now describes the actual shipped BLS-only key model per dig-ipc-protocol 0.2.0.

@MichaelTaylor3d
MichaelTaylor3d merged commit a4398f4 into main Jul 19, 2026
13 checks passed
@MichaelTaylor3d
MichaelTaylor3d deleted the feat/dig-identity-v0.4-bls branch July 19, 2026 10:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant