// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "libhwsec-foundation/crypto/elliptic_curve.h"

#include <optional>

#include "libhwsec-foundation/crypto/big_num_util.h"
#include "libhwsec-foundation/crypto/error_util.h"

#include <gtest/gtest.h>

#include <base/logging.h>

namespace hwsec_foundation {

namespace {

constexpr EllipticCurve::CurveType kCurve = EllipticCurve::CurveType::kPrime256;
constexpr int kScalarSizeInBytes = 32;
constexpr int kFieldElementSizeInBytes = 32;
// SPKI DER formatted (ecPublicKey, prime256v1) public point with valid point
// which is not on curve.
const char kSpkiDerPoint[] =
    "3059301306072A8648CE3D020106082A8648CE3D030107034200040102030405060708090A"
    "0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F"
    "303132333435363738393A3B3C3D3E3F40";

brillo::SecureBlob CreateBogusPointSpkiDer() {
  brillo::SecureBlob spki_der;
  if (!brillo::SecureBlob::HexStringToSecureBlob(kSpkiDerPoint, &spki_der)) {
    ADD_FAILURE() << "Failed to convert hex to SecureBlob";
    return brillo::SecureBlob();
  }

  return spki_der;
}

// Returns a EC_KEY object with public key set to provided `point`. Unlike
// `EllipticCurve::PointToEccKey`, doesn't check if the key is valid.
crypto::ScopedEC_KEY PointToEccKey(const EC_POINT& point,
                                   const EC_GROUP* group) {
  crypto::ScopedEC_Key key(EC_KEY_new());
  if (!key) {
    ADD_FAILURE() << "Failed to allocate EC_KEY structure: "
                  << GetOpenSSLErrors();
    return nullptr;
  }

  if (EC_KEY_set_group(key.get(), group) != 1) {
    ADD_FAILURE() << "Failed to set EC group: " << GetOpenSSLErrors();
    return nullptr;
  }

  if (!EC_KEY_set_public_key(key.get(), &point)) {
    ADD_FAILURE() << "Failed to set public key: " << GetOpenSSLErrors();
    return nullptr;
  }

  return key;
}

}  // namespace

class EllipticCurveTest : public testing::Test {
 public:
  void SetUp() override {
    context_ = CreateBigNumContext();
    ASSERT_TRUE(context_);
    ec_ = EllipticCurve::Create(kCurve, context_.get());
    ASSERT_TRUE(ec_);
  }

  // Creates point as generator multiplied by scalar_value.
  // Returns nullptr if error occurred.
  crypto::ScopedEC_POINT CreatePoint(BN_ULONG scalar_value) {
    crypto::ScopedBIGNUM scalar = BigNumFromValue(scalar_value);
    if (!scalar) {
      LOG(ERROR) << "Failed to create BIGNUM structure";
      return nullptr;
    }
    return ec_->MultiplyWithGenerator(*scalar, context_.get());
  }

  // Creates invalid point that is not on a curve.
  // Returns nullptr if error occurred.
  crypto::ScopedEC_POINT CreateInvalidPoint() {
    crypto::ScopedEC_POINT point = ec_->PointAtInfinityForTesting();
    if (!point) {
      LOG(ERROR) << "Failed to create point at infinity";
      return nullptr;
    }

    // Set point to some coordinates that are not on a curve.
    crypto::ScopedBIGNUM x = BigNumFromValue(123u);
    if (!x) {
      LOG(ERROR) << "Failed to create BIGNUM structure";
      return nullptr;
    }
    crypto::ScopedBIGNUM y = BigNumFromValue(321u);
    if (!y) {
      LOG(ERROR) << "Failed to create BIGNUM structure";
      return nullptr;
    }

    // Set affine coordinates outside of the curve. Assume the method will fail,
    // but it should still initialize the point.
    if (EC_POINT_set_affine_coordinates(ec_->GetGroup(), point.get(), x.get(),
                                        y.get(), context_.get()) == 1) {
      LOG(ERROR) << "Failed to set affine coords for invalid point";
      return nullptr;
    }

    // Capture OpenSSL error from error stack.
    std::string error = GetOpenSSLErrors();
    if (error.find("EC_POINT_set_affine_coordinates:point is not on curve") ==
        std::string::npos) {
      LOG(ERROR) << "Failed to create invalid point";
      return nullptr;
    }

    // Verify that the point is not at infinity anymore, so it was indeed set,
    // but it's not on a curve.
    if (ec_->IsPointAtInfinity(*point) ||
        ec_->IsPointValid(*point, context_.get())) {
      LOG(ERROR) << "Failed to create invalid point";
      return nullptr;
    }
    return point;
  }

