Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

skein_512.cpp
Go to the documentation of this file.
1 /*
2 * The Skein-512 hash function
3 * (C) 2009,2010,2014 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7
8 #include <botan/skein_512.h>
9 #include <botan/parsing.h>
10 #include <botan/exceptn.h>
11 #include <algorithm>
12
13 namespace Botan {
14
15 Skein_512::Skein_512(size_t arg_output_bits,
16 const std::string& arg_personalization) :
17 m_personalization(arg_personalization),
18 m_output_bits(arg_output_bits),
19 m_threefish(new Threefish_512),
20 m_T(2), m_buffer(64), m_buf_pos(0)
21 {
22 if(m_output_bits == 0 || m_output_bits % 8 != 0 || m_output_bits > 512)
23 throw Invalid_Argument("Bad output bits size for Skein-512");
24
25 initial_block();
26 }
27
28 std::string Skein_512::name() const
29 {
30 if(m_personalization != "")
31 return "Skein-512(" + std::to_string(m_output_bits) + "," +
32 m_personalization + ")";
33 return "Skein-512(" + std::to_string(m_output_bits) + ")";
34 }
35
36 HashFunction* Skein_512::clone() const
37 {
38 return new Skein_512(m_output_bits, m_personalization);
39 }
40
41 void Skein_512::clear()
42 {
43 zeroise(m_buffer);
44 m_buf_pos = 0;
45
46 initial_block();
47 }
48
49 void Skein_512::reset_tweak(type_code type, bool is_final)
50 {
51 m_T[0] = 0;
52
53 m_T[1] = (static_cast<uint64_t>(type) << 56) |
54 (static_cast<uint64_t>(1) << 62) |
55 (static_cast<uint64_t>(is_final) << 63);
56 }
57
58 void Skein_512::initial_block()
59 {
60 const uint8_t zeros[64] = { 0 };
61
62 m_threefish->set_key(zeros, sizeof(zeros));
63
64 // ASCII("SHA3") followed by version (0x0001) code
65 uint8_t config_str[32] = { 0x53, 0x48, 0x41, 0x33, 0x01, 0x00, 0 };
66 store_le(uint32_t(m_output_bits), config_str + 8);
67
68 reset_tweak(SKEIN_CONFIG, true);
69 ubi_512(config_str, sizeof(config_str));
70
71 if(m_personalization != "")
72 {
73 /*
74 This is a limitation of this implementation, and not of the
75 algorithm specification. Could be fixed relatively easily, but
76 doesn't seem worth the trouble.
77 */
78 if(m_personalization.length() > 64)
79 throw Invalid_Argument("Skein personalization must be less than 64 bytes");
80
81 const uint8_t* bits = reinterpret_cast<const uint8_t*>(m_personalization.data());
82 reset_tweak(SKEIN_PERSONALIZATION, true);
83 ubi_512(bits, m_personalization.length());
84 }
85
86 reset_tweak(SKEIN_MSG, false);
87 }
88
89 void Skein_512::ubi_512(const uint8_t msg[], size_t msg_len)
90 {
91 secure_vector<uint64_t> M(8);
92
93 do
94 {
95 const size_t to_proc = std::min<size_t>(msg_len, 64);
96 m_T[0] += to_proc;
97
98 load_le(M.data(), msg, to_proc / 8);
99
100 if(to_proc % 8)
101 {
102 for(size_t j = 0; j != to_proc % 8; ++j)
103 M[to_proc/8] |= static_cast<uint64_t>(msg[8*(to_proc/8)+j]) << (8*j);
104 }
105
106 m_threefish->skein_feedfwd(M, m_T);
107
108 // clear first flag if set
109 m_T[1] &= ~(static_cast<uint64_t>(1) << 62);
110
111 msg_len -= to_proc;
112 msg += to_proc;
113 } while(msg_len);
114 }
115
116 void Skein_512::add_data(const uint8_t input[], size_t length)
117 {
118 if(length == 0)
119 return;
120
121 if(m_buf_pos)
122 {
123 buffer_insert(m_buffer, m_buf_pos, input, length);
124 if(m_buf_pos + length > 64)
125 {
126 ubi_512(m_buffer.data(), m_buffer.size());
127
128 input += (64 - m_buf_pos);
129 length -= (64 - m_buf_pos);
130 m_buf_pos = 0;
131 }
132 }
133
134 const size_t full_blocks = (length - 1) / 64;
135
136 if(full_blocks)
137 ubi_512(input, 64*full_blocks);
138
139 length -= full_blocks * 64;
140
141 buffer_insert(m_buffer, m_buf_pos, input + full_blocks * 64, length);
142 m_buf_pos += length;
143 }
144
145 void Skein_512::final_result(uint8_t out[])
146 {
147 m_T[1] |= (static_cast<uint64_t>(1) << 63); // final block flag
148
149 for(size_t i = m_buf_pos; i != m_buffer.size(); ++i)
150 m_buffer[i] = 0;
151
152 ubi_512(m_buffer.data(), m_buf_pos);
153
154 const uint8_t counter[8] = { 0 };
155
156 reset_tweak(SKEIN_OUTPUT, true);
157 ubi_512(counter, sizeof(counter));
158
159 copy_out_vec_le(out, m_output_bits / 8, m_threefish->m_K);
160
161 m_buf_pos = 0;
162 initial_block();
163 }
164
165 }
Botan::Invalid_Argument
Definition: exceptn.h:34
Botan::Skein_512::clear
void clear() override
Definition: skein_512.cpp:41
Botan::ASN1::to_string
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:47
type
MechanismType type
Definition: p11_mechanism.cpp:43
Botan::Threefish_512
Definition: threefish.h:18
Botan::load_le
T load_le(const uint8_t in[], size_t off)
Definition: loadstor.h:129
Botan
Definition: alg_id.cpp:13
Botan::Skein_512::Skein_512
Skein_512(size_t output_bits=512, const std::string &personalization="")
Definition: skein_512.cpp:15
Botan::HashFunction
Definition: hash.h:19
Botan::buffer_insert
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition: secmem.h:133
Botan::Skein_512::clone
HashFunction * clone() const override
Definition: skein_512.cpp:36
Botan::store_le
void store_le(uint16_t in, uint8_t out[2])
Definition: loadstor.h:457
Botan::zeroise
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:211
Botan::copy_out_vec_le
void copy_out_vec_le(uint8_t out[], size_t out_bytes, const std::vector< T, Alloc > &in)
Definition: loadstor.h:697
Botan::Skein_512::name
std::string name() const override
Definition: skein_512.cpp:28