Switch the P-384 hash-to-curve to draft-07.

Leave the P-521 one alone as it's part of the current trust token
experiment. But suffix all the functions by their draft until everything
stabilizes. Also remove the ref_for_testing function since we can cite
the fixed test vectors from the upstream PR.

Change-Id: Ied89d26848c8ec1f6e8414a2385d9f3e491d7fb2
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/41067
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Steven Valdez <svaldez@google.com>
diff --git a/crypto/ec_extra/hash_to_curve.c b/crypto/ec_extra/hash_to_curve.c
index 04f37ad..6f8b599 100644
--- a/crypto/ec_extra/hash_to_curve.c
+++ b/crypto/ec_extra/hash_to_curve.c
@@ -28,21 +28,41 @@
 
 
 // This file implements hash-to-curve, as described in
-// draft-irtf-cfrg-hash-to-curve-06.
+// draft-irtf-cfrg-hash-to-curve-07.
+//
+// This hash-to-curve implementation is written generically with the
+// expectation that we will eventually wish to support other curves. If it
+// becomes a performance bottleneck, some possible optimizations by
+// specializing it to the curve:
+//
+// - Rather than using a generic |felem_exp|, specialize the exponentation to
+//   c2 with a faster addition chain.
+//
+// - |felem_mul| and |felem_sqr| are indirect calls to generic Montgomery
+//   code. Given the few curves, we could specialize
+//   |map_to_curve_simple_swu|. But doing this reasonably without duplicating
+//   code in C is difficult. (C++ templates would be useful here.)
+//
+// - P-521's Z and c2 have small power-of-two absolute values. We could save
+//   two multiplications in SSWU. (Other curves have reasonable values of Z
+//   and inconvenient c2.) This is unlikely to be worthwhile without C++
+//   templates to make specializing more convenient.
 
 // expand_message_xmd implements the operation described in section 5.3.1 of
