Note Disclosure
A note disclosure key is a compact, shareable string that lets you prove the exact contents of a shielded note — value, asset, and commitment — to any third party, without granting them any ability to spend the note.
This is Orbinum's mechanism for voluntary transparency: you remain private by default, but you can selectively reveal a note when you choose to.
Background: what a note is
When you shield tokens, the runtime records a commitment on-chain — a hash of the note's plaintext contents. The commitment is all that is ever publicly visible.
commitment = Poseidon4(value, asset_id, owner_pk_ax, blinding)
| Field | Description |
|---|---|
value | Token amount (e.g. 100000000000000000000000 for 100 000 ORB) |
asset_id | Asset identifier (0 = ORB) |
owner_pk_ax | x-coordinate of the owner's Baby JubJub public key |
blinding | Random 32-byte scalar preventing brute-force preimage recovery |
Because the commitment is a one-way hash, anyone can see it on-chain but no one can determine what it contains. A disclosure key solves this: it encodes the four inputs so that any holder can verify the hash and confirm the note's contents.
The disclosure key format
A disclosure key is a string with the prefix orbdisc: followed by a base64url-encoded JSON payload:
orbdisc:<base64url(JSON)>
The JSON payload (version 1):
{
"v": 1,
"c": "0x2d0aba56a9fb579a007a1980a6164f248682546aa460ea46956be66fabeb8ea7",
"val": "0x152d02c7e14af6800000",
"aid": "0x0",
"opk": "0x1d4a09a1ab9ffff52fbef32c393617d70c03c92835bc6331fbb4a45e381d9735",
"bld": "0x2dcbb6f4d229a19c91e1a4ee057bafa3a96573fa3655964486 4c811b13ae8d62"
}
All numeric values use little-endian hex — the canonical representation of BN254 field elements as used by the ZK circuit.
The same commitment appears in two forms in the system. On-chain (Substrate, block explorers) it is stored as big-endian H256. Inside the circuit and in the disclosure key it is stored as a little-endian BN254 field element. They are byte-reversed versions of each other.
Example:
On-chain (big-endian): 0xa78eebab6fe66b9546ea60a46a548286244f16a680197a009a57fba956ba0a2d
Disclosure key (LE): 0x2d0aba56a9fb579a007a1980a6164f248682546aa460ea46956be66fabeb8ea7
Both represent the same commitment.
What a disclosure key reveals
- Exact token amount (
value) - Asset type (
asset_id) - Owner's Baby JubJub public key (x-coordinate)
- Blinding scalar
- Commitment (cryptographically verified)
- Spending key
- Nullifier (cannot be derived without spending key)
- EVM wallet address
- Any other note owned by the same key
- Transaction history
Two separate key systems
Understanding why the owner public key is different from the EVM wallet address requires knowing how Orbinum's key system works.
Every user operates two independent key pairs:
| EVM keypair | Baby JubJub keypair | |
|---|---|---|
| Curve | secp256k1 | Baby JubJub (twisted Edwards) |
| Where it lives | Ethereum wallet (MetaMask, etc.) | Derived inside the SDK |
| Public identifier | EVM address (0xf24ff3a9...) | BJJ point x-coordinate (0x1d4a09a1...) |
| Purpose | Signs transactions, pays gas | Owns shielded notes, used in ZK circuits |
The BJJ keypair is ZK-friendly: scalar multiplications on Baby JubJub cost ~3 000–4 000 R1CS constraints inside a Groth16 circuit, versus hundreds of thousands for secp256k1. This is why notes use BJJ keys internally rather than EVM keys.
Spending key derivation
EVM wallet
└─ signMessage("orbinum-spending-key-v1:<address>")
└─ HKDF-SHA256(signature bytes)
└─ spending_key (BJJ scalar, kept secret)
└─ owner_pk = spending_key · G (BJJ point, Ax stored on-chain)
The spending key never leaves the SDK. The public key (owner_pk.Ax) is what gets embedded in the note commitment. It cannot be reverse-mapped to the EVM wallet address.
Cryptographic verification
When a recipient decodes a disclosure key, they recompute the commitment from the revealed inputs and compare it against the embedded "c" field:
recomputed = Poseidon4(value, asset_id, owner_pk_ax, blinding)
valid = (recomputed === commitment)
This is a cryptographic proof of knowledge of the preimage. A forged key with an incorrect value will produce a different hash and fail verification. The decodeNoteDisclosureKey function in the SDK returns null for any key that fails this check.
How to generate and verify a disclosure key
Generating a key (note owner)
import { createNoteDisclosureKey } from '@orbinum/sdk/shielded-pool/protocol';
const key = createNoteDisclosureKey(note);
// "orbdisc:eyJ2IjoxLCJjIjoi..."
The note must be a ZkNote — a decrypted note object held by the owner. The function extracts value, assetId, ownerPk, and blinding from the note and serialises them as a disclosure key. The spending key is never included.
Verifying a key (any third party)
import { decodeNoteDisclosureKey } from '@orbinum/sdk/shielded-pool/protocol';
const disclosure = decodeNoteDisclosureKey(key);
if (disclosure === null) {
// key is malformed, tampered, or contains an incorrect preimage
} else {
console.log('value :', disclosure.value); // bigint
console.log('assetId :', disclosure.assetId); // bigint
console.log('commitment verified ✓');
}
No network call is required. Verification is a local Poseidon hash computation.
Use cases
Share a disclosure key to prove that a specific commitment holds a given amount, without revealing your full balance or other notes.
Provide a disclosure key to a regulator or auditor for a specific note. They can verify the amount and asset without seeing the rest of your portfolio.
Prove to a counterparty that a payment was made by sharing the disclosure key for the output note of a private transfer.
Security properties
Each key covers exactly one note. Sharing a disclosure key does not reveal any information about other notes belonging to the same owner, even if they use the same Baby JubJub key.
A disclosure key encodes the blinding value. Anyone with the key can reconstruct the full Poseidon4 preimage and confirm the note's contents. Do not share disclosure keys with parties you do not intend to inform.
The spending key — which is required to generate a nullifier and spend the note — is never included in the disclosure key. A recipient of a disclosure key cannot spend or freeze the note.