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

org.bouncycastle.crypto.bls

## Class BLS12_381Pairing

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

-     public class BLS12_381Pairing
      extends java.lang.Object

  Optimal ate pairing on BLS12-381: a bilinear, non-degenerate map `e: G1 x G2 -> GT` where GT is the order-r subgroup of Fp^12 ^*.

  This implementation favours obvious correctness over performance:

  - G2 is lifted into `E(Fp^12)` via the D-twist isomorphism `(x', y') -> (x'/w^2, y'/w^3)`.
  - The Miller loop runs the textbook affine doubling / addition formulas on `E(Fp^12)` and computes the line evaluations as full (non-sparse) Fp^12 elements.
  - The final exponentiation is performed as a single Fp^12 modPow with exponent `(p^12 - 1) / r`, sidestepping the Frobenius-coefficient infrastructure that the spec-recommended easy/hard-part split would need.
  Sparse line evaluation, Frobenius-based final exponentiation, and a Jacobian-coord G2 in pairing context are all natural follow-on optimisations that preserve the public surface here.

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `static java.math.BigInteger` | `HARD_EXPONENT` Hard-part exponent `(p^4 - p^2 + 1) / r` (~1269 bits), applied after the Frobenius-based easy part.

  - ### Method Summary

    All Methods Static Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `static Fp12Element` | `hardPart(Fp12Element f)` The hard part of the final exponentiation, exposed for cross-package layered testing (the test classes live in `org.bouncycastle.crypto.hash2curve.test` and need direct access to the easy/hard split for KAT comparison against reference outputs).
    `static Fp12Element` | `multiPair(ECPoint[] g1Points, BLS12_381G2Point[] g2Points)` Multi-pairing: compute the product `e(P_0, Q_0) * e(P_1, Q_1) * ... * e(P_{n-1}, Q_{n-1})` with a single shared Miller loop and a single final exponentiation.
    `static Fp12Element` | `pair(ECPoint g1, BLS12_381G2Point g2)` Compute the optimal ate pairing `e(P, Q)` for `P` on BLS12-381 G1 and `Q` on BLS12-381 G2.

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

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

- - ### Field Detail

    - #### HARD_EXPONENT

          public static final java.math.BigInteger HARD_EXPONENT

      Hard-part exponent `(p^4 - p^2 + 1) / r` (~1269 bits), applied after the Frobenius-based easy part. The full final exponent `(p^12 - 1) / r` (~4317 bits) factors as `(p^6 - 1) * (p^2 + 1) * (p^4 - p^2 + 1) / r`; the easy part computes `f^((p^6 - 1)(p^2 + 1))` essentially for free using conjugation and one Frobenius² application, leaving only this shorter exponent for `Fp12Element.modPow(java.math.BigInteger)`.

  - ### Method Detail

    - #### pair

          public static Fp12Element pair(ECPoint g1,
                                         BLS12_381G2Point g2)

      Compute the optimal ate pairing `e(P, Q)` for `P` on BLS12-381 G1 and `Q` on BLS12-381 G2.
      Parameters:
        `g1` - a point on the BLS12-381 G1 curve. Must be in the prime-order subgroup; this method does not subgroup-check.
        `g2` - a point on the BLS12-381 G2 curve. Must be in the prime-order subgroup; this method does not subgroup-check.
      Returns:
        `e(P, Q)` as an Fp^12 element in the order-r subgroup of Fp^12 ^*. Returns 1 if either input is the point at infinity.

    - #### multiPair

          public static Fp12Element multiPair(ECPoint[] g1Points,
                                              BLS12_381G2Point[] g2Points)

      Multi-pairing: compute the product `e(P_0, Q_0) * e(P_1, Q_1) * ... * e(P_{n-1}, Q_{n-1})` with a single shared Miller loop and a single final exponentiation. This cuts a 2-pairing verification (e.g. BLS signature verify) to roughly the cost of one pair() call, since the dominant final exponentiation is performed only once.

      Pairs whose G1 or G2 component is the point at infinity are skipped (their pairing value is 1, identity in GT). If all pairs are skipped, the result is `Fp12Element.ONE`.

      Parameters:
        `g1Points` - G1 inputs.
        `g2Points` - G2 inputs; must be the same length as `g1Points`.
      Returns:
        the product of pairings as an element of GT.
      Throws:
        `java.lang.IllegalArgumentException` - if the arrays differ in length.

    - #### hardPart

          public static Fp12Element hardPart(Fp12Element f)

      The hard part of the final exponentiation, exposed for cross-package layered testing (the test classes live in `org.bouncycastle.crypto.hash2curve.test` and need direct access to the easy/hard split for KAT comparison against reference outputs). Not part of the intended public API of this class — production callers should use `pair(org.bouncycastle.math.ec.ECPoint, org.bouncycastle.crypto.bls.BLS12_381G2Point)` / `multiPair(org.bouncycastle.math.ec.ECPoint[], org.bouncycastle.crypto.bls.BLS12_381G2Point[])`.