// Copyright 2020 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <openssl/ec.h>

#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/nid.h>

#include <assert.h>

#include "../fipsmodule/bn/internal.h"
#include "../fipsmodule/ec/internal.h"
#include "../internal.h"
#include "internal.h"


// This file implements hash-to-curve, as described in RFC 9380.
//
// 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
// RFC 9380. It returns one on success and zero on error.
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) {
  // See https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/issues/352
  if (dst_len == 0) {
    OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return 0;
  }

  const size_t block_size = EVP_MD_block_size(md);
  const size_t md_size = EVP_MD_size(md);
  bssl::ScopedEVP_MD_CTX ctx;

  // Long DSTs are hashed down to size. See section 5.3.3.
  static_assert(EVP_MAX_MD_SIZE < 256, "hashed DST still too large");
  uint8_t dst_buf[EVP_MAX_MD_SIZE];
  if (dst_len >= 256) {
    static const char kPrefix[] = "H2C-OVERSIZE-DST-";
    if (!EVP_DigestInit_ex(ctx.get(), md, nullptr) ||
        !EVP_DigestUpdate(ctx.get(), kPrefix, sizeof(kPrefix) - 1) ||
        !EVP_DigestUpdate(ctx.get(), dst, dst_len) ||
        !EVP_DigestFinal_ex(ctx.get(), dst_buf, nullptr)) {
      return 0;
    }
    dst = dst_buf;
    dst_len = md_size;
  }
  uint8_t dst_len_u8 = (uint8_t)dst_len;

  // Compute b_0.
  static const uint8_t kZeros[EVP_MAX_MD_BLOCK_SIZE] = {0};
  // If |out_len| exceeds 16 bits then |i| will wrap below causing an error to
  // be returned. This depends on the static assert above.
  uint8_t l_i_b_str_zero[3] = {static_cast<uint8_t>(out_len >> 8),
                               static_cast<uint8_t>(out_len), 0};
  uint8_t b_0[EVP_MAX_MD_SIZE];
  if (!EVP_DigestInit_ex(ctx.get(), md, nullptr) ||
      !EVP_DigestUpdate(ctx.get(), kZeros, block_size) ||
      !EVP_DigestUpdate(ctx.get(), msg, msg_len) ||
      !EVP_DigestUpdate(ctx.get(), l_i_b_str_zero, sizeof(l_i_b_str_zero)) ||
      !EVP_DigestUpdate(ctx.get(), dst, dst_len) ||
      !EVP_DigestUpdate(ctx.get(), &dst_len_u8, 1) ||
      !EVP_DigestFinal_ex(ctx.get(), b_0, nullptr)) {
    return 0;
  }

  uint8_t b_i[EVP_MAX_MD_SIZE];
  uint8_t i = 1;
  while (out_len > 0) {
    if (i == 0) {
      // Input was too large.
      OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
      return 0;
    }
    if (i > 1) {
      for (size_t j = 0; j < md_size; j++) {
        b_i[j] ^= b_0[j];
      }
    } else {
      OPENSSL_memcpy(b_i, b_0, md_size);
    }

    if (!EVP_DigestInit_ex(ctx.get(), md, nullptr) ||
        !EVP_DigestUpdate(ctx.get(), b_i, md_size) ||
        !EVP_DigestUpdate(ctx.get(), &i, 1) ||
        !EVP_DigestUpdate(ctx.get(), dst, dst_len) ||
        !EVP_DigestUpdate(ctx.get(), &dst_len_u8, 1) ||
        !EVP_DigestFinal_ex(ctx.get(), b_i, nullptr)) {
      return 0;
    }

    size_t todo = out_len >= md_size ? md_size : out_len;
    OPENSSL_memcpy(out, b_i, todo);
    out += todo;
    out_len -= todo;
    i++;
  }

  return 1;
}

// 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 RFC 9380.
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;
  // We require 2^(8*L) < 2^(2*bits - 2) <= n^2 so to fit in bounds for
  // |felem_reduce| and |ec_scalar_reduce|. All defined hash-to-curve suites
  // define |k| to be well under this bound. (|k| is usually around half of
  // |p_bits|.)
  if (L * 8 >= 2 * bits - 2 || L > 2 * EC_MAX_BYTES) {
    assert(0);
    OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  *out = L;
  return 1;
}

