• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 15957064514

29 Jun 2025 04:12PM UTC coverage: 90.557% (-0.003%) from 90.56%
15957064514

push

github

web-flow
Merge pull request #4950 from randombit/jack/ec-scalar-hash

Add EC_Scalar::hash using RFC 9380's hash_to_field

98822 of 109127 relevant lines covered (90.56%)

12380796.15 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.52
/src/tests/test_ecc_h2c.cpp
1
/*
2
* (C) 2019,2020 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6

7
#include "tests.h"
8

9
#if defined(BOTAN_HAS_ECC_GROUP)
10
   #include <botan/ec_group.h>
11
#endif
12

13
#if defined(BOTAN_HAS_XMD)
14
   #include <botan/internal/xmd.h>
15
#endif
16

17
namespace Botan_Tests {
18

19
namespace {
20

21
#if defined(BOTAN_HAS_XMD)
22

23
class ECC_H2C_XMD_Tests final : public Text_Based_Test {
×
24
   public:
25
      ECC_H2C_XMD_Tests() : Text_Based_Test("pubkey/ec_h2c_xmd.vec", "Domain,Input,Output") {}
2✔
26

27
      bool clear_between_callbacks() const override { return false; }
20✔
28

29
      Test::Result run_one_test(const std::string& hash, const VarMap& vars) override {
20✔
30
         Test::Result result("ECC hash to curve XMD " + hash);
20✔
31

32
         const std::string domain = vars.get_req_str("Domain");
20✔
33
         const std::string input = vars.get_req_str("Input");
20✔
34
         const std::vector<uint8_t> expected = vars.get_req_bin("Output");
20✔
35

36
         std::vector<uint8_t> output(expected.size());
20✔
37
         Botan::expand_message_xmd(hash, output, input, domain);
20✔
38

39
         result.test_eq("XMD output", output, expected);
40✔
40
         return result;
20✔
41
      }
40✔
42
};
43

44
BOTAN_REGISTER_TEST("ec_h2c", "ec_h2c_xmd", ECC_H2C_XMD_Tests);
45

46
#endif
47

48
#if defined(BOTAN_HAS_XMD) && defined(BOTAN_HAS_ECC_GROUP)
49

50
class ECC_H2S_Tests final : public Text_Based_Test {
×
51
   public:
52
      ECC_H2S_Tests() : Text_Based_Test("pubkey/ec_h2s.vec", "Hash,Domain,Input,Output") {}
2✔
53

54
      bool clear_between_callbacks() const override { return false; }
18✔
55

56
      bool skip_this_test(const std::string& group_id, const VarMap&) override {
18✔
57
         return !Botan::EC_Group::supports_named_group(group_id);
18✔
58
      }
59

60
      Test::Result run_one_test(const std::string& group_id, const VarMap& vars) override {
18✔
61
         Test::Result result("ECC hash to scalar " + group_id);
18✔
62

63
         const std::string hash_fn = vars.get_req_str("Hash");
18✔
64
         const std::string domain_str = vars.get_req_str("Domain");
18✔
65
         const std::string input_str = vars.get_req_str("Input");
18✔
66
         const std::vector<uint8_t> expected_value = vars.get_req_bin("Output");
18✔
67

68
         auto input = std::span{reinterpret_cast<const uint8_t*>(input_str.data()), input_str.size()};
18✔
69
         auto domain = std::span{reinterpret_cast<const uint8_t*>(domain_str.data()), domain_str.size()};
18✔
70

71
         const auto group = Botan::EC_Group::from_name(group_id);
18✔
72

73
         try {
18✔
74
            auto scalar = Botan::EC_Scalar::hash(group, hash_fn, input, domain).serialize();
18✔
75
            result.test_eq("output", scalar, expected_value);
36✔
76
         } catch(Botan::Not_Implemented&) {
18✔
77
            result.test_note("Skipping due to not implemented");
×
78
         }
×
79

80
         return result;
36✔
81
      }
36✔
82
};
83

84
BOTAN_REGISTER_TEST("ec_h2c", "ec_h2s_kat", ECC_H2S_Tests);
85

86
#endif
87

88
#if defined(BOTAN_HAS_EC_HASH_TO_CURVE)
89

90
class ECC_H2C_Tests final : public Text_Based_Test {
×
91
   public:
92
      ECC_H2C_Tests() : Text_Based_Test("pubkey/ec_h2c.vec", "Group,Hash,Domain,Input,Point") {}
2✔
93

94
      bool clear_between_callbacks() const override { return false; }
43✔
95

96
      bool skip_this_test(const std::string&, const VarMap& vars) override {
43✔
97
         return !Botan::EC_Group::supports_named_group(vars.get_req_str("Group"));
43✔
98
      }
99

100
      Test::Result run_one_test(const std::string& method, const VarMap& vars) override {
43✔
101
         const std::string group_id = vars.get_req_str("Group");
43✔
102

103
         Test::Result result("ECC hash to curve " + method + " " + group_id);
129✔
104

105
         const std::string hash_fn = vars.get_req_str("Hash");
43✔
106
         const std::string domain_str = vars.get_req_str("Domain");
43✔
107
         const std::vector<uint8_t> input = vars.get_req_bin("Input");
43✔
108
         const std::vector<uint8_t> expected_point = vars.get_req_bin("Point");
43✔
109
         const bool random_oracle = method.find("-RO") != std::string::npos;
43✔
110

111
         auto domain = std::span{reinterpret_cast<const uint8_t*>(domain_str.data()), domain_str.size()};
43✔
112

113
         const auto group = Botan::EC_Group::from_name(group_id);
43✔
114

115
         try {
43✔
116
            std::vector<uint8_t> pt;
43✔
117
            if(random_oracle) {
43✔
118
               pt = Botan::EC_AffinePoint::hash_to_curve_ro(group, hash_fn, input, domain).serialize_uncompressed();
40✔
119
            } else {
120
               pt = Botan::EC_AffinePoint::hash_to_curve_nu(group, hash_fn, input, domain).serialize_uncompressed();
46✔
121
            }
122

123
            result.test_eq("Generated point serialization", pt, expected_point);
86✔
124
         } catch(Botan::Not_Implemented&) {
43✔
125
            result.test_note("Skipping due to not implemented");
×
126
         }
×
127

128
         return result;
86✔
129
      }
129✔
130
};
131

132
BOTAN_REGISTER_TEST("ec_h2c", "ec_h2c_kat", ECC_H2C_Tests);
133

134
#endif
135

136
}  // namespace
137

138
}  // namespace Botan_Tests
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc