Don't store a redundant copy of the order in EC_GROUP

BN_MONT_CTX already has the modulus, so just use it. This is one less
value to initialize statically.

Bug: 20
Change-Id: I78f73994ab595b795e99d67851bdff3b73fc3dd6
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/60926
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/ec_extra/ec_derive.c b/crypto/ec_extra/ec_derive.c
index 6904d7b..7e666d5 100644
--- a/crypto/ec_extra/ec_derive.c
+++ b/crypto/ec_extra/ec_derive.c
@@ -55,7 +55,8 @@
   }
 
   uint8_t derived[EC_KEY_DERIVE_EXTRA_BYTES + EC_MAX_BYTES];
-  size_t derived_len = BN_num_bytes(&group->order) + EC_KEY_DERIVE_EXTRA_BYTES;
+  size_t derived_len =
+      BN_num_bytes(EC_GROUP_get0_order(group)) + EC_KEY_DERIVE_EXTRA_BYTES;
   assert(derived_len <= sizeof(derived));
   if (!HKDF(derived, derived_len, EVP_sha256(), secret, secret_len,
             /*salt=*/NULL, /*salt_len=*/0, (const uint8_t *)info,
@@ -74,10 +75,10 @@
       // enough. 2^(num_bytes(order)) < 2^8 * order, so:
       //
       //    priv < 2^8 * order * 2^128 < order * order < order * R
-      !BN_from_montgomery(priv, priv, group->order_mont, ctx) ||
+      !BN_from_montgomery(priv, priv, group->order, ctx) ||
       // Multiply by R^2 and do another Montgomery reduction to compute
       // priv * R^-1 * R^2 * R^-1 = priv mod order.
-      !BN_to_montgomery(priv, priv, group->order_mont, ctx) ||
+      !BN_to_montgomery(priv, priv, group->order, ctx) ||
       !EC_POINT_mul(group, pub, priv, NULL, NULL, ctx) ||
       !EC_KEY_set_group(key, group) || !EC_KEY_set_public_key(key, pub) ||
       !EC_KEY_set_private_key(key, priv)) {
diff --git a/crypto/ec_extra/hash_to_curve.c b/crypto/ec_extra/hash_to_curve.c
index 3940336..433205c 100644
--- a/crypto/ec_extra/hash_to_curve.c
+++ b/crypto/ec_extra/hash_to_curve.c
@@ -197,15 +197,16 @@
 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, &group->order, k) ||
+  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 * group->order.width;
+  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;
diff --git a/crypto/evp/p_ec_asn1.c b/crypto/evp/p_ec_asn1.c
index 2659100..19ff2c0 100644
--- a/crypto/evp/p_ec_asn1.c
+++ b/crypto/evp/p_ec_asn1.c
@@ -215,7 +215,7 @@
     ERR_clear_error();
     return 0;
   }
-  return BN_num_bits(EC_GROUP_get0_order(group));
+  return EC_GROUP_order_bits(group);
 }
 
 static int ec_missing_parameters(const EVP_PKEY *pkey) {
diff --git a/crypto/fipsmodule/ec/ec.c b/crypto/fipsmodule/ec/ec.c
index ac14f2e..5337811 100644
--- a/crypto/fipsmodule/ec/ec.c
+++ b/crypto/fipsmodule/ec/ec.c
@@ -291,7 +291,6 @@
 
   ret->references = 1;
   ret->meth = meth;
-  BN_init(&ret->order);
 
   if (!meth->group_init(ret)) {
     OPENSSL_free(ret);
@@ -305,15 +304,9 @@
                                   const BIGNUM *order) {
   assert(group->generator == NULL);
 
-  if (!BN_copy(&group->order, order)) {
-    return 0;
-  }
-  // Store the order in minimal form, so it can be used with |BN_ULONG| arrays.
-  bn_set_minimal_width(&group->order);
-
-  BN_MONT_CTX_free(group->order_mont);
-  group->order_mont = BN_MONT_CTX_new_for_modulus(&group->order, NULL);
-  if (group->order_mont == NULL) {
+  BN_MONT_CTX_free(group->order);
+  group->order = BN_MONT_CTX_new_for_modulus(order, NULL);
+  if (group->order == NULL) {
     return 0;
   }
 
@@ -562,8 +555,7 @@
   }
 
   ec_point_free(group->generator, 0 /* don't free group */);
-  BN_free(&group->order);
-  BN_MONT_CTX_free(group->order_mont);
+  BN_MONT_CTX_free(group->order);
 
   OPENSSL_free(group);
 }
@@ -602,7 +594,7 @@
   return a->meth != b->meth ||
          a->generator == NULL ||
          b->generator == NULL ||
-         BN_cmp(&a->order, &b->order) != 0 ||
+         BN_cmp(&a->order->N, &b->order->N) != 0 ||
          BN_cmp(&a->field, &b->field) != 0 ||
          !ec_felem_equal(a, &a->a, &b->a) ||
          !ec_felem_equal(a, &a->b, &b->b) ||
@@ -614,8 +606,8 @@
 }
 
 const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) {
-  assert(!BN_is_zero(&group->order));
-  return &group->order;
+  assert(group->order != NULL);
+  return &group->order->N;
 }
 
 int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