// big_endian_to_words decodes |in| as a big-endian integer and writes the
// result to |out|. |num_words| must be large enough to contain the output.
static void big_endian_to_words(BN_ULONG *out, size_t num_words,
                                const uint8_t *in, size_t len) {
  assert(len <= num_words * sizeof(BN_ULONG));
  // Ensure any excess bytes are zeroed.
  OPENSSL_memset(out, 0, num_words * sizeof(BN_ULONG));
  uint8_t *out_u8 = (uint8_t *)out;
  for (size_t i = 0; i < len; i++) {
    out_u8[len - 1 - i] = in[i];
  }
}

// hash_to_field implements the operation described in section 5.2
// of RFC 9380, 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 L;
  uint8_t buf[4 * EC_MAX_BYTES];
  if (!num_bytes_to_derive(&L, &group->field.N, k) ||
      !expand_message_xmd(md, buf, 2 * L, msg, msg_len, dst, dst_len)) {
    return 0;
  }
  BN_ULONG words[2 * EC_MAX_WORDS];
  size_t num_words = 2 * group->field.N.width;
  big_endian_to_words(words, num_words, buf, L);
  group->meth->felem_reduce(group, out1, words, num_words);
  big_endian_to_words(words, num_words, buf + L, L);
  group->meth->felem_reduce(group, out2, words, num_words);
  return 1;
}

// hash_to_field1 implements the operation described in section 5.2
// of RFC 9380, with count = 1. |k| is the security factor.
static int hash_to_field1(const EC_GROUP *group, const EVP_MD *md,
                          EC_FELEM *out, const uint8_t *dst, size_t dst_len,
                          unsigned k, const uint8_t *msg, size_t msg_len) {
  size_t L;
  uint8_t buf[2 * EC_MAX_BYTES];
  if (!num_bytes_to_derive(&L, &group->field.N, k) ||
      !expand_message_xmd(md, buf, L, msg, msg_len, dst, dst_len)) {
    return 0;
  }
  BN_ULONG words[2 * EC_MAX_WORDS];
  size_t num_words = 2 * group->field.N.width;
  big_endian_to_words(words, num_words, buf, L);
  group->meth->felem_reduce(group, out, words, num_words);
  return 1;
}

// hash_to_scalar behaves like |hash_to_field2| but returns a value modulo the
// 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) {
  const BIGNUM *order = EC_GROUP_get0_order(group);
  size_t L;
  uint8_t buf[EC_MAX_BYTES * 2];
  if (!num_bytes_to_derive(&L, order, k) ||
      !expand_message_xmd(md, buf, L, msg, msg_len, dst, dst_len)) {
    return 0;
  }

  BN_ULONG words[2 * EC_MAX_WORDS];
  size_t num_words = 2 * order->width;
  big_endian_to_words(words, num_words, buf, L);
  ec_scalar_reduce(group, out, words, num_words);
  return 1;
}

static inline void mul_A(const EC_GROUP *group, EC_FELEM *out,
                         const EC_FELEM *in) {
  assert(group->a_is_minus3);
  EC_FELEM tmp;
  ec_felem_add(group, &tmp, in, in);      // tmp = 2*in
  ec_felem_add(group, &tmp, &tmp, &tmp);  // tmp = 4*in
  ec_felem_sub(group, out, in, &tmp);     // out = -3*in
}

// sgn0 implements the operation described in section 4.1.2 of RFC 9380.
static BN_ULONG sgn0(const EC_GROUP *group, const EC_FELEM *a) {
  uint8_t buf[EC_MAX_BYTES];
  size_t len;
  ec_felem_to_bytes(group, buf, &len, a);
  return buf[len - 1] & 1;
}

[[maybe_unused]] static int is_3mod4(const EC_GROUP *group) {
  return group->field.N.width > 0 && (group->field.N.d[0] & 3) == 3;
}

