Coverage Report

Created: 2021-06-10 10:30

/src/botan/src/lib/pubkey/xmss/xmss_wots_parameters.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * XMSS WOTS Parameters
3
 * Descibes a signature method for XMSS Winternitz One Time Signatures,
4
 * as defined in:
5
 * [1] XMSS: Extended Hash-Based Signatures,
6
 *     Request for Comments: 8391
7
 *     Release: May 2018.
8
 *     https://datatracker.ietf.org/doc/rfc8391/
9
 *
10
 * (C) 2016,2017,2018 Matthias Gierlings
11
 *
12
 * Botan is released under the Simplified BSD License (see license.txt)
13
 **/
14
15
#include <botan/xmss_wots.h>
16
#include <botan/internal/xmss_tools.h>
17
#include <botan/exceptn.h>
18
#include <cmath>
19
20
namespace Botan {
21
22
XMSS_WOTS_Parameters::ots_algorithm_t
23
XMSS_WOTS_Parameters::xmss_wots_id_from_string(const std::string& param_set)
24
0
   {
25
0
   if(param_set == "WOTSP-SHA2_256")
26
0
      { return WOTSP_SHA2_256; }
27
0
   if(param_set == "WOTSP-SHA2_512")
28
0
      { return WOTSP_SHA2_512; }
29
0
   if(param_set == "WOTSP-SHAKE_256")
30
0
      { return WOTSP_SHAKE_256; }
31
0
   if(param_set == "WOTSP-SHAKE_512")
32
0
      { return WOTSP_SHAKE_512; }
33
0
   throw Invalid_Argument("Unknown XMSS-WOTS algorithm param '" + param_set + "'");
34
0
   }
35
36
XMSS_WOTS_Parameters::XMSS_WOTS_Parameters(const std::string& param_set)
37
   : XMSS_WOTS_Parameters(xmss_wots_id_from_string(param_set))
38
0
   {}
39
40
XMSS_WOTS_Parameters::XMSS_WOTS_Parameters(ots_algorithm_t oid)
41
   : m_oid(oid)
42
0
   {
43
0
   switch(oid)
44
0
      {
45
0
      case WOTSP_SHA2_256:
46
0
         m_element_size = 32;
47
0
         m_w = 16;
48
0
         m_len = 67;
49
0
         m_name = "WOTSP-SHA2_256";
50
0
         m_hash_name = "SHA-256";
51
0
         m_strength = 256;
52
0
         break;
53
0
      case WOTSP_SHA2_512:
54
0
         m_element_size = 64;
55
0
         m_w = 16;
56
0
         m_len = 131;
57
0
         m_name = "WOTSP-SHA2_512";
58
0
         m_hash_name = "SHA-512";
59
0
         m_strength = 512;
60
0
         break;
61
0
      case WOTSP_SHAKE_256:
62
0
         m_element_size = 32;
63
0
         m_w = 16;
64
0
         m_len = 67;
65
0
         m_name = "WOTSP-SHAKE_256";
66
0
         m_hash_name = "SHAKE-128(256)";
67
0
         m_strength = 256;
68
0
         break;
69
0
      case WOTSP_SHAKE_512:
70
0
         m_element_size = 64;
71
0
         m_w = 16;
72
0
         m_len = 131;
73
0
         m_name = "WOTSP-SHAKE_512";
74
0
         m_hash_name = "SHAKE-256(512)";
75
0
         m_strength = 512;
76
0
         break;
77
0
      default:
78
0
         throw Not_Implemented("Algorithm id does not match any known XMSS WOTS algorithm id.");
79
0
         break;
80
0
      }
81
82
0
   m_lg_w = (m_w == 16) ? 4 : 2;
83
0
   m_len_1 = static_cast<size_t>(std::ceil((8 * element_size()) / m_lg_w));
84
0
   m_len_2 = static_cast<size_t>(
85
0
                floor(log2(m_len_1 * (wots_parameter() - 1)) / m_lg_w) + 1);
86
0
   BOTAN_ASSERT(m_len == m_len_1 + m_len_2, "Invalid XMSS WOTS parameter "
87
0
                "\"len\" detedted.");
88
0
   }
89
90
secure_vector<uint8_t>
91
XMSS_WOTS_Parameters::base_w(const secure_vector<uint8_t>& msg, size_t out_size) const
92
0
   {
93
0
   secure_vector<uint8_t> result;
94
0
   size_t in = 0;
95
0
   size_t total = 0;
96
0
   size_t bits = 0;
97
98
0
   for(size_t i = 0; i < out_size; i++)
99
0
      {
100
0
      if(bits == 0)
101
0
         {
102
0
         total = msg[in];
103
0
         in++;
104
0
         bits += 8;
105
0
         }
106
0
      bits -= m_lg_w;
107
0
      result.push_back(static_cast<uint8_t>((total >> bits) & (m_w - 1)));
108
0
      }
109
0
   return result;
110
0
   }
111
112
secure_vector<uint8_t>
113
XMSS_WOTS_Parameters::base_w(size_t value) const
114
0
   {
115
0
   value <<= (8 - ((m_len_2 * m_lg_w) % 8));
116
0
   size_t len_2_bytes = static_cast<size_t>(
117
0
                           std::ceil(static_cast<float>(m_len_2 * m_lg_w) / 8.f));
118
0
   secure_vector<uint8_t> result;
119
0
   XMSS_Tools::concat(result, value, len_2_bytes);
120
0
   return base_w(result, m_len_2);
121
0
   }
122
123
void
124
XMSS_WOTS_Parameters::append_checksum(secure_vector<uint8_t>& data)
125
0
   {
126
0
   size_t csum = 0;
127
128
0
   for(size_t i = 0; i < data.size(); i++)
129
0
      {
130
0
      csum += wots_parameter() - 1 - data[i];
131
0
      }
132
133
0
   secure_vector<uint8_t> csum_bytes = base_w(csum);
134
0
   std::move(csum_bytes.begin(), csum_bytes.end(), std::back_inserter(data));
135
0
   }
136
137
}