/* Copyright (c) 2020, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include <openssl/trust_token.h>

#include <openssl/bn.h>
#include <openssl/bytestring.h>
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/nid.h>
#include <openssl/rand.h>
#include <openssl/sha.h>

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

#include "internal.h"


typedef int (*hash_to_group_func_t)(const EC_GROUP *group, EC_RAW_POINT *out,
                                    const uint8_t t[TRUST_TOKEN_NONCE_SIZE]);
typedef int (*hash_to_scalar_func_t)(const EC_GROUP *group, EC_SCALAR *out,
                                     uint8_t *buf, size_t len);

typedef struct {
  const EC_GROUP *group;

  // hash_to_group implements the HashToGroup operation for VOPRFs. It returns
  // one on success and zero on error.
  hash_to_group_func_t hash_to_group;
  // hash_to_scalar implements the HashToScalar operation for VOPRFs. It returns
  // one on success and zero on error.
  hash_to_scalar_func_t hash_to_scalar;
} VOPRF_METHOD;

static const uint8_t kDefaultAdditionalData[32] = {0};

static int voprf_init_method(VOPRF_METHOD *method, int curve_nid,
                             hash_to_group_func_t hash_to_group,
                             hash_to_scalar_func_t hash_to_scalar) {
  method->group = EC_GROUP_new_by_curve_name(curve_nid);
  if (method->group == NULL) {
    return 0;
  }

  method->hash_to_group = hash_to_group;
  method->hash_to_scalar = hash_to_scalar;

  return 1;
}

static int cbb_add_point(CBB *out, const EC_GROUP *group,
                         const EC_AFFINE *point) {
  uint8_t *p;
  size_t len = ec_point_byte_len(group, POINT_CONVERSION_UNCOMPRESSED);
  return CBB_add_space(out, &p, len) &&
         ec_point_to_bytes(group, point, POINT_CONVERSION_UNCOMPRESSED, p,
                           len) == len &&
         CBB_flush(out);
}

static int cbb_serialize_point(CBB *out, const EC_GROUP *group,
                               const EC_AFFINE *point) {
  uint8_t *p;
  size_t len = ec_point_byte_len(group, POINT_CONVERSION_COMPRESSED);
  return CBB_add_u16(out, len) && CBB_add_space(out, &p, len) &&
         ec_point_to_bytes(group, point, POINT_CONVERSION_COMPRESSED, p, len) ==
             len &&
         CBB_flush(out);
}

static int cbs_get_point(CBS *cbs, const EC_GROUP *group, EC_AFFINE *out) {
  CBS child;
  size_t plen = 1 + 2 * BN_num_bytes(&group->field);
  if (!CBS_get_bytes(cbs, &child, plen) ||
      !ec_point_from_uncompressed(group, out, CBS_data(&child),
                                  CBS_len(&child))) {
    return 0;
  }
  return 1;
}

static int scalar_to_cbb(CBB *out, const EC_GROUP *group,
                         const EC_SCALAR *scalar) {
  uint8_t *buf;
  size_t scalar_len = BN_num_bytes(&group->order);
  if (!CBB_add_space(out, &buf, scalar_len)) {
    return 0;
  }
  ec_scalar_to_bytes(group, buf, &scalar_len, scalar);
  return 1;
}

static int scalar_from_cbs(CBS *cbs, const EC_GROUP *group, EC_SCALAR *out) {
  size_t scalar_len = BN_num_bytes(&group->order);
  CBS tmp;
  if (!CBS_get_bytes(cbs, &tmp, scalar_len)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
    return 0;
  }

  ec_scalar_from_bytes(group, out, CBS_data(&tmp), CBS_len(&tmp));
  return 1;
}

static int voprf_calculate_key(const VOPRF_METHOD *method, CBB *out_private,
                               CBB *out_public, const EC_SCALAR *priv) {
  const EC_GROUP *group = method->group;
  EC_RAW_POINT pub;
  EC_AFFINE pub_affine;
  if (!ec_point_mul_scalar_base(group, &pub, priv) ||
      !ec_jacobian_to_affine(group, &pub_affine, &pub)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_KEYGEN_FAILURE);
    return 0;
  }

  if (!scalar_to_cbb(out_private, group, priv) ||
      !cbb_add_point(out_public, group, &pub_affine)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
    return 0;
  }

  return 1;
}


static int voprf_generate_key(const VOPRF_METHOD *method, CBB *out_private,
                              CBB *out_public) {
  EC_SCALAR priv;
  if (!ec_random_nonzero_scalar(method->group, &priv, kDefaultAdditionalData)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_KEYGEN_FAILURE);
    return 0;
  }
  return voprf_calculate_key(method, out_private, out_public, &priv);
}

static int voprf_derive_key_from_secret(const VOPRF_METHOD *method,
                                        CBB *out_private, CBB *out_public,
                                        const uint8_t *secret,
                                        size_t secret_len) {
  static const uint8_t kKeygenLabel[] = "TrustTokenVOPRFKeyGen";

  EC_SCALAR priv;
  int ok = 0;
  CBB cbb;
  CBB_zero(&cbb);
  uint8_t *buf = NULL;
  size_t len;
  if (!CBB_init(&cbb, 0) ||
      !CBB_add_bytes(&cbb, kKeygenLabel, sizeof(kKeygenLabel)) ||
      !CBB_add_bytes(&cbb, secret, secret_len) ||
      !CBB_finish(&cbb, &buf, &len) ||
      !method->hash_to_scalar(method->group, &priv, buf, len)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_KEYGEN_FAILURE);
    goto err;
  }

  ok = voprf_calculate_key(method, out_private, out_public, &priv);

err:
  CBB_cleanup(&cbb);
  OPENSSL_free(buf);
  return ok;
}

static int voprf_client_key_from_bytes(const VOPRF_METHOD *method,
                                       TRUST_TOKEN_CLIENT_KEY *key,
                                       const uint8_t *in, size_t len) {
  const EC_GROUP *group = method->group;
  if (!ec_point_from_uncompressed(group, &key->pubs, in, len)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
    return 0;
  }

  return 1;
}

static int voprf_issuer_key_from_bytes(const VOPRF_METHOD *method,
                                       TRUST_TOKEN_ISSUER_KEY *key,
                                       const uint8_t *in, size_t len) {
  const EC_GROUP *group = method->group;
  if (!ec_scalar_from_bytes(group, &key->xs, in, len)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
    return 0;
  }

  // Recompute the public key.
  EC_RAW_POINT pub;
  if (!ec_point_mul_scalar_base(group, &pub, &key->xs) ||
      !ec_jacobian_to_affine(group, &key->pubs, &pub)) {
    return 0;
  }

  return 1;
}

static STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_blind(const VOPRF_METHOD *method,
                                                   CBB *cbb, size_t count,
                                                   int include_message,
                                                   const uint8_t *msg,
                                                   size_t msg_len) {
  SHA512_CTX hash_ctx;

  const EC_GROUP *group = method->group;
  STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens =
      sk_TRUST_TOKEN_PRETOKEN_new_null();
  if (pretokens == NULL) {
    goto err;
  }

  for (size_t i = 0; i < count; i++) {
    // Insert |pretoken| into |pretokens| early to simplify error-handling.
    TRUST_TOKEN_PRETOKEN *pretoken =
        OPENSSL_malloc(sizeof(TRUST_TOKEN_PRETOKEN));
    if (pretoken == NULL ||
        !sk_TRUST_TOKEN_PRETOKEN_push(pretokens, pretoken)) {
      TRUST_TOKEN_PRETOKEN_free(pretoken);
      goto err;
    }

    RAND_bytes(pretoken->salt, sizeof(pretoken->salt));
    if (include_message) {
      assert(SHA512_DIGEST_LENGTH == TRUST_TOKEN_NONCE_SIZE);
      SHA512_Init(&hash_ctx);
      SHA512_Update(&hash_ctx, pretoken->salt, sizeof(pretoken->salt));
      SHA512_Update(&hash_ctx, msg, msg_len);
      SHA512_Final(pretoken->t, &hash_ctx);
    } else {
      OPENSSL_memcpy(pretoken->t, pretoken->salt, TRUST_TOKEN_NONCE_SIZE);
    }

    // We sample r in Montgomery form to simplify inverting.
    EC_SCALAR r;
    if (!ec_random_nonzero_scalar(group, &r,
                                  kDefaultAdditionalData)) {
      goto err;
    }

    // pretoken->r is rinv.
    ec_scalar_inv0_montgomery(group, &pretoken->r, &r);
    // Convert both out of Montgomery form.
    ec_scalar_from_montgomery(group, &r, &r);
    ec_scalar_from_montgomery(group, &pretoken->r, &pretoken->r);

    // Tp is the blinded token in the VOPRF protocol.
    EC_RAW_POINT P, Tp;
    if (!method->hash_to_group(group, &P, pretoken->t) ||
        !ec_point_mul_scalar(group, &Tp, &P, &r) ||
        !ec_jacobian_to_affine(group, &pretoken->Tp, &Tp)) {
      goto err;
    }

    if (!cbb_add_point(cbb, group, &pretoken->Tp)) {
      goto err;
    }
  }

  return pretokens;

err:
  sk_TRUST_TOKEN_PRETOKEN_pop_free(pretokens, TRUST_TOKEN_PRETOKEN_free);
  return NULL;
}

static int hash_to_scalar_dleq(const VOPRF_METHOD *method, EC_SCALAR *out,
                               const EC_AFFINE *X, const EC_AFFINE *T,
                               const EC_AFFINE *W, const EC_AFFINE *K0,
                               const EC_AFFINE *K1) {
  static const uint8_t kDLEQLabel[] = "DLEQ";

  int ok = 0;
  CBB cbb;
  CBB_zero(&cbb);
  uint8_t *buf = NULL;
  size_t len;
  if (!CBB_init(&cbb, 0) ||
      !CBB_add_bytes(&cbb, kDLEQLabel, sizeof(kDLEQLabel)) ||
      !cbb_add_point(&cbb, method->group, X) ||
      !cbb_add_point(&cbb, method->group, T) ||
      !cbb_add_point(&cbb, method->group, W) ||
      !cbb_add_point(&cbb, method->group, K0) ||
      !cbb_add_point(&cbb, method->group, K1) ||
      !CBB_finish(&cbb, &buf, &len) ||
      !method->hash_to_scalar(method->group, out, buf, len)) {
    goto err;
  }

  ok = 1;

err:
  CBB_cleanup(&cbb);
  OPENSSL_free(buf);
  return ok;
}

static int hash_to_scalar_challenge(const VOPRF_METHOD *method, EC_SCALAR *out,
                                    const EC_AFFINE *Bm, const EC_AFFINE *a0,
                                    const EC_AFFINE *a1, const EC_AFFINE *a2,
                                    const EC_AFFINE *a3) {
  static const uint8_t kChallengeLabel[] = "Challenge";

  CBB cbb;
  uint8_t transcript[5 * EC_MAX_COMPRESSED + 2 + sizeof(kChallengeLabel) - 1];
  size_t len;
  if (!CBB_init_fixed(&cbb, transcript, sizeof(transcript)) ||
      !cbb_serialize_point(&cbb, method->group, Bm) ||
      !cbb_serialize_point(&cbb, method->group, a0) ||
      !cbb_serialize_point(&cbb, method->group, a1) ||
      !cbb_serialize_point(&cbb, method->group, a2) ||
      !cbb_serialize_point(&cbb, method->group, a3) ||
      !CBB_add_bytes(&cbb, kChallengeLabel, sizeof(kChallengeLabel) - 1) ||
      !CBB_finish(&cbb, NULL, &len) ||
      !method->hash_to_scalar(method->group, out, transcript, len)) {
    return 0;
  }

  return 1;
}

static int hash_to_scalar_batch(const VOPRF_METHOD *method, EC_SCALAR *out,
                                const CBB *points, size_t index) {
  static const uint8_t kDLEQBatchLabel[] = "DLEQ BATCH";
  if (index > 0xffff) {
    // The protocol supports only two-byte batches.
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
    return 0;
  }

  int ok = 0;
  CBB cbb;
  CBB_zero(&cbb);
  uint8_t *buf = NULL;
  size_t len;
  if (!CBB_init(&cbb, 0) ||
      !CBB_add_bytes(&cbb, kDLEQBatchLabel, sizeof(kDLEQBatchLabel)) ||
      !CBB_add_bytes(&cbb, CBB_data(points), CBB_len(points)) ||
      !CBB_add_u16(&cbb, (uint16_t)index) ||
      !CBB_finish(&cbb, &buf, &len) ||
      !method->hash_to_scalar(method->group, out, buf, len)) {
    goto err;
  }

  ok = 1;

err:
  CBB_cleanup(&cbb);
  OPENSSL_free(buf);
  return ok;
}

static int dleq_generate(const VOPRF_METHOD *method, CBB *cbb,
                         const TRUST_TOKEN_ISSUER_KEY *priv,
                         const EC_RAW_POINT *T, const EC_RAW_POINT *W) {
  const EC_GROUP *group = method->group;

  enum {
    idx_T,
    idx_W,
    idx_k0,
    idx_k1,
    num_idx,
  };
  EC_RAW_POINT jacobians[num_idx];

  // Setup the DLEQ proof.
  EC_SCALAR r;
  if (// r <- Zp
      !ec_random_nonzero_scalar(group, &r, kDefaultAdditionalData) ||
      // k0;k1 = r*(G;T)
      !ec_point_mul_scalar_base(group, &jacobians[idx_k0], &r) ||
      !ec_point_mul_scalar(group, &jacobians[idx_k1], T, &r))  {
    return 0;
  }

  EC_AFFINE affines[num_idx];
  jacobians[idx_T] = *T;
  jacobians[idx_W] = *W;
  if (!ec_jacobian_to_affine_batch(group, affines, jacobians, num_idx)) {
    return 0;
  }

  // Compute c = Hc(...).
  EC_SCALAR c;
  if (!hash_to_scalar_dleq(method, &c, &priv->pubs, &affines[idx_T],
                           &affines[idx_W], &affines[idx_k0],
                           &affines[idx_k1])) {
    return 0;
  }


  EC_SCALAR c_mont;
  ec_scalar_to_montgomery(group, &c_mont, &c);

  // u = r + c*xs
  EC_SCALAR u;
  ec_scalar_mul_montgomery(group, &u, &priv->xs, &c_mont);
  ec_scalar_add(group, &u, &r, &u);

  // Store DLEQ proof in transcript.
  if (!scalar_to_cbb(cbb, group, &c) ||
      !scalar_to_cbb(cbb, group, &u)) {
    return 0;
  }

  return 1;
}

static int mul_public_2(const EC_GROUP *group, EC_RAW_POINT *out,
                        const EC_RAW_POINT *p0, const EC_SCALAR *scalar0,
                        const EC_RAW_POINT *p1, const EC_SCALAR *scalar1) {
  EC_RAW_POINT points[2] = {*p0, *p1};
  EC_SCALAR scalars[2] = {*scalar0, *scalar1};
  return ec_point_mul_scalar_public_batch(group, out, /*g_scalar=*/NULL, points,
                                          scalars, 2);
}