// sqrt_ratio_3mod4 implements the operation described in appendix F.2.1.2
// of RFC 9380.
static BN_ULONG sqrt_ratio_3mod4(const EC_GROUP *group, const EC_FELEM *Z,
                                 const BN_ULONG *c1, size_t num_c1,
                                 const EC_FELEM *c2, EC_FELEM *out_y,
                                 const EC_FELEM *u, const EC_FELEM *v) {
  assert(is_3mod4(group));

  void (*const felem_mul)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a,
                          const EC_FELEM *b) = group->meth->felem_mul;
  void (*const felem_sqr)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a) =
      group->meth->felem_sqr;

  EC_FELEM tv1, tv2, tv3, y1, y2;
  felem_sqr(group, &tv1, v);                             // 1. tv1 = v^2
  felem_mul(group, &tv2, u, v);                          // 2. tv2 = u * v
  felem_mul(group, &tv1, &tv1, &tv2);                    // 3. tv1 = tv1 * tv2
  group->meth->felem_exp(group, &y1, &tv1, c1, num_c1);  // 4. y1 = tv1^c1
  felem_mul(group, &y1, &y1, &tv2);                      // 5. y1 = y1 * tv2
  felem_mul(group, &y2, &y1, c2);                        // 6. y2 = y1 * c2
  felem_sqr(group, &tv3, &y1);                           // 7. tv3 = y1^2
  felem_mul(group, &tv3, &tv3, v);                       // 8. tv3 = tv3 * v

  // 9. isQR = tv3 == u
  // 10. y = CMOV(y2, y1, isQR)
  // 11. return (isQR, y)
  //
  // Note the specification's CMOV function and our |ec_felem_select| have the
  // opposite argument order.
  ec_felem_sub(group, &tv1, &tv3, u);
  const BN_ULONG isQR = ~ec_felem_non_zero_mask(group, &tv1);
  ec_felem_select(group, out_y, isQR, &y1, &y2);
  return isQR;
}

// map_to_curve_simple_swu implements the operation described in section 6.6.2
// of RFC 9380, using the straight-line implementation in appendix F.2.
static void 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_JACOBIAN *out,
                                    const EC_FELEM *u) {
  // This function requires the prime be 3 mod 4, and that A = -3.
  assert(is_3mod4(group));
  assert(group->a_is_minus3);

  void (*const felem_mul)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a,
                          const EC_FELEM *b) = group->meth->felem_mul;
  void (*const felem_sqr)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a) =
      group->meth->felem_sqr;

  EC_FELEM tv1, tv2, tv3, tv4, tv5, tv6, x, y, y1;
  felem_sqr(group, &tv1, u);                             // 1. tv1 = u^2
  felem_mul(group, &tv1, Z, &tv1);                       // 2. tv1 = Z * tv1
  felem_sqr(group, &tv2, &tv1);                          // 3. tv2 = tv1^2
  ec_felem_add(group, &tv2, &tv2, &tv1);                 // 4. tv2 = tv2 + tv1
  ec_felem_add(group, &tv3, &tv2, ec_felem_one(group));  // 5. tv3 = tv2 + 1
  felem_mul(group, &tv3, &group->b, &tv3);               // 6. tv3 = B * tv3

  // 7. tv4 = CMOV(Z, -tv2, tv2 != 0)
  const BN_ULONG tv2_non_zero = ec_felem_non_zero_mask(group, &tv2);
  ec_felem_neg(group, &tv4, &tv2);
  ec_felem_select(group, &tv4, tv2_non_zero, &tv4, Z);

  mul_A(group, &tv4, &tv4);                 // 8. tv4 = A * tv4
  felem_sqr(group, &tv2, &tv3);             // 9. tv2 = tv3^2
  felem_sqr(group, &tv6, &tv4);             // 10. tv6 = tv4^2
  mul_A(group, &tv5, &tv6);                 // 11. tv5 = A * tv6
  ec_felem_add(group, &tv2, &tv2, &tv5);    // 12. tv2 = tv2 + tv5
  felem_mul(group, &tv2, &tv2, &tv3);       // 13. tv2 = tv2 * tv3
  felem_mul(group, &tv6, &tv6, &tv4);       // 14. tv6 = tv6 * tv4
  felem_mul(group, &tv5, &group->b, &tv6);  // 15. tv5 = B * tv6
  ec_felem_add(group, &tv2, &tv2, &tv5);    // 16. tv2 = tv2 + tv5
  felem_mul(group, &x, &tv1, &tv3);         // 17. x = tv1 * tv3

  // 18. (is_gx1_square, y1) = sqrt_ratio(tv2, tv6)
  const BN_ULONG is_gx1_square =
      sqrt_ratio_3mod4(group, Z, c1, num_c1, c2, &y1, &tv2, &tv6);

  felem_mul(group, &y, &tv1, u);  // 19. y = tv1 * u
  felem_mul(group, &y, &y, &y1);  // 20. y = y * y1

  // 21. x = CMOV(x, tv3, is_gx1_square)
  ec_felem_select(group, &x, is_gx1_square, &tv3, &x);
  // 22. y = CMOV(y, y1, is_gx1_square)
  ec_felem_select(group, &y, is_gx1_square, &y1, &y);

  // 23. e1 = sgn0(u) == sgn0(y)
  BN_ULONG sgn0_u = sgn0(group, u);
  BN_ULONG sgn0_y = sgn0(group, &y);
  BN_ULONG not_e1 = sgn0_u ^ sgn0_y;
  not_e1 = ((BN_ULONG)0) - not_e1;

  // 24. y = CMOV(-y, y, e1)
  ec_felem_neg(group, &tv1, &y);
  ec_felem_select(group, &y, not_e1, &tv1, &y);

  // 25. x = x / tv4
  //
  // Our output is in projective coordinates, so rather than inverting |tv4|
  // now, represent (x / tv4, y) as (x * tv4, y * tv4^3, tv4). This is much more
  // efficient if the caller will do further computation on the output. (If the
  // caller will immediately convert to affine coordinates, it is slightly less
  // efficient, but only by a few field multiplications.)
  felem_mul(group, &out->X, &x, &tv4);
  felem_mul(group, &out->Y, &y, &tv6);
  out->Z = tv4;
}

static int hash_to_curve(const EC_GROUP *group, const EVP_MD *md,
                         const EC_FELEM *Z, const EC_FELEM *c2, unsigned k,
                         EC_JACOBIAN *out, const uint8_t *dst, size_t dst_len,
                         const uint8_t *msg, size_t msg_len) {
  EC_FELEM u0, u1;
  if (!hash_to_field2(group, md, &u0, &u1, dst, dst_len, k, msg, msg_len)) {
    return 0;
  }

  // Compute |c1| = (p - 3) / 4.
  BN_ULONG c1[EC_MAX_WORDS];
  size_t num_c1 = group->field.N.width;
  if (!bn_copy_words(c1, num_c1, &group->field.N)) {
    return 0;
  }
  bn_rshift_words(c1, c1, /*shift=*/2, /*num=*/num_c1);

  EC_JACOBIAN Q0, Q1;
  map_to_curve_simple_swu(group, Z, c1, num_c1, c2, &Q0, &u0);
  map_to_curve_simple_swu(group, Z, c1, num_c1, c2, &Q1, &u1);

  group->meth->add(group, out, &Q0, &Q1);  // R = Q0 + Q1
  // All our curves have cofactor one, so |clear_cofactor| is a no-op.
  return 1;
}

static int encode_to_curve(const EC_GROUP *group, const EVP_MD *md,
                           const EC_FELEM *Z, const EC_FELEM *c2, unsigned k,
                           EC_JACOBIAN *out, const uint8_t *dst, size_t dst_len,
                           const uint8_t *msg, size_t msg_len) {
  EC_FELEM u;
  if (!hash_to_field1(group, md, &u, dst, dst_len, k, msg, msg_len)) {
    return 0;
  }

  // Compute |c1| = (p - 3) / 4.
  BN_ULONG c1[EC_MAX_WORDS];
  size_t num_c1 = group->field.N.width;
  if (!bn_copy_words(c1, num_c1, &group->field.N)) {
    return 0;
  }
  bn_rshift_words(c1, c1, /*shift=*/2, /*num=*/num_c1);

  map_to_curve_simple_swu(group, Z, c1, num_c1, c2, out, &u);
  // All our curves have cofactor one, so |clear_cofactor| is a no-op.
  return 1;
}

static int felem_from_u8(const EC_GROUP *group, EC_FELEM *out, uint8_t a) {
  uint8_t bytes[EC_MAX_BYTES] = {0};
  size_t len = BN_num_bytes(&group->field.N);
  bytes[len - 1] = a;
  return ec_felem_from_bytes(group, out, bytes, len);
}