@@ -626,7 +618,7 @@
 }
 
 int EC_GROUP_order_bits(const EC_GROUP *group) {
-  return BN_num_bits(&group->order);
+  return BN_num_bits(&group->order->N);
 }
 
 int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
@@ -931,11 +923,10 @@
   ERR_clear_error();
 
   // This is an unusual input, so we do not guarantee constant-time processing.
-  const BIGNUM *order = &group->order;
   BN_CTX_start(ctx);
   BIGNUM *tmp = BN_CTX_get(ctx);
   int ok = tmp != NULL &&
-           BN_nnmod(tmp, in, order, ctx) &&
+           BN_nnmod(tmp, in, EC_GROUP_get0_order(group), ctx) &&
            ec_bignum_to_scalar(group, out, tmp);
   BN_CTX_end(ctx);
   return ok;
@@ -1193,7 +1184,7 @@
   //
   // Additionally, one can manually check this property for built-in curves. It
   // is enforced for legacy custom curves in |EC_GROUP_set_generator|.
-  const BIGNUM *order = &group->order;
+  const BIGNUM *order = EC_GROUP_get0_order(group);
   BN_ULONG words[EC_MAX_WORDS + 1] = {0};
   bn_big_endian_to_words(words, order->width + 1, bytes, len);
   bn_reduce_once(out->words, words, /*carry=*/words[order->width], order->d,
diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c
index 84a29ab..d21d509 100644
--- a/crypto/fipsmodule/ec/ec_key.c
+++ b/crypto/fipsmodule/ec/ec_key.c
@@ -93,8 +93,8 @@
 
   OPENSSL_memset(wrapped, 0, sizeof(EC_WRAPPED_SCALAR));
   wrapped->bignum.d = wrapped->scalar.words;
-  wrapped->bignum.width = group->order.width;
-  wrapped->bignum.dmax = group->order.width;
+  wrapped->bignum.width = group->order->N.width;
+  wrapped->bignum.dmax = group->order->N.width;
   wrapped->bignum.flags = BN_FLG_STATIC_DATA;
   return wrapped;
 }
@@ -485,7 +485,7 @@
   }
 
   // Check that the group order is FIPS compliant (FIPS 186-4 B.4.2).
-  if (BN_num_bits(EC_GROUP_get0_order(key->group)) < 160) {
+  if (EC_GROUP_order_bits(key->group) < 160) {
     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER);
     return 0;
   }
