Coverage Report

Created: 2025-04-11 06:34

/src/botan/src/fuzzer/ecc_helper.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
* (C) 2015,2016 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6
7
#ifndef ECC_HELPERS_H_
8
#define ECC_HELPERS_H_
9
10
#include "fuzzers.h"
11
12
#include <botan/ec_group.h>
13
#include <botan/hex.h>
14
#include <botan/numthry.h>
15
#include <botan/reducer.h>
16
17
namespace {
18
19
0
inline std::ostream& operator<<(std::ostream& o, const Botan::EC_AffinePoint& point) {
20
0
   o << Botan::hex_encode(point.serialize_uncompressed()) << "\n";
21
0
   return o;
22
0
}
Unexecuted instantiation: ecc_p521.cpp:(anonymous namespace)::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, Botan::EC_AffinePoint const&)
Unexecuted instantiation: ecc_p256.cpp:(anonymous namespace)::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, Botan::EC_AffinePoint const&)
Unexecuted instantiation: ecc_p384.cpp:(anonymous namespace)::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, Botan::EC_AffinePoint const&)
Unexecuted instantiation: ecc_bp256.cpp:(anonymous namespace)::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, Botan::EC_AffinePoint const&)
23
24
inline Botan::BigInt decompress_point(bool yMod2,
25
                                      const Botan::BigInt& x,
26
                                      const Botan::BigInt& curve_p,
27
                                      const Botan::BigInt& curve_a,
28
0
                                      const Botan::BigInt& curve_b) {
29
0
   Botan::BigInt xpow3 = x * x * x;
30
0
31
0
   Botan::BigInt g = curve_a * x;
32
0
   g += xpow3;
33
0
   g += curve_b;
34
0
   g = g % curve_p;
35
0
36
0
   Botan::BigInt z = sqrt_modulo_prime(g, curve_p);
37
0
38
0
   if(z < 0) {
39
0
      throw Botan::Exception("Could not perform square root");
40
0
   }
41
0
42
0
   if(z.get_bit(0) != yMod2) {
43
0
      z = curve_p - z;
44
0
   }
45
0
46
0
   return z;
47
0
}
Unexecuted instantiation: ecc_p521.cpp:(anonymous namespace)::decompress_point(bool, Botan::BigInt const&, Botan::BigInt const&, Botan::BigInt const&, Botan::BigInt const&)
Unexecuted instantiation: ecc_p256.cpp:(anonymous namespace)::decompress_point(bool, Botan::BigInt const&, Botan::BigInt const&, Botan::BigInt const&, Botan::BigInt const&)
Unexecuted instantiation: ecc_p384.cpp:(anonymous namespace)::decompress_point(bool, Botan::BigInt const&, Botan::BigInt const&, Botan::BigInt const&, Botan::BigInt const&)
Unexecuted instantiation: ecc_bp256.cpp:(anonymous namespace)::decompress_point(bool, Botan::BigInt const&, Botan::BigInt const&, Botan::BigInt const&, Botan::BigInt const&)
48
49
183
inline void check_ecc_math(const Botan::EC_Group& group, std::span<const uint8_t> in) {
50
183
   const size_t hlen = in.size() / 2;
51
52
183
   const auto a = Botan::EC_Scalar::from_bytes_mod_order(group, in.subspan(0, hlen));
53
183
   const auto b = Botan::EC_Scalar::from_bytes_mod_order(group, in.subspan(hlen, in.size() - hlen));
54
183
   const auto c = a + b;
55
56
183
   if(a.is_zero() || b.is_zero() || c.is_zero()) {
57
13
      return;
58
13
   }
59
60
170
   auto& rng = fuzzer_rng();
61
170
   std::vector<Botan::BigInt> ws;
62
63
170
   const auto P1 = Botan::EC_AffinePoint::g_mul(a, rng, ws);
64
170
   const auto Q1 = Botan::EC_AffinePoint::g_mul(b, rng, ws);
65
170
   const auto R1 = Botan::EC_AffinePoint::g_mul(c, rng, ws);
66
67
170
   const auto S1 = P1.add(Q1);
68
170
   const auto T1 = Q1.add(P1);
69
70
170
   FUZZER_ASSERT_EQUAL(S1, R1);
71
170
   FUZZER_ASSERT_EQUAL(T1, R1);
72
73
170
   const auto g = Botan::EC_AffinePoint::generator(group);
74
75
170
   const auto P2 = g.mul(a, rng, ws);
76
170
   const auto Q2 = g.mul(b, rng, ws);
77
170
   const auto R2 = g.mul(c, rng, ws);
78
79
170
   const auto S2 = P2.add(Q2);
80
170
   const auto T2 = Q2.add(P2);
81
82
170
   FUZZER_ASSERT_EQUAL(S2, R2);
83
170
   FUZZER_ASSERT_EQUAL(T2, R2);
84
170
}
ecc_p521.cpp:(anonymous namespace)::check_ecc_math(Botan::EC_Group const&, std::__1::span<unsigned char const, 18446744073709551615ul>)
Line
Count
Source
49
48
inline void check_ecc_math(const Botan::EC_Group& group, std::span<const uint8_t> in) {
50
48
   const size_t hlen = in.size() / 2;
51
52
48
   const auto a = Botan::EC_Scalar::from_bytes_mod_order(group, in.subspan(0, hlen));
53
48
   const auto b = Botan::EC_Scalar::from_bytes_mod_order(group, in.subspan(hlen, in.size() - hlen));
54
48
   const auto c = a + b;
55
56
48
   if(a.is_zero() || b.is_zero() || c.is_zero()) {
57
3
      return;
58
3
   }
59
60
45
   auto& rng = fuzzer_rng();
61
45
   std::vector<Botan::BigInt> ws;
62
63
45
   const auto P1 = Botan::EC_AffinePoint::g_mul(a, rng, ws);
64
45
   const auto Q1 = Botan::EC_AffinePoint::g_mul(b, rng, ws);
65
45
   const auto R1 = Botan::EC_AffinePoint::g_mul(c, rng, ws);
66
67
45
   const auto S1 = P1.add(Q1);
68
45
   const auto T1 = Q1.add(P1);
69
70
45
   FUZZER_ASSERT_EQUAL(S1, R1);
71
45
   FUZZER_ASSERT_EQUAL(T1, R1);
72
73
45
   const auto g = Botan::EC_AffinePoint::generator(group);
74
75
45
   const auto P2 = g.mul(a, rng, ws);
76
45
   const auto Q2 = g.mul(b, rng, ws);
77
45
   const auto R2 = g.mul(c, rng, ws);
78
79
45
   const auto S2 = P2.add(Q2);
80
45
   const auto T2 = Q2.add(P2);
81
82
45
   FUZZER_ASSERT_EQUAL(S2, R2);
83
45
   FUZZER_ASSERT_EQUAL(T2, R2);
84
45
}
ecc_p256.cpp:(anonymous namespace)::check_ecc_math(Botan::EC_Group const&, std::__1::span<unsigned char const, 18446744073709551615ul>)
Line
Count
Source
49
40
inline void check_ecc_math(const Botan::EC_Group& group, std::span<const uint8_t> in) {
50
40
   const size_t hlen = in.size() / 2;
51
52
40
   const auto a = Botan::EC_Scalar::from_bytes_mod_order(group, in.subspan(0, hlen));
53
40
   const auto b = Botan::EC_Scalar::from_bytes_mod_order(group, in.subspan(hlen, in.size() - hlen));
54
40
   const auto c = a + b;
55
56
40
   if(a.is_zero() || b.is_zero() || c.is_zero()) {
57
4
      return;
58
4
   }
59
60
36
   auto& rng = fuzzer_rng();
61
36
   std::vector<Botan::BigInt> ws;
62
63
36
   const auto P1 = Botan::EC_AffinePoint::g_mul(a, rng, ws);
64
36
   const auto Q1 = Botan::EC_AffinePoint::g_mul(b, rng, ws);
65
36
   const auto R1 = Botan::EC_AffinePoint::g_mul(c, rng, ws);
66
67
36
   const auto S1 = P1.add(Q1);
68
36
   const auto T1 = Q1.add(P1);
69
70
36
   FUZZER_ASSERT_EQUAL(S1, R1);
71
36
   FUZZER_ASSERT_EQUAL(T1, R1);
72
73
36
   const auto g = Botan::EC_AffinePoint::generator(group);
74
75
36
   const auto P2 = g.mul(a, rng, ws);
76
36
   const auto Q2 = g.mul(b, rng, ws);
77
36
   const auto R2 = g.mul(c, rng, ws);
78
79
36
   const auto S2 = P2.add(Q2);
80
36
   const auto T2 = Q2.add(P2);
81
82
36
   FUZZER_ASSERT_EQUAL(S2, R2);
83
36
   FUZZER_ASSERT_EQUAL(T2, R2);
84
36
}
ecc_p384.cpp:(anonymous namespace)::check_ecc_math(Botan::EC_Group const&, std::__1::span<unsigned char const, 18446744073709551615ul>)
Line
Count
Source
49
44
inline void check_ecc_math(const Botan::EC_Group& group, std::span<const uint8_t> in) {
50
44
   const size_t hlen = in.size() / 2;
51
52
44
   const auto a = Botan::EC_Scalar::from_bytes_mod_order(group, in.subspan(0, hlen));
53
44
   const auto b = Botan::EC_Scalar::from_bytes_mod_order(group, in.subspan(hlen, in.size() - hlen));
54
44
   const auto c = a + b;
55
56
44
   if(a.is_zero() || b.is_zero() || c.is_zero()) {
57
3
      return;
58
3
   }
59
60
41
   auto& rng = fuzzer_rng();
61
41
   std::vector<Botan::BigInt> ws;
62
63
41
   const auto P1 = Botan::EC_AffinePoint::g_mul(a, rng, ws);
64
41
   const auto Q1 = Botan::EC_AffinePoint::g_mul(b, rng, ws);
65
41
   const auto R1 = Botan::EC_AffinePoint::g_mul(c, rng, ws);
66
67
41
   const auto S1 = P1.add(Q1);
68
41
   const auto T1 = Q1.add(P1);
69
70
41
   FUZZER_ASSERT_EQUAL(S1, R1);
71
41
   FUZZER_ASSERT_EQUAL(T1, R1);
72
73
41
   const auto g = Botan::EC_AffinePoint::generator(group);
74
75
41
   const auto P2 = g.mul(a, rng, ws);
76
41
   const auto Q2 = g.mul(b, rng, ws);
77
41
   const auto R2 = g.mul(c, rng, ws);
78
79
41
   const auto S2 = P2.add(Q2);
80
41
   const auto T2 = Q2.add(P2);
81
82
41
   FUZZER_ASSERT_EQUAL(S2, R2);
83
41
   FUZZER_ASSERT_EQUAL(T2, R2);
84
41
}
ecc_bp256.cpp:(anonymous namespace)::check_ecc_math(Botan::EC_Group const&, std::__1::span<unsigned char const, 18446744073709551615ul>)
Line
Count
Source
49
51
inline void check_ecc_math(const Botan::EC_Group& group, std::span<const uint8_t> in) {
50
51
   const size_t hlen = in.size() / 2;
51
52
51
   const auto a = Botan::EC_Scalar::from_bytes_mod_order(group, in.subspan(0, hlen));
53
51
   const auto b = Botan::EC_Scalar::from_bytes_mod_order(group, in.subspan(hlen, in.size() - hlen));
54
51
   const auto c = a + b;
55
56
51
   if(a.is_zero() || b.is_zero() || c.is_zero()) {
57
3
      return;
58
3
   }
59
60
48
   auto& rng = fuzzer_rng();
61
48
   std::vector<Botan::BigInt> ws;
62
63
48
   const auto P1 = Botan::EC_AffinePoint::g_mul(a, rng, ws);
64
48
   const auto Q1 = Botan::EC_AffinePoint::g_mul(b, rng, ws);
65
48
   const auto R1 = Botan::EC_AffinePoint::g_mul(c, rng, ws);
66
67
48
   const auto S1 = P1.add(Q1);
68
48
   const auto T1 = Q1.add(P1);
69
70
48
   FUZZER_ASSERT_EQUAL(S1, R1);
71
48
   FUZZER_ASSERT_EQUAL(T1, R1);
72
73
48
   const auto g = Botan::EC_AffinePoint::generator(group);
74
75
48
   const auto P2 = g.mul(a, rng, ws);
76
48
   const auto Q2 = g.mul(b, rng, ws);
77
48
   const auto R2 = g.mul(c, rng, ws);
78
79
48
   const auto S2 = P2.add(Q2);
80
48
   const auto T2 = Q2.add(P2);
81
82
48
   FUZZER_ASSERT_EQUAL(S2, R2);
83
48
   FUZZER_ASSERT_EQUAL(T2, R2);
84
48
}
85
86
}  // namespace
87
88
#endif