Identity & Authorization
The application-facing layer — threshold key enclaves, did:key identifiers, UCAN capability tokens, payload encryption, and WebAssembly code signing.
Everything below this section is code you call directly from an application. The primitives in Foundations, Signatures, and Threshold are the machinery; these five packages are the assembled product: a key that lives in two shares, an identifier derived from its public point, tokens that delegate narrow slices of authority over that key, and two supporting utilities for encrypting payloads and pinning executable code.
How the pieces compose
An enclave holds the key
mpc.NewEnclave() runs a 2-of-2 DKLs18 threshold ECDSA key generation on
secp256k1 and returns an Enclave. The private key never exists as a single scalar: it lives as a
validator share and a user share. Signing is a two-party protocol; refreshing rotates both shares
while leaving the public key fixed.
Its public point becomes an identifier
enclave.PubKeyBytes() yields the uncompressed public point. keys.NewFromMPCPubKey turns those
bytes into a keys.DID, whose String() is a did:key:z… identifier — a
multicodec varint prefix plus multibase base58btc. That string is the stable, resolvable name for
the key.
The identifier issues capability tokens
A UCAN token is a JWT whose issuer is that did:key, signed by the enclave.
Its att claim is a list of attenuations — (capability, resource) pairs. A holder can mint a
delegated token that narrows the set, never widens it, and attaches the parent as a proof.
Choosing a package
| You want to… | Use | Notes |
|---|---|---|
| Hold a signing key without a single point of compromise | mpc |
2-of-2 only; secp256k1 only |
| Name a public key with a stable string | keys |
RSA, Ed25519, secp256k1 |
| Grant another party scoped, expiring authority | ucan |
JWT-based, ucv header 0.9.0 |
| Encrypt a message to someone’s public key | ecies |
Thin wrapper over github.com/ecies/go/v2 |
Verify that a .wasm blob is the one you approved |
wasm |
Ed25519 signing + SHA-256 pinning |
| Parse a chain-specific address | — | keys/parsers is unfinished; see did |
A minimal end-to-end shape
package main
import (
"fmt"
"github.com/sonr-io/crypto/keys"
"github.com/sonr-io/crypto/mpc"
)
func main() {
// 1. Threshold key: both shares generated locally.
enclave, err := mpc.NewEnclave()
if err != nil {
panic(err)
}
// 2. Identifier derived from the enclave's public point.
did, err := keys.NewFromMPCPubKey(enclave.PubKeyBytes())
if err != nil {
panic(err)
}
fmt.Println("issuer:", did.String()) // did:key:z...
// 3. Two-party signature over a message, verified against the public key.
sig, err := enclave.Sign([]byte("hello"))
if err != nil {
panic(err)
}
ok, err := enclave.Verify([]byte("hello"), sig)
fmt.Println("valid:", ok, err)
}
Every one of these packages is generic over, or built on, the curve abstraction described in
Foundations → Curves. Curve, Point, and Scalar are not re-explained here.
Read this before you ship
This section is the least finished part of the repository. The pages below document the rough edges in place rather than around them, because several of them are the kind that silently weaken a security property instead of failing loudly.
Pages
did:key Identifiers
Multicodec + multibase encoding, the DID and PubKey types, the non-standard 66-byte signature
layout, and why to avoid keys/parsers.
MPC Enclave
2-of-2 threshold ECDSA lifecycle: keygen, sign, verify, refresh, import/export, and the real security model.
UCAN Tokens
Capabilities, attenuation, delegation chains, templates, MPC signing, and which authorization checks are not actually implemented.
ECIES
Encrypt to a secp256k1 public key. A thin, honest wrapper — plus one seed hazard.
WASM Module Signing
Ed25519 code signing and SHA-256 hash pinning for WebAssembly supply-chain verification.
Package Index
Every package in the module with its status at a glance.