Botan  1.11.31
emsa1.cpp
Go to the documentation of this file.
1 /*
2 * EMSA1
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/emsa1.h>
9 
10 namespace Botan {
11 
12 namespace {
13 
14 secure_vector<byte> emsa1_encoding(const secure_vector<byte>& msg,
15  size_t output_bits)
16  {
17  if(8*msg.size() <= output_bits)
18  return msg;
19 
20  size_t shift = 8*msg.size() - output_bits;
21 
22  size_t byte_shift = shift / 8, bit_shift = shift % 8;
23  secure_vector<byte> digest(msg.size() - byte_shift);
24 
25  for(size_t j = 0; j != msg.size() - byte_shift; ++j)
26  digest[j] = msg[j];
27 
28  if(bit_shift)
29  {
30  byte carry = 0;
31  for(size_t j = 0; j != digest.size(); ++j)
32  {
33  byte temp = digest[j];
34  digest[j] = (temp >> bit_shift) | carry;
35  carry = (temp << (8 - bit_shift));
36  }
37  }
38  return digest;
39  }
40 
41 }
42 
44  {
45  return new EMSA1(m_hash->clone());
46  }
47 
48 void EMSA1::update(const byte input[], size_t length)
49  {
50  m_hash->update(input, length);
51  }
52 
53 secure_vector<byte> EMSA1::raw_data()
54  {
55  return m_hash->final();
56  }
57 
58 secure_vector<byte> EMSA1::encoding_of(const secure_vector<byte>& msg,
59  size_t output_bits,
61  {
62  if(msg.size() != hash_output_length())
63  throw Encoding_Error("EMSA1::encoding_of: Invalid size for input");
64  return emsa1_encoding(msg, output_bits);
65  }
66 
67 bool EMSA1::verify(const secure_vector<byte>& coded,
68  const secure_vector<byte>& raw, size_t key_bits)
69  {
70  try {
71  if(raw.size() != m_hash->output_length())
72  throw Encoding_Error("EMSA1::encoding_of: Invalid size for input");
73 
74  secure_vector<byte> our_coding = emsa1_encoding(raw, key_bits);
75 
76  if(our_coding == coded) return true;
77  if(our_coding.empty() || our_coding[0] != 0) return false;
78  if(our_coding.size() <= coded.size()) return false;
79 
80  size_t offset = 0;
81  while(offset < our_coding.size() && our_coding[offset] == 0)
82  ++offset;
83  if(our_coding.size() - offset != coded.size())
84  return false;
85 
86  for(size_t j = 0; j != coded.size(); ++j)
87  if(coded[j] != our_coding[j+offset])
88  return false;
89 
90  return true;
91  }
92  catch(Invalid_Argument)
93  {
94  return false;
95  }
96  }
97 
98 }
EMSA1(HashFunction *hash)
Definition: emsa1.h:26
size_t hash_output_length() const
Definition: emsa1.h:31
std::unique_ptr< HashFunction > m_hash
Definition: emsa1.h:33
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:101
Definition: alg_id.cpp:13
EMSA * clone() override
Definition: emsa1.cpp:43
std::uint8_t byte
Definition: types.h:31