// kP256Sqrt10 is sqrt(10) in P-256's field. It was computed as follows in
// python3:
//
// p =  2**256 - 2**224 + 2**192 + 2**96 - 1
// c2 = pow(10, (p+1)//4, p)
// assert pow(c2, 2, p) == 10
// ", ".join("0x%02x" % b for b in c2.to_bytes(256//8, 'big'))
static const uint8_t kP256Sqrt10[] = {
    0xda, 0x53, 0x8e, 0x3b, 0xe1, 0xd8, 0x9b, 0x99, 0xc9, 0x78, 0xfc,
    0x67, 0x51, 0x80, 0xaa, 0xb2, 0x7b, 0x8d, 0x1f, 0xf8, 0x4c, 0x55,
    0xd5, 0xb6, 0x2c, 0xcd, 0x34, 0x27, 0xe4, 0x33, 0xc4, 0x7f};

// kP384Sqrt12 is sqrt(12) in P-384's field. It was computed as follows in
// python3:
//
// p = 2**384 - 2**128 - 2**96 + 2**32 - 1
// c2 = pow(12, (p+1)//4, p)
// assert pow(c2, 2, p) == 12
// ", ".join("0x%02x" % b for b in c2.to_bytes(384//8, 'big'))
static const uint8_t kP384Sqrt12[] = {
    0x2a, 0xcc, 0xb4, 0xa6, 0x56, 0xb0, 0x24, 0x9c, 0x71, 0xf0, 0x50, 0x0e,
    0x83, 0xda, 0x2f, 0xdd, 0x7f, 0x98, 0xe3, 0x83, 0xd6, 0x8b, 0x53, 0x87,
    0x1f, 0x87, 0x2f, 0xcb, 0x9c, 0xcb, 0x80, 0xc5, 0x3c, 0x0d, 0xe1, 0xf8,
    0xa8, 0x0f, 0x7e, 0x19, 0x14, 0xe2, 0xec, 0x69, 0xf5, 0xa6, 0x26, 0xb3};

int ec_hash_to_curve_p256_xmd_sha256_sswu(const EC_GROUP *group,
                                          EC_JACOBIAN *out, const uint8_t *dst,
                                          size_t dst_len, const uint8_t *msg,
                                          size_t msg_len) {
  // See section 8.3 of RFC 9380.
  if (EC_GROUP_get_curve_name(group) != NID_X9_62_prime256v1) {
    OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH);
    return 0;
  }

  // Z = -10, c2 = sqrt(10)
  EC_FELEM Z, c2;
  if (!felem_from_u8(group, &Z, 10) ||
      !ec_felem_from_bytes(group, &c2, kP256Sqrt10, sizeof(kP256Sqrt10))) {
    return 0;
  }
  ec_felem_neg(group, &Z, &Z);

  return hash_to_curve(group, EVP_sha256(), &Z, &c2, /*k=*/128, out, dst,
                       dst_len, msg, msg_len);
}

int EC_hash_to_curve_p256_xmd_sha256_sswu(const EC_GROUP *group, EC_POINT *out,
                                          const uint8_t *dst, size_t dst_len,
                                          const uint8_t *msg, size_t msg_len) {
  if (EC_GROUP_cmp(group, out->group, nullptr) != 0) {
    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    return 0;
  }
  return ec_hash_to_curve_p256_xmd_sha256_sswu(group, &out->raw, dst, dst_len,
                                               msg, msg_len);
}

int ec_hash_to_curve_p384_xmd_sha384_sswu(const EC_GROUP *group,
                                          EC_JACOBIAN *out, const uint8_t *dst,
                                          size_t dst_len, const uint8_t *msg,
                                          size_t msg_len) {
  // See section 8.3 of RFC 9380.
  if (EC_GROUP_get_curve_name(group) != NID_secp384r1) {
    OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH);
    return 0;
  }

  // Z = -12, c2 = sqrt(12)
  EC_FELEM Z, c2;
  if (!felem_from_u8(group, &Z, 12) ||
      !ec_felem_from_bytes(group, &c2, kP384Sqrt12, sizeof(kP384Sqrt12))) {
    return 0;
  }
  ec_felem_neg(group, &Z, &Z);

  return hash_to_curve(group, EVP_sha384(), &Z, &c2, /*k=*/192, out, dst,
                       dst_len, msg, msg_len);
}

