OpenCPN Partial API docs
FlexHash.cpp
1 
2 /******************************************************************************
3  *
4  * Project: OpenCPN
5  * Purpose: Hash of arbitrary length
6  * Author: Anton Samsonov
7  *
8  ***************************************************************************
9  * Copyright (C) 2010 by David S. Register *
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  * This program is distributed in the hope that it will be useful, *
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19  * GNU General Public License for more details. *
20  * *
21  * You should have received a copy of the GNU General Public License *
22  * along with this program; if not, write to the *
23  * Free Software Foundation, Inc., *
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
25  ***************************************************************************
26  *
27  */
28 
29 #include <vector>
30 #include <memory.h>
31 #include "FlexHash.h"
32 
33 #define FLEXHASH_INTERNAL_SIZE static_cast<size_t>(20)
34 
35 FlexHash::FlexHash(size_t output_octets) : m_Output(output_octets) {}
36 
37 void FlexHash::Reset(void) { sha1_starts(&this->m_Context); }
38 
39 void FlexHash::Update(const void* input, size_t input_octets) {
40  sha1_update(&this->m_Context, reinterpret_cast<const unsigned char*>(input),
41  input_octets);
42 }
43 
44 void FlexHash::Finish(void) {
45  unsigned char output[FLEXHASH_INTERNAL_SIZE];
46  sha1_finish(&this->m_Context, output);
47  if (this->m_Output.size() <= FLEXHASH_INTERNAL_SIZE) {
48  memcpy(&this->m_Output[0], output, this->m_Output.size());
49  } else {
50  memcpy(&this->m_Output[0], output, FLEXHASH_INTERNAL_SIZE);
51  size_t available_octets = FLEXHASH_INTERNAL_SIZE;
52  size_t remaining_octets = this->m_Output.size() - available_octets;
53  while (remaining_octets) {
54  size_t current_octets =
55  ((remaining_octets > FLEXHASH_INTERNAL_SIZE) ? FLEXHASH_INTERNAL_SIZE
56  : remaining_octets);
57  sha1_starts(&this->m_Context);
58  sha1_update(&this->m_Context,
59  reinterpret_cast<const unsigned char*>(&this->m_Output[0]),
60  available_octets);
61  sha1_finish(&this->m_Context, output);
62  memcpy(&this->m_Output[available_octets], output, current_octets);
63  available_octets += FLEXHASH_INTERNAL_SIZE;
64  remaining_octets -= current_octets;
65  }
66  }
67 }
68 
69 void FlexHash::Receive(void* output) {
70  memcpy(output, &this->m_Output[0], this->m_Output.size());
71 }
72 
73 void FlexHash::Compute(const void* input, size_t input_octets, void* output) {
74  this->Reset();
75  this->Update(input, input_octets);
76  this->Finish();
77  this->Receive(output);
78 }
79 
80 void FlexHash::Compute(const void* input, size_t input_octets, void* output,
81  size_t output_octets) {
82  FlexHash hasher(output_octets);
83  hasher.Compute(input, input_octets, output);
84 }
85 
86 bool FlexHash::Test(void) {
87  // Input test vector for "The quick brown fox jumps over the lazy dog".
88  static unsigned char input[] = {
89  0x54, 0x68, 0x65, 0x20, 0x71, 0x75, 0x69, 0x63, 0x6b, 0x20, 0x62,
90  0x72, 0x6f, 0x77, 0x6e, 0x20, 0x66, 0x6f, 0x78, 0x20, 0x6a, 0x75,
91  0x6d, 0x70, 0x73, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x74, 0x68,
92  0x65, 0x20, 0x6c, 0x61, 0x7a, 0x79, 0x20, 0x64, 0x6f, 0x67};
93  // Output test vector for SHA-1 engine and 256-bit result.
94  static unsigned char output_reference[] = {
95  0x2f, 0xd4, 0xe1, 0xc6, 0x7a, 0x2d, 0x28, 0xfc, 0xed, 0x84, 0x9e,
96  0xe1, 0xbb, 0x76, 0xe7, 0x39, 0x1b, 0x93, 0xeb, 0x12, 0xa4, 0xe4,
97  0xd2, 0x6f, 0xd0, 0xc6, 0x45, 0x5e, 0x23, 0xe2, 0x18, 0x7c};
98  char output_current[(sizeof output_reference)];
99  Compute(input, (sizeof input), output_current, (sizeof output_current));
100  return (memcmp(output_current, output_reference, (sizeof output_reference)) ==
101  0);
102 }