static int dleq_verify(const VOPRF_METHOD *method, CBS *cbs,
                       const TRUST_TOKEN_CLIENT_KEY *pub, const EC_RAW_POINT *T,
                       const EC_RAW_POINT *W) {
  const EC_GROUP *group = method->group;


  enum {
    idx_T,
    idx_W,
    idx_k0,
    idx_k1,
    num_idx,
  };
  EC_RAW_POINT jacobians[num_idx];

  // Decode the DLEQ proof.
  EC_SCALAR c, u;
  if (!scalar_from_cbs(cbs, group, &c) ||
      !scalar_from_cbs(cbs, group, &u)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
    return 0;
  }

  // k0;k1 = u*(G;T) - c*(pub;W)
  EC_RAW_POINT pubs;
  ec_affine_to_jacobian(group, &pubs, &pub->pubs);
  EC_SCALAR minus_c;
  ec_scalar_neg(group, &minus_c, &c);
  if (!ec_point_mul_scalar_public(group, &jacobians[idx_k0], &u, &pubs,
                                  &minus_c) ||
      !mul_public_2(group, &jacobians[idx_k1], T, &u, W, &minus_c)) {
    return 0;
  }

  // Check the DLEQ proof.
  EC_AFFINE affines[num_idx];
  jacobians[idx_T] = *T;
  jacobians[idx_W] = *W;
  if (!ec_jacobian_to_affine_batch(group, affines, jacobians, num_idx)) {
    return 0;
  }

  // Compute c = Hc(...).
  EC_SCALAR calculated;
  if (!hash_to_scalar_dleq(method, &calculated, &pub->pubs, &affines[idx_T],
                           &affines[idx_W], &affines[idx_k0],
                           &affines[idx_k1])) {
    return 0;
  }

  // c == calculated
  if (!ec_scalar_equal_vartime(group, &c, &calculated)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_PROOF);
    return 0;
  }

  return 1;
}

static int voprf_sign_tt(const VOPRF_METHOD *method,
                         const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs,
                         size_t num_requested, size_t num_to_issue) {
  const EC_GROUP *group = method->group;
  if (num_requested < num_to_issue) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  if (num_to_issue > ((size_t)-1) / sizeof(EC_RAW_POINT) ||
      num_to_issue > ((size_t)-1) / sizeof(EC_SCALAR)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
    return 0;
  }

  int ret = 0;
  EC_RAW_POINT *BTs = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT));
  EC_RAW_POINT *Zs = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT));
  EC_SCALAR *es = OPENSSL_malloc(num_to_issue * sizeof(EC_SCALAR));
  CBB batch_cbb;
  CBB_zero(&batch_cbb);
  if (!BTs ||
      !Zs ||
      !es ||
      !CBB_init(&batch_cbb, 0) ||
      !cbb_add_point(&batch_cbb, method->group, &key->pubs)) {
    goto err;
  }

  for (size_t i = 0; i < num_to_issue; i++) {
    EC_AFFINE BT_affine, Z_affine;
    EC_RAW_POINT BT, Z;
    if (!cbs_get_point(cbs, group, &BT_affine)) {
      OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
      goto err;
    }
    ec_affine_to_jacobian(group, &BT, &BT_affine);
    if (!ec_point_mul_scalar(group, &Z, &BT, &key->xs) ||
        !ec_jacobian_to_affine(group, &Z_affine, &Z) ||
        !cbb_add_point(cbb, group, &Z_affine)) {
      goto err;
    }

    if (!cbb_add_point(&batch_cbb, group, &BT_affine) ||
        !cbb_add_point(&batch_cbb, group, &Z_affine)) {
      goto err;
    }
    BTs[i] = BT;
    Zs[i] = Z;

    if (!CBB_flush(cbb)) {
      goto err;
    }
  }

  // The DLEQ batching construction is described in appendix B of
  // https://eprint.iacr.org/2020/072/20200324:214215. Note the additional
  // computations all act on public inputs.
  for (size_t i = 0; i < num_to_issue; i++) {
    if (!hash_to_scalar_batch(method, &es[i], &batch_cbb, i)) {
      goto err;
    }
  }

  EC_RAW_POINT BT_batch, Z_batch;
  if (!ec_point_mul_scalar_public_batch(group, &BT_batch,
                                        /*g_scalar=*/NULL, BTs, es,
                                        num_to_issue) ||
      !ec_point_mul_scalar_public_batch(group, &Z_batch,
                                        /*g_scalar=*/NULL, Zs, es,
                                        num_to_issue)) {
    goto err;
  }

  CBB proof;
  if (!CBB_add_u16_length_prefixed(cbb, &proof) ||
      !dleq_generate(method, &proof, key, &BT_batch, &Z_batch) ||
      !CBB_flush(cbb)) {
    goto err;
  }

  // Skip over any unused requests.
  size_t point_len = 1 + 2 * BN_num_bytes(&group->field);
  if (!CBS_skip(cbs, point_len * (num_requested - num_to_issue))) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
    goto err;
  }

  ret = 1;

err:
  OPENSSL_free(BTs);
  OPENSSL_free(Zs);
  OPENSSL_free(es);
  CBB_cleanup(&batch_cbb);
  return ret;
}

static STACK_OF(TRUST_TOKEN) *voprf_unblind_tt(
    const VOPRF_METHOD *method, const TRUST_TOKEN_CLIENT_KEY *key,
    const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count,
    uint32_t key_id) {
  const EC_GROUP *group = method->group;
  if (count > sk_TRUST_TOKEN_PRETOKEN_num(pretokens)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
    return NULL;
  }

  if (count > ((size_t)-1) / sizeof(EC_RAW_POINT) ||
      count > ((size_t)-1) / sizeof(EC_SCALAR)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
    return NULL;
  }

  int ok = 0;
  STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null();
  EC_RAW_POINT *BTs = OPENSSL_malloc(count * sizeof(EC_RAW_POINT));
  EC_RAW_POINT *Zs = OPENSSL_malloc(count * sizeof(EC_RAW_POINT));
  EC_SCALAR *es = OPENSSL_malloc(count * sizeof(EC_SCALAR));
  CBB batch_cbb;
  CBB_zero(&batch_cbb);
  if (ret == NULL ||
      BTs == NULL ||
      Zs == NULL ||
      es == NULL ||
      !CBB_init(&batch_cbb, 0) ||
      !cbb_add_point(&batch_cbb, method->group, &key->pubs)) {
    goto err;
  }

  for (size_t i = 0; i < count; i++) {
    const TRUST_TOKEN_PRETOKEN *pretoken =
        sk_TRUST_TOKEN_PRETOKEN_value(pretokens, i);

    EC_AFFINE Z_affine;
    if (!cbs_get_point(cbs, group, &Z_affine)) {
      OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
      goto err;
    }

    ec_affine_to_jacobian(group, &BTs[i], &pretoken->Tp);
    ec_affine_to_jacobian(group, &Zs[i], &Z_affine);

    if (!cbb_add_point(&batch_cbb, group, &pretoken->Tp) ||
        !cbb_add_point(&batch_cbb, group, &Z_affine)) {
      goto err;
    }

    // Unblind the token.
    // pretoken->r is rinv.
    EC_RAW_POINT N;
    EC_AFFINE N_affine;
    if (!ec_point_mul_scalar(group, &N, &Zs[i], &pretoken->r) ||
        !ec_jacobian_to_affine(group, &N_affine, &N)) {
      goto err;
    }

    // Serialize the token. Include |key_id| to avoid an extra copy in the layer
    // above.
    CBB token_cbb;
    size_t point_len = 1 + 2 * BN_num_bytes(&group->field);
    if (!CBB_init(&token_cbb, 4 + TRUST_TOKEN_NONCE_SIZE + (2 + point_len)) ||
        !CBB_add_u32(&token_cbb, key_id) ||
        !CBB_add_bytes(&token_cbb, pretoken->salt, TRUST_TOKEN_NONCE_SIZE) ||
        !cbb_add_point(&token_cbb, group, &N_affine) ||
        !CBB_flush(&token_cbb)) {
      CBB_cleanup(&token_cbb);
      goto err;
    }

    TRUST_TOKEN *token =
        TRUST_TOKEN_new(CBB_data(&token_cbb), CBB_len(&token_cbb));
    CBB_cleanup(&token_cbb);
    if (token == NULL ||
        !sk_TRUST_TOKEN_push(ret, token)) {
      TRUST_TOKEN_free(token);
      goto err;
    }
  }

  // The DLEQ batching construction is described in appendix B of
  // https://eprint.iacr.org/2020/072/20200324:214215. Note the additional
  // computations all act on public inputs.
  for (size_t i = 0; i < count; i++) {
    if (!hash_to_scalar_batch(method, &es[i], &batch_cbb, i)) {
      goto err;
    }
  }

  EC_RAW_POINT BT_batch, Z_batch;
  if (!ec_point_mul_scalar_public_batch(group, &BT_batch,
                                        /*g_scalar=*/NULL, BTs, es, count) ||
      !ec_point_mul_scalar_public_batch(group, &Z_batch,
                                        /*g_scalar=*/NULL, Zs, es, count)) {
    goto err;
  }

  CBS proof;
  if (!CBS_get_u16_length_prefixed(cbs, &proof) ||
      !dleq_verify(method, &proof, key, &BT_batch, &Z_batch) ||
      CBS_len(&proof) != 0) {
    goto err;
  }

  ok = 1;

err:
  OPENSSL_free(BTs);
  OPENSSL_free(Zs);
  OPENSSL_free(es);
  CBB_cleanup(&batch_cbb);
  if (!ok) {
    sk_TRUST_TOKEN_pop_free(ret, TRUST_TOKEN_free);
    ret = NULL;
  }
  return ret;
}

static void sha384_update_u16(SHA512_CTX *ctx, uint16_t v) {
  uint8_t buf[2] = {v >> 8, v & 0xff};
  SHA384_Update(ctx, buf, 2);
}

static void sha384_update_point_with_length(
     SHA512_CTX *ctx, const EC_GROUP *group, const EC_AFFINE *point) {
  uint8_t buf[EC_MAX_COMPRESSED];
  size_t len = ec_point_to_bytes(group, point, POINT_CONVERSION_COMPRESSED,
                                 buf, sizeof(buf));
  assert(len > 0);
  sha384_update_u16(ctx, (uint16_t)len);
  SHA384_Update(ctx, buf, len);
}

static int compute_composite_seed(const VOPRF_METHOD *method,
                                  uint8_t out[SHA384_DIGEST_LENGTH],
                                  const EC_AFFINE *pub) {
  const EC_GROUP *group = method->group;
  static const uint8_t kSeedDST[] = "Seed-OPRFV1-\x01-P384-SHA384";

  SHA512_CTX hash_ctx;
  SHA384_Init(&hash_ctx);
  sha384_update_point_with_length(&hash_ctx, group, pub);
  sha384_update_u16(&hash_ctx, sizeof(kSeedDST) - 1);
  SHA384_Update(&hash_ctx, kSeedDST, sizeof(kSeedDST) - 1);
  SHA384_Final(out, &hash_ctx);

  return 1;
}

static int compute_composite_element(const VOPRF_METHOD *method,
                                     uint8_t seed[SHA384_DIGEST_LENGTH],
                                     EC_SCALAR *di, size_t index,
                                     const EC_AFFINE *C, const EC_AFFINE *D) {
  static const uint8_t kCompositeLabel[] = "Composite";
  const EC_GROUP *group = method->group;

  if (index > UINT16_MAX) {
    return 0;
  }

  CBB cbb;
  uint8_t transcript[2 + SHA384_DIGEST_LENGTH + 2 + 2 * EC_MAX_COMPRESSED +
                     sizeof(kCompositeLabel) - 1];
  size_t len;
  if (!CBB_init_fixed(&cbb, transcript, sizeof(transcript)) ||
      !CBB_add_u16(&cbb, SHA384_DIGEST_LENGTH) ||
      !CBB_add_bytes(&cbb, seed, SHA384_DIGEST_LENGTH) ||
      !CBB_add_u16(&cbb, index) ||
      !cbb_serialize_point(&cbb, group, C) ||
      !cbb_serialize_point(&cbb, group, D) ||
      !CBB_add_bytes(&cbb, kCompositeLabel,
                     sizeof(kCompositeLabel) - 1) ||
      !CBB_finish(&cbb, NULL, &len) ||
      !method->hash_to_scalar(method->group, di, transcript, len)) {
    return 0;
  }

  return 1;
}

static int generate_proof(const VOPRF_METHOD *method, CBB *cbb,
                          const TRUST_TOKEN_ISSUER_KEY *priv,
                          const EC_SCALAR *r, const EC_RAW_POINT *M,
                          const EC_RAW_POINT *Z) {
  const EC_GROUP *group = method->group;

  enum {
    idx_M,
    idx_Z,
    idx_t2,
    idx_t3,
    num_idx,
  };
  EC_RAW_POINT jacobians[num_idx];

  if (!ec_point_mul_scalar_base(group, &jacobians[idx_t2], r) ||
      !ec_point_mul_scalar(group, &jacobians[idx_t3], M, r)) {
    return 0;
  }


  EC_AFFINE affines[num_idx];
  jacobians[idx_M] = *M;
  jacobians[idx_Z] = *Z;
  if (!ec_jacobian_to_affine_batch(group, affines, jacobians, num_idx)) {
    return 0;
  }

  EC_SCALAR c;
  if (!hash_to_scalar_challenge(method, &c, &priv->pubs, &affines[idx_M],
                                &affines[idx_Z], &affines[idx_t2],
                                &affines[idx_t3])) {
    return 0;
  }

  EC_SCALAR c_mont;
  ec_scalar_to_montgomery(group, &c_mont, &c);

  // s = r - c*xs
  EC_SCALAR s;
  ec_scalar_mul_montgomery(group, &s, &priv->xs, &c_mont);
  ec_scalar_sub(group, &s, r, &s);

  // Store DLEQ proof in transcript.
  if (!scalar_to_cbb(cbb, group, &c) ||
      !scalar_to_cbb(cbb, group, &s)) {
    return 0;
  }

  return 1;
}

static int verify_proof(const VOPRF_METHOD *method, CBS *cbs,
                        const TRUST_TOKEN_CLIENT_KEY *pub,
                        const EC_RAW_POINT *M, const EC_RAW_POINT *Z) {
  const EC_GROUP *group = method->group;

  enum {
    idx_M,
    idx_Z,
    idx_t2,
    idx_t3,
    num_idx,
  };
  EC_RAW_POINT jacobians[num_idx];

  EC_SCALAR c, s;
  if (!scalar_from_cbs(cbs, group, &c) ||
      !scalar_from_cbs(cbs, group, &s)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
    return 0;
  }

  EC_RAW_POINT pubs;
  ec_affine_to_jacobian(group, &pubs, &pub->pubs);
  if (!ec_point_mul_scalar_public(group, &jacobians[idx_t2], &s, &pubs,
                                  &c) ||
      !mul_public_2(group, &jacobians[idx_t3], M, &s, Z, &c)) {
    return 0;
  }

  EC_AFFINE affines[num_idx];
  jacobians[idx_M] = *M;
  jacobians[idx_Z] = *Z;
  if (!ec_jacobian_to_affine_batch(group, affines, jacobians, num_idx)) {
    return 0;
  }

  EC_SCALAR expected_c;
  if (!hash_to_scalar_challenge(method, &expected_c, &pub->pubs,
                                &affines[idx_M], &affines[idx_Z],
                                &affines[idx_t2], &affines[idx_t3])) {
    return 0;
  }

  // c == expected_c
  if (!ec_scalar_equal_vartime(group, &c, &expected_c)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_PROOF);
    return 0;
  }

  return 1;
}

static int voprf_sign_impl(const VOPRF_METHOD *method,
                           const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb,
                           CBS *cbs, size_t num_requested, size_t num_to_issue,
                           const EC_SCALAR *proof_scalar) {
  const EC_GROUP *group = method->group;
  if (num_requested < num_to_issue) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  if (num_to_issue > ((size_t)-1) / sizeof(EC_RAW_POINT) ||
      num_to_issue > ((size_t)-1) / sizeof(EC_SCALAR)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
    return 0;
  }

  int ret = 0;
  EC_RAW_POINT *BTs = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT));
  EC_RAW_POINT *Zs = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT));
  EC_SCALAR *dis = OPENSSL_malloc(num_to_issue * sizeof(EC_SCALAR));
  if (!BTs || !Zs || !dis) {
    goto err;
  }

  uint8_t seed[SHA384_DIGEST_LENGTH];
  if (!compute_composite_seed(method, seed, &key->pubs)) {
    goto err;
  }

  // This implements the BlindEvaluateBatch as defined in section 4 of
  // draft-robert-privacypass-batched-tokens-01, based on the constructions
  // in draft-irtf-cfrg-voprf-21. To optimize the computation of the proof,
  // the computation of di is done during the token signing and passed into
  // the proof generation.
  for (size_t i = 0; i < num_to_issue; i++) {
    EC_AFFINE BT_affine, Z_affine;
    EC_RAW_POINT BT, Z;
    if (!cbs_get_point(cbs, group, &BT_affine)) {
      OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
      goto err;
    }
    ec_affine_to_jacobian(group, &BT, &BT_affine);
    if (!ec_point_mul_scalar(group, &Z, &BT, &key->xs) ||
        !ec_jacobian_to_affine(group, &Z_affine, &Z) ||
        !cbb_add_point(cbb, group, &Z_affine)) {
      goto err;
    }
    BTs[i] = BT;
    Zs[i] = Z;
    if (!compute_composite_element(method, seed, &dis[i], i, &BT_affine,
                                   &Z_affine)) {
      goto err;
    }

    if (!CBB_flush(cbb)) {
      goto err;
    }
  }

  EC_RAW_POINT M, Z;
  if (!ec_point_mul_scalar_public_batch(group, &M,
                                        /*g_scalar=*/NULL, BTs, dis,
                                        num_to_issue) ||
      !ec_point_mul_scalar(group, &Z, &M, &key->xs)) {
    goto err;
  }

  CBB proof;
  if (!CBB_add_u16_length_prefixed(cbb, &proof) ||
      !generate_proof(method, &proof, key, proof_scalar, &M, &Z) ||
      !CBB_flush(cbb)) {
    goto err;
  }

  // Skip over any unused requests.
  size_t point_len = 1 + 2 * BN_num_bytes(&group->field);
  if (!CBS_skip(cbs, point_len * (num_requested - num_to_issue))) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
    goto err;
  }

  ret = 1;

err:
  OPENSSL_free(BTs);
  OPENSSL_free(Zs);
  OPENSSL_free(dis);
  return ret;
}

static int voprf_sign(const VOPRF_METHOD *method,
                      const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs,
                      size_t num_requested, size_t num_to_issue) {
  EC_SCALAR proof_scalar;
  if (!ec_random_nonzero_scalar(method->group, &proof_scalar,
                                kDefaultAdditionalData)) {
    return 0;
  }

  return voprf_sign_impl(method, key, cbb, cbs, num_requested, num_to_issue,
                         &proof_scalar);
}

static int voprf_sign_with_proof_scalar_for_testing(
    const VOPRF_METHOD *method, const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb,
    CBS *cbs, size_t num_requested, size_t num_to_issue,
    const uint8_t *proof_scalar_buf, size_t proof_scalar_len) {
  EC_SCALAR proof_scalar;
  if (!ec_scalar_from_bytes(method->group, &proof_scalar, proof_scalar_buf,
                            proof_scalar_len)) {
    return 0;
  }
  return voprf_sign_impl(method, key, cbb, cbs, num_requested, num_to_issue,
                         &proof_scalar);
}

static STACK_OF(TRUST_TOKEN) *voprf_unblind(
    const VOPRF_METHOD *method, const TRUST_TOKEN_CLIENT_KEY *key,
    const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count,
    uint32_t key_id) {
  const EC_GROUP *group = method->group;
  if (count > sk_TRUST_TOKEN_PRETOKEN_num(pretokens)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
    return NULL;
  }

  if (count > ((size_t)-1) / sizeof(EC_RAW_POINT) ||
      count > ((size_t)-1) / sizeof(EC_SCALAR)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
    return NULL;
  }

  int ok = 0;
  STACK_OF(TRUST_TOKEN) *ret = sk_TRUST_TOKEN_new_null();
  EC_RAW_POINT *BTs = OPENSSL_malloc(count * sizeof(EC_RAW_POINT));
  EC_RAW_POINT *Zs = OPENSSL_malloc(count * sizeof(EC_RAW_POINT));
  EC_SCALAR *dis = OPENSSL_malloc(count * sizeof(EC_SCALAR));
  if (ret == NULL || !BTs || !Zs || !dis) {
    goto err;
  }

  uint8_t seed[SHA384_DIGEST_LENGTH];
  if (!compute_composite_seed(method, seed, &key->pubs)) {
    goto err;
  }

  for (size_t i = 0; i < count; i++) {
    const TRUST_TOKEN_PRETOKEN *pretoken =
        sk_TRUST_TOKEN_PRETOKEN_value(pretokens, i);

    EC_AFFINE Z_affine;
    if (!cbs_get_point(cbs, group, &Z_affine)) {
      OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
      goto err;
    }

    ec_affine_to_jacobian(group, &BTs[i], &pretoken->Tp);
    ec_affine_to_jacobian(group, &Zs[i], &Z_affine);
    if (!compute_composite_element(method, seed, &dis[i], i, &pretoken->Tp,
                                   &Z_affine)) {
      goto err;
    }

    // Unblind the token.
    // pretoken->r is rinv.
    EC_RAW_POINT N;
    EC_AFFINE N_affine;
    if (!ec_point_mul_scalar(group, &N, &Zs[i], &pretoken->r) ||
        !ec_jacobian_to_affine(group, &N_affine, &N)) {
      goto err;
    }

    // Serialize the token. Include |key_id| to avoid an extra copy in the layer
    // above.
    CBB token_cbb;
    size_t point_len = 1 + 2 * BN_num_bytes(&group->field);
    if (!CBB_init(&token_cbb, 4 + TRUST_TOKEN_NONCE_SIZE + (2 + point_len)) ||
        !CBB_add_u32(&token_cbb, key_id) ||
        !CBB_add_bytes(&token_cbb, pretoken->salt, TRUST_TOKEN_NONCE_SIZE) ||
        !cbb_add_point(&token_cbb, group, &N_affine) ||
        !CBB_flush(&token_cbb)) {
      CBB_cleanup(&token_cbb);
      goto err;
    }

    TRUST_TOKEN *token =
        TRUST_TOKEN_new(CBB_data(&token_cbb), CBB_len(&token_cbb));
    CBB_cleanup(&token_cbb);
    if (token == NULL ||
        !sk_TRUST_TOKEN_push(ret, token)) {
      TRUST_TOKEN_free(token);
      goto err;
    }
  }

  EC_RAW_POINT M, Z;
  if (!ec_point_mul_scalar_public_batch(group, &M,
                                        /*g_scalar=*/NULL, BTs, dis,
                                        count) ||
      !ec_point_mul_scalar_public_batch(group, &Z,
                                        /*g_scalar=*/NULL, Zs, dis,
                                        count)) {
    goto err;
  }

  CBS proof;
  if (!CBS_get_u16_length_prefixed(cbs, &proof) ||
      !verify_proof(method, &proof, key, &M, &Z) ||
      CBS_len(&proof) != 0) {
    goto err;
  }

  ok = 1;

err:
  OPENSSL_free(BTs);
  OPENSSL_free(Zs);
  OPENSSL_free(dis);
  if (!ok) {
    sk_TRUST_TOKEN_pop_free(ret, TRUST_TOKEN_free);
    ret = NULL;
  }
  return ret;
}

static int voprf_read(const VOPRF_METHOD *method,
                      const TRUST_TOKEN_ISSUER_KEY *key,
                      uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE],
                      const uint8_t *token, size_t token_len,
                      int include_message, const uint8_t *msg, size_t msg_len) {
  const EC_GROUP *group = method->group;
  CBS cbs, salt;
  CBS_init(&cbs, token, token_len);
  EC_AFFINE Ws;
  if (!CBS_get_bytes(&cbs, &salt, TRUST_TOKEN_NONCE_SIZE) ||
      !cbs_get_point(&cbs, group, &Ws) ||
      CBS_len(&cbs) != 0) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN);
    return 0;
  }

  if (include_message) {
    SHA512_CTX hash_ctx;
    assert(SHA512_DIGEST_LENGTH == TRUST_TOKEN_NONCE_SIZE);
    SHA512_Init(&hash_ctx);
    SHA512_Update(&hash_ctx, CBS_data(&salt), CBS_len(&salt));
    SHA512_Update(&hash_ctx, msg, msg_len);
    SHA512_Final(out_nonce, &hash_ctx);
  } else {
    OPENSSL_memcpy(out_nonce, CBS_data(&salt), CBS_len(&salt));
  }


  EC_RAW_POINT T;
  if (!method->hash_to_group(group, &T, out_nonce)) {
    return 0;
  }

  EC_RAW_POINT Ws_calculated;
  if (!ec_point_mul_scalar(group, &Ws_calculated, &T, &key->xs) ||
      !ec_affine_jacobian_equal(group, &Ws, &Ws_calculated)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BAD_VALIDITY_CHECK);
    return 0;
  }

  return 1;
}


// VOPRF experiment v2.

static int voprf_exp2_hash_to_group(const EC_GROUP *group, EC_RAW_POINT *out,
                                    const uint8_t t[TRUST_TOKEN_NONCE_SIZE]) {
  const uint8_t kHashTLabel[] = "TrustToken VOPRF Experiment V2 HashToGroup";
  return ec_hash_to_curve_p384_xmd_sha512_sswu_draft07(
      group, out, kHashTLabel, sizeof(kHashTLabel), t, TRUST_TOKEN_NONCE_SIZE);
}

static int voprf_exp2_hash_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
                             uint8_t *buf, size_t len) {
  const uint8_t kHashCLabel[] = "TrustToken VOPRF Experiment V2 HashToScalar";
  return ec_hash_to_scalar_p384_xmd_sha512_draft07(
      group, out, kHashCLabel, sizeof(kHashCLabel), buf, len);
}

static int voprf_exp2_ok = 0;
static VOPRF_METHOD voprf_exp2_method;
static CRYPTO_once_t voprf_exp2_method_once = CRYPTO_ONCE_INIT;

static void voprf_exp2_init_method_impl(void) {
  voprf_exp2_ok =
      voprf_init_method(&voprf_exp2_method, NID_secp384r1,
                        voprf_exp2_hash_to_group, voprf_exp2_hash_to_scalar);
}

static int voprf_exp2_init_method(void) {
  CRYPTO_once(&voprf_exp2_method_once, voprf_exp2_init_method_impl);
  if (!voprf_exp2_ok) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR);
    return 0;
  }
  return 1;
}

int voprf_exp2_generate_key(CBB *out_private, CBB *out_public) {
  if (!voprf_exp2_init_method()) {
    return 0;
  }

  return voprf_generate_key(&voprf_exp2_method, out_private, out_public);
}

int voprf_exp2_derive_key_from_secret(CBB *out_private, CBB *out_public,
                                      const uint8_t *secret,
                                      size_t secret_len) {
  if (!voprf_exp2_init_method()) {
    return 0;
  }

  return voprf_derive_key_from_secret(&voprf_exp2_method, out_private,
                                      out_public, secret, secret_len);
}

int voprf_exp2_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key,
                                     const uint8_t *in, size_t len) {
  if (!voprf_exp2_init_method()) {
    return 0;
  }
  return voprf_client_key_from_bytes(&voprf_exp2_method, key, in, len);
}

int voprf_exp2_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key,
                                     const uint8_t *in, size_t len) {
  if (!voprf_exp2_init_method()) {
    return 0;
  }
  return voprf_issuer_key_from_bytes(&voprf_exp2_method, key, in, len);
}

STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_exp2_blind(CBB *cbb, size_t count,
                                                 int include_message,
                                                 const uint8_t *msg,
                                                 size_t msg_len) {
  if (!voprf_exp2_init_method()) {
    return NULL;
  }
  return voprf_blind(&voprf_exp2_method, cbb, count, include_message, msg,
                     msg_len);
}

int voprf_exp2_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs,
                    size_t num_requested, size_t num_to_issue,
                    uint8_t private_metadata) {
  if (!voprf_exp2_init_method() || private_metadata != 0) {
    return 0;
  }
  return voprf_sign_tt(&voprf_exp2_method, key, cbb, cbs, num_requested,
                       num_to_issue);
}

STACK_OF(TRUST_TOKEN) *voprf_exp2_unblind(
    const TRUST_TOKEN_CLIENT_KEY *key,
    const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count,
    uint32_t key_id) {
  if (!voprf_exp2_init_method()) {
    return NULL;
  }
  return voprf_unblind_tt(&voprf_exp2_method, key, pretokens, cbs, count,
                          key_id);
}

int voprf_exp2_read(const TRUST_TOKEN_ISSUER_KEY *key,
                    uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE],
                    uint8_t *out_private_metadata, const uint8_t *token,
                    size_t token_len, int include_message, const uint8_t *msg,
                    size_t msg_len) {
  if (!voprf_exp2_init_method()) {
    return 0;
  }
  return voprf_read(&voprf_exp2_method, key, out_nonce, token, token_len,
                    include_message, msg, msg_len);
}

// VOPRF PST v1.

static int voprf_pst1_hash_to_group(const EC_GROUP *group, EC_RAW_POINT *out,
                                    const uint8_t t[TRUST_TOKEN_NONCE_SIZE]) {
  const uint8_t kHashTLabel[] = "HashToGroup-OPRFV1-\x01-P384-SHA384";
  return ec_hash_to_curve_p384_xmd_sha384_sswu(group, out, kHashTLabel,
                                               sizeof(kHashTLabel) - 1, t,
                                               TRUST_TOKEN_NONCE_SIZE);
}

static int voprf_pst1_hash_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
                             uint8_t *buf, size_t len) {
  const uint8_t kHashCLabel[] = "HashToScalar-OPRFV1-\x01-P384-SHA384";
  return ec_hash_to_scalar_p384_xmd_sha384(group, out, kHashCLabel,
                                           sizeof(kHashCLabel) - 1, buf, len);
}

static int voprf_pst1_ok = 0;
static VOPRF_METHOD voprf_pst1_method;
static CRYPTO_once_t voprf_pst1_method_once = CRYPTO_ONCE_INIT;

static void voprf_pst1_init_method_impl(void) {
  voprf_pst1_ok =
      voprf_init_method(&voprf_pst1_method, NID_secp384r1,
                        voprf_pst1_hash_to_group, voprf_pst1_hash_to_scalar);
}

static int voprf_pst1_init_method(void) {
  CRYPTO_once(&voprf_pst1_method_once, voprf_pst1_init_method_impl);
  if (!voprf_pst1_ok) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR);
    return 0;
  }
  return 1;
}

int voprf_pst1_generate_key(CBB *out_private, CBB *out_public) {
  if (!voprf_pst1_init_method()) {
    return 0;
  }

  return voprf_generate_key(&voprf_pst1_method, out_private, out_public);
}

int voprf_pst1_derive_key_from_secret(CBB *out_private, CBB *out_public,
                                      const uint8_t *secret,
                                      size_t secret_len) {
  if (!voprf_pst1_init_method()) {
    return 0;
  }

  return voprf_derive_key_from_secret(&voprf_pst1_method, out_private,
                                      out_public, secret, secret_len);
}

int voprf_pst1_client_key_from_bytes(TRUST_TOKEN_CLIENT_KEY *key,
                                     const uint8_t *in, size_t len) {
  if (!voprf_pst1_init_method()) {
    return 0;
  }
  return voprf_client_key_from_bytes(&voprf_pst1_method, key, in, len);
}

int voprf_pst1_issuer_key_from_bytes(TRUST_TOKEN_ISSUER_KEY *key,
                                     const uint8_t *in, size_t len) {
  if (!voprf_pst1_init_method()) {
    return 0;
  }
  return voprf_issuer_key_from_bytes(&voprf_pst1_method, key, in, len);
}

STACK_OF(TRUST_TOKEN_PRETOKEN) *voprf_pst1_blind(CBB *cbb, size_t count,
                                                 int include_message,
                                                 const uint8_t *msg,
                                                 size_t msg_len) {
  if (!voprf_pst1_init_method()) {
    return NULL;
  }
  return voprf_blind(&voprf_pst1_method, cbb, count, include_message, msg,
                     msg_len);
}

int voprf_pst1_sign(const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs,
                    size_t num_requested, size_t num_to_issue,
                    uint8_t private_metadata) {
  if (!voprf_pst1_init_method() || private_metadata != 0) {
    return 0;
  }
  return voprf_sign(&voprf_pst1_method, key, cbb, cbs, num_requested,
                    num_to_issue);
}


int voprf_pst1_sign_with_proof_scalar_for_testing(
    const TRUST_TOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs, size_t num_requested,
    size_t num_to_issue, uint8_t private_metadata,
    const uint8_t *proof_scalar_buf, size_t proof_scalar_len) {
  if (!voprf_pst1_init_method() || private_metadata != 0) {
    return 0;
  }
  return voprf_sign_with_proof_scalar_for_testing(
      &voprf_pst1_method, key, cbb, cbs, num_requested, num_to_issue,
      proof_scalar_buf, proof_scalar_len);
}

STACK_OF(TRUST_TOKEN) *voprf_pst1_unblind(
    const TRUST_TOKEN_CLIENT_KEY *key,
    const STACK_OF(TRUST_TOKEN_PRETOKEN) *pretokens, CBS *cbs, size_t count,
    uint32_t key_id) {
  if (!voprf_pst1_init_method()) {
    return NULL;
  }
  return voprf_unblind(&voprf_pst1_method, key, pretokens, cbs, count, key_id);
}

int voprf_pst1_read(const TRUST_TOKEN_ISSUER_KEY *key,
                    uint8_t out_nonce[TRUST_TOKEN_NONCE_SIZE],
                    uint8_t *out_private_metadata, const uint8_t *token,
                    size_t token_len, int include_message, const uint8_t *msg,
                    size_t msg_len) {
  if (!voprf_pst1_init_method()) {
    return 0;
  }
  return voprf_read(&voprf_pst1_method, key, out_nonce, token, token_len,
                    include_message, msg, msg_len);
}
