--- title: Signatures description: Choosing between BLS aggregation, BBS+ selective disclosure, ECDSA canonicalization, verifiable random functions, and the chain-specific Schnorr variants. sidebar: order: 1 icon: pen-tool --- Five very different things live under this heading, and they are not interchangeable. Before you pick one, decide which property you actually need: **aggregation** (many signatures collapse into one), **selective disclosure** (a holder proves a subset of signed attributes), **determinism and canonical encoding** (the same message always yields the same bytes), **verifiable randomness** (an output nobody can predict but everybody can check), or **wire compatibility with a specific blockchain**. Every package here is a distinct construction with its own key type. There is no shared `Signer` interface across them, and keys from one scheme are never valid in another. ## Pick a scheme | Goal | Package | Page | | --- | --- | --- | | Collapse N signatures over N messages into one 96-byte object | `signatures/bls/bls_sig` | [BLS](/signatures/bls) | | Multi-signature: N signers, one message, one aggregate check | `signatures/bls/bls_sig` (`SigPop`) | [BLS](/signatures/bls) | | Split a signing key into `t`-of-`n` shares with no interaction | `signatures/bls/bls_sig` | [BLS](/signatures/bls) | | Sign a vector of attributes; let the holder reveal only some | `signatures/bbs` | [BBS+](/signatures/bbs) | | Issue a credential over messages the issuer must not see | `signatures/bbs` | [BBS+](/signatures/bbs) | | Kill ECDSA signature malleability before storing or comparing | `ecdsa` | [ECDSA utilities](/signatures/ecdsa) | | Sign with ECDSA without depending on runtime entropy | `ecdsa` | [ECDSA utilities](/signatures/ecdsa) | | Unpredictable-but-verifiable per-message output (leader election, lotteries) | `vrf` | [VRF](/signatures/vrf) | | Sign a Mina payment or delegation transaction | `signatures/schnorr/mina` | [Chain schemes](/signatures/chain-schemes) | | Produce a NEM/Symbol Keccak-flavoured Ed25519 signature | `signatures/schnorr/nem` | [Chain schemes](/signatures/chain-schemes) | Some adjacent things are documented elsewhere: - The **interactive Schnorr proof of knowledge** (`zkp/schnorr`) is a ZKP, not a signature scheme — see [zero-knowledge/schnorr](/zero-knowledge/schnorr). - **Threshold ECDSA** and **threshold Ed25519** (FROST) produce ordinary ECDSA / Ed25519 signatures from distributed shares — see [threshold ECDSA](/threshold/threshold-ecdsa) and [threshold Ed25519](/threshold/threshold-ed25519). BLS threshold signing on this page is a different, much simpler construction: it needs no rounds of interaction. ## What these packages assume about curves `signatures/bbs` and the Mina scheme are written against the [`core/curves`](/foundations/curves) `Curve` / `Point` / `Scalar` abstraction — BBS+ specifically requires a `*curves.PairingCurve` (`curves.BLS12381(...)`). `signatures/bls/bls_sig` bypasses the abstraction entirely and calls the low-level `core/curves/native/bls12381` backend directly, so it is hard-wired to BLS12-381. The `ecdsa` package operates on stdlib `crypto/ecdsa` and `crypto/elliptic` types, and `vrf` on a vendored Edwards25519 implementation. ## The shared proof toolkit: `signatures/common` `signatures/common` holds the sigma-protocol plumbing that BBS+ (and code composing proofs with BBS+) builds on. It is a building-block package — you rarely import it alone, but you will import it to construct BBS+ proof messages. | Symbol | Kind | Purpose | | --- | --- | --- | | `Challenge` | `= curves.Scalar` | Fiat-Shamir challenge value | | `Commitment` | `= curves.Point` | Pedersen commitment to one or more scalars | | `Nonce` | `= curves.Scalar` | Freshness / replay protection in a proof | | `SignatureBlinding` | `= curves.PairingScalar` | Blinding factor for blind signing | | `HmacDrbg` | struct | HMAC deterministic random bit generator, any hash, auto-reseeding | | `ProofCommittedBuilder` | struct | Accumulates `(point, scalar)` commitments into Schnorr proofs | | `ProofMessage` | interface | Classifies a signed message as revealed or hidden | The four aliases are Go **type aliases**, not defined types: a `common.Nonce` *is* a `curves.Scalar`, so no conversion is needed and the compiler will not stop you passing a challenge where a nonce belongs. Treat the names as documentation, not as type safety. ### `ProofMessage` and its three implementations `ProofMessage` is how a BBS+ prover declares, per message, whether it is disclosed: ```go type ProofMessage interface { IsHidden() bool GetBlinding(reader io.Reader) curves.Scalar GetMessage() curves.Scalar } ```