The Selective Disclosure Problem

A signed document contains many fields. A KYC record might include name, date of birth, address, nationality, ID number, and verification status. But a lending protocol only needs to know "is this person verified and not sanctioned?" — not their home address.

Without selective disclosure, you face a binary choice: share everything or share nothing. Lemma introduces a third option: share exactly the fields that matter, with cryptographic proof that they belong to the original signed document.

How BBS+ Selective Disclosure Works

Lemma uses BBS+ signatures as the default selective disclosure mechanism. The SDK's disclose module provides a complete BBS+ implementation:

Key generation and message preparation:

import { disclose } from "@lemmaoracle/sdk";

// Generate BBS+ key pair
const kp = await disclose.generateKeyPair();

// Convert payload to sorted "key:value" messages
const messages = disclose.payloadToMessages({
  age: 25,
  name: "Alice",
  country: "JP",
});
// → ["age:25", "country:JP", "name:Alice"]

Issuer signs the full document:

const signed = await disclose.sign(client, {
  messages,
  secretKey: kp.secretKey,
  header: new TextEncoder().encode("my-app-header"),
  issuerId: "issuer-1",
});
// signed.signature → BBS+ signature

Holder reveals only selected attributes:

const revealed = await disclose.reveal(client, {
  signature: signed.signature,
  messages,
  publicKey: signed.publicKey,
  disclosedIndexes: [0], // index of "age:25" in messages array
  header: signed.header,
});
// revealed.disclosed → { age: "25" }
// revealed.proof → BBS+ selective disclosure proof

// Wrap for spec compliance
const sd = disclose.toSelectiveDisclosure(revealed);
// sd.format → "bbs+", sd.disclosedAttributes → { age: "25" }, sd.proof → hex-encoded

The proof mathematically guarantees that { age: 25 } is part of the document the issuer signed, without revealing any other field. The verifier never sees the full document.

Provenance Survives Partial Views

A common concern with selective disclosure is loss of context. If you only see one field, how do you know it is trustworthy?

In Lemma, disclosed attributes carry full provenance:

Even a single disclosed field traces back to its origin through an unbroken chain of cryptographic evidence.

Role-Based and Party-Specific Views

Different consumers need different views of the same document:

Each view is generated from the same signed document with a different attributes array passed to disclose.reveal. No separate copies of the data are created. No additional signing steps are needed.

Future-Proof Design

The SDK's disclose namespace is named for the function it performs, not the cryptographic scheme it uses. The initial implementation uses BBS+, but the API is designed to support SD-JWT and other mechanisms without changing the developer-facing interface. When you call disclose.reveal, you are expressing intent ("show only these fields") rather than choosing a specific algorithm.

Complete BBS+ API

The disclose module includes all necessary BBS+ operations: