/* 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/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 <openssl/trust_token.h>

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

#include "internal.h"


// get_h returns the generator H for PMBTokens.
//
// x: 66591746412783875033873351891229753622964683369847172829242944646280287810
//    81195403447871073952234683395256591180452378091073292247502091640572714366
//    588045092
// y: 12347430519393087872533727997980072129796839266949808299436682045034861065
//    18810630511924722292325611253427311923464047364545304196431830383014967865
//    162306253
//
// This point was generated with the following Python code.

/*
import hashlib

SEED_H = 'PrivacyPass H'

A = -3
B = 0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00
P = 2**521 - 1

def get_y(x):
  y2 = (x**3 + A*x + B) % P
  y = pow(y2, (P+1)/4, P)
  if (y*y) % P != y2:
    raise ValueError("point not on curve")
  return y

def bit(h,i):
  return (ord(h[i/8]) >> (i%8)) & 1

b = 521
def decode_point(so):
  s = hashlib.sha256(so + '0').digest() + hashlib.sha256(so + '1').digest() + \
      hashlib.sha256(so + '2').digest()

  x = 0
  for i in range(0,b):
    x = x + (long(bit(s,i))<<i)
  if x >= P:
    raise ValueError("x out of range")
  y = get_y(x)
  if y & 1 != bit(s,b-1): y = P-y
  return (x, y)


def gen_point(seed):
  v = hashlib.sha256(seed).digest()
  it = 1
  while True:
    try:
      x,y = decode_point(v)
    except Exception, e:
      print e
      it += 1
      v = hashlib.sha256(v).digest()
      continue
    print "Found in %d iterations:" % it
    print "  x = %d" % x
    print "  y = %d" % y
    print " Encoded (hex): (%x, %x)" % (x, y)
    return (x, y)

if __name__ == "__main__":
  gen_point(SEED_H)
*/

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

// TODO(svaldez): Update to use hash2curve to generate H.
static int get_h(EC_RAW_POINT *out_h) {
  EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp521r1);
  if (group == NULL) {
    return 0;
  }

  static const uint8_t kH[] = {
      0x04, 0x01, 0xf0, 0xa9, 0xf7, 0x9e, 0xbc, 0x12, 0x6c, 0xef, 0xd1, 0xab,
      0x29, 0x10, 0x03, 0x6f, 0x4e, 0xf5, 0xbd, 0xeb, 0x0f, 0x6b, 0xc0, 0x5c,
      0x0e, 0xce, 0xfe, 0x59, 0x45, 0xd1, 0x3e, 0x25, 0x33, 0x7e, 0x4c, 0xda,
      0x64, 0x53, 0x54, 0x4e, 0xf9, 0x76, 0x0d, 0x6d, 0xc5, 0x39, 0x2a, 0xd4,
      0xce, 0x84, 0x6e, 0x31, 0xc2, 0x86, 0x21, 0xf9, 0x5c, 0x98, 0xb9, 0x3d,
      0x01, 0x74, 0x9f, 0xc5, 0x1e, 0x47, 0x24, 0x00, 0x5c, 0x17, 0x62, 0x51,
      0x7d, 0x32, 0x5e, 0x29, 0xac, 0x52, 0x14, 0x75, 0x6f, 0x36, 0xd9, 0xc7,
      0xfa, 0xbb, 0xa9, 0x3b, 0x9d, 0x70, 0x49, 0x1e, 0xb4, 0x53, 0xbc, 0x55,
      0xea, 0xad, 0x8f, 0x26, 0x1d, 0xe0, 0xbc, 0xf3, 0x50, 0x5c, 0x7e, 0x66,
      0x41, 0xb5, 0x61, 0x70, 0x12, 0x72, 0xac, 0x6a, 0xb0, 0x6e, 0x78, 0x3d,
      0x17, 0x08, 0xe3, 0xdf, 0x3c, 0xff, 0xa6, 0xa0, 0xea, 0x96, 0x67, 0x92,
      0xcd,
  };

  return ec_point_from_uncompressed(group, out_h, kH, sizeof(kH));
}

static int mul_twice(const EC_GROUP *group, EC_RAW_POINT *out,
                     const EC_RAW_POINT *g, const EC_SCALAR *g_scalar,
                     const EC_RAW_POINT *p, const EC_SCALAR *p_scalar) {
  EC_RAW_POINT tmp1, tmp2;
  if (!ec_point_mul_scalar(group, &tmp1, g, g_scalar) ||
      !ec_point_mul_scalar(group, &tmp2, p, p_scalar)) {
    return 0;
  }

  group->meth->add(group, out, &tmp1, &tmp2);
  return 1;
}

static int mul_twice_base(const EC_GROUP *group, EC_RAW_POINT *out,
                          const EC_SCALAR *base_scalar, const EC_RAW_POINT *p,
                          const EC_SCALAR *p_scalar) {
  EC_RAW_POINT tmp1, tmp2;
  if (!ec_point_mul_scalar_base(group, &tmp1, base_scalar) ||
      !ec_point_mul_scalar(group, &tmp2, p, p_scalar)) {
    return 0;
  }

  group->meth->add(group, out, &tmp1, &tmp2);
  return 1;
}

// (v0;v1) = p_scalar*(G;p1) + q_scalar*(q0;q1) - r_scalar*(r0;r1)
static int mul_add_and_sub(const EC_GROUP *group, EC_RAW_POINT *out_v0,
                           EC_RAW_POINT *out_v1, const EC_RAW_POINT *p1,
                           const EC_SCALAR *p_scalar, const EC_RAW_POINT *q0,
                           const EC_RAW_POINT *q1, const EC_SCALAR *q_scalar,
                           const EC_RAW_POINT *r0, const EC_RAW_POINT *r1,
                           const EC_SCALAR *r_scalar) {
  EC_RAW_POINT tmp0, tmp1, v0, v1;
  if (!mul_twice_base(group, &v0, p_scalar, q0, q_scalar) ||
      !mul_twice(group, &v1, p1, p_scalar, q1, q_scalar) ||
      !ec_point_mul_scalar(group, &tmp0, r0, r_scalar) ||
      !ec_point_mul_scalar(group, &tmp1, r1, r_scalar)) {
    return 0;
  }
  ec_GFp_simple_invert(group, &tmp0);
  ec_GFp_simple_invert(group, &tmp1);
  group->meth->add(group, out_v0, &v0, &tmp0);
  group->meth->add(group, out_v1, &v1, &tmp1);
  return 1;
}

// generate_keypair generates a keypair for the PMBTokens construction.
// |out_x| and |out_y| are set to the secret half of the keypair, while
// |*out_pub| is set to the public half of the keypair. It returns one on
// success and zero on failure.
static int generate_keypair(EC_SCALAR *out_x, EC_SCALAR *out_y,
                            EC_RAW_POINT *out_pub, const EC_GROUP *group) {
  EC_RAW_POINT h;
  if (!get_h(&h) ||
      !ec_random_nonzero_scalar(group, out_x, kDefaultAdditionalData) ||
      !ec_random_nonzero_scalar(group, out_y, kDefaultAdditionalData) ||
      !mul_twice_base(group, out_pub, out_x, &h, out_y)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    return 0;
  }
  return 1;
}

static int point_to_cbb(CBB *out, const EC_GROUP *group,
                        const EC_RAW_POINT *point) {
  size_t len =
      ec_point_to_bytes(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0);
  if (len == 0) {
    return 0;
  }
  uint8_t *p;
  return CBB_add_space(out, &p, len) &&
         ec_point_to_bytes(group, point, POINT_CONVERSION_UNCOMPRESSED, p,
                           len) == len;
}

int TRUST_TOKEN_generate_key(uint8_t *out_priv_key, size_t *out_priv_key_len,
                             size_t max_priv_key_len, uint8_t *out_pub_key,
                             size_t *out_pub_key_len, size_t max_pub_key_len,
                             uint32_t id) {
  EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp521r1);
  if (group == NULL) {
    return 0;
  }

  EC_RAW_POINT pub0, pub1, pubs;
  EC_SCALAR x0, y0, x1, y1, xs, ys;
  if (!generate_keypair(&x0, &y0, &pub0, group) ||
      !generate_keypair(&x1, &y1, &pub1, group) ||
      !generate_keypair(&xs, &ys, &pubs, group)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_KEYGEN_FAILURE);
    return 0;
  }

  int ret = 0;
  CBB cbb;
  CBB_zero(&cbb);
  size_t scalar_len = BN_num_bytes(&group->order);
  if (!CBB_init_fixed(&cbb, out_priv_key, max_priv_key_len) ||
      !CBB_add_u32(&cbb, id)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
    goto err;
  }

  const EC_SCALAR *scalars[] = {&x0, &y0, &x1, &y1, &xs, &ys};
  for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(scalars); i++) {
    uint8_t *buf;
    if (!CBB_add_space(&cbb, &buf, scalar_len)) {
      OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
      goto err;
    }
    ec_scalar_to_bytes(group, buf, &scalar_len, scalars[i]);
  }

  if (!CBB_finish(&cbb, NULL, out_priv_key_len)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
    goto err;
  }

  CBB pub_cbb;
  if (!CBB_init_fixed(&cbb, out_pub_key, max_pub_key_len) ||
      !CBB_add_u32(&cbb, id) ||
      !CBB_add_u16_length_prefixed(&cbb, &pub_cbb) ||
      !point_to_cbb(&pub_cbb, group, &pub0) ||
      !CBB_add_u16_length_prefixed(&cbb, &pub_cbb) ||
      !point_to_cbb(&pub_cbb, group, &pub1) ||
      !CBB_add_u16_length_prefixed(&cbb, &pub_cbb) ||
      !point_to_cbb(&pub_cbb, group, &pubs) ||
      !CBB_finish(&cbb, NULL, out_pub_key_len)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL);
    goto err;
  }

  ret = 1;

err:
  CBB_cleanup(&cbb);
  return ret;
}

void PMBTOKEN_PRETOKEN_free(PMBTOKEN_PRETOKEN *pretoken) {
  OPENSSL_free(pretoken);
}

void PMBTOKEN_TOKEN_free(PMBTOKEN_TOKEN *token) {
  OPENSSL_free(token);
}

int pmbtoken_compute_public(struct trust_token_issuer_key_st *key) {
  EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp521r1);
  if (group == NULL) {
    return 0;
  }

  EC_RAW_POINT h;
  if (!get_h(&h) ||
      !mul_twice_base(group, &key->pubs, &key->xs, &h, &key->ys) ||
      !mul_twice_base(group, &key->pub0, &key->x0, &h, &key->y0) ||
      !mul_twice_base(group, &key->pub1, &key->x1, &h, &key->y1)) {
    return 0;
  }

  return 1;
}

// hash_t implements the H_t operation in PMBTokens. It returns on on success
// and zero on error.
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_draft06(
      group, out, kHashTLabel, sizeof(kHashTLabel), t, PMBTOKEN_NONCE_SIZE);
}

// hash_s implements the H_s operation in PMBTokens. It returns on on success
// and zero on error.
static int hash_s(EC_GROUP *group, EC_RAW_POINT *out, const EC_RAW_POINT *t,
                  const uint8_t s[PMBTOKEN_NONCE_SIZE]) {
  const uint8_t kHashSLabel[] = "PMBTokensV0 HashS";
  int ret = 0;
  CBB cbb;
  uint8_t *buf = NULL;
  size_t len;
  if (!CBB_init(&cbb, 0) ||
      !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_draft06(
          group, out, kHashSLabel, sizeof(kHashSLabel), buf, len)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  ret = 1;

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

PMBTOKEN_PRETOKEN *pmbtoken_blind(void) {
  EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp521r1);
  if (group == NULL) {
    return NULL;
  }

  PMBTOKEN_PRETOKEN *pretoken = OPENSSL_malloc(sizeof(PMBTOKEN_PRETOKEN));
  if (pretoken == NULL) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  RAND_bytes(pretoken->t, sizeof(pretoken->t));

  // We sample |pretoken->r| in Montgomery form to simplify inverting.
  if (!ec_random_nonzero_scalar(group, &pretoken->r,
                                kDefaultAdditionalData)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    goto err;
  }

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

  EC_RAW_POINT T;
  if (!hash_t(group, &T, pretoken->t) ||
      !ec_point_mul_scalar(group, &pretoken->Tp, &T, &rinv)) {
    goto err;
  }

  return pretoken;

err:
  OPENSSL_free(pretoken);
  return NULL;
}

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_draft06(
      group, out, kHashCLabel, sizeof(kHashCLabel), buf, len);
}

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)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    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 hash_c_dleq(const EC_GROUP *group, EC_SCALAR *out,
                       const EC_RAW_POINT *X, const EC_RAW_POINT *T,
                       const EC_RAW_POINT *S, const EC_RAW_POINT *W,
                       const EC_RAW_POINT *K0, const EC_RAW_POINT *K1) {
  static const uint8_t kDLEQ2Label[] = "DLEQ2";

  int ok = 0;
  CBB cbb;
  CBB_zero(&cbb);
  uint8_t *buf = NULL;
  size_t len;
  if (!CBB_init(&cbb, 0) ||
      !CBB_add_bytes(&cbb, kDLEQ2Label, sizeof(kDLEQ2Label)) ||
      !point_to_cbb(&cbb, group, X) ||
      !point_to_cbb(&cbb, group, T) ||
      !point_to_cbb(&cbb, group, S) ||
      !point_to_cbb(&cbb, group, W) ||
      !point_to_cbb(&cbb, group, K0) ||
      !point_to_cbb(&cbb, group, K1) ||
      !CBB_finish(&cbb, &buf, &len) ||
      !hash_c(group, out, buf, len)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  ok = 1;

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

static int hash_c_dleqor(const EC_GROUP *group, EC_SCALAR *out,
                         const EC_RAW_POINT *X0, const EC_RAW_POINT *X1,
                         const EC_RAW_POINT *T, const EC_RAW_POINT *S,
                         const EC_RAW_POINT *W, const EC_RAW_POINT *K00,
                         const EC_RAW_POINT *K01, const EC_RAW_POINT *K10,
                         const EC_RAW_POINT *K11) {
  static const uint8_t kDLEQOR2Label[] = "DLEQOR2";

  int ok = 0;
  CBB cbb;
  CBB_zero(&cbb);
  uint8_t *buf = NULL;
  size_t len;
  if (!CBB_init(&cbb, 0) ||
      !CBB_add_bytes(&cbb, kDLEQOR2Label, sizeof(kDLEQOR2Label)) ||
      !point_to_cbb(&cbb, group, X0) ||
      !point_to_cbb(&cbb, group, X1) ||
      !point_to_cbb(&cbb, group, T) ||
      !point_to_cbb(&cbb, group, S) ||
      !point_to_cbb(&cbb, group, W) ||
      !point_to_cbb(&cbb, group, K00) ||
      !point_to_cbb(&cbb, group, K01) ||
      !point_to_cbb(&cbb, group, K10) ||
      !point_to_cbb(&cbb, group, K11) ||
      !CBB_finish(&cbb, &buf, &len) ||
      !hash_c(group, out, buf, len)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  ok = 1;

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

// The DLEQ2 and DLEQOR2 constructions are described in appendix B of
// https://eprint.iacr.org/2020/072/20200324:214215. DLEQ2 is an instance of
// DLEQOR2 with only one value (n=1).

static int dleq_generate(const EC_GROUP *group, uint8_t **out_proof,
                         size_t *out_proof_len,
                         const struct trust_token_issuer_key_st *priv,
                         const EC_RAW_POINT *T, const EC_RAW_POINT *S,
                         const EC_RAW_POINT *W, const EC_RAW_POINT *Ws,
                         uint8_t private_metadata) {
  int ok = 0;
  CBB proof;
  if (!CBB_init(&proof, 0)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    return 0;
  }

  EC_RAW_POINT h;
  if (!get_h(&h)) {
    goto err;
  }

  // Generate DLEQ2 proof for the validity token.

  // ks0, ks1 <- Zp
  EC_SCALAR ks0, ks1;
  if (!ec_random_nonzero_scalar(group, &ks0, kDefaultAdditionalData) ||
      !ec_random_nonzero_scalar(group, &ks1, kDefaultAdditionalData)) {
    goto err;
  }

  // Ks = ks0*(G;T) + ks1*(H;S)
  EC_RAW_POINT Ks0, Ks1;
  if (!mul_twice_base(group, &Ks0, &ks0, &h, &ks1) ||
      !mul_twice(group, &Ks1, T, &ks0, S, &ks1)) {
    goto err;
  }

  // cs = Hc(...)
  EC_SCALAR cs;
  if (!hash_c_dleq(group, &cs, &priv->pubs, T, S, Ws, &Ks0, &Ks1)) {
    goto err;
  }

  EC_SCALAR cs_mont;
  ec_scalar_to_montgomery(group, &cs_mont, &cs);

  // In each of these products, only one operand is in Montgomery form, so the
  // product does not need to be converted.

  // us = ks0 + cs*xs
  EC_SCALAR us;
  ec_scalar_mul_montgomery(group, &us, &priv->xs, &cs_mont);
  ec_scalar_add(group, &us, &ks0, &us);

  // vs = ks1 + cs*ys
  EC_SCALAR vs;
  ec_scalar_mul_montgomery(group, &vs, &priv->ys, &cs_mont);
  ec_scalar_add(group, &vs, &ks1, &vs);

  // Store DLEQ2 proof in transcript.
  if (!scalar_to_cbb(&proof, group, &cs) ||
      !scalar_to_cbb(&proof, group, &us) ||
      !scalar_to_cbb(&proof, group, &vs)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  // Generate DLEQOR2 proof for the private metadata token.
  BN_ULONG mask = ((BN_ULONG)0) - (private_metadata&1);

  // Select values of xb, yb (keys corresponding to the private metadata value)
  // and pubo (public key corresponding to the other value) in constant time.
  EC_RAW_POINT pubo;
  EC_SCALAR xb, yb;
  ec_scalar_select(group, &xb, mask, &priv->x1, &priv->x0);
  ec_scalar_select(group, &yb, mask, &priv->y1, &priv->y0);
  ec_point_select(group, &pubo, mask, &priv->pub0, &priv->pub1);

  // k0, k1 <- Zp
  EC_SCALAR k0, k1;
  if (!ec_random_nonzero_scalar(group, &k0, kDefaultAdditionalData) ||
      !ec_random_nonzero_scalar(group, &k1, kDefaultAdditionalData)) {
    goto err;
  }

  // Kb = k0*(G;T) + k1*(H;S)
  EC_RAW_POINT Kb0, Kb1;
  if (!mul_twice_base(group, &Kb0, &k0, &h, &k1) ||
      !mul_twice(group, &Kb1, T, &k0, S, &k1)) {
    goto err;
  }

  // co, uo, vo <- Zp
  EC_SCALAR co, uo, vo;
  if (!ec_random_nonzero_scalar(group, &co, kDefaultAdditionalData) ||
      !ec_random_nonzero_scalar(group, &uo, kDefaultAdditionalData) ||
      !ec_random_nonzero_scalar(group, &vo, kDefaultAdditionalData)) {
    goto err;
  }

  // Ko = uo*(G;T) + vo*(H;S) - co*(pubo;W)
  EC_RAW_POINT Ko0, Ko1;
  if (!mul_add_and_sub(group, &Ko0, &Ko1, T, &uo, &h, S, &vo, &pubo, W, &co)) {
    goto err;
  }

  // Select the K corresponding to K0 and K1 in constant-time.
  EC_RAW_POINT K00, K01, K10, K11;
  ec_point_select(group, &K00, mask, &Ko0, &Kb0);
  ec_point_select(group, &K01, mask, &Ko1, &Kb1);
  ec_point_select(group, &K10, mask, &Kb0, &Ko0);
  ec_point_select(group, &K11, mask, &Kb1, &Ko1);

  // c = Hc(...)
  EC_SCALAR c;
  if (!hash_c_dleqor(group, &c, &priv->pub0, &priv->pub1, T, S, W, &K00, &K01,
                     &K10, &K11)) {
    goto err;
  }

  // cb = c - co
  EC_SCALAR cb, ub, vb;
  ec_scalar_sub(group, &cb, &c, &co);

  EC_SCALAR cb_mont;
  ec_scalar_to_montgomery(group, &cb_mont, &cb);

  // In each of these products, only one operand is in Montgomery form, so the
  // product does not need to be converted.

  // ub = k0 + cb*xb
  ec_scalar_mul_montgomery(group, &ub, &xb, &cb_mont);
  ec_scalar_add(group, &ub, &k0, &ub);

  // vb = k1 + cb*yb
  ec_scalar_mul_montgomery(group, &vb, &yb, &cb_mont);
  ec_scalar_add(group, &vb, &k1, &vb);

  // Select c, u, v in constant-time.
  EC_SCALAR c0, c1, u0, u1, v0, v1;
  ec_scalar_select(group, &c0, mask, &co, &cb);
  ec_scalar_select(group, &u0, mask, &uo, &ub);
  ec_scalar_select(group, &v0, mask, &vo, &vb);
  ec_scalar_select(group, &c1, mask, &cb, &co);
  ec_scalar_select(group, &u1, mask, &ub, &uo);
  ec_scalar_select(group, &v1, mask, &vb, &vo);

  // Store DLEQOR2 proof in transcript.
  if (!scalar_to_cbb(&proof, group, &c0) ||
      !scalar_to_cbb(&proof, group, &c1) ||
      !scalar_to_cbb(&proof, group, &u0) ||
      !scalar_to_cbb(&proof, group, &u1) ||
      !scalar_to_cbb(&proof, group, &v0) ||
      !scalar_to_cbb(&proof, group, &v1) ||
      !CBB_finish(&proof, out_proof, out_proof_len)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  ok = 1;

err:
  CBB_cleanup(&proof);
  return ok;
}

static int dleq_verify(const EC_GROUP *group, const uint8_t *proof,
                       size_t proof_len,
                       const struct trust_token_client_key_st *pub,
                       const EC_RAW_POINT *T, const EC_RAW_POINT *S,
                       const EC_RAW_POINT *W, const EC_RAW_POINT *Ws) {
  EC_RAW_POINT h;
  if (!get_h(&h)) {
    return 0;
  }

  // Verify the DLEQ2 proof over the validity token.

  CBS cbs;
  CBS_init(&cbs, proof, proof_len);
  EC_SCALAR cs, us, vs;
  if (!scalar_from_cbs(&cbs, group, &cs) ||
      !scalar_from_cbs(&cbs, group, &us) ||
      !scalar_from_cbs(&cbs, group, &vs)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
    return 0;
  }

  // Ks = us*(G;T) + vs*(H;S) - cs*(pubs;Ws)
  EC_RAW_POINT Ks0, Ks1;
  if (!mul_add_and_sub(group, &Ks0, &Ks1, T, &us, &h, S, &vs, &pub->pubs, Ws,
                       &cs)) {
    return 0;
  }

  // calculated = Hc(...)
  EC_SCALAR calculated;
  if (!hash_c_dleq(group, &calculated, &pub->pubs, T, S, Ws, &Ks0, &Ks1)) {
    return 0;
  }

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

  // Verify the DLEQOR2 proof over the private metadata token.

  EC_SCALAR c0, c1, u0, u1, v0, v1;
  if (!scalar_from_cbs(&cbs, group, &c0) ||
      !scalar_from_cbs(&cbs, group, &c1) ||
      !scalar_from_cbs(&cbs, group, &u0) ||
      !scalar_from_cbs(&cbs, group, &u1) ||
      !scalar_from_cbs(&cbs, group, &v0) ||
      !scalar_from_cbs(&cbs, group, &v1) ||
      CBS_len(&cbs) != 0) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
    return 0;
  }

  // K0 = u0*(G;T) + v0*(H;S) - c0*(pub0;W)
  EC_RAW_POINT K00, K01;
  if (!mul_add_and_sub(group, &K00, &K01, T, &u0, &h, S, &v0, &pub->pub0, W,
                       &c0)) {
    return 0;
  }

  // K1 = u1*(G;T) + v1*(H;S) - c1*(pub1;Ws)
  EC_RAW_POINT K10, K11;
  if (!mul_add_and_sub(group, &K10, &K11, T, &u1, &h, S, &v1, &pub->pub1, W,
                       &c1)) {
    return 0;
  }

  // calculated = Hc(...)
  if (!hash_c_dleqor(group, &calculated, &pub->pub0, &pub->pub1, T, S, W, &K00,
                     &K01, &K10, &K11)) {
    return 0;
  }

  // c = c0 + c1
  EC_SCALAR c;
  ec_scalar_add(group, &c, &c0, &c1);

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

  return 1;
}

int pmbtoken_sign(const TRUST_TOKEN_ISSUER *ctx,
                  uint8_t out_s[PMBTOKEN_NONCE_SIZE], EC_RAW_POINT *out_Wp,
                  EC_RAW_POINT *out_Wsp, uint8_t **out_proof,
                  size_t *out_proof_len, const EC_RAW_POINT *Tp,
                  uint32_t key_id, uint8_t private_metadata) {
  EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp521r1);
  if (group == NULL) {
    return 0;
  }

  if (ctx->num_keys == 0) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_NO_KEYS_CONFIGURED);
    return 0;
  }
  const struct trust_token_issuer_key_st *key = NULL;
  for (size_t i = 0; i < ctx->num_keys; i++) {
    if (ctx->keys[i].id == key_id) {
      key = &ctx->keys[i];
      break;
    }
  }

  if (key == NULL) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_KEY_ID);
    return 0;
  }

  EC_SCALAR xb, yb;
  BN_ULONG mask = ((BN_ULONG)0) - (private_metadata & 1);
  ec_scalar_select(group, &xb, mask, &key->x1, &key->x0);
  ec_scalar_select(group, &yb, mask, &key->y1, &key->y0);

  RAND_bytes(out_s, PMBTOKEN_NONCE_SIZE);

  EC_RAW_POINT Sp;
  if (!hash_s(group, &Sp, Tp, out_s)) {
    return 0;
  }

  if (!mul_twice(group, out_Wp, Tp, &xb, &Sp, &yb) ||
      !mul_twice(group, out_Wsp, Tp, &key->xs, &Sp, &key->ys)) {
    return 0;
  }

  return dleq_generate(group, out_proof, out_proof_len, key, Tp, &Sp, out_Wp,
                       out_Wsp, private_metadata);
}

int pmbtoken_unblind(PMBTOKEN_TOKEN *out_token,
                     const struct trust_token_client_key_st *key,
                     const uint8_t s[PMBTOKEN_NONCE_SIZE],
                     const EC_RAW_POINT *Wp, const EC_RAW_POINT *Wsp,
                     const uint8_t *proof, size_t proof_len,
                     const PMBTOKEN_PRETOKEN *pretoken) {
  EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp521r1);
  if (group == NULL) {
    return 0;
  }

  EC_RAW_POINT Sp;
  if (!hash_s(group, &Sp, &pretoken->Tp, s)) {
    return 0;
  }

  if (!dleq_verify(group, proof, proof_len, key, &pretoken->Tp, &Sp, Wp, Wsp)) {
    return 0;
  }

  OPENSSL_memcpy(out_token->t, pretoken->t, PMBTOKEN_NONCE_SIZE);
  if (!ec_point_mul_scalar(group, &out_token->S, &Sp, &pretoken->r) ||
      !ec_point_mul_scalar(group, &out_token->W, Wp, &pretoken->r) ||
      !ec_point_mul_scalar(group, &out_token->Ws, Wsp, &pretoken->r)) {
    return 0;
  }

  return 1;
}

int pmbtoken_read(const TRUST_TOKEN_ISSUER *ctx, uint8_t *out_private_metadata,
                  const PMBTOKEN_TOKEN *token, uint32_t key_id) {
  EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp521r1);
  if (group == NULL) {
    return 0;
  }

  if (ctx->num_keys == 0) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_NO_KEYS_CONFIGURED);
    return 0;
  }
  const struct trust_token_issuer_key_st *key = NULL;
  for (size_t i = 0; i < ctx->num_keys; i++) {
    if (ctx->keys[i].id == key_id) {
      key = &ctx->keys[i];
      break;
    }
  }

  if (key == NULL) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_KEY_ID);
    return 0;
  }

  EC_RAW_POINT T;
  if (!hash_t(group, &T, token->t)) {
    return 0;
  }

  EC_RAW_POINT calculated;
  // Check the validity of the token.
  if (!mul_twice(group, &calculated, &T, &key->xs, &token->S, &key->ys) ||
      !ec_GFp_simple_points_equal(group, &calculated, &token->Ws)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BAD_VALIDITY_CHECK);
    return 0;
  }

  EC_RAW_POINT W0, W1;
  if (!mul_twice(group, &W0, &T, &key->x0, &token->S, &key->y0) ||
      !mul_twice(group, &W1, &T, &key->x1, &token->S, &key->y1)) {
    return 0;
  }

  const int is_W0 = ec_GFp_simple_points_equal(group, &W0, &token->W);
  const int is_W1 = ec_GFp_simple_points_equal(group, &W1, &token->W);
  const int is_valid = is_W0 ^ is_W1;
  if (!is_valid) {
    // Invalid tokens will fail the validity check above.
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  *out_private_metadata = is_W1;
  return 1;
}
