Skip to content

AP2 support - add secp256r1 signing keys - #567

Merged
mike-parkhill merged 5 commits into
masterfrom
ap2/v0.2-secp256r1-signing-keys
Jul 28, 2026
Merged

AP2 support - add secp256r1 signing keys#567
mike-parkhill merged 5 commits into
masterfrom
ap2/v0.2-secp256r1-signing-keys

Conversation

@mike-parkhill

Copy link
Copy Markdown
Contributor

No description provided.

mike-parkhill and others added 2 commits July 28, 2026 16:28
AP2 v0.2 mandates require a P-256 (ES256) holder key for the cnf claim,
and wallet DIDs only supported Ed25519. Adds a secp256r1 branch to
keypairToKeydoc/keyDocToKeypair/generateKeyDoc (reusing the existing
Secp256r1Keypair from @docknetwork/credential-sdk, no new crypto), plus
a narrow signWithKeyDoc RPC method that returns a raw signature over
caller-supplied bytes — distinct from createSignedJWT, which builds a
full JWT itself.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds a way to create and sign with a bare (non-did:key) signing key
attached to an existing DID, on top of the wasm-layer secp256r1 support
added in the previous commit. Distinct from createDIDKey: it doesn't
mint a new did:key document, since the AP2 mandate cnf key doesn't need
one — just a keypair the wallet can sign with later by keyId.

Includes a Node crypto round-trip test (generate key, sign, verify via
Secp256r1Keypair.verify) plus invalid-controller and unknown-keyId
rejection tests, added as a .js file since this repo's jest testMatch
only picks up .test.js, not .test.ts (a pre-existing gap — the existing
did-provider.test.ts is not run by `npm test` either).

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds AP2-oriented support for P-256 (secp256r1) signing keys by enabling generation/storage of secp256r1 key documents and exposing a “raw bytes” signing API (distinct from JWT signing) through the wasm DID service and the core DID provider.

Changes:

  • Add secp256r1 key generation support and key document encoding (multibase/multicodec + base58 fields).
  • Add a signWithKeyDoc RPC method and core provider helpers createSigningKey / signWithKeyId.
  • Add core-level tests covering secp256r1 key creation, signing, and basic input validation.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/wasm/src/services/dids/service.ts Adds secp256r1 generation option and introduces signWithKeyDoc for raw signing.
packages/wasm/src/services/dids/service-rpc.ts Exposes signWithKeyDoc via the DID JSON-RPC client wrapper.
packages/wasm/src/services/dids/keypair-utils.js Adds multicodec headers for P-256 and serializes secp256r1 key docs.
packages/wasm/src/services/credential/utils.js Enables restoring a Secp256r1Keypair from stored key docs.
packages/core/src/types.ts Extends IDIDProvider with createSigningKey and signWithKeyId.
packages/core/src/did-provider.ts Implements createSigningKey and signWithKeyId using the wasm DID service.
packages/core/src/did-provider-signing-key.test.js Adds test coverage for creating secp256r1 keys and signing/verifying.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +122 to +126
const publicKeyBase58 = bs58.encode(publicKey);
const privateKeyBase58 = bs58.encode(pk);

const keyId = id || key.id || `${controller}#secp256r1-1`;
keyDoc = {
Comment on lines +127 to +131
async signWithKeyDoc({data, privateKeyDoc}) {
const keypair = privateKeyDoc.keypair || (await keyDocToKeypair(privateKeyDoc));
const message = data instanceof Uint8Array ? data : new Uint8Array(data);
return new Uint8Array(keypair.sign(message).bytes);
}
Comment on lines +245 to +255
export async function signWithKeyId({wallet, keyId, data}) {
assert(!!wallet, 'wallet is required');
assert(!!keyId, 'keyId is required');

const keyDoc = await wallet.getDocumentById(keyId);
if (!keyDoc) {
throw new Error(`No stored key document found for keyId: ${keyId}`);
}

return didServiceRPC.signWithKeyDoc({privateKeyDoc: keyDoc, data});
}
@mike-parkhill
mike-parkhill merged commit da88000 into master Jul 28, 2026
7 checks passed
@mike-parkhill
mike-parkhill deleted the ap2/v0.2-secp256r1-signing-keys branch July 28, 2026 21:17
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.

3 participants