Coverage Report

Created: 2022-05-14 06:06

/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
#include <botan/ec_group.h>
12
#include <botan/reducer.h>
13
#include <botan/numthry.h>
14
15
namespace {
16
17
inline std::ostream& operator<<(std::ostream& o, const Botan::PointGFp& point)
18
0
   {
19
0
   o << point.get_affine_x() << "," << point.get_affine_y();
20
0
   return o;
21
0
   }
Unexecuted instantiation: ecc_bp256.cpp:(anonymous namespace)::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, Botan::PointGFp const&)
Unexecuted instantiation: ecc_p384.cpp:(anonymous namespace)::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, Botan::PointGFp const&)
Unexecuted instantiation: ecc_p521.cpp:(anonymous namespace)::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, Botan::PointGFp const&)
Unexecuted instantiation: ecc_p256.cpp:(anonymous namespace)::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, Botan::PointGFp const&)
22
23
Botan::BigInt decompress_point(bool yMod2,
24
                               const Botan::BigInt& x,
25
                               const Botan::BigInt& curve_p,
26
                               const Botan::BigInt& curve_a,
27
                               const Botan::BigInt& curve_b)
28
5.28k
   {
29
5.28k
   Botan::BigInt xpow3 = x * x * x;
30
31
5.28k
   Botan::BigInt g = curve_a * x;
32
5.28k
   g += xpow3;
33
5.28k
   g += curve_b;
34
5.28k
   g = g % curve_p;
35
36
5.28k
   Botan::BigInt z = ressol(g, curve_p);
37
38
5.28k
   if(z < 0)
39
2.08k
      throw Botan::Exception("Could not perform square root");
40
41
3.20k
   if(z.get_bit(0) != yMod2)
42
1.66k
      z = curve_p - z;
43
44
3.20k
   return z;
45
5.28k
   }
ecc_bp256.cpp:(anonymous namespace)::decompress_point(bool, Botan::BigInt const&, Botan::BigInt const&, Botan::BigInt const&, Botan::BigInt const&)
Line
Count
Source
28
1.29k
   {
29
1.29k
   Botan::BigInt xpow3 = x * x * x;
30
31
1.29k
   Botan::BigInt g = curve_a * x;
32
1.29k
   g += xpow3;
33
1.29k
   g += curve_b;
34
1.29k
   g = g % curve_p;
35
36
1.29k
   Botan::BigInt z = ressol(g, curve_p);
37
38
1.29k
   if(z < 0)
39
579
      throw Botan::Exception("Could not perform square root");
40
41
718
   if(z.get_bit(0) != yMod2)
42
363
      z = curve_p - z;
43
44
718
   return z;
45
1.29k
   }
ecc_p384.cpp:(anonymous namespace)::decompress_point(bool, Botan::BigInt const&, Botan::BigInt const&, Botan::BigInt const&, Botan::BigInt const&)
Line
Count
Source
28
1.35k
   {
29
1.35k
   Botan::BigInt xpow3 = x * x * x;
30
31
1.35k
   Botan::BigInt g = curve_a * x;
32
1.35k
   g += xpow3;
33
1.35k
   g += curve_b;
34
1.35k
   g = g % curve_p;
35
36
1.35k
   Botan::BigInt z = ressol(g, curve_p);
37
38
1.35k
   if(z < 0)
39
524
      throw Botan::Exception("Could not perform square root");
40
41
827
   if(z.get_bit(0) != yMod2)
42
342
      z = curve_p - z;
43
44
827
   return z;
45
1.35k
   }
ecc_p521.cpp:(anonymous namespace)::decompress_point(bool, Botan::BigInt const&, Botan::BigInt const&, Botan::BigInt const&, Botan::BigInt const&)
Line
Count
Source
28
1.30k
   {
29
1.30k
   Botan::BigInt xpow3 = x * x * x;
30
31
1.30k
   Botan::BigInt g = curve_a * x;
32
1.30k
   g += xpow3;
33
1.30k
   g += curve_b;
34
1.30k
   g = g % curve_p;
35
36
1.30k
   Botan::BigInt z = ressol(g, curve_p);
37
38
1.30k
   if(z < 0)
39
462
      throw Botan::Exception("Could not perform square root");
40
41
844
   if(z.get_bit(0) != yMod2)
42
505
      z = curve_p - z;
43
44
844
   return z;
45
1.30k
   }
ecc_p256.cpp:(anonymous namespace)::decompress_point(bool, Botan::BigInt const&, Botan::BigInt const&, Botan::BigInt const&, Botan::BigInt const&)
Line
Count
Source
28
1.33k
   {
29
1.33k
   Botan::BigInt xpow3 = x * x * x;
30
31
1.33k
   Botan::BigInt g = curve_a * x;
32
1.33k
   g += xpow3;
33
1.33k
   g += curve_b;
34
1.33k
   g = g % curve_p;
35
36
1.33k
   Botan::BigInt z = ressol(g, curve_p);
37
38
1.33k
   if(z < 0)
39
520
      throw Botan::Exception("Could not perform square root");
40
41
815
   if(z.get_bit(0) != yMod2)
42
452
      z = curve_p - z;
43
44
815
   return z;
45
1.33k
   }
46
47
void check_ecc_math(const Botan::EC_Group& group,
48
                    const uint8_t in[], size_t len)
49
5.28k
   {
50
   // These depend only on the group, which is also static
51
5.28k
   static const Botan::PointGFp base_point = group.get_base_point();
52
53
   // This is shared across runs to reduce overhead
54
5.28k
   static std::vector<Botan::BigInt> ws(Botan::PointGFp::WORKSPACE_SIZE);
55
56
5.28k
   const size_t hlen = len / 2;
57
5.28k
   const Botan::BigInt a = Botan::BigInt::decode(in, hlen);
58
5.28k
   const Botan::BigInt b = Botan::BigInt::decode(in + hlen, len - hlen);
59
5.28k
   const Botan::BigInt c = a + b;
60
61
5.28k
   const Botan::PointGFp P1 = base_point * a;
62
5.28k
   const Botan::PointGFp Q1 = base_point * b;
63
5.28k
   const Botan::PointGFp R1 = base_point * c;
64
65
5.28k
   const Botan::PointGFp S1 = P1 + Q1;
66
5.28k
   const Botan::PointGFp T1 = Q1 + P1;
67
68
5.28k
   FUZZER_ASSERT_EQUAL(S1, R1);
69
5.28k
   FUZZER_ASSERT_EQUAL(T1, R1);
70
71
5.28k
   const Botan::PointGFp P2 = group.blinded_base_point_multiply(a, fuzzer_rng(), ws);
72
5.28k
   const Botan::PointGFp Q2 = group.blinded_base_point_multiply(b, fuzzer_rng(), ws);
73
5.28k
   const Botan::PointGFp R2 = group.blinded_base_point_multiply(c, fuzzer_rng(), ws);
74
5.28k
   const Botan::PointGFp S2 = P2 + Q2;
75
5.28k
   const Botan::PointGFp T2 = Q2 + P2;
76
77
5.28k
   FUZZER_ASSERT_EQUAL(S2, R2);
78
5.28k
   FUZZER_ASSERT_EQUAL(T2, R2);
79
80
5.28k
   const Botan::PointGFp P3 = group.blinded_var_point_multiply(base_point, a, fuzzer_rng(), ws);
81
5.28k
   const Botan::PointGFp Q3 = group.blinded_var_point_multiply(base_point, b, fuzzer_rng(), ws);
82
5.28k
   const Botan::PointGFp R3 = group.blinded_var_point_multiply(base_point, c, fuzzer_rng(), ws);
83
5.28k
   const Botan::PointGFp S3 = P3 + Q3;
84
5.28k
   const Botan::PointGFp T3 = Q3 + P3;
85
86
5.28k
   FUZZER_ASSERT_EQUAL(S3, R3);
87
5.28k
   FUZZER_ASSERT_EQUAL(T3, R3);
88
89
5.28k
   FUZZER_ASSERT_EQUAL(S1, S2);
90
5.28k
   FUZZER_ASSERT_EQUAL(S1, S3);
91
92
5.28k
   try
93
5.28k
      {
94
5.28k
      const auto yp = decompress_point(true, a, group.get_p(), group.get_a(), group.get_b());
95
5.28k
      const auto pt_p = group.blinded_var_point_multiply(group.point(a, yp), b, fuzzer_rng(), ws);
96
97
5.28k
      const auto yn = -yp;
98
5.28k
      const auto pt_n = group.blinded_var_point_multiply(group.point(a, yn), b, fuzzer_rng(), ws);
99
100
5.28k
      FUZZER_ASSERT_EQUAL(pt_p, -pt_n);
101
5.28k
      }
102
5.28k
   catch(...) {}
103
5.28k
   }
ecc_bp256.cpp:(anonymous namespace)::check_ecc_math(Botan::EC_Group const&, unsigned char const*, unsigned long)
Line
Count
Source
49
1.29k
   {
50
   // These depend only on the group, which is also static
51
1.29k
   static const Botan::PointGFp base_point = group.get_base_point();
52
53
   // This is shared across runs to reduce overhead
54
1.29k
   static std::vector<Botan::BigInt> ws(Botan::PointGFp::WORKSPACE_SIZE);
55
56
1.29k
   const size_t hlen = len / 2;
57
1.29k
   const Botan::BigInt a = Botan::BigInt::decode(in, hlen);
58
1.29k
   const Botan::BigInt b = Botan::BigInt::decode(in + hlen, len - hlen);
59
1.29k
   const Botan::BigInt c = a + b;
60
61
1.29k
   const Botan::PointGFp P1 = base_point * a;
62
1.29k
   const Botan::PointGFp Q1 = base_point * b;
63
1.29k
   const Botan::PointGFp R1 = base_point * c;
64
65
1.29k
   const Botan::PointGFp S1 = P1 + Q1;
66
1.29k
   const Botan::PointGFp T1 = Q1 + P1;
67
68
1.29k
   FUZZER_ASSERT_EQUAL(S1, R1);
69
1.29k
   FUZZER_ASSERT_EQUAL(T1, R1);
70
71
1.29k
   const Botan::PointGFp P2 = group.blinded_base_point_multiply(a, fuzzer_rng(), ws);
72
1.29k
   const Botan::PointGFp Q2 = group.blinded_base_point_multiply(b, fuzzer_rng(), ws);
73
1.29k
   const Botan::PointGFp R2 = group.blinded_base_point_multiply(c, fuzzer_rng(), ws);
74
1.29k
   const Botan::PointGFp S2 = P2 + Q2;
75
1.29k
   const Botan::PointGFp T2 = Q2 + P2;
76
77
1.29k
   FUZZER_ASSERT_EQUAL(S2, R2);
78
1.29k
   FUZZER_ASSERT_EQUAL(T2, R2);
79
80
1.29k
   const Botan::PointGFp P3 = group.blinded_var_point_multiply(base_point, a, fuzzer_rng(), ws);
81
1.29k
   const Botan::PointGFp Q3 = group.blinded_var_point_multiply(base_point, b, fuzzer_rng(), ws);
82
1.29k
   const Botan::PointGFp R3 = group.blinded_var_point_multiply(base_point, c, fuzzer_rng(), ws);
83
1.29k
   const Botan::PointGFp S3 = P3 + Q3;
84
1.29k
   const Botan::PointGFp T3 = Q3 + P3;
85
86
1.29k
   FUZZER_ASSERT_EQUAL(S3, R3);
87
1.29k
   FUZZER_ASSERT_EQUAL(T3, R3);
88
89
1.29k
   FUZZER_ASSERT_EQUAL(S1, S2);
90
1.29k
   FUZZER_ASSERT_EQUAL(S1, S3);
91
92
1.29k
   try
93
1.29k
      {
94
1.29k
      const auto yp = decompress_point(true, a, group.get_p(), group.get_a(), group.get_b());
95
1.29k
      const auto pt_p = group.blinded_var_point_multiply(group.point(a, yp), b, fuzzer_rng(), ws);
96
97
1.29k
      const auto yn = -yp;
98
1.29k
      const auto pt_n = group.blinded_var_point_multiply(group.point(a, yn), b, fuzzer_rng(), ws);
99
100
1.29k
      FUZZER_ASSERT_EQUAL(pt_p, -pt_n);
101
1.29k
      }
102
1.29k
   catch(...) {}
103
1.29k
   }
ecc_p384.cpp:(anonymous namespace)::check_ecc_math(Botan::EC_Group const&, unsigned char const*, unsigned long)
Line
Count
Source
49
1.35k
   {
50
   // These depend only on the group, which is also static
51
1.35k
   static const Botan::PointGFp base_point = group.get_base_point();
52
53
   // This is shared across runs to reduce overhead
54
1.35k
   static std::vector<Botan::BigInt> ws(Botan::PointGFp::WORKSPACE_SIZE);
55
56
1.35k
   const size_t hlen = len / 2;
57
1.35k
   const Botan::BigInt a = Botan::BigInt::decode(in, hlen);
58
1.35k
   const Botan::BigInt b = Botan::BigInt::decode(in + hlen, len - hlen);
59
1.35k
   const Botan::BigInt c = a + b;
60
61
1.35k
   const Botan::PointGFp P1 = base_point * a;
62
1.35k
   const Botan::PointGFp Q1 = base_point * b;
63
1.35k
   const Botan::PointGFp R1 = base_point * c;
64
65
1.35k
   const Botan::PointGFp S1 = P1 + Q1;
66
1.35k
   const Botan::PointGFp T1 = Q1 + P1;
67
68
1.35k
   FUZZER_ASSERT_EQUAL(S1, R1);
69
1.35k
   FUZZER_ASSERT_EQUAL(T1, R1);
70
71
1.35k
   const Botan::PointGFp P2 = group.blinded_base_point_multiply(a, fuzzer_rng(), ws);
72
1.35k
   const Botan::PointGFp Q2 = group.blinded_base_point_multiply(b, fuzzer_rng(), ws);
73
1.35k
   const Botan::PointGFp R2 = group.blinded_base_point_multiply(c, fuzzer_rng(), ws);
74
1.35k
   const Botan::PointGFp S2 = P2 + Q2;
75
1.35k
   const Botan::PointGFp T2 = Q2 + P2;
76
77
1.35k
   FUZZER_ASSERT_EQUAL(S2, R2);
78
1.35k
   FUZZER_ASSERT_EQUAL(T2, R2);
79
80
1.35k
   const Botan::PointGFp P3 = group.blinded_var_point_multiply(base_point, a, fuzzer_rng(), ws);
81
1.35k
   const Botan::PointGFp Q3 = group.blinded_var_point_multiply(base_point, b, fuzzer_rng(), ws);
82
1.35k
   const Botan::PointGFp R3 = group.blinded_var_point_multiply(base_point, c, fuzzer_rng(), ws);
83
1.35k
   const Botan::PointGFp S3 = P3 + Q3;
84
1.35k
   const Botan::PointGFp T3 = Q3 + P3;
85
86
1.35k
   FUZZER_ASSERT_EQUAL(S3, R3);
87
1.35k
   FUZZER_ASSERT_EQUAL(T3, R3);
88
89
1.35k
   FUZZER_ASSERT_EQUAL(S1, S2);
90
1.35k
   FUZZER_ASSERT_EQUAL(S1, S3);
91
92
1.35k
   try
93
1.35k
      {
94
1.35k
      const auto yp = decompress_point(true, a, group.get_p(), group.get_a(), group.get_b());
95
1.35k
      const auto pt_p = group.blinded_var_point_multiply(group.point(a, yp), b, fuzzer_rng(), ws);
96
97
1.35k
      const auto yn = -yp;
98
1.35k
      const auto pt_n = group.blinded_var_point_multiply(group.point(a, yn), b, fuzzer_rng(), ws);
99
100
1.35k
      FUZZER_ASSERT_EQUAL(pt_p, -pt_n);
101
1.35k
      }
102
1.35k
   catch(...) {}
103
1.35k
   }
ecc_p521.cpp:(anonymous namespace)::check_ecc_math(Botan::EC_Group const&, unsigned char const*, unsigned long)
Line
Count
Source
49
1.30k
   {
50
   // These depend only on the group, which is also static
51
1.30k
   static const Botan::PointGFp base_point = group.get_base_point();
52
53
   // This is shared across runs to reduce overhead
54
1.30k
   static std::vector<Botan::BigInt> ws(Botan::PointGFp::WORKSPACE_SIZE);
55
56
1.30k
   const size_t hlen = len / 2;
57
1.30k
   const Botan::BigInt a = Botan::BigInt::decode(in, hlen);
58
1.30k
   const Botan::BigInt b = Botan::BigInt::decode(in + hlen, len - hlen);
59
1.30k
   const Botan::BigInt c = a + b;
60
61
1.30k
   const Botan::PointGFp P1 = base_point * a;
62
1.30k
   const Botan::PointGFp Q1 = base_point * b;
63
1.30k
   const Botan::PointGFp R1 = base_point * c;
64
65
1.30k
   const Botan::PointGFp S1 = P1 + Q1;
66
1.30k
   const Botan::PointGFp T1 = Q1 + P1;
67
68
1.30k
   FUZZER_ASSERT_EQUAL(S1, R1);
69
1.30k
   FUZZER_ASSERT_EQUAL(T1, R1);
70
71
1.30k
   const Botan::PointGFp P2 = group.blinded_base_point_multiply(a, fuzzer_rng(), ws);
72
1.30k
   const Botan::PointGFp Q2 = group.blinded_base_point_multiply(b, fuzzer_rng(), ws);
73
1.30k
   const Botan::PointGFp R2 = group.blinded_base_point_multiply(c, fuzzer_rng(), ws);
74
1.30k
   const Botan::PointGFp S2 = P2 + Q2;
75
1.30k
   const Botan::PointGFp T2 = Q2 + P2;
76
77
1.30k
   FUZZER_ASSERT_EQUAL(S2, R2);
78
1.30k
   FUZZER_ASSERT_EQUAL(T2, R2);
79
80
1.30k
   const Botan::PointGFp P3 = group.blinded_var_point_multiply(base_point, a, fuzzer_rng(), ws);
81
1.30k
   const Botan::PointGFp Q3 = group.blinded_var_point_multiply(base_point, b, fuzzer_rng(), ws);
82
1.30k
   const Botan::PointGFp R3 = group.blinded_var_point_multiply(base_point, c, fuzzer_rng(), ws);
83
1.30k
   const Botan::PointGFp S3 = P3 + Q3;
84
1.30k
   const Botan::PointGFp T3 = Q3 + P3;
85
86
1.30k
   FUZZER_ASSERT_EQUAL(S3, R3);
87
1.30k
   FUZZER_ASSERT_EQUAL(T3, R3);
88
89
1.30k
   FUZZER_ASSERT_EQUAL(S1, S2);
90
1.30k
   FUZZER_ASSERT_EQUAL(S1, S3);
91
92
1.30k
   try
93
1.30k
      {
94
1.30k
      const auto yp = decompress_point(true, a, group.get_p(), group.get_a(), group.get_b());
95
1.30k
      const auto pt_p = group.blinded_var_point_multiply(group.point(a, yp), b, fuzzer_rng(), ws);
96
97
1.30k
      const auto yn = -yp;
98
1.30k
      const auto pt_n = group.blinded_var_point_multiply(group.point(a, yn), b, fuzzer_rng(), ws);
99
100
1.30k
      FUZZER_ASSERT_EQUAL(pt_p, -pt_n);
101
1.30k
      }
102
1.30k
   catch(...) {}
103
1.30k
   }