int EC_hash_to_curve_p384_xmd_sha384_sswu(const EC_GROUP *group, EC_POINT *out,
                                          const uint8_t *dst, size_t dst_len,
                                          const uint8_t *msg, size_t msg_len) {
  if (EC_GROUP_cmp(group, out->group, nullptr) != 0) {
    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    return 0;
  }
  return ec_hash_to_curve_p384_xmd_sha384_sswu(group, &out->raw, dst, dst_len,
                                               msg, msg_len);
}

int ec_encode_to_curve_p256_xmd_sha256_sswu(const EC_GROUP *group,
                                            EC_JACOBIAN *out,
                                            const uint8_t *dst, size_t dst_len,
                                            const uint8_t *msg,
                                            size_t msg_len) {
  // See section 8.3 of RFC 9380.
  if (EC_GROUP_get_curve_name(group) != NID_X9_62_prime256v1) {
    OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH);
    return 0;
  }

  // Z = -10, c2 = sqrt(10)
  EC_FELEM Z, c2;
  if (!felem_from_u8(group, &Z, 10) ||
      !ec_felem_from_bytes(group, &c2, kP256Sqrt10, sizeof(kP256Sqrt10))) {
    return 0;
  }
  ec_felem_neg(group, &Z, &Z);

  return encode_to_curve(group, EVP_sha256(), &Z, &c2, /*k=*/128, out, dst,
                         dst_len, msg, msg_len);
}

int EC_encode_to_curve_p256_xmd_sha256_sswu(const EC_GROUP *group,
                                            EC_POINT *out, const uint8_t *dst,
                                            size_t dst_len, const uint8_t *msg,
                                            size_t msg_len) {
  if (EC_GROUP_cmp(group, out->group, nullptr) != 0) {
    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    return 0;
  }
  return ec_encode_to_curve_p256_xmd_sha256_sswu(group, &out->raw, dst, dst_len,
                                                 msg, msg_len);
}

int ec_encode_to_curve_p384_xmd_sha384_sswu(const EC_GROUP *group,
                                            EC_JACOBIAN *out,
                                            const uint8_t *dst, size_t dst_len,
                                            const uint8_t *msg,
                                            size_t msg_len) {
  // See section 8.3 of RFC 9380.
  if (EC_GROUP_get_curve_name(group) != NID_secp384r1) {
    OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH);
    return 0;
  }

  // Z = -12, c2 = sqrt(12)
  EC_FELEM Z, c2;
  if (!felem_from_u8(group, &Z, 12) ||
      !ec_felem_from_bytes(group, &c2, kP384Sqrt12, sizeof(kP384Sqrt12))) {
    return 0;
  }
  ec_felem_neg(group, &Z, &Z);

  return encode_to_curve(group, EVP_sha384(), &Z, &c2, /*k=*/192, out, dst,
                         dst_len, msg, msg_len);
}

int EC_encode_to_curve_p384_xmd_sha384_sswu(const EC_GROUP *group,
                                            EC_POINT *out, const uint8_t *dst,
                                            size_t dst_len, const uint8_t *msg,
                                            size_t msg_len) {
  if (EC_GROUP_cmp(group, out->group, nullptr) != 0) {
    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    return 0;
  }
  return ec_encode_to_curve_p384_xmd_sha384_sswu(group, &out->raw, dst, dst_len,
                                                 msg, msg_len);
}

int ec_hash_to_scalar_p384_xmd_sha384(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_sha384(), out, dst, dst_len, /*k=*/192, msg,
                        msg_len);
}

int ec_hash_to_curve_p384_xmd_sha512_sswu_draft07(
    const EC_GROUP *group, EC_JACOBIAN *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;
  }

  // Z = -12, c2 = sqrt(12)
  EC_FELEM Z, c2;
  if (!felem_from_u8(group, &Z, 12) ||
      !ec_felem_from_bytes(group, &c2, kP384Sqrt12, sizeof(kP384Sqrt12))) {
    return 0;
  }
  ec_felem_neg(group, &Z, &Z);

  return hash_to_curve(group, EVP_sha512(), &Z, &c2, /*k=*/192, out, dst,
                       dst_len, msg, 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);
}
