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");