ecc_p256.cpp:(anonymous namespace)::check_ecc_math(Botan::EC_Group const&, unsigned char const*, unsigned long)
Line
Count
Source
49
1.33k
   {
50
   // These depend only on the group, which is also static
51
1.33k
   static const Botan::PointGFp base_point = group.get_base_point();
52
53
   // This is shared across runs to reduce overhead
54
1.33k
   static std::vector<Botan::BigInt> ws(Botan::PointGFp::WORKSPACE_SIZE);
55
56
1.33k
   const size_t hlen = len / 2;
57
1.33k
   const Botan::BigInt a = Botan::BigInt::decode(in, hlen);
58
1.33k
   const Botan::BigInt b = Botan::BigInt::decode(in + hlen, len - hlen);
59
1.33k
   const Botan::BigInt c = a + b;
60
61
1.33k
   const Botan::PointGFp P1 = base_point * a;
62
1.33k
   const Botan::PointGFp Q1 = base_point * b;
63
1.33k
   const Botan::PointGFp R1 = base_point * c;
64
65
1.33k
   const Botan::PointGFp S1 = P1 + Q1;
66
1.33k
   const Botan::PointGFp T1 = Q1 + P1;
67
68
1.33k
   FUZZER_ASSERT_EQUAL(S1, R1);
69
1.33k
   FUZZER_ASSERT_EQUAL(T1, R1);
70
71
1.33k
   const Botan::PointGFp P2 = group.blinded_base_point_multiply(a, fuzzer_rng(), ws);
72
1.33k
   const Botan::PointGFp Q2 = group.blinded_base_point_multiply(b, fuzzer_rng(), ws);
73
1.33k
   const Botan::PointGFp R2 = group.blinded_base_point_multiply(c, fuzzer_rng(), ws);
74
1.33k
   const Botan::PointGFp S2 = P2 + Q2;
75
1.33k
   const Botan::PointGFp T2 = Q2 + P2;
76
77
1.33k
   FUZZER_ASSERT_EQUAL(S2, R2);
78
1.33k
   FUZZER_ASSERT_EQUAL(T2, R2);
79
80
1.33k
   const Botan::PointGFp P3 = group.blinded_var_point_multiply(base_point, a, fuzzer_rng(), ws);
81
1.33k
   const Botan::PointGFp Q3 = group.blinded_var_point_multiply(base_point, b, fuzzer_rng(), ws);
82
1.33k
   const Botan::PointGFp R3 = group.blinded_var_point_multiply(base_point, c, fuzzer_rng(), ws);
83
1.33k
   const Botan::PointGFp S3 = P3 + Q3;
84
1.33k
   const Botan::PointGFp T3 = Q3 + P3;
85
86
1.33k
   FUZZER_ASSERT_EQUAL(S3, R3);
87
1.33k
   FUZZER_ASSERT_EQUAL(T3, R3);
88
89
1.33k
   FUZZER_ASSERT_EQUAL(S1, S2);
90
1.33k
   FUZZER_ASSERT_EQUAL(S1, S3);
91
92
1.33k
   try
93
1.33k
      {
94
1.33k
      const auto yp = decompress_point(true, a, group.get_p(), group.get_a(), group.get_b());
95
1.33k
      const auto pt_p = group.blinded_var_point_multiply(group.point(a, yp), b, fuzzer_rng(), ws);
96
97
1.33k
      const auto yn = -yp;
98
1.33k
      const auto pt_n = group.blinded_var_point_multiply(group.point(a, yn), b, fuzzer_rng(), ws);
99
100
1.33k
      FUZZER_ASSERT_EQUAL(pt_p, -pt_n);
101
1.33k
      }
102
1.33k
   catch(...) {}
103
1.33k
   }
104
105
}
106
107
#endif