diff --git a/crypto/fipsmodule/ec/ec_montgomery.c b/crypto/fipsmodule/ec/ec_montgomery.c
index 78e0507..9ba4ff8 100644
--- a/crypto/fipsmodule/ec/ec_montgomery.c
+++ b/crypto/fipsmodule/ec/ec_montgomery.c
@@ -457,7 +457,7 @@
                                         const EC_JACOBIAN *p,
                                         const EC_SCALAR *r) {
   if (!group->field_greater_than_order ||
-      group->field.width != group->order.width) {
+      group->field.width != group->order->N.width) {
     // Do not bother optimizing this case. p > order in all commonly-used
     // curves.
     return ec_GFp_simple_cmp_x_coordinate(group, p, r);
@@ -488,7 +488,7 @@
   if (bn_less_than_words(r->words, group->field_minus_order.words,
                          group->field.width)) {
     // We can ignore the carry because: r + group_order < p < 2^256.
-    bn_add_words(r_Z2.words, r->words, group->order.d, group->field.width);
+    bn_add_words(r_Z2.words, r->words, group->order->N.d, group->field.width);
     ec_GFp_mont_felem_mul(group, &r_Z2, &r_Z2, &Z2_mont);
     if (ec_felem_equal(group, &r_Z2, &X)) {
       return 1;
diff --git a/crypto/fipsmodule/ec/internal.h b/crypto/fipsmodule/ec/internal.h
index bb41815..02c8d7e 100644
--- a/crypto/fipsmodule/ec/internal.h
+++ b/crypto/fipsmodule/ec/internal.h
@@ -595,11 +595,10 @@
   // to avoid a reference cycle. Additionally, Z is guaranteed to be one, so X
   // and Y are suitable for use as an |EC_AFFINE|.
   EC_POINT *generator;
-  BIGNUM order;
 
   int curve_name;  // optional NID for named curve
 
-  BN_MONT_CTX *order_mont;  // data for ECDSA inverse
+  BN_MONT_CTX *order;
 
   // The following members are handled by the method functions,
   // even if they appear generic
diff --git a/crypto/fipsmodule/ec/p256-nistz.c b/crypto/fipsmodule/ec/p256-nistz.c
index 85343fd..49b825b 100644
--- a/crypto/fipsmodule/ec/p256-nistz.c
+++ b/crypto/fipsmodule/ec/p256-nistz.c
@@ -563,8 +563,8 @@
   }
 #endif
 
-  assert(group->order.width == P256_LIMBS);
-  if (!beeu_mod_inverse_vartime(out->words, in->words, group->order.d)) {
+  assert(group->order->N.width == P256_LIMBS);
+  if (!beeu_mod_inverse_vartime(out->words, in->words, group->order->N.d)) {
     return 0;
   }
 
@@ -580,7 +580,7 @@
     return 0;
   }
 
-  assert(group->order.width == P256_LIMBS);
+  assert(group->order->N.width == P256_LIMBS);
   assert(group->field.width == P256_LIMBS);
 
   // We wish to compare X/Z^2 with r. This is equivalent to comparing X with
@@ -602,7 +602,7 @@
   if (bn_less_than_words(r->words, group->field_minus_order.words,
                          P256_LIMBS)) {
     // We can ignore the carry because: r + group_order < p < 2^256.
-    bn_add_words(r_Z2, r->words, group->order.d, P256_LIMBS);
+    bn_add_words(r_Z2, r->words, group->order->N.d, P256_LIMBS);
     ecp_nistz256_mul_mont(r_Z2, r_Z2, Z2_mont);
     if (OPENSSL_memcmp(r_Z2, X, sizeof(r_Z2)) == 0) {
       return 1;
diff --git a/crypto/fipsmodule/ec/p256.c b/crypto/fipsmodule/ec/p256.c
index 76e865f..27a25f7 100644
--- a/crypto/fipsmodule/ec/p256.c
+++ b/crypto/fipsmodule/ec/p256.c
@@ -710,12 +710,12 @@
   // Therefore there is a small possibility, less than 1/2^128, that group_order
   // < p.x < P. in that case we need not only to compare against |r| but also to
   // compare against r+group_order.
-  assert(group->field.width == group->order.width);
+  assert(group->field.width == group->order->N.width);
   if (bn_less_than_words(r->words, group->field_minus_order.words,
                          group->field.width)) {
     // We can ignore the carry because: r + group_order < p < 2^256.
     EC_FELEM tmp;
-    bn_add_words(tmp.words, r->words, group->order.d, group->order.width);
+    bn_add_words(tmp.words, r->words, group->order->N.d, group->order->N.width);
     fiat_p256_from_generic(r_Z2, &tmp);
     fiat_p256_mul(r_Z2, r_Z2, Z2_mont);
     if (OPENSSL_memcmp(&r_Z2, &X, sizeof(r_Z2)) == 0) {
diff --git a/crypto/fipsmodule/ec/scalar.c b/crypto/fipsmodule/ec/scalar.c
index 036049e..5c6f664 100644
--- a/crypto/fipsmodule/ec/scalar.c
+++ b/crypto/fipsmodule/ec/scalar.c
@@ -23,8 +23,9 @@
 
 int ec_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
                         const BIGNUM *in) {
-  if (!bn_copy_words(out->words, group->order.width, in) ||
-      !bn_less_than_words(out->words, group->order.d, group->order.width)) {
+  if (!bn_copy_words(out->words, group->order->N.width, in) ||
+      !bn_less_than_words(out->words, group->order->N.d,
+                          group->order->N.width)) {
     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR);
     return 0;
   }
@@ -34,12 +35,12 @@
 int ec_scalar_equal_vartime(const EC_GROUP *group, const EC_SCALAR *a,
                             const EC_SCALAR *b) {
   return OPENSSL_memcmp(a->words, b->words,
-                        group->order.width * sizeof(BN_ULONG)) == 0;
+                        group->order->N.width * sizeof(BN_ULONG)) == 0;
 }
 
 int ec_scalar_is_zero(const EC_GROUP *group, const EC_SCALAR *a) {
   BN_ULONG mask = 0;
-  for (int i = 0; i < group->order.width; i++) {
+  for (int i = 0; i < group->order->N.width; i++) {
     mask |= a->words[i];
   }
   return mask == 0;
@@ -47,27 +48,28 @@
 
 int ec_random_nonzero_scalar(const EC_GROUP *group, EC_SCALAR *out,
                              const uint8_t additional_data[32]) {
-  return bn_rand_range_words(out->words, 1, group->order.d, group->order.width,
-                             additional_data);
+  return bn_rand_range_words(out->words, 1, group->order->N.d,
+                             group->order->N.width, additional_data);
 }
 
 void ec_scalar_to_bytes(const EC_GROUP *group, uint8_t *out, size_t *out_len,
                         const EC_SCALAR *in) {
-  size_t len = BN_num_bytes(&group->order);
-  bn_words_to_big_endian(out, len, in->words, group->order.width);
+  size_t len = BN_num_bytes(&group->order->N);
+  bn_words_to_big_endian(out, len, in->words, group->order->N.width);
   *out_len = len;
 }
 
 int ec_scalar_from_bytes(const EC_GROUP *group, EC_SCALAR *out,
                          const uint8_t *in, size_t len) {
-  if (len != BN_num_bytes(&group->order)) {
+  if (len != BN_num_bytes(&group->order->N)) {
     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR);
     return 0;
   }
 
-  bn_big_endian_to_words(out->words, group->order.width, in, len);
+  bn_big_endian_to_words(out->words, group->order->N.width, in, len);
 
-  if (!bn_less_than_words(out->words, group->order.d, group->order.width)) {
+  if (!bn_less_than_words(out->words, group->order->N.d,
+                          group->order->N.width)) {
     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR);
     return 0;
   }
@@ -78,15 +80,15 @@
 void ec_scalar_reduce(const EC_GROUP *group, EC_SCALAR *out,
                       const BN_ULONG *words, size_t num) {
   // Convert "from" Montgomery form so the value is reduced modulo the order.
-  bn_from_montgomery_small(out->words, group->order.width, words, num,
-                           group->order_mont);
+  bn_from_montgomery_small(out->words, group->order->N.width, words, num,
+                           group->order);
   // Convert "to" Montgomery form to remove the R^-1 factor added.
   ec_scalar_to_montgomery(group, out, out);
 }
 
 void ec_scalar_add(const EC_GROUP *group, EC_SCALAR *r, const EC_SCALAR *a,
                    const EC_SCALAR *b) {
-  const BIGNUM *order = &group->order;
+  const BIGNUM *order = &group->order->N;
   BN_ULONG tmp[EC_MAX_WORDS];
   bn_mod_add_words(r->words, a->words, b->words, order->d, tmp, order->width);
   OPENSSL_cleanse(tmp, sizeof(tmp));
@@ -94,7 +96,7 @@
 
 void ec_scalar_sub(const EC_GROUP *group, EC_SCALAR *r, const EC_SCALAR *a,
                    const EC_SCALAR *b) {
-  const BIGNUM *order = &group->order;
+  const BIGNUM *order = &group->order->N;
   BN_ULONG tmp[EC_MAX_WORDS];
   bn_mod_sub_words(r->words, a->words, b->words, order->d, tmp, order->width);
   OPENSSL_cleanse(tmp, sizeof(tmp));
@@ -108,35 +110,35 @@
 
 void ec_scalar_select(const EC_GROUP *group, EC_SCALAR *out, BN_ULONG mask,
                       const EC_SCALAR *a, const EC_SCALAR *b) {
-  const BIGNUM *order = &group->order;
+  const BIGNUM *order = &group->order->N;
   bn_select_words(out->words, mask, a->words, b->words, order->width);
 }
 
 void ec_scalar_to_montgomery(const EC_GROUP *group, EC_SCALAR *r,
                              const EC_SCALAR *a) {
-  const BIGNUM *order = &group->order;
-  bn_to_montgomery_small(r->words, a->words, order->width, group->order_mont);
+  const BIGNUM *order = &group->order->N;
+  bn_to_montgomery_small(r->words, a->words, order->width, group->order);
 }
 
 void ec_scalar_from_montgomery(const EC_GROUP *group, EC_SCALAR *r,
                                const EC_SCALAR *a) {
-  const BIGNUM *order = &group->order;
+  const BIGNUM *order = &group->order->N;
   bn_from_montgomery_small(r->words, order->width, a->words, order->width,
-                           group->order_mont);
+                           group->order);
 }
 
 void ec_scalar_mul_montgomery(const EC_GROUP *group, EC_SCALAR *r,
                               const EC_SCALAR *a, const EC_SCALAR *b) {
-  const BIGNUM *order = &group->order;
+  const BIGNUM *order = &group->order->N;
   bn_mod_mul_montgomery_small(r->words, a->words, b->words, order->width,
-                              group->order_mont);
+                              group->order);
 }
 
 void ec_simple_scalar_inv0_montgomery(const EC_GROUP *group, EC_SCALAR *r,
                                       const EC_SCALAR *a) {
-  const BIGNUM *order = &group->order;
+  const BIGNUM *order = &group->order->N;
   bn_mod_inverse0_prime_mont_small(r->words, a->words, order->width,
-                                   group->order_mont);
+                                   group->order);
 }
 
 int ec_simple_scalar_to_montgomery_inv_vartime(const EC_GROUP *group,
diff --git a/crypto/fipsmodule/ec/simple_mul.c b/crypto/fipsmodule/ec/simple_mul.c
index 9a72a66..62786e6 100644
--- a/crypto/fipsmodule/ec/simple_mul.c
+++ b/crypto/fipsmodule/ec/simple_mul.c
@@ -40,7 +40,7 @@
   }
 
   // Divide bits in |scalar| into windows.
-  unsigned bits = BN_num_bits(&group->order);
+  unsigned bits =  EC_GROUP_order_bits(group);
   int r_is_at_infinity = 1;
   for (unsigned i = bits - 1; i < bits; i--) {
     if (!r_is_at_infinity) {
@@ -48,7 +48,7 @@
     }
     if (i % 5 == 0) {
       // Compute the next window value.
-      const size_t width = group->order.width;
+      const size_t width = group->order->N.width;
       uint8_t window = bn_is_bit_set_words(scalar->words, width, i + 4) << 4;
       window |= bn_is_bit_set_words(scalar->words, width, i + 3) << 3;
       window |= bn_is_bit_set_words(scalar->words, width, i + 2) << 2;
@@ -99,7 +99,7 @@
                                          EC_JACOBIAN *out,
                                          const EC_JACOBIAN precomp[17],
                                          const EC_SCALAR *scalar, unsigned i) {
-  const size_t width = group->order.width;
+  const size_t width = group->order->N.width;
   uint8_t window = bn_is_bit_set_words(scalar->words, width, i + 4) << 5;
   window |= bn_is_bit_set_words(scalar->words, width, i + 3) << 4;
   window |= bn_is_bit_set_words(scalar->words, width, i + 2) << 3;
@@ -138,7 +138,7 @@
   }
 
   // Divide bits in |scalar| into windows.
-  unsigned bits = BN_num_bits(&group->order);
+  unsigned bits = EC_GROUP_order_bits(group);
   int r_is_at_infinity = 1;
   for (unsigned i = bits; i <= bits; i--) {
     if (!r_is_at_infinity) {
@@ -212,7 +212,7 @@
                                         EC_JACOBIAN *out,
                                         const EC_PRECOMP *precomp,
                                         const EC_SCALAR *scalar, unsigned i) {
-  const size_t width = group->order.width;
+  const size_t width = group->order->N.width;
   unsigned stride = ec_GFp_mont_comb_stride(group);
   // Select the bits corresponding to the comb shifted up by |i|.
   unsigned window = 0;
diff --git a/crypto/fipsmodule/ec/wnaf.c b/crypto/fipsmodule/ec/wnaf.c
index beb9295..c9935fc 100644
--- a/crypto/fipsmodule/ec/wnaf.c
+++ b/crypto/fipsmodule/ec/wnaf.c
@@ -138,8 +138,8 @@
     // we shift and add at most one copy of |bit|, this will continue to hold
     // afterwards.
     window_val >>= 1;
-    window_val +=
-        bit * bn_is_bit_set_words(scalar->words, group->order.width, j + w + 1);
+    window_val += bit * bn_is_bit_set_words(scalar->words,
+                                            group->order->N.width, j + w + 1);
     assert(window_val <= next_bit);
   }
 
@@ -183,7 +183,7 @@
                                  const EC_SCALAR *g_scalar,
                                  const EC_JACOBIAN *points,
                                  const EC_SCALAR *scalars, size_t num) {
-  size_t bits = BN_num_bits(&group->order);
+  size_t bits = EC_GROUP_order_bits(group);
   size_t wNAF_len = bits + 1;
 
   int ret = 0;
diff --git a/crypto/fipsmodule/ecdsa/ecdsa.c b/crypto/fipsmodule/ecdsa/ecdsa.c
index 1be147f..3bd018d 100644
--- a/crypto/fipsmodule/ecdsa/ecdsa.c
+++ b/crypto/fipsmodule/ecdsa/ecdsa.c
@@ -71,7 +71,7 @@
 // ECDSA.
 static void digest_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
                              const uint8_t *digest, size_t digest_len) {
-  const BIGNUM *order = &group->order;
+  const BIGNUM *order = EC_GROUP_get0_order(group);
   size_t num_bits = BN_num_bits(order);
   // Need to truncate digest if it is too long: first truncate whole bytes.
   size_t num_bytes = (num_bits + 7) / 8;
diff --git a/crypto/trust_token/pmbtoken.c b/crypto/trust_token/pmbtoken.c
index d49a2b8..93a0191 100644
--- a/crypto/trust_token/pmbtoken.c
+++ b/crypto/trust_token/pmbtoken.c
@@ -201,7 +201,7 @@
   }
 
   const EC_SCALAR *scalars[] = {x0, y0, x1, y1, xs, ys};
-  size_t scalar_len = BN_num_bytes(&group->order);
+  size_t scalar_len = BN_num_bytes(EC_GROUP_get0_order(group));
   for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(scalars); i++) {
     uint8_t *buf;
     if (!CBB_add_space(out_private, &buf, scalar_len)) {
@@ -290,7 +290,7 @@
   const EC_GROUP *group = method->group;
   CBS cbs, tmp;
   CBS_init(&cbs, in, len);
-  size_t scalar_len = BN_num_bytes(&group->order);
+  size_t scalar_len = BN_num_bytes(EC_GROUP_get0_order(group));
   EC_SCALAR *scalars[] = {&key->x0, &key->y0, &key->x1,
                           &key->y1, &key->xs, &key->ys};
   for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(scalars); i++) {
@@ -390,7 +390,7 @@
 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);
+  size_t scalar_len = BN_num_bytes(EC_GROUP_get0_order(group));
   if (!CBB_add_space(out, &buf, scalar_len)) {
     return 0;
   }
@@ -399,7 +399,7 @@
 }
 
 static int scalar_from_cbs(CBS *cbs, const EC_GROUP *group, EC_SCALAR *out) {
-  size_t scalar_len = BN_num_bytes(&group->order);
+  size_t scalar_len = BN_num_bytes(EC_GROUP_get0_order(group));
   CBS tmp;
   if (!CBS_get_bytes(cbs, &tmp, scalar_len)) {
     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
diff --git a/crypto/trust_token/voprf.c b/crypto/trust_token/voprf.c
index ea7c193..e62aca5 100644
--- a/crypto/trust_token/voprf.c
+++ b/crypto/trust_token/voprf.c
@@ -95,7 +95,7 @@
 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);
+  size_t scalar_len = BN_num_bytes(EC_GROUP_get0_order(group));
   if (!CBB_add_space(out, &buf, scalar_len)) {
     return 0;
   }
@@ -104,7 +104,7 @@
 }
 
 static int scalar_from_cbs(CBS *cbs, const EC_GROUP *group, EC_SCALAR *out) {
-  size_t scalar_len = BN_num_bytes(&group->order);
+  size_t scalar_len = BN_num_bytes(EC_GROUP_get0_order(group));
   CBS tmp;
   if (!CBS_get_bytes(cbs, &tmp, scalar_len)) {
     OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);