BLS12_381ProofOfPossession (Bouncy Castle Library 1.85 API Specification)
Date: 2026-07-12

org.bouncycastle.crypto.bls

## Class BLS12_381ProofOfPossession

- java.lang.Object
- - org.bouncycastle.crypto.bls.BLS12_381ProofOfPossession

-     public class BLS12_381ProofOfPossession
      extends java.lang.Object

  BLS signatures ProofOfPossession suite over BLS12-381, per draft-irtf-cfrg-bls-signature: signature suite `BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_` together with a separate proof-of-possession message that uses the `BLS_POP_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_` DST.

  This suite is the only one that supports `fastAggregateVerify(org.bouncycastle.math.ec.ECPoint[], byte[], org.bouncycastle.crypto.bls.BLS12_381G2Point)` — all signers signed the same message, so verification reduces to summing the public keys and running a single pairing check. The standalone `popProve(java.math.BigInteger)`/`popVerify(org.bouncycastle.math.ec.ECPoint, org.bouncycastle.crypto.bls.BLS12_381G2Point)` primitives let a registry verifier confirm that a signer holds the secret key for their declared public key before accepting their signatures into an aggregate.

  The public-key bytes used in the `popProve(java.math.BigInteger)`/`popVerify(org.bouncycastle.math.ec.ECPoint, org.bouncycastle.crypto.bls.BLS12_381G2Point)` hash input are the Zcash-format 48-byte compressed G1 encoding produced by `BLS12_381Serialization.compressG1(org.bouncycastle.math.ec.ECPoint)`, matching draft-irtf-cfrg-bls-signature's `point_to_pubkey`.

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `static byte[]` | `DST`
    `static byte[]` | `POP_DST`

  - ### Method Summary

    All Methods Static Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `static boolean` | `aggregateVerify(ECPoint[] pks, byte[][] messages, BLS12_381G2Point sigAgg)` Aggregate verification under the ProofOfPossession suite.
    `static boolean` | `fastAggregateVerify(ECPoint[] pks, byte[] message, BLS12_381G2Point sigAgg)` Fast aggregate verification: every signer signed the same message, so `e(G1, sig_agg) == e(sum(pk_i), H(message))` reduces to a single pairing check on the aggregated public key.
    `static BLS12_381G2Point` | `popProve(java.math.BigInteger sk)` Generate a proof-of-possession for `sk`.
    `static boolean` | `popVerify(ECPoint pk, BLS12_381G2Point proof)` Verify a proof-of-possession against the declared public key.
    `static BLS12_381G2Point` | `sign(java.math.BigInteger sk, byte[] message)`
    `static boolean` | `verify(ECPoint pk, byte[] message, BLS12_381G2Point signature)`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### DST

          public static final byte[] DST

    - #### POP_DST

          public static final byte[] POP_DST

  - ### Method Detail

    - #### sign

          public static BLS12_381G2Point sign(java.math.BigInteger sk,
                                              byte[] message)

    - #### verify

          public static boolean verify(ECPoint pk,
                                       byte[] message,
                                       BLS12_381G2Point signature)

    - #### popProve

          public static BLS12_381G2Point popProve(java.math.BigInteger sk)

      Generate a proof-of-possession for `sk`. The proof is bound to `SkToPk(sk)` via the POP DST and the public-key encoding so a verifier can confirm the signer holds the matching secret key without any context message.

    - #### popVerify

          public static boolean popVerify(ECPoint pk,
                                          BLS12_381G2Point proof)

      Verify a proof-of-possession against the declared public key.

    - #### aggregateVerify

          public static boolean aggregateVerify(ECPoint[] pks,
                                                byte[][] messages,
                                                BLS12_381G2Point sigAgg)

      Aggregate verification under the ProofOfPossession suite. Distinct messages are not required because the standalone PoP step is expected to have screened out rogue keys before any aggregation is attempted.

    - #### fastAggregateVerify

          public static boolean fastAggregateVerify(ECPoint[] pks,
                                                    byte[] message,
                                                    BLS12_381G2Point sigAgg)

      Fast aggregate verification: every signer signed the same message, so `e(G1, sig_agg) == e(sum(pk_i), H(message))` reduces to a single pairing check on the aggregated public key. Caller is expected to have run `popVerify(org.bouncycastle.math.ec.ECPoint, org.bouncycastle.crypto.bls.BLS12_381G2Point)` on each `pk_i` before trusting the aggregate.