Botan  1.10.9
comb4p.cpp
Go to the documentation of this file.
1 /*
2 * Comb4P hash combiner
3 * (C) 2010 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/comb4p.h>
9 #include <botan/internal/xor_buf.h>
10 #include <stdexcept>
11 
12 namespace Botan {
13 
14 namespace {
15 
16 void comb4p_round(MemoryRegion<byte>& out,
17  const MemoryRegion<byte>& in,
18  byte round_no,
19  HashFunction* h1,
20  HashFunction* h2)
21  {
22  h1->update(round_no);
23  h2->update(round_no);
24 
25  h1->update(&in[0], in.size());
26  h2->update(&in[0], in.size());
27 
28  SecureVector<byte> h_buf = h1->final();
29  xor_buf(&out[0], &h_buf[0], std::min(out.size(), h_buf.size()));
30 
31  h_buf = h2->final();
32  xor_buf(&out[0], &h_buf[0], std::min(out.size(), h_buf.size()));
33  }
34 
35 }
36 
38  hash1(h1), hash2(h2)
39  {
40  if(hash1->name() == hash2->name())
41  throw std::invalid_argument("Comb4P: Must use two distinct hashes");
42 
43  if(hash1->output_length() != hash2->output_length())
44  throw std::invalid_argument("Comb4P: Incompatible hashes " +
45  hash1->name() + " and " +
46  hash2->name());
47 
48  clear();
49  }
50 
52  {
53  if(hash1->hash_block_size() == hash2->hash_block_size())
54  return hash1->hash_block_size();
55 
56  /*
57  * Return LCM of the block sizes? This would probably be OK for
58  * HMAC, which is the main thing relying on knowing the block size.
59  */
60  return 0;
61  }
62 
64  {
65  hash1->clear();
66  hash2->clear();
67 
68  // Prep for processing next message, if any
69  hash1->update(0);
70  hash2->update(0);
71  }
72 
73 void Comb4P::add_data(const byte input[], size_t length)
74  {
75  hash1->update(input, length);
76  hash2->update(input, length);
77  }
78 
79 void Comb4P::final_result(byte out[])
80  {
81  SecureVector<byte> h1 = hash1->final();
82  SecureVector<byte> h2 = hash2->final();
83 
84  // First round
85  xor_buf(&h1[0], &h2[0], std::min(h1.size(), h2.size()));
86 
87  // Second round
88  comb4p_round(h2, h1, 1, hash1, hash2);
89 
90  // Third round
91  comb4p_round(h1, h2, 2, hash1, hash2);
92 
93  copy_mem(out , &h1[0], h1.size());
94  copy_mem(out + h1.size(), &h2[0], h2.size());
95 
96  // Prep for processing next message, if any
97  hash1->update(0);
98  hash2->update(0);
99  }
100 
101 }
102 
void clear()
Definition: comb4p.cpp:63
Comb4P(HashFunction *h1, HashFunction *h2)
Definition: comb4p.cpp:37
virtual void clear()=0
size_t hash_block_size() const
Definition: comb4p.cpp:51
unsigned char byte
Definition: types.h:22
void update(const byte in[], size_t length)
Definition: buf_comp.h:33
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:22
virtual std::string name() const =0
void final(byte out[])
Definition: buf_comp.h:80
virtual size_t hash_block_size() const
Definition: hash.h:32
void xor_buf(byte out[], const byte in[], size_t length)
Definition: xor_buf.h:21
virtual size_t output_length() const =0