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

org.bouncycastle.crypto.hash2curve

## Class OPRFHashToScalar

- java.lang.Object
- - org.bouncycastle.crypto.hash2curve.OPRFHashToScalar

-     public class OPRFHashToScalar
      extends java.lang.Object

  Generic implementation of HashToScalar as used in OPRF (RFC 9497).

  This implementation intentionally provides a *single* unified HashToScalar construction for all supported prime-order elliptic curve groups (P-256, P-384, P-521, Curve25519, Ristretto255, and Decaf448). Although RFC 9497 appears to specify different procedures for NIST curves and Edwards-family curves, these procedures are mathematically equivalent to one another and can be implemented using one common algorithm.

  ## Background

  RFC 9497 defines HashToScalar as follows:

  - For NIST curves: use `hash_to_field` from RFC 9380 with modulus equal to the group order.
  - For other curves (Curve25519, Ristretto255, Decaf448): expand the input using `expand_message_xmd`, interpret the output as an integer, and reduce it modulo the group order.

  At first glance these appear to be fundamentally different algorithms. However, the use of hash_to_field for NIST curves is 100% equivalent to doing the same message_expansion_xmd operation described for other curves. That is:

         uniform_bytes = expand_message_xmd(msg, DST, L)
         scalar        = OS2IP(uniform_bytes) mod q

  where `L = ceil((log2(q) + k) / 8)` and `k` is the security parameter for the ciphersuite. This is precisely the construction used for the Edwards-family curves. In other words, *both branches of RFC 9497 ultimately specify the same mathematical operation*.

  ## Rationale for a unified implementation

  Using a single generic implementation has several advantages:

  - It avoids duplicating two code paths that differ only superficially.
  - It eliminates any ambiguity between curve field primes and group-order primes.
  - It has been verified through test vectors of OPRF to produce a 100% compliant result
  - It provides a consistent and auditable design across all curves.

  For these reasons, this class implements the general form:

         uniform_bytes = expand_message_xmd(msg, DST, L)
         scalar        = OS2IP(uniform_bytes) mod group_order

  This behavior is fully compliant with RFC 9497 and RFC 9380 and is applicable to all prime-order elliptic-curve groups.

- - ### Constructor Summary

    Constructors
    Constructor and Description
    `OPRFHashToScalar(ECCurve curve, Digest digest, int k, int s)` Constructs an instance of the OPRFHashToScalar class, which handles the process of encoding a message into a scalar value based on the provided elliptic curve and digest algorithm.
    `OPRFHashToScalar(ECCurve curve, ExtendedDigest digest, int k)` Constructs an instance of the OPRFHashToScalar class, which handles the process of encoding a message into a scalar value based on the provided elliptic curve and digest algorithm.

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `java.math.BigInteger` | `process(byte[] input, byte[] dst)` Hash the input message to a uniformly distributed scalar value on the elliptic curve.

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

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

- - ### Constructor Detail

    - #### OPRFHashToScalar

          public OPRFHashToScalar(ECCurve curve,
                                  Digest digest,
                                  int k,
                                  int s)

      Constructs an instance of the OPRFHashToScalar class, which handles the process of encoding a message into a scalar value based on the provided elliptic curve and digest algorithm.
      Parameters:
        `curve` - the elliptic curve (ECCurve) used for the hashing process
        `digest` - the digest algorithm (Digest) used for message hashing and expansion
        `k` - the security parameter affecting the size of hashed output
        `s` - the input block size parameter for the cryptographic digest algorithm

    - #### OPRFHashToScalar

          public OPRFHashToScalar(ECCurve curve,
                                  ExtendedDigest digest,
                                  int k)

      Constructs an instance of the OPRFHashToScalar class, which handles the process of encoding a message into a scalar value based on the provided elliptic curve and digest algorithm.
      Parameters:
        `curve` - the elliptic curve (ECCurve) used for the hashing process
        `digest` - the digest algorithm (Digest) used for message hashing and expansion
        `k` - the security parameter affecting the size of hashed output

  - ### Method Detail

    - #### process

          public java.math.BigInteger process(byte[] input,
                                              byte[] dst)

      Hash the input message to a uniformly distributed scalar value on the elliptic curve.
      Parameters:
        `input` - the input message as a byte array
        `dst` - the domain separation tag as a byte array
      Returns:
        a scalar value (BigInteger) derived from the input message