1//
2// DigestEngine.cpp
3//
4// Library: Foundation
5// Package: Crypt
6// Module: DigestEngine
7//
8// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
9// and Contributors.
10//
11// SPDX-License-Identifier: BSL-1.0
12//
13
14
15#include "Poco/DigestEngine.h"
16#include "Poco/Exception.h"
17
18
19namespace Poco
20{
21
22DigestEngine::DigestEngine()
23{
24}
25
26
27DigestEngine::~DigestEngine()
28{
29}
30
31
32std::string DigestEngine::digestToHex(const Digest& bytes)
33{
34 static const char digits[] = "0123456789abcdef";
35 std::string result;
36 result.reserve(bytes.size() * 2);
37 for (Digest::const_iterator it = bytes.begin(); it != bytes.end(); ++it)
38 {
39 unsigned char c = *it;
40 result += digits[(c >> 4) & 0xF];
41 result += digits[c & 0xF];
42 }
43 return result;
44}
45
46
47DigestEngine::Digest DigestEngine::digestFromHex(const std::string& digest)
48{
49 if (digest.size() % 2 != 0)
50 throw DataFormatException();
51 Digest result;
52 result.reserve(digest.size() / 2);
53 for (std::size_t i = 0; i < digest.size(); ++i)
54 {
55 int c = 0;
56 // first upper 4 bits
57 if (digest[i] >= '0' && digest[i] <= '9')
58 c = digest[i] - '0';
59 else if (digest[i] >= 'a' && digest[i] <= 'f')
60 c = digest[i] - 'a' + 10;
61 else if (digest[i] >= 'A' && digest[i] <= 'F')
62 c = digest[i] - 'A' + 10;
63 else
64 throw DataFormatException();
65 c <<= 4;
66 ++i;
67 if (digest[i] >= '0' && digest[i] <= '9')
68 c += digest[i] - '0';
69 else if (digest[i] >= 'a' && digest[i] <= 'f')
70 c += digest[i] - 'a' + 10;
71 else if (digest[i] >= 'A' && digest[i] <= 'F')
72 c += digest[i] - 'A' + 10;
73 else
74 throw DataFormatException();
75
76 result.push_back(static_cast<unsigned char>(c));
77 }
78 return result;
79}
80
81
82bool DigestEngine::constantTimeEquals(const Digest& d1, const Digest& d2)
83{
84 if (d1.size() != d2.size()) return false;
85
86 int result = 0;
87 Digest::const_iterator it1 = d1.begin();
88 Digest::const_iterator it2 = d2.begin();
89 Digest::const_iterator end1 = d1.end();
90 while (it1 != end1)
91 {
92 result |= *it1++ ^ *it2++;
93 }
94 return result == 0;
95}
96
97
98} // namespace Poco
99
100