diff --git a/src/cli/speed.cpp b/src/cli/speed.cpp index cc9cfb09a59..5244b66e6fc 100644 --- a/src/cli/speed.cpp +++ b/src/cli/speed.cpp @@ -748,6 +748,12 @@ class Speed final : public Command { bench_os2ecp(ecc_groups, msec); } +#endif +#if defined(BOTAN_HAS_EC_HASH_TO_CURVE) + else if(algo == "ec_h2c") + { + bench_ec_h2c(msec); + } #endif else if(algo == "RNG") { @@ -1223,6 +1229,41 @@ class Speed final : public Command #endif +#if defined(BOTAN_HAS_EC_HASH_TO_CURVE) + void bench_ec_h2c(const std::chrono::milliseconds runtime) + { + for(std::string group_name : { "secp256r1", "secp384r1", "secp521r1" }) + { + auto h2c_ro_timer = make_timer(group_name + "-RO", "", "hash to curve"); + auto h2c_nu_timer = make_timer(group_name + "-NU", "", "hash to curve"); + + const Botan::EC_Group group(group_name); + + while(h2c_ro_timer->under(runtime)) + { + std::vector input(32); + + rng().randomize(input.data(), input.size()); + + const Botan::PointGFp p1 = h2c_ro_timer->run([&]() { + return group.hash_to_curve("SHA-256", input.data(), input.size(), nullptr, 0, true); + }); + + BOTAN_ASSERT_NOMSG(p1.on_the_curve()); + + const Botan::PointGFp p2 = h2c_nu_timer->run([&]() { + return group.hash_to_curve("SHA-256", input.data(), input.size(), nullptr, 0, false); + }); + + BOTAN_ASSERT_NOMSG(p2.on_the_curve()); + } + + record_result(h2c_ro_timer); + record_result(h2c_nu_timer); + } + } +#endif + #if defined(BOTAN_HAS_FPE_FE1) void bench_fpe_fe1(const std::chrono::milliseconds runtime) diff --git a/src/lib/math/numbertheory/monty.cpp b/src/lib/math/numbertheory/monty.cpp index a6e22c9b76c..e89f497deb6 100644 --- a/src/lib/math/numbertheory/monty.cpp +++ b/src/lib/math/numbertheory/monty.cpp @@ -433,6 +433,11 @@ Montgomery_Int Montgomery_Int::square(secure_vector& ws) const return Montgomery_Int(m_params, m_params->sqr(m_v, ws), false); } +Montgomery_Int Montgomery_Int::cube(secure_vector& ws) const + { + return Montgomery_Int(m_params, m_params->sqr(m_v, ws), false); + } + Montgomery_Int Montgomery_Int::multiplicative_inverse() const { secure_vector ws; diff --git a/src/lib/math/numbertheory/monty.h b/src/lib/math/numbertheory/monty.h index b4c90397e42..a3ceb23e018 100644 --- a/src/lib/math/numbertheory/monty.h +++ b/src/lib/math/numbertheory/monty.h @@ -106,6 +106,8 @@ class BOTAN_UNSTABLE_API Montgomery_Int final Montgomery_Int square(secure_vector& ws) const; + Montgomery_Int cube(secure_vector& ws) const; + Montgomery_Int& square_this(secure_vector& ws); Montgomery_Int& square_this_n_times(secure_vector& ws, size_t n); diff --git a/src/lib/math/numbertheory/reducer.h b/src/lib/math/numbertheory/reducer.h index b1c2c87a9f6..54e97b4588e 100644 --- a/src/lib/math/numbertheory/reducer.h +++ b/src/lib/math/numbertheory/reducer.h @@ -31,6 +31,13 @@ class BOTAN_PUBLIC_API(2,0) Modular_Reducer BigInt multiply(const BigInt& x, const BigInt& y) const { return reduce(x * y); } + /** + * Multiply mod p + * @return (x * y * z) % p + */ + BigInt multiply(const BigInt& x, const BigInt& y, const BigInt& z) const + { return multiply(x, multiply(y, z)); } + /** * Square mod p * @param x the value to square diff --git a/src/lib/pubkey/ec_group/ec_group.cpp b/src/lib/pubkey/ec_group/ec_group.cpp index b253f56ab00..fc150113d08 100644 --- a/src/lib/pubkey/ec_group/ec_group.cpp +++ b/src/lib/pubkey/ec_group/ec_group.cpp @@ -19,6 +19,10 @@ #include #include +#if defined(BOTAN_HAS_EC_HASH_TO_CURVE) + #include +#endif + namespace Botan { class EC_Group_Data final @@ -613,6 +617,15 @@ PointGFp EC_Group::OS2ECP(const uint8_t bits[], size_t len) const PointGFp EC_Group::point(const BigInt& x, const BigInt& y) const { + #if 0 + BigInt l = (x*x*x + x*get_a() + get_b()) % get_p(); + BigInt r = (y*y) % get_p(); + + if(l != r) + { + printf("invalid point in EC_Group::point\n"); + } +#endif // TODO: randomize the representation? return PointGFp(data().curve(), x, y); } @@ -660,6 +673,46 @@ PointGFp EC_Group::zero_point() const return PointGFp(data().curve()); } +PointGFp EC_Group::hash_to_curve(const std::string& hash_fn, + const uint8_t input[], + size_t input_len, + const std::string& domain, + bool random_oracle) const + { + return this->hash_to_curve(hash_fn, + input, + input_len, + reinterpret_cast(domain.c_str()), + domain.size(), + random_oracle); + } + +PointGFp EC_Group::hash_to_curve(const std::string& hash_fn, + const uint8_t input[], + size_t input_len, + const uint8_t domain_sep[], + size_t domain_sep_len, + bool random_oracle) const + { +#if defined(BOTAN_HAS_EC_HASH_TO_CURVE) + + // Only have SSWU currently + if(get_a().is_zero() || get_b().is_zero() || get_p() % 4 == 1) + { + throw Not_Implemented("EC_Group::hash_to_curve not available for this curve type"); + } + + return hash_to_curve_sswu(*this, hash_fn, + input, input_len, + domain_sep, domain_sep_len, + random_oracle); + +#else + BOTAN_UNUSED(hash_fn, random_oracle, input, input_len, domain_sep, domain_sep_len); + throw Not_Implemented("EC_Group::hash_to_curve functionality not available in this configuration"); +#endif + } + std::vector EC_Group::DER_encode(EC_Group_Encoding form) const { diff --git a/src/lib/pubkey/ec_group/ec_group.h b/src/lib/pubkey/ec_group/ec_group.h index 03a4463a0e5..6ae180ee905 100644 --- a/src/lib/pubkey/ec_group/ec_group.h +++ b/src/lib/pubkey/ec_group/ec_group.h @@ -223,6 +223,14 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final */ BigInt multiply_mod_order(const BigInt& x, const BigInt& y, const BigInt& z) const; + /* + * Return x^3 modulo the order + */ + inline BigInt cube_mod_order(const BigInt& x) const + { + return multiply_mod_order(x, square_mod_order(x)); + } + /** * Check if y is a plausible point on the curve * @@ -290,6 +298,44 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final */ BigInt random_scalar(RandomNumberGenerator& rng) const; + /** + * Hash onto the curve. + * For some curve types no mapping is currently available, in this + * case this function will throw an exception. + * + * @param hash_fn the hash function to use (typically "SHA-256" or "SHA-512") + * @param input the input to hash + * @param input_len length of input in bytes + * @param domain_sep a domain seperator + * @param domain_sep_len length of domain_sep in bytes + * @param random_oracle if the mapped point must be uniform (use + "true" here unless you know what you are doing) + */ + PointGFp hash_to_curve(const std::string& hash_fn, + const uint8_t input[], + size_t input_len, + const uint8_t domain_sep[], + size_t domain_sep_len, + bool random_oracle = true) const; + + /** + * Hash onto the curve. + * For some curve types no mapping is currently available, in this + * case this function will throw an exception. + * + * @param hash_fn the hash function to use (typically "SHA-256" or "SHA-512") + * @param input the input to hash + * @param input_len length of input in bytes + * @param domain_sep a domain seperator + * @param random_oracle if the mapped point must be uniform (use + "true" here unless you know what you are doing) + */ + PointGFp hash_to_curve(const std::string& hash_fn, + const uint8_t input[], + size_t input_len, + const std::string& domain_sep, + bool random_oracle = true) const; + /** * Return the zero (or infinite) point on this curve */ diff --git a/src/lib/pubkey/ec_h2c/ec_h2c.cpp b/src/lib/pubkey/ec_h2c/ec_h2c.cpp new file mode 100644 index 00000000000..4a1d69fdddf --- /dev/null +++ b/src/lib/pubkey/ec_h2c/ec_h2c.cpp @@ -0,0 +1,208 @@ +/* +* (C) 2019,2020,2021 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include +#include + +namespace Botan { + +void expand_message_xmd(const std::string& hash_fn, + uint8_t output[], + size_t output_len, + const uint8_t input[], + size_t input_len, + const uint8_t domain_sep[], + size_t domain_sep_len) + { + if(domain_sep_len > 0xFF) + throw Invalid_Argument("expand_message_xmd domain seperator too long"); + + auto hash = HashFunction::create_or_throw(hash_fn); + const size_t block_size = hash->hash_block_size(); + if(block_size == 0) + throw Invalid_Argument("expand_message_xmd cannot be used with " + hash_fn); + + const size_t hash_output_size = hash->output_length(); + if(output_len > 255*hash_output_size || output_len > 0xFFFF) + throw Invalid_Argument("expand_message_xmd requested output length too long"); + + // Compute b_0 = H(msg_prime) = H(Z_pad || msg || l_i_b_str || 0x00 || DST_prime) + + hash->update(std::vector(block_size)); + hash->update(input, input_len); + hash->update_be(static_cast(output_len)); + hash->update(0x00); + hash->update(domain_sep, domain_sep_len); + hash->update(static_cast(domain_sep_len)); + + const secure_vector b_0 = hash->final(); + + // Compute b_1 = H(b_0 || 0x01 || DST_prime) + + hash->update(b_0); + hash->update(0x01); + hash->update(domain_sep, domain_sep_len); + hash->update(static_cast(domain_sep_len)); + + secure_vector b_i = hash->final(); + + uint8_t cnt = 2; + while(output_len > 0) + { + const size_t produced = std::min(output_len, hash_output_size); + + copy_mem(output, b_i.data(), produced); + output += produced; + output_len -= produced; + + // Now compute the next b_i + + b_i ^= b_0; + hash->update(b_i); + hash->update(cnt); + hash->update(domain_sep, domain_sep_len); + hash->update(static_cast(domain_sep_len)); + hash->final(b_i.data()); + cnt += 1; + } + } + +namespace { + +std::vector +hash_to_field(const EC_Group& group, + const Modular_Reducer& mod_p, + const std::string& hash_fn, + uint8_t count, + const uint8_t input[], size_t input_len, + const uint8_t domain_sep[], size_t domain_sep_len) + { + const size_t k = (group.get_order_bits() + 1) / 2; + const size_t L = (group.get_p_bits() + k + 7) / 8; + + std::vector results; + results.reserve(count); + + secure_vector output(L * count); + expand_message_xmd(hash_fn, + output.data(), output.size(), + input, input_len, + domain_sep, domain_sep_len); + + for(size_t i = 0; i != count; ++i) + { + BigInt v(&output[i*L], L); + results.push_back(mod_p.reduce(v)); + } + + return results; + } + +BigInt sswu_z(const EC_Group& group) + { + const BigInt& p = group.get_p(); + const OID oid = group.get_curve_oid(); + + if(oid == OID{1,2,840,10045,3,1,7}) // secp256r1 + return p - 10; + if(oid == OID{1,3,132,0,34}) // secp384r1 + return p - 12; + if(oid == OID{1,3,132,0,35}) // secp521r1 + return p - 4; + + return 0; + } + +BigInt ct_choose(bool first, const BigInt& x, const BigInt& y) + { + BigInt z = y; + z.ct_cond_assign(first, x); + return z; + } + +PointGFp map_to_curve_sswu(const EC_Group& group, const Modular_Reducer& mod_p, const BigInt& u) + { + const BigInt& p = group.get_p(); + const BigInt& A = group.get_a(); + const BigInt& B = group.get_b(); + const BigInt Z = sswu_z(group); + + if(Z.is_zero() || A.is_zero() || B.is_zero() || p % 4 != 3) + throw Invalid_Argument("map_to_curve_sswu does not support this curve"); + + // These values could be precomputed: + const BigInt c1 = mod_p.multiply(p - B, inverse_mod(A, p)); + const BigInt c2 = mod_p.multiply(p - 1, inverse_mod(Z, p)); + + /* + * See Appendix F.2 of draft-irtf-cfrg-hash-to-curve + */ + + const BigInt tv1 = mod_p.multiply(Z, mod_p.square(u)); + const BigInt tv2 = mod_p.square(tv1); + + BigInt x1 = inverse_mod(tv1 + tv2, p); + const bool e1 = x1.is_zero(); + x1 += 1; + x1.ct_cond_assign(e1, c2); + x1 = mod_p.multiply(x1, c1); + + // gx1 = x1^3 + A*x1 + B; + BigInt gx1 = mod_p.square(x1); + gx1 += A; + gx1 = mod_p.multiply(gx1, x1); + gx1 += B; + gx1 = mod_p.reduce(gx1); + + const BigInt x2 = mod_p.multiply(tv1, x1); + + // gx2 = (Z * u^2)^3 * gx1 + const BigInt gx2 = mod_p.multiply(gx1, mod_p.multiply(tv1, tv2)); + + // assumes p % 4 == 3 + const bool gx1_is_square = (power_mod(gx1, (p-1)/2, p) <= 1); + + const BigInt x = ct_choose(gx1_is_square, x1, x2); + const BigInt y2 = ct_choose(gx1_is_square, gx1, gx2); + + // assumes p % 4 == 3 + const BigInt y = power_mod(y2, (p + 1)/4, p); + const BigInt neg_y = p - y; + + const bool uy_sign = u.get_bit(0) != y.get_bit(0); + return group.point(x, ct_choose(uy_sign, neg_y, y)); + } + +} + +PointGFp hash_to_curve_sswu(const EC_Group& group, + const std::string& hash_fn, + const uint8_t input[], + size_t input_len, + const uint8_t domain_sep[], + size_t domain_sep_len, + bool random_oracle) + { + const Modular_Reducer mod_p(group.get_p()); + + const uint8_t count = (random_oracle ? 2 : 1); + + const auto u = hash_to_field(group, mod_p, hash_fn, count, + input, input_len, + domain_sep, domain_sep_len); + + PointGFp pt = map_to_curve_sswu(group, mod_p, u[0]); + + for(size_t i = 1; i != u.size(); ++i) + pt += map_to_curve_sswu(group, mod_p, u[i]); + + return pt; + } + +} diff --git a/src/lib/pubkey/ec_h2c/ec_h2c.h b/src/lib/pubkey/ec_h2c/ec_h2c.h new file mode 100644 index 00000000000..f932e76a566 --- /dev/null +++ b/src/lib/pubkey/ec_h2c/ec_h2c.h @@ -0,0 +1,47 @@ +/* +* (C) 2019,2020,2021 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_ECC_HASH_TO_CURVE_H_ +#define BOTAN_ECC_HASH_TO_CURVE_H_ + +#include +#include +#include + +namespace Botan { + +class EC_Group; + +/** +* expand_message_xmd +*/ +void BOTAN_TEST_API expand_message_xmd(const std::string& hash_fn, + uint8_t output[], + size_t output_len, + const uint8_t input[], + size_t input_len, + const uint8_t domain_sep[], + size_t domain_sep_len); + + +/** +* Hash an input onto an elliptic curve point using the +* methods from draft-irtf-cfrg-hash-to-curve +* +* This method requires that the ECC group have (a*b) != 0 +* which excludes certain groups including secp256k1 +*/ +PointGFp hash_to_curve_sswu(const EC_Group& group, + const std::string& hash_fn, + const uint8_t input[], + size_t input_len, + const uint8_t domain_sep[], + size_t domain_sep_len, + bool random_oracle); + +} + +#endif diff --git a/src/lib/pubkey/ec_h2c/info.txt b/src/lib/pubkey/ec_h2c/info.txt new file mode 100644 index 00000000000..af342a2def8 --- /dev/null +++ b/src/lib/pubkey/ec_h2c/info.txt @@ -0,0 +1,12 @@ + +EC_HASH_TO_CURVE -> 20210420 + + + +ec_group +hash + + + +ec_h2c.h + diff --git a/src/scripts/test_cli.py b/src/scripts/test_cli.py index 7d69f821170..2fe2ade16b1 100755 --- a/src/scripts/test_cli.py +++ b/src/scripts/test_cli.py @@ -1147,12 +1147,12 @@ def cli_speed_pk_tests(_tmp_dir): pk_algos = ["ECDSA", "ECDH", "SM2", "ECKCDSA", "ECGDSA", "GOST-34.10", "DH", "DSA", "ElGamal", "Ed25519", "Curve25519", "NEWHOPE", "McEliece", - "RSA", "RSA_keygen", "XMSS"] + "RSA", "RSA_keygen", "XMSS", "ec_h2c"] output = test_cli("speed", ["--msec=%d" % (msec)] + pk_algos, None).split('\n') # ECDSA-secp256r1 106 keygen/sec; 9.35 ms/op 37489733 cycles/op (1 op in 9 ms) - format_re = re.compile(r'^.* [0-9]+ ([A-Za-z ]+)/sec; [0-9]+\.[0-9]+ ms/op .*\([0-9]+ (op|ops) in [0-9\.]+ ms\)') + format_re = re.compile(r'^.* [0-9]+ ([A-Za-z0-9 ]+)/sec; [0-9]+\.[0-9]+ ms/op .*\([0-9]+ (op|ops) in [0-9\.]+ ms\)') for line in output: if format_re.match(line) is None: logging.error("Unexpected line %s", line) diff --git a/src/tests/data/pubkey/ec_h2c.vec b/src/tests/data/pubkey/ec_h2c.vec new file mode 100644 index 00000000000..3e705d06047 --- /dev/null +++ b/src/tests/data/pubkey/ec_h2c.vec @@ -0,0 +1,151 @@ +[SSWU-RO] +Group = secp256r1 +Hash = SHA-256 +Domain = QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_ + +Input = +PointX = 0x2c15230b26dbc6fc9a37051158c95b79656e17a1a920b11394ca91c44247d3e4 +PointY = 0x8a7a74985cc5c776cdfe4b1f19884970453912e9d31528c060be9ab5c43e8415 + +Input = abc +PointX = 0x0bb8b87485551aa43ed54f009230450b492fead5f1cc91658775dac4a3388a0f +PointY = 0x5c41b3d0731a27a7b14bc0bf0ccded2d8751f83493404c84a88e71ffd424212e + +Input = abcdef0123456789 +PointX = 0x65038ac8f2b1def042a5df0b33b1f4eca6bff7cb0f9c6c1526811864e544ed80 +PointY = 0xcad44d40a656e7aff4002a8de287abc8ae0482b5ae825822bb870d6df9b56ca3 + +Input = q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq +PointX = 0x4be61ee205094282ba8a2042bcb48d88dfbb609301c49aa8b078533dc65a0b5d +PointY = 0x98f8df449a072c4721d241a3b1236d3caccba603f916ca680f4539d2bfb3c29e + +Input = a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +PointX = 0x457ae2981f70ca85d8e24c308b14db22f3e3862c5ea0f652ca38b5e49cd64bc5 +PointY = 0xecb9f0eadc9aeed232dabc53235368c1394c78de05dd96893eefa62b0f4757dc + +[SSWU-NU] +Group = secp256r1 +Hash = SHA-256 +Domain = QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_NU_ + +Input = +PointX = 0xf871caad25ea3b59c16cf87c1894902f7e7b2c822c3d3f73596c5ace8ddd14d1 +PointY = 0x87b9ae23335bee057b99bac1e68588b18b5691af476234b8971bc4f011ddc99b + +Input = abc +PointX = 0xfc3f5d734e8dce41ddac49f47dd2b8a57257522a865c124ed02b92b5237befa4 +PointY = 0xfe4d197ecf5a62645b9690599e1d80e82c500b22ac705a0b421fac7b47157866 + +Input = abcdef0123456789 +PointX = 0xf164c6674a02207e414c257ce759d35eddc7f55be6d7f415e2cc177e5d8faa84 +PointY = 0x3aa274881d30db70485368c0467e97da0e73c18c1d00f34775d012b6fcee7f97 + +Input = q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq +PointX = 0x324532006312be4f162614076460315f7a54a6f85544da773dc659aca0311853 +PointY = 0x8d8197374bcd52de2acfefc8a54fe2c8d8bebd2a39f16be9b710e4b1af6ef883 + +Input = a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +PointX = 0x5c4bad52f81f39c8e8de1260e9a06d72b8b00a0829a8ea004a610b0691bea5d9 +PointY = 0xc801e7c0782af1f74f24fc385a8555da0582032a3ce038de637ccdcb16f7ef7b + +[SSWU-RO] +Group = secp384r1 +Hash = SHA-512 +Domain = QUUX-V01-CS02-with-P384_XMD:SHA-512_SSWU_RO_ + +Input = +PointX = 0xc3144d47428d071d4169420c91006a0bd48d7259d492af86e7f82d98e3497519d8550045557b7d55cc2a0f339df088b9 +PointY = 0xaa5f165f0146101363d1b34fe65bcf638532e3b2eb1744cdbd60e9384c6c1838bbaea988963cc9f0f0902798e9f8058a + + +Input = abc +PointX = 0x7bce42d575e64bc7828478f1bba94000c3ddb02ac03052061a7b7ff81479823350e2a8e1da74e17be3016ab163094bcf +PointY = 0x6634b2f0acb32b84b75ecfad96c676b3863cb3cec4f76c9bccef1894a650830e60cd1c0f20c9d05e9ee58d8a611db87d + + +Input = abcdef0123456789 +PointX = 0xaf1a87bee29167676e41d8eb0518a9e44e570207519c11fa126c33f32d62bbf6d312fd5812b182d59389f26ea496e58d +PointY = 0x76ab30527be12a53a3bd63457072840ea516aa945fbe2dc48a42cfbd031c3f93896e4a66093b2f56cc9da4694ec95f27 + +Input = q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq +PointX = 0x5c24f67b2175279f4e94a0af9cf09213f0e7e2e3ccb6d4feae9403281c1962507ba0588ef895c9b7c6cff28ce1d15a1f +PointY = 0x259ce2c65f35f5fb3a611e5bbf56d2979ce9de429afd6271fbda57c3d412c78292d0cb6f27e0ee96f91fba9f0af54327 + +Input = a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +PointX = 0xed18cea59aabd90a3c84b48eeb09b42409f42340aec2ec1b70687215fa4befc64fd4de4620d12e70b9890ad9a70e6ee8 +PointY = 0xdbc9b0e5e718539c785b7b787829a1c01b92591aed954e08b853dc96fb303ba4bc8aad06712b8b3b4fae2047d6269d68 + +[SSWU-NU] +Group = secp384r1 +Hash = SHA-512 +Domain = QUUX-V01-CS02-with-P384_XMD:SHA-512_SSWU_NU_ + +Input = +PointX = 0x5b87392cdbf306d62141cf266a1fcc8b6a8129469b1e4a56a16db6371b70279d3155514580300f77a23dbeaa70eeda32 +PointY = 0x9094b16177a04f5c5afac87efc78b6e65a2583a5adc91c04cd508fd602d528530eb54932dff8b7e156d470996606cd9c + +Input = abc +PointX = 0x496ed56a37cb85a82826a4234948dd3ceee17da6412c87242165b7f798b702f2292237bddac386cfcfa8f22e7b85ca2d +PointY = 0x9524181274d1313c12872ea835c7ddc9444124d22aae6e474d55b1fe68e480250374e689e6c2745323da7222732d2cce + +Input = abcdef0123456789 +PointX = 0xa1289920ba2c52de5f384b1316788438ac5564a20c2e0f7ff0ff2fa34cb4488bd4683c0cc45ee6234b4a515ddda31f99 +PointY = 0xb5e24b855275729db25cecc83ec5fc1dcf8f055ad981a0901448d84c6278cd10a28f65316db5ae1f5738ed06ae9c2f55 + +Input = q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq +PointX = 0xa0ed20ca2c7c69a6b7a3e5b9cf77d8f9bd979aa83a7f75e5f90d6becd107925e5dcbbd96978ab74a7b5e96b48135d04c +PointY = 0x4c9ed613516ae3e818139b6c9aea2ac42063c06ff0303a38c101ab822c15d5fe6413e64adbac82a0da770cf110d7ace9 + +Input = a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +PointX = 0xbc36cda196f8084052fc41a5c4ef5c9e1c724cc0bd83ef8eaef07bb2cbc3db99ff5cdb31ba3018a6afe59b0db040c980 +PointY = 0x5106450163d90d99d3191bc92f8a3d116f15b18b23eff8e9996481c6878bd16c8e202f44abc3d09325c2016b5dacc8f0 + +[SSWU-RO] +Group = secp521r1 +Hash = SHA-512 +Domain = QUUX-V01-CS02-with-P521_XMD:SHA-512_SSWU_RO_ + +Input = +PointX = 0x00fd767cebb2452030358d0e9cf907f525f50920c8f607889a6a35680727f64f4d66b161fafeb2654bea0d35086bec0a10b30b14adef3556ed9f7f1bc23cecc9c088 +PointY = 0x0169ba78d8d851e930680322596e39c78f4fe31b97e57629ef6460ddd68f8763fd7bd767a4e94a80d3d21a3c2ee98347e024fc73ee1c27166dc3fe5eeef782be411d + +Input = abc +PointX = 0x002f89a1677b28054b50d15e1f81ed6669b5a2158211118ebdef8a6efc77f8ccaa528f698214e4340155abc1fa08f8f613ef14a043717503d57e267d57155cf784a4 +PointY = 0x010e0be5dc8e753da8ce51091908b72396d3deed14ae166f66d8ebf0a4e7059ead169ea4bead0232e9b700dd380b316e9361cfdba55a08c73545563a80966ecbb86d + +Input = abcdef0123456789 +PointX = 0x006e200e276a4a81760099677814d7f8794a4a5f3658442de63c18d2244dcc957c645e94cb0754f95fcf103b2aeaf94411847c24187b89fb7462ad3679066337cbc4 +PointY = 0x001dd8dfa9775b60b1614f6f169089d8140d4b3e4012949b52f98db2deff3e1d97bf73a1fa4d437d1dcdf39b6360cc518d8ebcc0f899018206fded7617b654f6b168 + +Input = q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq +PointX = 0x01b264a630bd6555be537b000b99a06761a9325c53322b65bdc41bf196711f9708d58d34b3b90faf12640c27b91c70a507998e55940648caa8e71098bf2bc8d24664 +PointY = 0x01ea9f445bee198b3ee4c812dcf7b0f91e0881f0251aab272a12201fd89b1a95733fd2a699c162b639e9acdcc54fdc2f6536129b6beb0432be01aa8da02df5e59aaa + +Input = a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +PointX = 0x00c12bc3e28db07b6b4d2a2b1167ab9e26fc2fa85c7b0498a17b0347edf52392856d7e28b8fa7a2dd004611159505835b687ecf1a764857e27e9745848c436ef3925 +PointY = 0x01cd287df9a50c22a9231beb452346720bb163344a41c5f5a24e8335b6ccc595fd436aea89737b1281aecb411eb835f0b939073fdd1dd4d5a2492e91ef4a3c55bcbd + +[SSWU-NU] +Group = secp521r1 +Hash = SHA-512 +Domain = QUUX-V01-CS02-with-P521_XMD:SHA-512_SSWU_NU_ + +Input = +PointX = 0x01ec604b4e1e3e4c7449b7a41e366e876655538acf51fd40d08b97be066f7d020634e906b1b6942f9174b417027c953d75fb6ec64b8cee2a3672d4f1987d13974705 +PointY = 0x00944fc439b4aad2463e5c9cfa0b0707af3c9a42e37c5a57bb4ecd12fef9fb21508568aedcdd8d2490472df4bbafd79081c81e99f4da3286eddf19be47e9c4cf0e91 + +Input = abc +PointX = 0x00c720ab56aa5a7a4c07a7732a0a4e1b909e32d063ae1b58db5f0eb5e09f08a9884bff55a2bef4668f715788e692c18c1915cd034a6b998311fcf46924ce66a2be9a +PointY = 0x003570e87f91a4f3c7a56be2cb2a078ffc153862a53d5e03e5dad5bccc6c529b8bab0b7dbb157499e1949e4edab21cf5d10b782bc1e945e13d7421ad8121dbc72b1d + +Input = abcdef0123456789 +PointX = 0x00bcaf32a968ff7971b3bbd9ce8edfbee1309e2019d7ff373c38387a782b005dce6ceffccfeda5c6511c8f7f312f343f3a891029c5858f45ee0bf370aba25fc990cc +PointY = 0x00923517e767532d82cb8a0b59705eec2b7779ce05f9181c7d5d5e25694ef8ebd4696343f0bc27006834d2517215ecf79482a84111f50c1bae25044fe1dd77744bbd + +Input = q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq +PointX = 0x001ac69014869b6c4ad7aa8c443c255439d36b0e48a0f57b03d6fe9c40a66b4e2eaed2a93390679a5cc44b3a91862b34b673f0e92c83187da02bf3db967d867ce748 +PointY = 0x00d5603d530e4d62b30fccfa1d90c2206654d74291c1db1c25b86a051ee3fffc294e5d56f2e776853406bd09206c63d40f37ad8829524cf89ad70b5d6e0b4a3b7341 + +Input = a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +PointX = 0x01801de044c517a80443d2bd4f503a9e6866750d2f94a22970f62d721f96e4310e4a828206d9cdeaa8f2d476705cc3bbc490a6165c687668f15ec178a17e3d27349b +PointY = 0x0068889ea2e1442245fe42bfda9e58266828c0263119f35a61631a3358330f3bb84443fcb54fcd53a1d097fccbe310489b74ee143fc2938959a83a1f7dd4a6fd395b diff --git a/src/tests/data/pubkey/ec_h2c_xmd.vec b/src/tests/data/pubkey/ec_h2c_xmd.vec new file mode 100644 index 00000000000..e0a257cdd52 --- /dev/null +++ b/src/tests/data/pubkey/ec_h2c_xmd.vec @@ -0,0 +1,65 @@ +[SHA-256] +Domain = QUUX-V01-CS02-with-expander + +Input = +Output = f659819a6473c1835b25ea59e3d38914c98b374f0970b7e4c92181df928fca88 + +Input = abc +Output = 1c38f7c211ef233367b2420d04798fa4698080a8901021a795a1151775fe4da7 + +Input = abcdef0123456789 +Output = 8f7e7b66791f0da0dbb5ec7c22ec637f79758c0a48170bfb7c4611bd304ece89 + +Input = q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq +Output = 72d5aa5ec810370d1f0013c0df2f1d65699494ee2a39f72e1716b1b964e1c642 + +Input = a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +Output = 3b8e704fc48336aca4c2a12195b720882f2162a4b7b13a9c350db46f429b771b + +Input = +Output = 8bcffd1a3cae24cf9cd7ab85628fd111bb17e3739d3b53f89580d217aa79526f1708354a76a402d3569d6a9d19ef3de4d0b991e4f54b9f20dcde9b95a66824cbdf6c1a963a1913d43fd7ac443a02fc5d9d8d77e2071b86ab114a9f34150954a7531da568a1ea8c760861c0cde2005afc2c114042ee7b5848f5303f0611cf297f + +Input = abc +Output = fe994ec51bdaa821598047b3121c149b364b178606d5e72bfbb713933acc29c186f316baecf7ea22212f2496ef3f785a27e84a40d8b299cec56032763eceeff4c61bd1fe65ed81decafff4a31d0198619c0aa0c6c51fca15520789925e813dcfd318b542f8799441271f4db9ee3b8092a7a2e8d5b75b73e28fb1ab6b4573c192 + +Input = abcdef0123456789 +Output = c9ec7941811b1e19ce98e21db28d22259354d4d0643e301175e2f474e030d32694e9dd5520dde93f3600d8edad94e5c364903088a7228cc9eff685d7eaac50d5a5a8229d083b51de4ccc3733917f4b9535a819b445814890b7029b5de805bf62b33a4dc7e24acdf2c924e9fe50d55a6b832c8c84c7f82474b34e48c6d43867be + +Input = q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq +Output = 48e256ddba722053ba462b2b93351fc966026e6d6db493189798181c5f3feea377b5a6f1d8368d7453faef715f9aecb078cd402cbd548c0e179c4ed1e4c7e5b048e0a39d31817b5b24f50db58bb3720fe96ba53db947842120a068816ac05c159bb5266c63658b4f000cbf87b1209a225def8ef1dca917bcda79a1e42acd8069 + +Input = a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +Output = 396962db47f749ec3b5042ce2452b619607f27fd3939ece2746a7614fb83a1d097f554df3927b084e55de92c7871430d6b95c2a13896d8a33bc48587b1f66d21b128a1a8240d5b0c26dfe795a1a842a0807bb148b77c2ef82ed4b6c9f7fcb732e7f94466c8b51e52bf378fba044a31f5cb44583a892f5969dcd73b3fa128816e + +[SHA-512] +Domain = QUUX-V01-CS02-with-expander + +Input = +Output = 2eaa1f7b5715f4736e6a5dbe288257abf1faa028680c1d938cd62ac699ead642 + +Input = abc +Output = 0eeda81f69376c80c0f8986496f22f21124cb3c562cf1dc608d2c13005553b0f + +Input = abcdef0123456789 +Output = 2e375fc05e05e80dbf3083796fde2911789d9e8847e1fcebf4ca4b36e239b338 + +Input = q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq +Output = c37f9095fe7fe4f01c03c3540c1229e6ac8583b07510085920f62ec66acc0197 + +Input = a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +Output = af57a7f56e9ed2aa88c6eab45c8c6e7638ae02da7c92cc04f6648c874ebd560e + +Input = +Output = 0687ce02eba5eb3faf1c3c539d1f04babd3c0f420edae244eeb2253b6c6d6865145c31458e824b4e87ca61c3442dc7c8c9872b0b7250aa33e0668ccebbd2b386de658ca11a1dcceb51368721ae6dcd2d4bc86eaebc4e0d11fa02ad053289c9b28a03da6c942b2e12c14e88dbde3b0ba619d6214f47212b628f3e1b537b66efcf + +Input = abc +Output = 779ae4fd8a92f365e4df96b9fde97b40486bb005c1a2096c86f55f3d92875d89045fbdbc4a0e9f2d3e1e6bcd870b2d7131d868225b6fe72881a81cc5166b5285393f71d2e68bb0ac603479959370d06bdbe5f0d8bfd9af9494d1e4029bd68ab35a561341dd3f866b3ef0c95c1fdfaab384ce24a23427803dda1db0c7d8d5344a + +Input = abcdef0123456789 +Output = f0953d28846a50e9f88b7ae35b643fc43733c9618751b569a73960c655c068db7b9f044ad5a40d49d91c62302eaa26163c12abfa982e2b5d753049e000adf7630ae117aeb1fb9b61fc724431ac68b369e12a9481b4294384c3c890d576a79264787bc8076e7cdabe50c044130e480501046920ff090c1a091c88391502f0fbac + +Input = q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq +Output = 64d3e59f0bc3c5e653011c914b419ba8310390a9585311fddb26791d26663bd71971c347e1b5e88ba9274d2445ed9dcf48eea9528d807b7952924159b7c27caa4f25a2ea94df9508e70a7012dfce0e8021b37e59ea21b80aa9af7f1a1f2efa4fbe523c4266ce7d342acaacd438e452c501c131156b4945515e9008d2b155c258 + +Input = a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +Output = 01524feea5b22f6509f6b1e805c97df94faf4d821b01aadeebc89e9daaed0733b4544e50852fd3e019d58eaad6d267a134c8bc2c08bc46c10bfeff3ee03110bcd8a0d695d75a34092bd8b677bdd369a13325549abab54f4ac907b712bdd3567f38c4554c51902b735b81f43a7ef6f938c7690d107c052c7e7b795ac635b3200a diff --git a/src/tests/test_ecc_h2c.cpp b/src/tests/test_ecc_h2c.cpp new file mode 100644 index 00000000000..9e667e91547 --- /dev/null +++ b/src/tests/test_ecc_h2c.cpp @@ -0,0 +1,93 @@ +/* +* (C) 2019,2020 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "tests.h" + +#if defined(BOTAN_HAS_EC_HASH_TO_CURVE) + #include + #include +#endif + +namespace Botan_Tests { + +namespace { + +#if defined(BOTAN_HAS_EC_HASH_TO_CURVE) + +class ECC_H2C_XMD_Tests final : public Text_Based_Test + { + public: + ECC_H2C_XMD_Tests() : Text_Based_Test("pubkey/ec_h2c_xmd.vec", "Domain,Input,Output") {} + + bool clear_between_callbacks() const override { return false; } + + Test::Result run_one_test(const std::string& hash, const VarMap& vars) override + { + Test::Result result("ECC hash to curve XMD " + hash); + + const std::string domain = vars.get_req_str("Domain"); + const std::string input = vars.get_req_str("Input"); + const std::vector expected = vars.get_req_bin("Output"); + + std::vector output(expected.size()); + Botan::expand_message_xmd(hash, output.data(), output.size(), + reinterpret_cast(input.data()), + input.size(), + reinterpret_cast(domain.data()), + domain.size()); + + result.test_eq("XMD output", output, expected); + return result; + } + + }; + +BOTAN_REGISTER_TEST("ec_h2c", "ec_h2c_xmd", ECC_H2C_XMD_Tests); + +class ECC_H2C_Tests final : public Text_Based_Test + { + public: + ECC_H2C_Tests() : Text_Based_Test("pubkey/ec_h2c.vec", "Group,Hash,Domain,Input,PointX,PointY") {} + + bool clear_between_callbacks() const override { return false; } + + Test::Result run_one_test(const std::string& method, const VarMap& vars) override + { + const std::string group_id = vars.get_req_str("Group"); + + Test::Result result("ECC hash to curve " + method + " " + group_id); + + const std::string hash = vars.get_req_str("Hash"); + const std::string domain = vars.get_req_str("Domain"); + const std::string input = vars.get_req_str("Input"); + const BigInt exp_point_x = vars.get_req_bn("PointX"); + const BigInt exp_point_y = vars.get_req_bn("PointY"); + const bool random_oracle = method.find("-RO") != std::string::npos; + + Botan::EC_Group group(group_id); + + const auto point = group.hash_to_curve(hash, + reinterpret_cast(input.data()), + input.size(), + domain, + random_oracle); + + result.confirm("Generated point is on the curve", point.on_the_curve()); + + result.test_eq("Affine X", point.get_affine_x(), exp_point_x); + result.test_eq("Affine Y", point.get_affine_y(), exp_point_y); + + return result; + } + }; + +BOTAN_REGISTER_TEST("ec_h2c", "ec_h2c_kat", ECC_H2C_Tests); + +#endif + +} + +} diff --git a/src/tests/test_ecc_pointmul.cpp b/src/tests/test_ecc_pointmul.cpp index 28231a16981..ede4a80fab8 100644 --- a/src/tests/test_ecc_pointmul.cpp +++ b/src/tests/test_ecc_pointmul.cpp @@ -6,6 +6,10 @@ #include "tests.h" +#if defined(BOTAN_HAS_ECDSA) + #include +#endif + #if defined(BOTAN_HAS_ECC_GROUP) #include #endif diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp index f9305354f8d..9913872645a 100644 --- a/src/tests/tests.cpp +++ b/src/tests/tests.cpp @@ -1093,7 +1093,7 @@ std::vector Text_Based_Test::run() oss << "Test # " << test_cnt << " "; if(!header.empty()) oss << header << " "; - oss << " failed [Key=" << vars.get_req_str(m_output_key) << "]"; + oss << " failed [" << m_output_key << "=" << vars.get_req_str(m_output_key) << "]"; result.test_note(oss.str()); } @@ -1105,8 +1105,8 @@ std::vector Text_Based_Test::run() oss << "Test # " << test_cnt << " "; if(!header.empty()) oss << header << " "; - oss << " failed with exception '" << e.what() << "'"; - oss << " [Key=" << vars.get_req_str(m_output_key) << "]"; + oss << "[" << m_output_key << "=" << vars.get_req_str(m_output_key) << "]" + << " failed with exception '" << e.what() << "'"; results.push_back(Test::Result::Failure(header_or_name, oss.str())); }