-// draft-irtf-cfrg-hash-to-curve-06. It returns one on success and zero on
-// allocation failure or if |out_len| was too large.
+// draft-irtf-cfrg-hash-to-curve-07. It returns one on success and zero on
+// allocation failure or if |out_len| was too large. If |is_draft06| is one, it
+// implements the operation from draft-irtf-cfrg-hash-to-curve-06 instead.
 static int expand_message_xmd(const EVP_MD *md, uint8_t *out, size_t out_len,
                               const uint8_t *msg, size_t msg_len,
-                              const uint8_t *dst, size_t dst_len) {
+                              const uint8_t *dst, size_t dst_len,
+                              int is_draft06) {
   int ret = 0;
   const size_t block_size = EVP_MD_block_size(md);
   const size_t md_size = EVP_MD_size(md);
   EVP_MD_CTX ctx;
   EVP_MD_CTX_init(&ctx);
 
-  // Long DSTs are hashed down to size.
+  // Long DSTs are hashed down to size. See section 5.3.3.
   OPENSSL_STATIC_ASSERT(EVP_MAX_MD_SIZE < 256, "hashed DST still too large");
   uint8_t dst_buf[EVP_MAX_MD_SIZE];
   if (dst_len >= 256) {
@@ -68,8 +88,9 @@
       !EVP_DigestUpdate(&ctx, kZeros, block_size) ||
       !EVP_DigestUpdate(&ctx, msg, msg_len) ||
       !EVP_DigestUpdate(&ctx, l_i_b_str_zero, sizeof(l_i_b_str_zero)) ||
-      !EVP_DigestUpdate(&ctx, &dst_len_u8, 1) ||
+      (is_draft06 && !EVP_DigestUpdate(&ctx, &dst_len_u8, 1)) ||
       !EVP_DigestUpdate(&ctx, dst, dst_len) ||
+      (!is_draft06 && !EVP_DigestUpdate(&ctx, &dst_len_u8, 1)) ||
       !EVP_DigestFinal_ex(&ctx, b_0, NULL)) {
     goto err;
   }
@@ -93,8 +114,9 @@
     if (!EVP_DigestInit_ex(&ctx, md, NULL) ||
         !EVP_DigestUpdate(&ctx, b_i, md_size) ||
         !EVP_DigestUpdate(&ctx, &i, 1) ||
-        !EVP_DigestUpdate(&ctx, &dst_len_u8, 1) ||
+        (is_draft06 && !EVP_DigestUpdate(&ctx, &dst_len_u8, 1)) ||
         !EVP_DigestUpdate(&ctx, dst, dst_len) ||
+        (!is_draft06 && !EVP_DigestUpdate(&ctx, &dst_len_u8, 1)) ||
         !EVP_DigestFinal_ex(&ctx, b_i, NULL)) {
       goto err;
     }
@@ -115,7 +137,7 @@
 
 // num_bytes_to_derive determines the number of bytes to derive when hashing to
 // a number modulo |modulus|. See the hash_to_field operation defined in
-// section 5.2 of draft-irtf-cfrg-hash-to-curve-06.
+// section 5.2 of draft-irtf-cfrg-hash-to-curve-07.
 static int num_bytes_to_derive(size_t *out, const BIGNUM *modulus, unsigned k) {
   size_t bits = BN_num_bits(modulus);
   size_t L = (bits + k + 7) / 8;
@@ -148,16 +170,17 @@
 }
 
 // hash_to_field implements the operation described in section 5.2
-// of draft-irtf-cfrg-hash-to-curve-06, with count = 2. |k| is the security
+// of draft-irtf-cfrg-hash-to-curve-07, with count = 2. |k| is the security
 // factor.
 static int hash_to_field2(const EC_GROUP *group, const EVP_MD *md,
                           EC_FELEM *out1, EC_FELEM *out2, const uint8_t *dst,
                           size_t dst_len, unsigned k, const uint8_t *msg,
-                          size_t msg_len) {
+                          size_t msg_len, int is_draft06) {
   size_t L;
   uint8_t buf[4 * EC_MAX_BYTES];
   if (!num_bytes_to_derive(&L, &group->field, k) ||
-      !expand_message_xmd(md, buf, 2 * L, msg, msg_len, dst, dst_len)) {
+      !expand_message_xmd(md, buf, 2 * L, msg, msg_len, dst, dst_len,
+                          is_draft06)) {
     return 0;
   }
   BN_ULONG words[2 * EC_MAX_WORDS];
@@ -173,11 +196,12 @@
 // group order rather than a field element. |k| is the security factor.
 static int hash_to_scalar(const EC_GROUP *group, const EVP_MD *md,
                           EC_SCALAR *out, const uint8_t *dst, size_t dst_len,
-                          unsigned k, const uint8_t *msg, size_t msg_len) {
+                          unsigned k, const uint8_t *msg, size_t msg_len,
+                          int is_draft06) {
   size_t L;
   uint8_t buf[EC_MAX_BYTES * 2];
   if (!num_bytes_to_derive(&L, &group->order, k) ||
-      !expand_message_xmd(md, buf, L, msg, msg_len, dst, dst_len)) {
+      !expand_message_xmd(md, buf, L, msg, msg_len, dst, dst_len, is_draft06)) {
     return 0;
   }
 
@@ -206,7 +230,7 @@
 }
 
 // sgn0_le implements the operation described in section 4.1.2 of
-// draft-irtf-cfrg-hash-to-curve-06.
+// draft-irtf-cfrg-hash-to-curve-07.
 static BN_ULONG sgn0_le(const EC_GROUP *group, const EC_FELEM *a) {
   uint8_t buf[EC_MAX_BYTES];
   size_t len;
@@ -215,8 +239,8 @@
 }
 
 // map_to_curve_simple_swu implements the operation described in section 6.6.2
-// of draft-irtf-cfrg-hash-to-curve-06, using the optimization in appendix D.2.
-// It returns one on success and zero on error.
+// of draft-irtf-cfrg-hash-to-curve-07, using the optimization in appendix
+// D.2.1. It returns one on success and zero on error.
 static int map_to_curve_simple_swu(const EC_GROUP *group, const EC_FELEM *Z,
                                    const BN_ULONG *c1, size_t num_c1,
                                    const EC_FELEM *c2, EC_RAW_POINT *out,
@@ -286,9 +310,10 @@
 static int hash_to_curve(const EC_GROUP *group, const EVP_MD *md,
                          const EC_FELEM *Z, const EC_FELEM *c2, unsigned k,
                          EC_RAW_POINT *out, const uint8_t *dst, size_t dst_len,
-                         const uint8_t *msg, size_t msg_len) {
+                         const uint8_t *msg, size_t msg_len, int is_draft06) {
   EC_FELEM u0, u1;
-  if (!hash_to_field2(group, md, &u0, &u1, dst, dst_len, k, msg, msg_len)) {
+  if (!hash_to_field2(group, md, &u0, &u1, dst, dst_len, k, msg, msg_len,
+                      is_draft06)) {
     return 0;
   }
 
@@ -318,11 +343,10 @@
   return ec_felem_from_bytes(group, out, bytes, len);
 }
 
-int ec_hash_to_curve_p384_xmd_sha512_sswu(const EC_GROUP *group,
-                                          EC_RAW_POINT *out, const uint8_t *dst,
-                                          size_t dst_len, const uint8_t *msg,
-                                          size_t msg_len) {
-  // See section 8.3 of draft-irtf-cfrg-hash-to-curve-06.
+int ec_hash_to_curve_p384_xmd_sha512_sswu_draft07(
+    const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst,
+    size_t dst_len, const uint8_t *msg, size_t msg_len) {
+  // See section 8.3 of draft-irtf-cfrg-hash-to-curve-07.
   if (EC_GROUP_get_curve_name(group) != NID_secp384r1) {
     OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH);
     return 0;
@@ -352,48 +376,24 @@
   ec_felem_neg(group, &Z, &Z);
 
   return hash_to_curve(group, EVP_sha512(), &Z, &c2, /*k=*/192, out, dst,
-                       dst_len, msg, msg_len);
+                       dst_len, msg, msg_len, /*is_draft06=*/0);
 }
 
-int ec_hash_to_scalar_p384_xmd_sha512(const EC_GROUP *group, EC_SCALAR *out,
-                                      const uint8_t *dst, size_t dst_len,
-                                      const uint8_t *msg, size_t msg_len) {
+int ec_hash_to_scalar_p384_xmd_sha512_draft07(
+    const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len,
+    const uint8_t *msg, size_t msg_len) {
   if (EC_GROUP_get_curve_name(group) != NID_secp384r1) {
     OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH);
     return 0;
   }
 
   return hash_to_scalar(group, EVP_sha512(), out, dst, dst_len, /*k=*/192, msg,
-                        msg_len);
+                        msg_len, /*is_draft06=*/0);
 }
 
-static int hash_to_curve_p521_xmd_sswu(const EC_GROUP *group, EC_RAW_POINT *out,
-                                       const uint8_t *dst, size_t dst_len,
-                                       const EVP_MD *md, unsigned k,
-                                       const uint8_t *msg, size_t msg_len) {
-  // This hash-to-curve implementation is written generically with the
-  // expectation that we will eventually wish to support P-256 or P-384. If it
-  // becomes a performance bottleneck, some possible optimizations by
-  // specializing it to the curve:
-  //
-  // - c1 = (p-3)/4 = 2^519-1. |felem_exp| costs 515S + 119M for this exponent.
-  //   A more efficient addition chain for c1 would cost 518S + 12M, but it
-  //   would require specializing the particular exponent.
-  //
-  // - P-521, while large, is a Mersenne prime, so we can likely do better than
-  //   the generic Montgomery implementation if we specialize the field
-  //   operations (below).
-  //
-  // - |felem_mul| and |felem_sqr| are indirect calls to generic Montgomery
-  //   code. Given the few curves, we could specialize
-  //   |map_to_curve_simple_swu|. But doing this reasonably without duplicating
-  //   code in C is difficult. (C++ templates would be useful here.)
-  //
-  // - P-521's Z and c2 have small power-of-two absolute values. We could save
-  //   two multiplications in SSWU. (Other curves have reasonable values of Z
-  //   and inconvenient c2.) This is unlikely to be worthwhile without C++
-  //   templates to make specializing more convenient.
-
+int ec_hash_to_curve_p521_xmd_sha512_sswu_draft06(
+    const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst,
+    size_t dst_len, const uint8_t *msg, size_t msg_len) {
   // See section 8.3 of draft-irtf-cfrg-hash-to-curve-06.
   if (EC_GROUP_get_curve_name(group) != NID_secp521r1) {
     OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH);
@@ -408,38 +408,18 @@
   }
   ec_felem_neg(group, &Z, &Z);
 
-  return hash_to_curve(group, md, &Z, &c2, k, out, dst, dst_len, msg, msg_len);
+  return hash_to_curve(group, EVP_sha512(), &Z, &c2, /*k=*/256, out, dst,
+                       dst_len, msg, msg_len, /*is_draft06=*/1);
 }
 
-int ec_hash_to_curve_p521_xmd_sha512_sswu(const EC_GROUP *group,
-                                          EC_RAW_POINT *out, const uint8_t *dst,
-                                          size_t dst_len, const uint8_t *msg,
-                                          size_t msg_len) {
-  return hash_to_curve_p521_xmd_sswu(group, out, dst, dst_len, EVP_sha512(),
-                                     /*k=*/256, msg, msg_len);
-}
-
-int ec_hash_to_curve_p521_xmd_sha512_sswu_ref_for_testing(
-    const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst,
-    size_t dst_len, const uint8_t *msg, size_t msg_len) {
-  // The specification defines the P-521 suites inconsistently. It specifies
-  // L = 96 for hash_to_field, but computing L from k as specified gives L = 98.
-  // See https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/issues/237.
-  //
-  // Setting k to 240 gives L = 96. We implement this variation to test with the
-  // original test vectors, which were computed with the smaller L.
-  return hash_to_curve_p521_xmd_sswu(group, out, dst, dst_len, EVP_sha512(),
-                                     /*k=*/240, msg, msg_len);
-}
-
-int ec_hash_to_scalar_p521_xmd_sha512(const EC_GROUP *group, EC_SCALAR *out,
-                                      const uint8_t *dst, size_t dst_len,
-                                      const uint8_t *msg, size_t msg_len) {
+int ec_hash_to_scalar_p521_xmd_sha512_draft06(
+    const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len,
+    const uint8_t *msg, size_t msg_len) {
   if (EC_GROUP_get_curve_name(group) != NID_secp521r1) {
     OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH);
     return 0;
   }
 
   return hash_to_scalar(group, EVP_sha512(), out, dst, dst_len, /*k=*/256, msg,
-                        msg_len);
+                        msg_len, /*is_draft06=*/1);
 }
diff --git a/crypto/ec_extra/internal.h b/crypto/ec_extra/internal.h
index eea282c..940a414 100644
--- a/crypto/ec_extra/internal.h
+++ b/crypto/ec_extra/internal.h
@@ -27,48 +27,46 @@
 // Hash-to-curve.
 //
 // The following functions implement primitives from
-// draft-irtf-cfrg-hash-to-curve-06. We currently only implement the P-384 and
-// P-521 suites, but others can be added as needed. The |dst| parameter in each
-// function is the domain separation tag and must be unique for each protocol
-// and between the |hash_to_curve| and |hash_to_scalar| variants. See
-// section 3.1 of the spec for additional guidance on this parameter.
+// draft-irtf-cfrg-hash-to-curve. The |dst| parameter in each function is the
+// domain separation tag and must be unique for each protocol and between the
+// |hash_to_curve| and |hash_to_scalar| variants. See section 3.1 of the spec
+// for additional guidance on this parameter.
 
-// ec_hash_to_curve_p384_sha512_sswu hashes |msg| to a point on |group| and
-// writes the result to |out|, implementing the P384_XMD:SHA-512_SSWU_RO_ suite.
-// It returns one on success and zero on error.
-OPENSSL_EXPORT int ec_hash_to_curve_p384_xmd_sha512_sswu(
+// ec_hash_to_curve_p384_xmd_sha512_sswu_draft07 hashes |msg| to a point on
+// |group| and writes the result to |out|, implementing the
+// P384_XMD:SHA-512_SSWU_RO_ suite from draft-irtf-cfrg-hash-to-curve-07. It
+// returns one on success and zero on error.
+OPENSSL_EXPORT int ec_hash_to_curve_p384_xmd_sha512_sswu_draft07(
     const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst,
     size_t dst_len, const uint8_t *msg, size_t msg_len);
 
-// ec_hash_to_scalar_p384_xmd_sha512 hashes |msg| to a scalar on |group| and
-// writes the result to |out|, using the hash_to_field operation from the
-// P384_XMD:SHA-512_SSWU_RO_ suite, but generating a value modulo the group
-// order rather than a field element.
-OPENSSL_EXPORT int ec_hash_to_scalar_p384_xmd_sha512(
+// ec_hash_to_scalar_p384_xmd_sha512_draft07 hashes |msg| to a scalar on |group|
+// and writes the result to |out|, using the hash_to_field operation from the
+// P384_XMD:SHA-512_SSWU_RO_ suite from draft-irtf-cfrg-hash-to-curve-07, but
+// generating a value modulo the group order rather than a field element.
+OPENSSL_EXPORT int ec_hash_to_scalar_p384_xmd_sha512_draft07(
     const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len,
     const uint8_t *msg, size_t msg_len);
 
-// ec_hash_to_curve_p521_sha512_sswu hashes |msg| to a point on |group| and
-// writes the result to |out|, implementing the P521_XMD:SHA-512_SSWU_RO_ suite.
-// It returns one on success and zero on error.
-OPENSSL_EXPORT int ec_hash_to_curve_p521_xmd_sha512_sswu(
-    const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst,
-    size_t dst_len, const uint8_t *msg, size_t msg_len);
-
-// ec_hash_to_curve_p521_xmd_sha512_sswu_ref_for_testing behaves like
-// |ec_hash_to_curve_p521_sha512_sswu| but reproduces a spec issue reflected in
-// the original test vectors.
+// ec_hash_to_curve_p521_xmd_sha512_sswu_draft06 hashes |msg| to a point on
+// |group| and writes the result to |out|, implementing the
+// P521_XMD:SHA-512_SSWU_RO_ suite from draft-irtf-cfrg-hash-to-curve-06. It
+// returns one on success and zero on error.
 //
-// This function is exposed for test purposes and should not be used elsewhere.
-OPENSSL_EXPORT int ec_hash_to_curve_p521_xmd_sha512_sswu_ref_for_testing(
+// This function implements an older version of the draft and should not be used
+// in new code.
+OPENSSL_EXPORT int ec_hash_to_curve_p521_xmd_sha512_sswu_draft06(
     const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst,
     size_t dst_len, const uint8_t *msg, size_t msg_len);
 
-// ec_hash_to_scalar_p521_xmd_sha512 hashes |msg| to a scalar on |group| and
-// writes the result to |out|, using the hash_to_field operation from the
-// P521_XMD:SHA-512_SSWU_RO_ suite, but generating a value modulo the group
-// order rather than a field element.
-OPENSSL_EXPORT int ec_hash_to_scalar_p521_xmd_sha512(
+// ec_hash_to_scalar_p521_xmd_sha512_draft06 hashes |msg| to a scalar on |group|
+// and writes the result to |out|, using the hash_to_field operation from the
+// P521_XMD:SHA-512_SSWU_RO_ suite from draft-irtf-cfrg-hash-to-curve-06, but
+// generating a value modulo the group order rather than a field element.
+//
+// This function implements an older version of the draft and should not be used
+// in new code.
+OPENSSL_EXPORT int ec_hash_to_scalar_p521_xmd_sha512_draft06(
     const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len,
     const uint8_t *msg, size_t msg_len);
 
diff --git a/crypto/fipsmodule/ec/ec_test.cc b/crypto/fipsmodule/ec/ec_test.cc
index e08da93..59d55b5 100644
--- a/crypto/fipsmodule/ec/ec_test.cc
+++ b/crypto/fipsmodule/ec/ec_test.cc
@@ -1135,26 +1135,26 @@
     const char *y_hex;
   };
   static const HashToCurveTest kTests[] = {
-      // See draft-irtf-cfrg-hash-to-curve-06, appendix G.2.1.
-      {&ec_hash_to_curve_p384_xmd_sha512_sswu, NID_secp384r1,
+      // See draft-irtf-cfrg-hash-to-curve-07, appendix G.2.1.
+      {&ec_hash_to_curve_p384_xmd_sha512_sswu_draft07, NID_secp384r1,
        "P384_XMD:SHA-512_SSWU_RO_TESTGEN", "",
-       "619d4168877421106aecb16ec35d84b7fdfa215cdb446d82bac49f"
-       "6eab51a34b4d5314823f7639293cf6471c6c981a99",
-       "e5035c694665ca25b2c57542673af6b91288110b0b0689657cd031"
-       "96976d82dec104fd9f91296c85d1ed94bc9309840e"},
-      {&ec_hash_to_curve_p384_xmd_sha512_sswu, NID_secp384r1,
+       "2fc0b9efdd63a8e43b4db88dc12f03c798f6fd91bccac0c9096185"
+       "4386e58fdc54fc2a01f0f358759054ce1f9b762025",
+       "949b936fabb72cdb02cd7980b86cb6a3adf286658e81301648851d"
+       "b8a49d9bec00ccb57698d559fc5960fa5030a8e54b"},
+      {&ec_hash_to_curve_p384_xmd_sha512_sswu_draft07, NID_secp384r1,
        "P384_XMD:SHA-512_SSWU_RO_TESTGEN", "abc",
-       "d7c33555606b86c3ffaa1a645f806bac9d553a769f5a735d75a395"
-       "d58a70956b6d3bdbd6a6a8c83121678a036005208a",
-       "e1c55f372a905040576f61fbc07e9664359e76f3e7b5be8dfe7224"
-       "720f85753a823e94a3f886ced2ec5ce13b1248147a"},
-      {&ec_hash_to_curve_p384_xmd_sha512_sswu, NID_secp384r1,
+       "4f3338035391e8ce8ce40c974136f0edc97f392ffd44a643338741"
+       "8ed1b8c2603487e1688ec151f048fbc6b2c138c92f",
+       "152b90aef6558be328a3168855fb1906452e7167b0f7c8a56ff9d4"
+       "fa87d6fb522cdf8e409db54418b2c764fd26260757"},
+      {&ec_hash_to_curve_p384_xmd_sha512_sswu_draft07, NID_secp384r1,
        "P384_XMD:SHA-512_SSWU_RO_TESTGEN", "abcdef0123456789",
-       "d1f4bdd7ef9ee1c2d57ccd2b3b80123ccf3eb64b2f0a3ad26b8cd1"
-       "a8a8e411aadb9922d0e66a89ef0e78dba1489e23ea",
-       "9f376abd97ab8838c604a05ad17be1dfe0d924ddf0184341ec8e5a"
-       "ef9efb0f6559ab3048b4e1e0e42ac19ccb6d1dd892"},
-      {&ec_hash_to_curve_p384_xmd_sha512_sswu, NID_secp384r1,
+       "e9e5d7ac397e123d060ad44301cbc8eb972f6e64ebcff29dcc9b9a"
+       "10357902aace2240c580fec85e5b427d98b4e80703",
+       "916cb8963521ad75105be43cc4148e5a5bbb4fcf107f1577e4f7fa"
+       "3ca58cd786aa76890c8e687d2353393bc16c78ec4d"},
+      {&ec_hash_to_curve_p384_xmd_sha512_sswu_draft07, NID_secp384r1,
        "P384_XMD:SHA-512_SSWU_RO_TESTGEN",
        "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
@@ -1166,55 +1166,17 @@
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-       "1b669293d6edfd55ca7f9725d72fc62b55a8829738404a1239f2ca"
-       "783ad8f8a3ebe2ce54a28fcb6e9eca85d1ce29a929",
-       "25556bc2c6382c261feb362519f1e5d616518810262c358fb80e45"
-       "803ebcd0ce830b594da7a0e9de9eb13ad2d9191d34"},
+       "41941db59a7b8b633bd5bfa462f1e29a9f18e5a341445d90fc6eb9"
+       "37f2913224287b9dfb64742851f760eb14ca115ff9",
+       "1510e764f1be968d661b7aaecb26a6d38c98e5205ca150f0ae426d"
+       "2c3983c68e3a9ffb283c6ae4891d891b5705500475"},
 
-      // See draft-irtf-cfrg-hash-to-curve-06, appendix G.3.1. Note these tests
-      // use |ec_hash_to_curve_p521_xmd_sha512_sswu_ref_for_testing| due to a
+      // Note these tests do not match the tests vectors
+      // draft-irtf-cfrg-hash-to-curve-06 due to a
       // spec issue. See
-      // https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/issues/237. We
-      // expose and test this function to check our consistency with the rest of
-      // the reference implementation.
-      {&ec_hash_to_curve_p521_xmd_sha512_sswu_ref_for_testing, NID_secp521r1,
-       "P521_XMD:SHA-512_SSWU_RO_TESTGEN", "",
-       "00ad6cb736cb0565a2b6c52dd9e53f76a9a40a44c73bfaacef03c3"
-       "ef62a9a23920b7df4de1b92754de7bb3013d9d36049da001136e7f"
-       "4b1b0ba10beac862a2b3d3c5",
-       "01c2ecab1b6f7bb6797a4b5bd416b385e891926fc17f230f2406f3"
-       "d47076526c5d90bfb4d0170fd8a339de1a66e6304d280d0404fb68"
-       "5b2ca07e2742a770b681bf56"},
-      {&ec_hash_to_curve_p521_xmd_sha512_sswu_ref_for_testing, NID_secp521r1,
-       "P521_XMD:SHA-512_SSWU_RO_TESTGEN", "abcdef0123456789",
-       "019f0195e514da4243a4d2de4b7ed2415d5205c6da11eb7deae70b"
-       "e78a61bb89ebf17f7c9970ee20b4152ae50c95e55f626bc7350d5a"
-       "0f530a91f48047bd90eeeaa7",
-       "016eaa02cd5511a96eed4ffc965bdc3f1fdbb7f4c9895eabdf168b"
-       "44250278ebca55474bc89a2f246b8fb959010502aab8a9385319bc"
-       "f69f74dd8f518bea1c7fafde"},
-      {&ec_hash_to_curve_p521_xmd_sha512_sswu_ref_for_testing, NID_secp521r1,
-       "P521_XMD:SHA-512_SSWU_RO_TESTGEN",
-       "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-       "00de3dd7780cfcd538f7b3067d8da52c522a031244dc0d327e6e99"
-       "ef331be475354a0b481a22e0d4d35b232da260baac5b693a827a20"
-       "b1f328a416ffc47ad945a4dc",
-       "016bb6c5c965c6a80a4a5e0c2c7bbd841766eac695f88a730076b3"
-       "2d4399da01609a4a17b59a21f4f58a174d6110081b96e5aaedead3"
-       "cfd4252e74de969680ba74ab"},
-
-      // The above test vectors with the expectations updated to compute
-      // hash_to_field correctly.
-      {&ec_hash_to_curve_p521_xmd_sha512_sswu, NID_secp521r1,
+      // https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/pull/238 for
+      // corrected test vectors.
+      {&ec_hash_to_curve_p521_xmd_sha512_sswu_draft06, NID_secp521r1,
        "P521_XMD:SHA-512_SSWU_RO_TESTGEN", "",
        "00758617b5e40aa8b30fcfd3c7453ad1abeff158de5697d6f1ccb8"
        "4690aaa8bb6692986200d16206e85e4f39f1d2829fee1a5904a089"
@@ -1222,7 +1184,15 @@
        "016edf324d95fcbe4a30f06751f16cdd5d0b49921dd653cefb3ea2"
        "dc2b5b903e36d9924a65407283588cc6c224ab6d6324c73cdc166c"
        "e1530b46984b459e966349b3"},
-      {&ec_hash_to_curve_p521_xmd_sha512_sswu, NID_secp521r1,
+      {&ec_hash_to_curve_p521_xmd_sha512_sswu_draft06, NID_secp521r1,
+       "P521_XMD:SHA-512_SSWU_RO_TESTGEN", "abc",
+       "00dcec1a83b676247293e96b1672f67aa5d041a4ded49f542a971a"
+       "60603dd39194f4d8e587f640563a9ab57dcc69af638129b220683f"
+       "f03ed9ad8cfdff3833a01452",
+       "01edc4b497be85361a0afc508058792dc7fc6499a4c51fa3475093"
+       "fd9951ea46fe055e1b007a12caf9be1ce3028bd0b4ca4ffa5200f9"
+       "d11e7fc96e068276ad1319c2"},
+      {&ec_hash_to_curve_p521_xmd_sha512_sswu_draft06, NID_secp521r1,
        "P521_XMD:SHA-512_SSWU_RO_TESTGEN", "abcdef0123456789",
        "01f58bfb34825d028c392976a09cebee829734f7714c84b8a13580"
        "afcc2eb4726e18e307476c1fccdc857a3d6767fd2882875ab132b7"
@@ -1230,7 +1200,7 @@
        "00ee0d2d0bfb0bdc6215814fe7096a3dfbf020dce4f0645e8e21a9"
        "0d6a6113a5ca61ae7d8f3b485b04f2eb2b85e34fc7f9f1bf367386"
        "2e03932b0acc3655e84d480f"},
-      {&ec_hash_to_curve_p521_xmd_sha512_sswu, NID_secp521r1,
+      {&ec_hash_to_curve_p521_xmd_sha512_sswu_draft06, NID_secp521r1,
        "P521_XMD:SHA-512_SSWU_RO_TESTGEN",
        "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
@@ -1250,7 +1220,7 @@
        "7351a76fce44347c72a6fe9a"},
 
       // Custom test vector which triggers long DST path.
-      {&ec_hash_to_curve_p521_xmd_sha512_sswu, NID_secp521r1,
+      {&ec_hash_to_curve_p521_xmd_sha512_sswu_draft06, NID_secp521r1,
        "P521_XMD:SHA-512_SSWU_RO_TESTGEN_aaaaaaaaaaaaaaaaaaaaa"
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
@@ -1299,9 +1269,9 @@
   EC_RAW_POINT p;
   static const uint8_t kDST[] = {0, 1, 2, 3};
   static const uint8_t kMessage[] = {4, 5, 6, 7};
-  EXPECT_FALSE(ec_hash_to_curve_p521_xmd_sha512_sswu(
+  EXPECT_FALSE(ec_hash_to_curve_p521_xmd_sha512_sswu_draft06(
       p224.get(), &p, kDST, sizeof(kDST), kMessage, sizeof(kMessage)));
-  EXPECT_FALSE(ec_hash_to_curve_p384_xmd_sha512_sswu(
+  EXPECT_FALSE(ec_hash_to_curve_p384_xmd_sha512_sswu_draft07(
       p224.get(), &p, kDST, sizeof(kDST), kMessage, sizeof(kMessage)));
 }
 
@@ -1316,15 +1286,15 @@
     const char *result_hex;
   };
   static const HashToScalarTest kTests[] = {
-      {&ec_hash_to_scalar_p384_xmd_sha512, NID_secp384r1,
+      {&ec_hash_to_scalar_p384_xmd_sha512_draft07, NID_secp384r1,
        "P384_XMD:SHA-512_SCALAR_TEST", "",
-       "55f24775dd8ec265d9d1bf2f25b83806daf119db8646b3d263b156"
-       "8dbae4ee54aeafc757e4aa197da85504ad124d8ac8"},
-      {&ec_hash_to_scalar_p384_xmd_sha512, NID_secp384r1,
+       "9687acc2de56c3cf94c0e05b6811a21aa480092254ec0532bdce63"
+       "140ecd340f09dc2d45d77e21fb0aa76f7707b8a676"},
+      {&ec_hash_to_scalar_p384_xmd_sha512_draft07, NID_secp384r1,
        "P384_XMD:SHA-512_SCALAR_TEST", "abcdef0123456789",
-       "3af11c58bf0a3ee3560207c6bed9b5ecca5dc330426a6e1a601d36"
-       "c15d3818aeb48afb182036750bc5b46e6c20e8e2ff"},
-      {&ec_hash_to_scalar_p384_xmd_sha512, NID_secp384r1,
+       "8f8076022a68233cbcecaceae68c2068f132724f001caa78619eff"
+       "1ffc58fa871db73fe9034fc9cf853c384ed34b5666"},
+      {&ec_hash_to_scalar_p384_xmd_sha512_draft07, NID_secp384r1,
        "P384_XMD:SHA-512_SCALAR_TEST",
        "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
@@ -1336,19 +1306,19 @@
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-       "2d5f927d15283f89d9d4932f93b77ab837e90bdf26b5f8beb2c794"
-       "bbd83032b6f1a445ef9f343a2b9311657e86e6ad43"},
-      {&ec_hash_to_scalar_p521_xmd_sha512, NID_secp521r1,
+       "750f2fae7d2b2f41ac737d180c1d4363d85a1504798b4976d40921"
+       "1ddb3651c13a5b4daba9975cdfce18336791131915"},
+      {&ec_hash_to_scalar_p521_xmd_sha512_draft06, NID_secp521r1,
        "P521_XMD:SHA-512_SCALAR_TEST", "",
        "01a6206c2fc677c11d51807bf46d64a17f92396673074c5cee9299"
        "4d28eec5445d5ed89799b30b39c964ecf62f39d59e7d43de15d910"
        "c2c1d69f3ebc01eab241e5dc"},
-      {&ec_hash_to_scalar_p521_xmd_sha512, NID_secp521r1,
+      {&ec_hash_to_scalar_p521_xmd_sha512_draft06, NID_secp521r1,
        "P521_XMD:SHA-512_SCALAR_TEST", "abcdef0123456789",
        "00af484a5d9389a9912f555234c578d4b1b7c4a6f5009018d133a4"
        "069172c9f5ce2d853b8643fe7bb50a83427ed3520a7a793c41a455"
        "a02aa99431434fb6b5b0b26e"},
-      {&ec_hash_to_scalar_p521_xmd_sha512, NID_secp521r1,
+      {&ec_hash_to_scalar_p521_xmd_sha512_draft06, NID_secp521r1,
        "P521_XMD:SHA-512_SCALAR_TEST",
        "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
@@ -1388,8 +1358,8 @@
   EC_SCALAR scalar;
   static const uint8_t kDST[] = {0, 1, 2, 3};
   static const uint8_t kMessage[] = {4, 5, 6, 7};
-  EXPECT_FALSE(ec_hash_to_scalar_p521_xmd_sha512(
+  EXPECT_FALSE(ec_hash_to_scalar_p521_xmd_sha512_draft06(
       p224.get(), &scalar, kDST, sizeof(kDST), kMessage, sizeof(kMessage)));
-  EXPECT_FALSE(ec_hash_to_scalar_p384_xmd_sha512(
+  EXPECT_FALSE(ec_hash_to_scalar_p384_xmd_sha512_draft07(
       p224.get(), &scalar, kDST, sizeof(kDST), kMessage, sizeof(kMessage)));
 }
diff --git a/crypto/trust_token/pmbtoken.c b/crypto/trust_token/pmbtoken.c
index 4b9451d..192eba9 100644
--- a/crypto/trust_token/pmbtoken.c
+++ b/crypto/trust_token/pmbtoken.c
@@ -293,7 +293,7 @@
 static int hash_t(EC_GROUP *group, EC_RAW_POINT *out,
                   const uint8_t t[PMBTOKEN_NONCE_SIZE]) {
   const uint8_t kHashTLabel[] = "PMBTokensV0 HashT";
-  return ec_hash_to_curve_p521_xmd_sha512_sswu(
+  return ec_hash_to_curve_p521_xmd_sha512_sswu_draft06(
       group, out, kHashTLabel, sizeof(kHashTLabel), t, PMBTOKEN_NONCE_SIZE);
 }
 
@@ -310,8 +310,8 @@
       !point_to_cbb(&cbb, group, t) ||
       !CBB_add_bytes(&cbb, s, PMBTOKEN_NONCE_SIZE) ||
       !CBB_finish(&cbb, &buf, &len) ||
-      !ec_hash_to_curve_p521_xmd_sha512_sswu(group, out, kHashSLabel,
-                                             sizeof(kHashSLabel), buf, len)) {
+      !ec_hash_to_curve_p521_xmd_sha512_sswu_draft06(
+          group, out, kHashSLabel, sizeof(kHashSLabel), buf, len)) {
     OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
     goto err;
   }
@@ -367,8 +367,8 @@
 static int hash_c(const EC_GROUP *group, EC_SCALAR *out, uint8_t *buf,
                   size_t len) {
   const uint8_t kHashCLabel[] = "PMBTokensV0 HashC";
-  return ec_hash_to_scalar_p521_xmd_sha512(group, out, kHashCLabel,
-                                           sizeof(kHashCLabel), buf, len);
+  return ec_hash_to_scalar_p521_xmd_sha512_draft06(
+      group, out, kHashCLabel, sizeof(kHashCLabel), buf, len);
 }
 
 static int scalar_to_cbb(CBB *out, const EC_GROUP *group,
diff --git a/tool/speed.cc b/tool/speed.cc
index f403fe8..c91c25b 100644
--- a/tool/speed.cc
+++ b/tool/speed.cc
@@ -962,7 +962,7 @@
     }
     if (!TimeFunction(&results, [&]() -> bool {
           EC_RAW_POINT out;
-          return ec_hash_to_curve_p521_xmd_sha512_sswu(
+          return ec_hash_to_curve_p521_xmd_sha512_sswu_draft06(
               group, &out, kLabel, sizeof(kLabel), input, sizeof(input));
         })) {
       fprintf(stderr, "hash-to-curve failed.\n");
@@ -972,7 +972,7 @@
 
     if (!TimeFunction(&results, [&]() -> bool {
           EC_SCALAR out;
-          return ec_hash_to_scalar_p521_xmd_sha512(
+          return ec_hash_to_scalar_p521_xmd_sha512_draft06(
               group, &out, kLabel, sizeof(kLabel), input, sizeof(input));
         })) {
       fprintf(stderr, "hash-to-scalar failed.\n");
@@ -988,7 +988,7 @@
     }
     if (!TimeFunction(&results, [&]() -> bool {
           EC_RAW_POINT out;
-          return ec_hash_to_curve_p384_xmd_sha512_sswu(
+          return ec_hash_to_curve_p384_xmd_sha512_sswu_draft07(
               group, &out, kLabel, sizeof(kLabel), input, sizeof(input));
         })) {
       fprintf(stderr, "hash-to-curve failed.\n");
@@ -998,7 +998,7 @@
 
     if (!TimeFunction(&results, [&]() -> bool {
           EC_SCALAR out;
-          return ec_hash_to_scalar_p384_xmd_sha512(
+          return ec_hash_to_scalar_p384_xmd_sha512_draft07(
               group, &out, kLabel, sizeof(kLabel), input, sizeof(input));
         })) {
       fprintf(stderr, "hash-to-scalar failed.\n");