 protected:
  ScopedBN_CTX context_;
  std::optional<EllipticCurve> ec_;
};

TEST_F(EllipticCurveTest, GetCurveType) {
  std::optional<EllipticCurve> ec_256 = EllipticCurve::Create(
      EllipticCurve::CurveType::kPrime256, context_.get());
  ASSERT_TRUE(ec_256);
  EXPECT_EQ(ec_256->GetCurveType(), EllipticCurve::CurveType::kPrime256);

  std::optional<EllipticCurve> ec_384 = EllipticCurve::Create(
      EllipticCurve::CurveType::kPrime384, context_.get());
  ASSERT_TRUE(ec_384);
  EXPECT_EQ(ec_384->GetCurveType(), EllipticCurve::CurveType::kPrime384);

  std::optional<EllipticCurve> ec_521 = EllipticCurve::Create(
      EllipticCurve::CurveType::kPrime521, context_.get());
  ASSERT_TRUE(ec_521);
  EXPECT_EQ(ec_521->GetCurveType(), EllipticCurve::CurveType::kPrime521);
}

TEST_F(EllipticCurveTest, ScalarAndAffineCoordinateSizeInBytes) {
  EXPECT_EQ(ec_->ScalarSizeInBytes(), kScalarSizeInBytes);
  EXPECT_EQ(ec_->AffineCoordinateSizeInBytes(), kFieldElementSizeInBytes);
}

TEST_F(EllipticCurveTest, PointAtInfinity) {
  crypto::ScopedEC_POINT point = ec_->PointAtInfinityForTesting();
  ASSERT_TRUE(point);
  EXPECT_TRUE(ec_->IsPointValid(*point, context_.get()));
  EXPECT_TRUE(ec_->IsPointAtInfinity(*point));
}

TEST_F(EllipticCurveTest, RandomNonZeroScalar) {
  // Generates random secret. Note that this is non-deterministic,
  // so we just check if the output is smaller than curve order
  // and non-zero.
  crypto::ScopedBIGNUM secret = ec_->RandomNonZeroScalar(context_.get());
  ASSERT_TRUE(secret);
  EXPECT_EQ(BN_cmp(secret.get(), ec_->GetOrderForTesting()), -1);
  EXPECT_EQ(BN_is_zero(secret.get()), 0);
}

TEST_F(EllipticCurveTest, SubjectPublicKeyInfoConversions) {
  crypto::ScopedEC_KEY key = ec_->GenerateKey(context_.get());
  ASSERT_TRUE(key);
  // Encode the public key:
  brillo::SecureBlob spki_der_point_blob;
  ASSERT_TRUE(ec_->EncodeToSpkiDer(key, &spki_der_point_blob, context_.get()));
  // Decode the public key:
  crypto::ScopedEC_POINT spki_der_decoded_key =
      ec_->DecodeFromSpkiDer(spki_der_point_blob, context_.get());
  // Compare the keys:
  EXPECT_TRUE(ec_->AreEqual(*EC_KEY_get0_public_key(key.get()),
                            *spki_der_decoded_key, context_.get()));

  // Test conversions of invalid or infinite points.
  brillo::SecureBlob point_blob;
  crypto::ScopedEC_POINT invalid_point = CreateInvalidPoint();
  ASSERT_TRUE(invalid_point);
  crypto::ScopedEC_KEY invalid_point_key =
      PointToEccKey(*invalid_point, ec_->GetGroup());
  ASSERT_TRUE(invalid_point_key);
  EXPECT_FALSE(
      ec_->EncodeToSpkiDer(invalid_point_key, &point_blob, context_.get()));

  crypto::ScopedEC_POINT point_at_inf = ec_->PointAtInfinityForTesting();
  ASSERT_TRUE(point_at_inf);
  crypto::ScopedEC_KEY point_at_inf_key =
      PointToEccKey(*point_at_inf, ec_->GetGroup());
  ASSERT_TRUE(point_at_inf_key);
  EXPECT_FALSE(
      ec_->EncodeToSpkiDer(point_at_inf_key, &point_blob, context_.get()));

  crypto::ScopedEC_POINT decoded_key =
      ec_->DecodeFromSpkiDer(brillo::SecureBlob("not_a_point"), context_.get());
  EXPECT_FALSE(decoded_key);
  decoded_key =
      ec_->DecodeFromSpkiDer(CreateBogusPointSpkiDer(), context_.get());
  EXPECT_FALSE(decoded_key);
}

TEST_F(EllipticCurveTest, PointToEccKey) {
  crypto::ScopedEC_KEY key = ec_->GenerateKey(context_.get());
  ASSERT_TRUE(key);
  const EC_POINT* public_key = EC_KEY_get0_public_key(key.get());
  ASSERT_TRUE(public_key);

  crypto::ScopedEC_KEY key_1 = ec_->PointToEccKey(*public_key);
  ASSERT_TRUE(key_1);
  const EC_POINT* public_key_1 = EC_KEY_get0_public_key(key_1.get());
  ASSERT_TRUE(public_key_1);

  EXPECT_TRUE(ec_->AreEqual(*public_key, *public_key_1, context_.get()));

  // Test conversions of invalid or infinite points.
  brillo::SecureBlob point_blob;
  crypto::ScopedEC_POINT invalid_point = CreateInvalidPoint();
  ASSERT_TRUE(invalid_point);
  crypto::ScopedEC_KEY invalid_point_key = ec_->PointToEccKey(*invalid_point);
  EXPECT_FALSE(invalid_point_key);

  crypto::ScopedEC_POINT point_at_inf = ec_->PointAtInfinityForTesting();
  ASSERT_TRUE(point_at_inf);
  crypto::ScopedEC_KEY point_at_inf_key = ec_->PointToEccKey(*point_at_inf);
  EXPECT_FALSE(point_at_inf_key);
}

TEST_F(EllipticCurveTest, PointToEccKeySubjectPublicKeyInfoConversions) {
  crypto::ScopedEC_KEY key = ec_->GenerateKey(context_.get());
  ASSERT_TRUE(key);
  const EC_POINT* public_key = EC_KEY_get0_public_key(key.get());
  ASSERT_TRUE(public_key);
  crypto::ScopedEC_KEY key_1 = ec_->PointToEccKey(*public_key);
  ASSERT_TRUE(key_1);

  brillo::SecureBlob spki_der_public_key, spki_der_public_key_1;
  ASSERT_TRUE(ec_->EncodeToSpkiDer(key, &spki_der_public_key, context_.get()));
  ASSERT_TRUE(
      ec_->EncodeToSpkiDer(key_1, &spki_der_public_key_1, context_.get()));
  EXPECT_EQ(spki_der_public_key, spki_der_public_key_1);
}

TEST_F(EllipticCurveTest, Add) {
  crypto::ScopedEC_POINT point1 = CreatePoint(1u);
  ASSERT_TRUE(point1);
  crypto::ScopedEC_POINT point2 = CreatePoint(2u);
  ASSERT_TRUE(point2);
  crypto::ScopedEC_POINT point3 = CreatePoint(3u);
  ASSERT_TRUE(point3);

  crypto::ScopedEC_POINT result = ec_->Add(*point1, *point2, context_.get());
  ASSERT_TRUE(result);
  EXPECT_TRUE(ec_->AreEqual(*result, *point3, context_.get()));

  // Double the point.
  result = ec_->Add(*point1, *point1, context_.get());
  ASSERT_TRUE(result);
  EXPECT_TRUE(ec_->AreEqual(*result, *point2, context_.get()));

  // Add point to its inverse.
  crypto::ScopedEC_POINT inv_point3 = CreatePoint(3u);
  ASSERT_EQ(EC_POINT_invert(ec_->GetGroup(), inv_point3.get(), context_.get()),
            1);
  result = ec_->Add(*point3, *inv_point3, context_.get());
  ASSERT_TRUE(result);
  EXPECT_TRUE(ec_->IsPointAtInfinity(*result));

  // Check if inverse of nG is (order-n)*G.
  crypto::ScopedBIGNUM order_sub_3 = BigNumFromValue(3u);
  ASSERT_TRUE(order_sub_3);
  ASSERT_EQ(
      BN_sub(order_sub_3.get(), ec_->GetOrderForTesting(), order_sub_3.get()),
      1);
  result = ec_->MultiplyWithGenerator(*order_sub_3, context_.get());
  EXPECT_TRUE(ec_->AreEqual(*inv_point3, *result, context_.get()));

  // Double point at infinity.
  crypto::ScopedEC_POINT point_at_inf = ec_->PointAtInfinityForTesting();
  result = ec_->Add(*point_at_inf, *point_at_inf, context_.get());
  ASSERT_TRUE(result);
  EXPECT_TRUE(ec_->IsPointAtInfinity(*point_at_inf));
}

TEST_F(EllipticCurveTest, MultiplicationWithGenerator) {
  crypto::ScopedBIGNUM scalar1 = BigNumFromValue(123u);
  ASSERT_TRUE(scalar1);
  crypto::ScopedBIGNUM scalar2 = BigNumFromValue(321u);
  ASSERT_TRUE(scalar2);
  crypto::ScopedBIGNUM scalar_prod = CreateBigNum();
  ASSERT_TRUE(scalar_prod);
  ASSERT_EQ(
      BN_mul(scalar_prod.get(), scalar1.get(), scalar2.get(), context_.get()),
      1);
  EXPECT_EQ(BN_get_word(scalar_prod.get()), 123u * 321u);

  // Test if (G*scalar1)*scalar2 = G*(scalar1*scalar2).
  crypto::ScopedEC_POINT point1 =
      ec_->MultiplyWithGenerator(*scalar1, context_.get());
  EXPECT_TRUE(ec_->IsPointValidAndFinite(*point1, context_.get()));
  crypto::ScopedEC_POINT point2 =
      ec_->Multiply(*point1, *scalar2, context_.get());
  EXPECT_TRUE(ec_->IsPointValidAndFinite(*point2, context_.get()));
  crypto::ScopedEC_POINT point_prod =
      ec_->MultiplyWithGenerator(*scalar_prod, context_.get());
  EXPECT_TRUE(ec_->IsPointValidAndFinite(*point_prod, context_.get()));
  EXPECT_TRUE(ec_->AreEqual(*point2, *point_prod, context_.get()));
}

TEST_F(EllipticCurveTest, MultiplyWithGeneratorByBigScalars) {
  // Get big scalars of curve order.
  crypto::ScopedBIGNUM scalar1 = BigNumFromValue(123u);
  ASSERT_TRUE(scalar1);
  ASSERT_EQ(BN_sub(scalar1.get(), ec_->GetOrderForTesting(), scalar1.get()), 1);
  crypto::ScopedBIGNUM scalar2 = BigNumFromValue(321u);
  ASSERT_TRUE(scalar2);
  ASSERT_EQ(BN_sub(scalar2.get(), ec_->GetOrderForTesting(), scalar2.get()), 1);

  crypto::ScopedBIGNUM scalar_sum = CreateBigNum();
  ASSERT_TRUE(scalar_sum);
  ASSERT_EQ(BN_add(scalar_sum.get(), scalar1.get(), scalar2.get()), 1);
  // Expect scalar_sum > order.
  EXPECT_EQ(BN_cmp(scalar_sum.get(), ec_->GetOrderForTesting()), 1);
  // Multiplication by scalar greater than order should fail.
  EXPECT_FALSE(ec_->MultiplyWithGenerator(*scalar_sum, context_.get()));

  crypto::ScopedBIGNUM scalar_mod_sum =
      ec_->ModAdd(*scalar1, *scalar2, context_.get());
  ASSERT_TRUE(scalar_mod_sum);
  // Expect scalar_mod_sum < order.
  EXPECT_EQ(BN_cmp(scalar_mod_sum.get(), ec_->GetOrderForTesting()), -1);

  // Test if G*scalar1 + G*scalar2 = G*((scalar1 + scalar2) mod order).
  crypto::ScopedEC_POINT point1 =
      ec_->MultiplyWithGenerator(*scalar1, context_.get());
  ASSERT_TRUE(point1);
  EXPECT_TRUE(ec_->IsPointValidAndFinite(*point1, context_.get()));
  crypto::ScopedEC_POINT point2 =
      ec_->MultiplyWithGenerator(*scalar2, context_.get());
  ASSERT_TRUE(point2);
  EXPECT_TRUE(ec_->IsPointValidAndFinite(*point2, context_.get()));
  crypto::ScopedEC_POINT point_sum1 =
      ec_->MultiplyWithGenerator(*scalar_mod_sum, context_.get());
  ASSERT_TRUE(point_sum1);
  EXPECT_TRUE(ec_->IsPointValidAndFinite(*point_sum1, context_.get()));
  crypto::ScopedEC_POINT point_sum2 =
      ec_->Add(*point1, *point2, context_.get());
  ASSERT_TRUE(point_sum2);
  EXPECT_TRUE(ec_->IsPointValidAndFinite(*point_sum2, context_.get()));
  EXPECT_TRUE(ec_->AreEqual(*point_sum1, *point_sum2, context_.get()));
}

TEST_F(EllipticCurveTest, MultiplyWithGeneratorByZero) {
  crypto::ScopedBIGNUM scalar = BigNumFromValue(0);
  crypto::ScopedEC_POINT point =
      ec_->MultiplyWithGenerator(*scalar, context_.get());
  EXPECT_TRUE(ec_->IsPointValid(*point, context_.get()));
  EXPECT_TRUE(ec_->IsPointAtInfinity(*point));
}

TEST_F(EllipticCurveTest, MultiplyWithPointAtInfinity) {
  crypto::ScopedBIGNUM scalar = BigNumFromValue(123u);
  ASSERT_TRUE(scalar);
  crypto::ScopedEC_POINT point = ec_->PointAtInfinityForTesting();
  ASSERT_TRUE(point);

  crypto::ScopedEC_POINT result =
      ec_->Multiply(*point, *scalar, context_.get());
  ASSERT_TRUE(result);
  EXPECT_TRUE(ec_->IsPointAtInfinity(*result));

  // Try 0 x point at infinity. The result should be also point at infinity.
  scalar = BigNumFromValue(0u);
  ASSERT_TRUE(scalar);
  result = ec_->Multiply(*point, *scalar, context_.get());
  ASSERT_TRUE(result);
  EXPECT_TRUE(ec_->IsPointAtInfinity(*result));
}

TEST_F(EllipticCurveTest, MultiplyWithInvalidPoint) {
  crypto::ScopedBIGNUM scalar = BigNumFromValue(1u);
  ASSERT_TRUE(scalar);
  crypto::ScopedEC_POINT point = CreateInvalidPoint();
  ASSERT_TRUE(point);

  // Verify that multiplication does not accept bogus point as the input.
  crypto::ScopedEC_POINT result =
      ec_->Multiply(*point, *scalar, context_.get());
  EXPECT_FALSE(result);
}

TEST_F(EllipticCurveTest, MultiplyWithGeneratorByNegative) {
  crypto::ScopedBIGNUM scalar1 = BigNumFromValue(123u);
  ASSERT_TRUE(scalar1);
  crypto::ScopedBIGNUM scalar2 = BigNumFromValue(321u);
  ASSERT_TRUE(scalar2);

  crypto::ScopedEC_POINT point1 =
      ec_->MultiplyWithGenerator(*scalar1, context_.get());
  crypto::ScopedEC_POINT point2 =
      ec_->MultiplyWithGenerator(*scalar2, context_.get());
  BN_set_negative(scalar1.get(), 1);
  crypto::ScopedEC_POINT inverse_point1 =
      ec_->MultiplyWithGenerator(*scalar1, context_.get());

  crypto::ScopedEC_POINT point_sum_12 =
      ec_->Add(*point1, *point2, context_.get());
  crypto::ScopedEC_POINT point_sum_all =
      ec_->Add(*point_sum_12, *inverse_point1, context_.get());
  // Validates that after adding the inversion of point1 its contribution
  // cancels out and we are left with point2.
  ASSERT_TRUE(ec_->AreEqual(*point2, *point_sum_all, context_.get()));
}

TEST_F(EllipticCurveTest, GenerateKey) {
  crypto::ScopedEC_KEY key = ec_->GenerateKey(context_.get());
  ASSERT_TRUE(key);
  const BIGNUM* private_key = EC_KEY_get0_private_key(key.get());
  ASSERT_TRUE(private_key);
  const EC_POINT* public_key = EC_KEY_get0_public_key(key.get());
  ASSERT_TRUE(public_key);

  // Validate that private_key * G = public_key.
  crypto::ScopedEC_POINT expected_public_key =
      ec_->MultiplyWithGenerator(*private_key, context_.get());
  EXPECT_TRUE(ec_->AreEqual(*expected_public_key, *public_key, context_.get()));
}

TEST_F(EllipticCurveTest, GenerateKeysAsSecureBlobs) {
  brillo::SecureBlob public_blob;
  brillo::SecureBlob private_blob;
  ASSERT_TRUE(ec_->GenerateKeysAsSecureBlobs(&public_blob, &private_blob,
                                             context_.get()));
  crypto::ScopedEC_POINT public_key =
      ec_->DecodeFromSpkiDer(public_blob, context_.get());
  ASSERT_TRUE(public_key);
  crypto::ScopedBIGNUM private_key = SecureBlobToBigNum(private_blob);
  ASSERT_TRUE(private_key);

  // Validate that private_key * G = public_key.
  crypto::ScopedEC_POINT expected_public_key =
      ec_->MultiplyWithGenerator(*private_key, context_.get());
  EXPECT_TRUE(ec_->AreEqual(*expected_public_key, *public_key, context_.get()));
}

TEST_F(EllipticCurveTest, InvertPoint) {
  crypto::ScopedBIGNUM scalar = BigNumFromValue(123u);
  ASSERT_TRUE(scalar);
  crypto::ScopedEC_POINT point =
      ec_->MultiplyWithGenerator(*scalar, context_.get());

  BN_set_negative(scalar.get(), 1);
  crypto::ScopedEC_POINT inverse_point =
      ec_->MultiplyWithGenerator(*scalar, context_.get());

  EXPECT_TRUE(ec_->InvertPoint(point.get(), context_.get()));

  // Validates that the inverted point equals to inverse_point.
  EXPECT_TRUE(ec_->AreEqual(*inverse_point, *point, context_.get()));
}

TEST_F(EllipticCurveTest, InversePointAddition) {
  crypto::ScopedBIGNUM scalar1 = BigNumFromValue(123u);
  ASSERT_TRUE(scalar1);
  crypto::ScopedBIGNUM scalar2 = BigNumFromValue(321u);
  ASSERT_TRUE(scalar2);

  crypto::ScopedEC_POINT point1 =
      ec_->MultiplyWithGenerator(*scalar1, context_.get());
  ASSERT_TRUE(point1);
  crypto::ScopedEC_POINT point2 =
      ec_->MultiplyWithGenerator(*scalar2, context_.get());
  ASSERT_TRUE(point2);
  crypto::ScopedEC_POINT point_sum_12 =
      ec_->Add(*point1, *point2, context_.get());
  ASSERT_TRUE(point_sum_12);

  ec_->InvertPoint(point1.get(), context_.get());
  crypto::ScopedEC_POINT point_sum_all =
      ec_->Add(*point_sum_12, *point1, context_.get());
  ASSERT_TRUE(point_sum_all);
  // Validates that after adding the inverted point1 its contribution
  // cancels out and we are left with point2.
  EXPECT_TRUE(ec_->AreEqual(*point2, *point_sum_all, context_.get()));
}

TEST_F(EllipticCurveTest, ScalarRangeCheck) {
  std::string str_ff(32, static_cast<char>(0xff));
  brillo::SecureBlob blob_ff(str_ff.begin(), str_ff.end());
  crypto::ScopedBIGNUM num_ff = SecureBlobToBigNum(blob_ff);
  EXPECT_FALSE(ec_->IsScalarValid(*num_ff));

  std::string str_23(32, static_cast<char>(0x23));
  brillo::SecureBlob blob_23(str_23.begin(), str_23.end());
  crypto::ScopedBIGNUM num_23 = SecureBlobToBigNum(blob_23);
  EXPECT_TRUE(ec_->IsScalarValid(*num_23));

  std::string str_cc(32, static_cast<char>(0xcc));
  brillo::SecureBlob blob_cc(str_cc.begin(), str_cc.end());
  crypto::ScopedBIGNUM num_cc = SecureBlobToBigNum(blob_cc);
  EXPECT_TRUE(ec_->IsScalarValid(*num_cc));

  std::string str_00(32, static_cast<char>(0));
  brillo::SecureBlob blob_00(str_00.begin(), str_00.end());
  crypto::ScopedBIGNUM num_00 = SecureBlobToBigNum(blob_00);
  EXPECT_TRUE(ec_->IsScalarValid(*num_00));

  EXPECT_FALSE(ec_->IsScalarValid(*ec_->GetOrderForTesting()));
}

}  // namespace hwsec_foundation
