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