Class OPRFHashToScalar
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_fieldfrom 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
ConstructorsConstructorDescriptionOPRFHashToScalar(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
Modifier and TypeMethodDescriptionprocess(byte[] input, byte[] dst) Hash the input message to a uniformly distributed scalar value on the elliptic curve.
-
Constructor Details
-
OPRFHashToScalar
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 processdigest- the digest algorithm (Digest) used for message hashing and expansionk- the security parameter affecting the size of hashed outputs- the input block size parameter for the cryptographic digest algorithm
-
OPRFHashToScalar
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 processdigest- the digest algorithm (Digest) used for message hashing and expansionk- the security parameter affecting the size of hashed output
-
-
Method Details
-
process
Hash the input message to a uniformly distributed scalar value on the elliptic curve.- Parameters:
input- the input message as a byte arraydst- the domain separation tag as a byte array- Returns:
- a scalar value (BigInteger) derived from the input message
-