~ubuntu-branches/debian/sid/botan/sid

« back to all changes in this revision

Viewing changes to src/lib/hash/comb4p/comb4p.cpp

  • Committer: Package Import Robot
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2018-03-01 22:23:25 UTC
  • mfrom: (1.2.2)
  • Revision ID: package-import@ubuntu.com-20180301222325-7p7vc45gu3hta34d
Tags: 2.4.0-2
* Don't remove .doctrees from the manual if it doesn't exist.
* Don't specify parallel to debhelper.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
* Comb4P hash combiner
 
3
* (C) 2010 Jack Lloyd
 
4
*
 
5
* Botan is released under the Simplified BSD License (see license.txt)
 
6
*/
 
7
 
 
8
#include <botan/comb4p.h>
 
9
#include <botan/exceptn.h>
 
10
 
 
11
namespace Botan {
 
12
 
 
13
namespace {
 
14
 
 
15
void comb4p_round(secure_vector<uint8_t>& out,
 
16
                  const secure_vector<uint8_t>& in,
 
17
                  uint8_t round_no,
 
18
                  HashFunction& h1,
 
19
                  HashFunction& h2)
 
20
   {
 
21
   h1.update(round_no);
 
22
   h2.update(round_no);
 
23
 
 
24
   h1.update(in.data(), in.size());
 
25
   h2.update(in.data(), in.size());
 
26
 
 
27
   secure_vector<uint8_t> h_buf = h1.final();
 
28
   xor_buf(out.data(), h_buf.data(), std::min(out.size(), h_buf.size()));
 
29
 
 
30
   h_buf = h2.final();
 
31
   xor_buf(out.data(), h_buf.data(), std::min(out.size(), h_buf.size()));
 
32
   }
 
33
 
 
34
}
 
35
 
 
36
Comb4P::Comb4P(HashFunction* h1, HashFunction* h2) :
 
37
   m_hash1(h1), m_hash2(h2)
 
38
   {
 
39
   if(m_hash1->name() == m_hash2->name())
 
40
      throw Invalid_Argument("Comb4P: Must use two distinct hashes");
 
41
 
 
42
   if(m_hash1->output_length() != m_hash2->output_length())
 
43
      throw Invalid_Argument("Comb4P: Incompatible hashes " +
 
44
                                  m_hash1->name() + " and " +
 
45
                                  m_hash2->name());
 
46
 
 
47
   clear();
 
48
   }
 
49
 
 
50
size_t Comb4P::hash_block_size() const
 
51
   {
 
52
   if(m_hash1->hash_block_size() == m_hash2->hash_block_size())
 
53
      return m_hash1->hash_block_size();
 
54
 
 
55
   /*
 
56
   * Return LCM of the block sizes? This would probably be OK for
 
57
   * HMAC, which is the main thing relying on knowing the block size.
 
58
   */
 
59
   return 0;
 
60
   }
 
61
 
 
62
void Comb4P::clear()
 
63
   {
 
64
   m_hash1->clear();
 
65
   m_hash2->clear();
 
66
 
 
67
   // Prep for processing next message, if any
 
68
   m_hash1->update(0);
 
69
   m_hash2->update(0);
 
70
   }
 
71
 
 
72
std::unique_ptr<HashFunction> Comb4P::copy_state() const
 
73
   {
 
74
   std::unique_ptr<Comb4P> copy(new Comb4P);
 
75
   copy->m_hash1 = m_hash1->copy_state();
 
76
   copy->m_hash2 = m_hash2->copy_state();
 
77
   return std::move(copy);
 
78
   }
 
79
 
 
80
void Comb4P::add_data(const uint8_t input[], size_t length)
 
81
   {
 
82
   m_hash1->update(input, length);
 
83
   m_hash2->update(input, length);
 
84
   }
 
85
 
 
86
void Comb4P::final_result(uint8_t out[])
 
87
   {
 
88
   secure_vector<uint8_t> h1 = m_hash1->final();
 
89
   secure_vector<uint8_t> h2 = m_hash2->final();
 
90
 
 
91
   // First round
 
92
   xor_buf(h1.data(), h2.data(), std::min(h1.size(), h2.size()));
 
93
 
 
94
   // Second round
 
95
   comb4p_round(h2, h1, 1, *m_hash1, *m_hash2);
 
96
 
 
97
   // Third round
 
98
   comb4p_round(h1, h2, 2, *m_hash1, *m_hash2);
 
99
 
 
100
   copy_mem(out            , h1.data(), h1.size());
 
101
   copy_mem(out + h1.size(), h2.data(), h2.size());
 
102
 
 
103
   // Prep for processing next message, if any
 
104
   m_hash1->update(0);
 
105
   m_hash2->update(0);
 
106
   }
 
107
 
 
108
}
 
109