Botan 3.6.1
Crypto and TLS for C&
md4.cpp
Go to the documentation of this file.
1/*
2* MD4
3* (C) 1999-2007 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/internal/md4.h>
9
10#include <botan/internal/bit_ops.h>
11#include <botan/internal/loadstor.h>
12#include <botan/internal/rotate.h>
13
14namespace Botan {
15
16namespace {
17
18inline void FF4(uint32_t& A, uint32_t& B, uint32_t& C, uint32_t& D, uint32_t M0, uint32_t M1, uint32_t M2, uint32_t M3)
19
20{
21 A += choose(B, C, D) + M0;
22 A = rotl<3>(A);
23
24 D += choose(A, B, C) + M1;
25 D = rotl<7>(D);
26
27 C += choose(D, A, B) + M2;
28 C = rotl<11>(C);
29
30 B += choose(C, D, A) + M3;
31 B = rotl<19>(B);
32}
33
34inline void GG4(uint32_t& A, uint32_t& B, uint32_t& C, uint32_t& D, uint32_t M0, uint32_t M1, uint32_t M2, uint32_t M3)
35
36{
37 /*
38 These are choose(D, B | C, B & C) but the below expression
39 takes advantage of the fact that B & C is a subset of B | C
40 to eliminate an and
41 */
42
43 A += ((B & C) | (D & (B | C))) + M0 + 0x5A827999;
44 A = rotl<3>(A);
45
46 D += ((A & B) | (C & (A | B))) + M1 + 0x5A827999;
47 D = rotl<5>(D);
48
49 C += ((D & A) | (B & (D | A))) + M2 + 0x5A827999;
50 C = rotl<9>(C);
51
52 B += ((C & D) | (A & (C | D))) + M3 + 0x5A827999;
53 B = rotl<13>(B);
54}
55
56inline void HH4(uint32_t& A, uint32_t& B, uint32_t& C, uint32_t& D, uint32_t M0, uint32_t M1, uint32_t M2, uint32_t M3)
57
58{
59 A += (B ^ C ^ D) + M0 + 0x6ED9EBA1;
60 A = rotl<3>(A);
61
62 D += (A ^ B ^ C) + M1 + 0x6ED9EBA1;
63 D = rotl<9>(D);
64
65 C += (A ^ B ^ D) + M2 + 0x6ED9EBA1;
66 C = rotl<11>(C);
67
68 B += (A ^ C ^ D) + M3 + 0x6ED9EBA1;
69 B = rotl<15>(B);
70}
71
72} // namespace
73
74/*
75* MD4 Compression Function
76*/
77void MD4::compress_n(digest_type& digest, std::span<const uint8_t> input, size_t blocks) {
78 uint32_t A = digest[0], B = digest[1], C = digest[2], D = digest[3];
79
80 BufferSlicer in(input);
81
82 std::array<uint32_t, 16> M;
83
84 for(size_t i = 0; i != blocks; ++i) {
85 load_le(M, in.take<block_bytes>());
86
87 // clang-format off
88
89 FF4(A, B, C, D, M[ 0], M[ 1], M[ 2], M[ 3]);
90 FF4(A, B, C, D, M[ 4], M[ 5], M[ 6], M[ 7]);
91 FF4(A, B, C, D, M[ 8], M[ 9], M[10], M[11]);
92 FF4(A, B, C, D, M[12], M[13], M[14], M[15]);
93
94 GG4(A, B, C, D, M[ 0], M[ 4], M[ 8], M[12]);
95 GG4(A, B, C, D, M[ 1], M[ 5], M[ 9], M[13]);
96 GG4(A, B, C, D, M[ 2], M[ 6], M[10], M[14]);
97 GG4(A, B, C, D, M[ 3], M[ 7], M[11], M[15]);
98
99 HH4(A, B, C, D, M[ 0], M[ 8], M[ 4], M[12]);
100 HH4(A, B, C, D, M[ 2], M[10], M[ 6], M[14]);
101 HH4(A, B, C, D, M[ 1], M[ 9], M[ 5], M[13]);
102 HH4(A, B, C, D, M[ 3], M[11], M[ 7], M[15]);
103
104 // clang-format on
105
106 A = (digest[0] += A);
107 B = (digest[1] += B);
108 C = (digest[2] += C);
109 D = (digest[3] += D);
110 }
111
113}
114
115void MD4::init(digest_type& digest) {
116 digest.assign({0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476});
117}
118
119std::unique_ptr<HashFunction> MD4::new_object() const {
120 return std::make_unique<MD4>();
121}
122
123std::unique_ptr<HashFunction> MD4::copy_state() const {
124 return std::make_unique<MD4>(*this);
125}
126
127void MD4::add_data(std::span<const uint8_t> input) {
128 m_md.update(input);
129}
130
131void MD4::final_result(std::span<uint8_t> output) {
132 m_md.final(output);
133}
134
135} // namespace Botan
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59
bool empty() const
Definition stl_util.h:129
std::span< const uint8_t > take(const size_t count)
Definition stl_util.h:98
secure_vector< uint32_t > digest_type
Definition md4.h:20
static void init(digest_type &digest)
Definition md4.cpp:115
static void compress_n(digest_type &digest, std::span< const uint8_t > input, size_t blocks)
Definition md4.cpp:77
std::unique_ptr< HashFunction > copy_state() const override
Definition md4.cpp:123
static constexpr size_t block_bytes
Definition md4.h:24
std::unique_ptr< HashFunction > new_object() const override
Definition md4.cpp:119
constexpr T rotl(T input)
Definition rotate.h:21
constexpr T choose(T mask, T a, T b)
Definition bit_ops.h:193
constexpr auto load_le(ParamTs &&... params)
Definition loadstor.h:521