cc/subtle/subtle_util_boringssl_test.cc
// Test with test vectors from Wycheproof project.
Test with test vectors from Wycheproof project.
Test with test vectors from Wycheproof project .
bool WycheproofTest(const rapidjson::Value& root) {
  int errors = 0;
  for (const rapidjson::Value& test_group : root["testGroups"].GetArray()) {
    std::string curve_str = test_group["curve"].GetString();
    if (!(curve_str == "secp256r1" || curve_str == "secp384r1" ||
          curve_str == "secp521r1")) {
      continue;
    }
    EllipticCurveType curve =
        WycheproofUtil::GetEllipticCurveType(test_group["curve"]);
    for (const rapidjson::Value& test : test_group["tests"].GetArray()) {
      std::string id = absl::StrCat(test["tcId"].GetInt());
      std::string comment = test["comment"].GetString();
      std::string pub_bytes = WycheproofUtil::GetBytes(test["public"]);
      std::string priv_bytes = WycheproofUtil::GetBytes(test["private"]);
      std::string expected_shared_bytes =
          WycheproofUtil::GetBytes(test["shared"]);
      std::string result = test["result"].GetString();
      EcPointFormat format = EcPointFormat::UNCOMPRESSED;
      for (const rapidjson::Value& flag : test["flags"].GetArray()) {
        if (std::string(flag.GetString()) == "CompressedPoint") {
          format = EcPointFormat::COMPRESSED;
        }
      }
      bool skip = false;
      for (const rapidjson::Value& flag : test["flags"].GetArray()) {
        if (std::string(flag.GetString()) == "UnnamedCurve") {
          skip = true;
          break;
        }
      }
      if (skip) {
        continue;
      }
      auto status_or_point_size = EcUtil::EncodingSizeInBytes(curve, format);
      if (!status_or_point_size.ok()) {
        continue;
      }
      size_t point_size = status_or_point_size.ValueOrDie();
      if (point_size > pub_bytes.size()) {
        continue;
      }
      pub_bytes = pub_bytes.substr(pub_bytes.size() - point_size, point_size);
      auto status_or_ec_point =
          SubtleUtilBoringSSL ::EcPointDecode(curve, format, pub_bytes);
      if (!status_or_ec_point.ok()) {
        if (result == "valid") {
          ADD_FAILURE() << "Could not decode public key with tcId:" << id
                        << " error:" << GetError()
                        << status_or_ec_point.status();
        }
        continue;
      }
      internal::SslUniquePtr<EC_POINT> pub_key =
          std::move(status_or_ec_point.ValueOrDie());
      internal::SslUniquePtr<BIGNUM> priv_key(
          BN_bin2bn(reinterpret_cast<const unsigned char*>(priv_bytes.data()),
                    priv_bytes.size(), nullptr));
      auto status_or_shared = SubtleUtilBoringSSL ::ComputeEcdhSharedSecret(
          curve, priv_key.get(), pub_key.get());
      if (status_or_shared.ok()) {
        util::SecretData shared = status_or_shared.ValueOrDie();
        if (result == "invalid") {
          ADD_FAILURE() << "Computed shared secret with invalid test vector"
                        << ", tcId= " << id;
          errors++;
        } else if (util::SecretDataAsStringView(shared) !=
                   expected_shared_bytes) {
          ADD_FAILURE() << "Computed wrong shared secret with tcId: " << id;
          errors++;
        }
      } else {
        if (result == "valid" || result == "acceptable") {
          ADD_FAILURE() << "Could not compute shared secret with tcId:" << id;
          errors++;
        }
      }
    }
  }
  return errors == 0;
}
bool WycheproofTest ( const rapidjson :: Value & root ) { int errors = 0 ; for ( const rapidjson :: Value & test_group : root [ " " ] . GetArray ( ) ) { std :: string curve_str = test_group [ " " ] . GetString ( ) ; if ( ! ( curve_str == " " || curve_str == " " || curve_str == " " ) ) { continue ; } EllipticCurveType curve = WycheproofUtil :: GetEllipticCurveType ( test_group [ " " ] ) ; for ( const rapidjson :: Value & test : test_group [ " " ] . GetArray ( ) ) { std :: string id = absl :: StrCat ( test [ " " ] . GetInt ( ) ) ; std :: string comment = test [ " " ] . GetString ( ) ; std :: string pub_bytes = WycheproofUtil :: GetBytes ( test [ " " ] ) ; std :: string priv_bytes = WycheproofUtil :: GetBytes ( test [ " " ] ) ; std :: string expected_shared_bytes = WycheproofUtil :: GetBytes ( test [ " " ] ) ; std :: string result = test [ " " ] . GetString ( ) ; EcPointFormat format = EcPointFormat :: UNCOMPRESSED ; for ( const rapidjson :: Value & flag : test [ " " ] . GetArray ( ) ) { if ( std :: string ( flag . GetString ( ) ) == " " ) { format = EcPointFormat :: COMPRESSED ; } } bool skip = false ; for ( const rapidjson :: Value & flag : test [ " " ] . GetArray ( ) ) { if ( std :: string ( flag . GetString ( ) ) == " " ) { skip = true ; break ; } } if ( skip ) { continue ; } auto status_or_point_size = EcUtil :: EncodingSizeInBytes ( curve , format ) ; if ( ! status_or_point_size . ok ( ) ) { continue ; } size_t point_size = status_or_point_size . ValueOrDie ( ) ; if ( point_size > pub_bytes . size ( ) ) { continue ; } pub_bytes = pub_bytes . substr ( pub_bytes . size ( ) - point_size , point_size ) ; auto status_or_ec_point = SubtleUtilBoringSSL :: EcPointDecode ( curve , format , pub_bytes ) ; if ( ! status_or_ec_point . ok ( ) ) { if ( result == " " ) { ADD_FAILURE ( ) << " " << id << " " << GetError ( ) << status_or_ec_point . status ( ) ; } continue ; } internal :: SslUniquePtr < EC_POINT > pub_key = std :: move ( status_or_ec_point . ValueOrDie ( ) ) ; internal :: SslUniquePtr < BIGNUM > priv_key ( BN_bin2bn ( reinterpret_cast < const unsigned char * > ( priv_bytes . data ( ) ) , priv_bytes . size ( ) , nullptr ) ) ; auto status_or_shared = SubtleUtilBoringSSL :: ComputeEcdhSharedSecret ( curve , priv_key . get ( ) , pub_key . get ( ) ) ; if ( status_or_shared . ok ( ) ) { util :: SecretData shared = status_or_shared . ValueOrDie ( ) ; if ( result == " " ) { ADD_FAILURE ( ) << " " << " " << id ; errors ++ ; } else if ( util :: SecretDataAsStringView ( shared ) != expected_shared_bytes ) { ADD_FAILURE ( ) << " " << id ; errors ++ ; } } else { if ( result == " " || result == " " ) { ADD_FAILURE ( ) << " " << id ; errors ++ ; } } } } return errors == 0 ; }
Test with test vectors from Wycheproof project.
Test with test vectors from Wycheproof project .
// Tink only supports secp256r1, secp384r1 or secp521r1. // Wycheproof's ECDH public key uses ASN encoding while Tink uses X9.62 // format point encoding. For the purpose of testing, we note the // followings: //  + The prefix of ASN encoding contains curve name, so we can skip test //  vector with "UnnamedCurve". //  + The suffix of ASN encoding is X9.62 format point encoding. // TODO(quannguyen): Use X9.62 test vectors once it's available.