1 /* 2 * Chocobo1/Hash 3 * 4 * Copyright 2017-2020 by Mike Tzou (Chocobo1) 5 * https://github.com/Chocobo1/Hash 6 * 7 * Licensed under GNU General Public License 3 or later. 8 * 9 * @license GPL3 <https://www.gnu.org/licenses/gpl-3.0-standalone.html> 10 */ 11 12 #ifndef CHOCOBO1_RIPEMD_128_H 13 #define CHOCOBO1_RIPEMD_128_H 14 15 #include <array> 16 #include <cassert> 17 #include <climits> 18 #include <cmath> 19 #include <cstdint> 20 #include <initializer_list> 21 #include <string> 22 #include <type_traits> 23 #include <vector> 24 25 #if (__cplusplus > 201703L) 26 #include <version> 27 #endif 28 29 #ifndef USE_STD_SPAN_CHOCOBO1_HASH 30 #if (__cpp_lib_span >= 202002L) 31 #define USE_STD_SPAN_CHOCOBO1_HASH 1 32 #else 33 #define USE_STD_SPAN_CHOCOBO1_HASH 0 34 #endif 35 #endif 36 37 #if (USE_STD_SPAN_CHOCOBO1_HASH == 1) 38 #include <span> 39 #else 40 #include "gsl/span" 41 #endif 42 43 44 namespace Chocobo1 45 { 46 // Use these!! 47 // RIPEMD_128(); 48 } 49 50 51 namespace Chocobo1 52 { 53 // users should ignore things in this namespace 54 55 namespace Hash 56 { 57 #ifndef CONSTEXPR_CPP17_CHOCOBO1_HASH 58 #if __cplusplus >= 201703L 59 #define CONSTEXPR_CPP17_CHOCOBO1_HASH constexpr 60 #else 61 #define CONSTEXPR_CPP17_CHOCOBO1_HASH 62 #endif 63 #endif 64 65 #if (USE_STD_SPAN_CHOCOBO1_HASH == 1) 66 using IndexType = std::size_t; 67 #else 68 using IndexType = gsl::index; 69 #endif 70 71 #ifndef CHOCOBO1_HASH_BUFFER_IMPL 72 #define CHOCOBO1_HASH_BUFFER_IMPL 73 template <typename T, IndexType N> 74 class Buffer 75 { 76 public: 77 using value_type = T; 78 using index_type = IndexType; 79 using size_type = std::size_t; 80 81 constexpr Buffer() = default; 82 constexpr Buffer(const Buffer &) = default; 83 Buffer(const std::initializer_list<T> initList)84 CONSTEXPR_CPP17_CHOCOBO1_HASH Buffer(const std::initializer_list<T> initList) 85 { 86 #if !defined(NDEBUG) 87 // check if out-of-bounds 88 static_cast<void>(m_array.at(m_dataEndIdx + initList.size() - 1)); 89 #endif 90 91 for (const auto &i : initList) 92 { 93 m_array[m_dataEndIdx] = i; 94 ++m_dataEndIdx; 95 } 96 } 97 98 template <typename InputIt> Buffer(const InputIt first,const InputIt last)99 constexpr Buffer(const InputIt first, const InputIt last) 100 { 101 for (InputIt iter = first; iter != last; ++iter) 102 { 103 this->fill(*iter); 104 } 105 } 106 107 constexpr T& operator[](const index_type pos) 108 { 109 return m_array[pos]; 110 } 111 112 constexpr T operator[](const index_type pos) const 113 { 114 return m_array[pos]; 115 } 116 117 CONSTEXPR_CPP17_CHOCOBO1_HASH void fill(const T &value, const index_type count = 1) 118 { 119 #if !defined(NDEBUG) 120 // check if out-of-bounds 121 static_cast<void>(m_array.at(m_dataEndIdx + count - 1)); 122 #endif 123 124 for (index_type i = 0; i < count; ++i) 125 { 126 m_array[m_dataEndIdx] = value; 127 ++m_dataEndIdx; 128 } 129 } 130 131 template <typename InputIt> push_back(const InputIt first,const InputIt last)132 constexpr void push_back(const InputIt first, const InputIt last) 133 { 134 for (InputIt iter = first; iter != last; ++iter) 135 { 136 this->fill(*iter); 137 } 138 } 139 clear()140 constexpr void clear() 141 { 142 m_array = {}; 143 m_dataEndIdx = 0; 144 } 145 empty()146 constexpr bool empty() const 147 { 148 return (m_dataEndIdx == 0); 149 } 150 size()151 constexpr size_type size() const 152 { 153 return m_dataEndIdx; 154 } 155 data()156 constexpr const T* data() const 157 { 158 return m_array.data(); 159 } 160 161 private: 162 std::array<T, N> m_array {}; 163 index_type m_dataEndIdx = 0; 164 }; 165 #endif 166 167 168 namespace RIPEMD_128_NS 169 { 170 class RIPEMD_128 171 { 172 // https://homes.esat.kuleuven.be/~bosselae/ripemd160.html 173 174 public: 175 using Byte = uint8_t; 176 using ResultArrayType = std::array<Byte, 16>; 177 178 #if (USE_STD_SPAN_CHOCOBO1_HASH == 1) 179 template <typename T, std::size_t Extent = std::dynamic_extent> 180 using Span = std::span<T, Extent>; 181 #else 182 template <typename T, std::size_t Extent = gsl::dynamic_extent> 183 using Span = gsl::span<T, Extent>; 184 #endif 185 186 187 constexpr RIPEMD_128(); 188 189 constexpr void reset(); 190 CONSTEXPR_CPP17_CHOCOBO1_HASH RIPEMD_128& finalize(); // after this, only `toArray()`, `toString()`, `toVector()`, `reset()` are available 191 192 std::string toString() const; 193 std::vector<Byte> toVector() const; 194 CONSTEXPR_CPP17_CHOCOBO1_HASH ResultArrayType toArray() const; 195 196 CONSTEXPR_CPP17_CHOCOBO1_HASH RIPEMD_128& addData(const Span<const Byte> inData); 197 CONSTEXPR_CPP17_CHOCOBO1_HASH RIPEMD_128& addData(const void *ptr, const std::size_t length); 198 template <std::size_t N> 199 CONSTEXPR_CPP17_CHOCOBO1_HASH RIPEMD_128& addData(const Byte (&array)[N]); 200 template <typename T, std::size_t N> 201 RIPEMD_128& addData(const T (&array)[N]); 202 template <typename T> 203 RIPEMD_128& addData(const Span<T> inSpan); 204 205 private: 206 CONSTEXPR_CPP17_CHOCOBO1_HASH void addDataImpl(const Span<const Byte> data); 207 208 static constexpr int BLOCK_SIZE = 64; 209 210 Buffer<Byte, (BLOCK_SIZE * 2)> m_buffer; // x2 for paddings 211 uint64_t m_sizeCounter = 0; 212 213 uint32_t m_h[4] = {}; 214 }; 215 216 217 // helpers 218 template <typename T> 219 class Loader 220 { 221 // this class workaround loading data from unaligned memory boundaries 222 // also eliminate endianness issues 223 public: Loader(const uint8_t * ptr)224 explicit constexpr Loader(const uint8_t *ptr) 225 : m_ptr(ptr) 226 { 227 } 228 229 constexpr T operator[](const IndexType idx) const 230 { 231 static_assert(std::is_same<T, uint32_t>::value, ""); 232 // handle specific endianness here 233 const uint8_t *ptr = m_ptr + (sizeof(T) * idx); 234 return ( (static_cast<T>(*(ptr + 0)) << 0) 235 | (static_cast<T>(*(ptr + 1)) << 8) 236 | (static_cast<T>(*(ptr + 2)) << 16) 237 | (static_cast<T>(*(ptr + 3)) << 24)); 238 } 239 240 private: 241 const uint8_t *m_ptr; 242 }; 243 244 template <typename R, typename T> ror(const T x,const unsigned int s)245 constexpr R ror(const T x, const unsigned int s) 246 { 247 static_assert(std::is_unsigned<R>::value, ""); 248 static_assert(std::is_unsigned<T>::value, ""); 249 return static_cast<R>(x >> s); 250 } 251 252 template <typename T> rotl(const T x,const unsigned int s)253 constexpr T rotl(const T x, const unsigned int s) 254 { 255 static_assert(std::is_unsigned<T>::value, ""); 256 if (s == 0) 257 return x; 258 return ((x << s) | (x >> ((sizeof(T) * 8) - s))); 259 } 260 261 262 // RIPEMD_128()263 constexpr RIPEMD_128::RIPEMD_128() 264 { 265 static_assert((CHAR_BIT == 8), "Sorry, we don't support exotic CPUs"); 266 reset(); 267 } 268 reset()269 constexpr void RIPEMD_128::reset() 270 { 271 m_buffer.clear(); 272 m_sizeCounter = 0; 273 274 m_h[0] = 0x67452301; 275 m_h[1] = 0xEFCDAB89; 276 m_h[2] = 0x98BADCFE; 277 m_h[3] = 0x10325476; 278 } 279 finalize()280 CONSTEXPR_CPP17_CHOCOBO1_HASH RIPEMD_128& RIPEMD_128::finalize() 281 { 282 m_sizeCounter += m_buffer.size(); 283 284 // append 1 bit 285 m_buffer.fill(1 << 7); 286 287 // append paddings 288 const size_t len = BLOCK_SIZE - ((m_buffer.size() + 8) % BLOCK_SIZE); 289 m_buffer.fill(0, (len + 8)); 290 291 // append size in bits 292 const uint64_t sizeCounterBits = m_sizeCounter * 8; 293 const uint32_t sizeCounterBitsL = ror<uint32_t>(sizeCounterBits, 0); 294 const uint32_t sizeCounterBitsH = ror<uint32_t>(sizeCounterBits, 32); 295 for (int i = 0; i < 4; ++i) 296 { 297 m_buffer[m_buffer.size() - 8 + i] = ror<Byte>(sizeCounterBitsL, (8 * i)); 298 m_buffer[m_buffer.size() - 4 + i] = ror<Byte>(sizeCounterBitsH, (8 * i)); 299 } 300 301 addDataImpl({m_buffer.data(), m_buffer.size()}); 302 m_buffer.clear(); 303 304 return (*this); 305 } 306 toString()307 std::string RIPEMD_128::toString() const 308 { 309 const auto a = toArray(); 310 std::string ret; 311 ret.resize(2 * a.size()); 312 313 auto retPtr = &ret.front(); 314 for (const auto c : a) 315 { 316 const Byte upper = ror<Byte>(c, 4); 317 *(retPtr++) = static_cast<char>((upper < 10) ? (upper + '0') : (upper - 10 + 'a')); 318 319 const Byte lower = c & 0xf; 320 *(retPtr++) = static_cast<char>((lower < 10) ? (lower + '0') : (lower - 10 + 'a')); 321 } 322 323 return ret; 324 } 325 toVector()326 std::vector<RIPEMD_128::Byte> RIPEMD_128::toVector() const 327 { 328 const auto a = toArray(); 329 return {a.begin(), a.end()}; 330 } 331 toArray()332 CONSTEXPR_CPP17_CHOCOBO1_HASH RIPEMD_128::ResultArrayType RIPEMD_128::toArray() const 333 { 334 const Span<const uint32_t> state(m_h); 335 const int dataSize = sizeof(decltype(state)::value_type); 336 337 ResultArrayType ret {}; 338 auto retPtr = ret.data(); 339 for (const auto i : state) 340 { 341 for (int j = 0; j < dataSize; ++j) 342 *(retPtr++) = ror<Byte>(i, (j * 8)); 343 } 344 345 return ret; 346 } 347 addData(const Span<const Byte> inData)348 CONSTEXPR_CPP17_CHOCOBO1_HASH RIPEMD_128& RIPEMD_128::addData(const Span<const Byte> inData) 349 { 350 Span<const Byte> data = inData; 351 352 if (!m_buffer.empty()) 353 { 354 const size_t len = std::min<size_t>((BLOCK_SIZE - m_buffer.size()), data.size()); // try fill to BLOCK_SIZE bytes 355 m_buffer.push_back(data.begin(), (data.begin() + len)); 356 357 if (m_buffer.size() < BLOCK_SIZE) // still doesn't fill the buffer 358 return (*this); 359 360 addDataImpl({m_buffer.data(), m_buffer.size()}); 361 m_buffer.clear(); 362 363 data = data.subspan(len); 364 } 365 366 const size_t dataSize = data.size(); 367 if (dataSize < BLOCK_SIZE) 368 { 369 m_buffer = {data.begin(), data.end()}; 370 return (*this); 371 } 372 373 const size_t len = dataSize - (dataSize % BLOCK_SIZE); // align on BLOCK_SIZE bytes 374 addDataImpl(data.first(len)); 375 376 if (len < dataSize) // didn't consume all data 377 m_buffer = {(data.begin() + len), data.end()}; 378 379 return (*this); 380 } 381 addData(const void * ptr,const std::size_t length)382 CONSTEXPR_CPP17_CHOCOBO1_HASH RIPEMD_128& RIPEMD_128::addData(const void *ptr, const std::size_t length) 383 { 384 // Span::size_type = std::size_t 385 return addData({static_cast<const Byte*>(ptr), length}); 386 } 387 388 template <std::size_t N> addData(const Byte (& array)[N])389 CONSTEXPR_CPP17_CHOCOBO1_HASH RIPEMD_128& RIPEMD_128::addData(const Byte (&array)[N]) 390 { 391 return addData({array, N}); 392 } 393 394 template <typename T, std::size_t N> addData(const T (& array)[N])395 RIPEMD_128& RIPEMD_128::addData(const T (&array)[N]) 396 { 397 return addData({reinterpret_cast<const Byte*>(array), (sizeof(T) * N)}); 398 } 399 400 template <typename T> addData(const Span<T> inSpan)401 RIPEMD_128& RIPEMD_128::addData(const Span<T> inSpan) 402 { 403 return addData({reinterpret_cast<const Byte*>(inSpan.data()), inSpan.size_bytes()}); 404 } 405 addDataImpl(const Span<const Byte> data)406 CONSTEXPR_CPP17_CHOCOBO1_HASH void RIPEMD_128::addDataImpl(const Span<const Byte> data) 407 { 408 assert((data.size() % BLOCK_SIZE) == 0); 409 410 m_sizeCounter += data.size(); 411 412 for (size_t i = 0, iend = static_cast<size_t>(data.size() / BLOCK_SIZE); i < iend; ++i) 413 { 414 const Loader<uint32_t> x(static_cast<const Byte *>(data.data() + (i * BLOCK_SIZE))); 415 416 const auto f1 = [](const uint32_t x, const uint32_t y, const uint32_t z) -> uint32_t 417 { 418 return (x ^ y ^ z); 419 }; 420 const auto f2 = [](const uint32_t x, const uint32_t y, const uint32_t z) -> uint32_t 421 { 422 return ((x & (y ^ z)) ^ z); // alternative 423 }; 424 const auto f3 = [](const uint32_t x, const uint32_t y, const uint32_t z) -> uint32_t 425 { 426 return ((x | (~y)) ^ z); 427 }; 428 const auto f4 = [](const uint32_t x, const uint32_t y, const uint32_t z) -> uint32_t 429 { 430 return (((x ^ y) & z) ^ y); // alternative 431 }; 432 433 uint32_t a = m_h[0]; 434 uint32_t b = m_h[1]; 435 uint32_t c = m_h[2]; 436 uint32_t d = m_h[3]; 437 const auto lineLeft = [x](uint32_t &a, uint32_t &b, uint32_t &c, uint32_t &d, const auto &f, const uint32_t k, const unsigned int r, const unsigned int s) -> void 438 { 439 a = rotl((a + f(b, c, d) + x[r] + k), s); 440 }; 441 442 uint32_t aa = m_h[0]; 443 uint32_t bb = m_h[1]; 444 uint32_t cc = m_h[2]; 445 uint32_t dd = m_h[3]; 446 const auto &lineRight = lineLeft; 447 448 lineLeft(a, b, c, d, f1, 0x00000000, 0, 11); 449 lineLeft(d, a, b, c, f1, 0x00000000, 1, 14); 450 lineRight(aa, bb, cc, dd, f4, 0x50A28BE6, 5, 8); 451 lineRight(dd, aa, bb, cc, f4, 0x50A28BE6, 14, 9); 452 lineLeft(c, d, a, b, f1, 0x00000000, 2, 15); 453 lineLeft(b, c, d, a, f1, 0x00000000, 3, 12); 454 lineRight(cc, dd, aa, bb, f4, 0x50A28BE6, 7, 9); 455 lineRight(bb, cc, dd, aa, f4, 0x50A28BE6, 0, 11); 456 lineLeft(a, b, c, d, f1, 0x00000000, 4, 5); 457 lineLeft(d, a, b, c, f1, 0x00000000, 5, 8); 458 lineRight(aa, bb, cc, dd, f4, 0x50A28BE6, 9, 13); 459 lineRight(dd, aa, bb, cc, f4, 0x50A28BE6, 2, 15); 460 lineLeft(c, d, a, b, f1, 0x00000000, 6, 7); 461 lineLeft(b, c, d, a, f1, 0x00000000, 7, 9); 462 lineRight(cc, dd, aa, bb, f4, 0x50A28BE6, 11, 15); 463 lineRight(bb, cc, dd, aa, f4, 0x50A28BE6, 4, 5); 464 lineLeft(a, b, c, d, f1, 0x00000000, 8, 11); 465 lineLeft(d, a, b, c, f1, 0x00000000, 9, 13); 466 lineRight(aa, bb, cc, dd, f4, 0x50A28BE6, 13, 7); 467 lineRight(dd, aa, bb, cc, f4, 0x50A28BE6, 6, 7); 468 lineLeft(c, d, a, b, f1, 0x00000000, 10, 14); 469 lineLeft(b, c, d, a, f1, 0x00000000, 11, 15); 470 lineRight(cc, dd, aa, bb, f4, 0x50A28BE6, 15, 8); 471 lineRight(bb, cc, dd, aa, f4, 0x50A28BE6, 8, 11); 472 lineLeft(a, b, c, d, f1, 0x00000000, 12, 6); 473 lineLeft(d, a, b, c, f1, 0x00000000, 13, 7); 474 lineRight(aa, bb, cc, dd, f4, 0x50A28BE6, 1, 14); 475 lineRight(dd, aa, bb, cc, f4, 0x50A28BE6, 10, 14); 476 lineLeft(c, d, a, b, f1, 0x00000000, 14, 9); 477 lineLeft(b, c, d, a, f1, 0x00000000, 15, 8); 478 lineRight(cc, dd, aa, bb, f4, 0x50A28BE6, 3, 12); 479 lineRight(bb, cc, dd, aa, f4, 0x50A28BE6, 12, 6); 480 lineLeft(a, b, c, d, f2, 0x5A827999, 7, 7); 481 lineLeft(d, a, b, c, f2, 0x5A827999, 4, 6); 482 lineRight(aa, bb, cc, dd, f3, 0x5C4DD124, 6, 9); 483 lineRight(dd, aa, bb, cc, f3, 0x5C4DD124, 11, 13); 484 lineLeft(c, d, a, b, f2, 0x5A827999, 13, 8); 485 lineLeft(b, c, d, a, f2, 0x5A827999, 1, 13); 486 lineRight(cc, dd, aa, bb, f3, 0x5C4DD124, 3, 15); 487 lineRight(bb, cc, dd, aa, f3, 0x5C4DD124, 7, 7); 488 lineLeft(a, b, c, d, f2, 0x5A827999, 10, 11); 489 lineLeft(d, a, b, c, f2, 0x5A827999, 6, 9); 490 lineRight(aa, bb, cc, dd, f3, 0x5C4DD124, 0, 12); 491 lineRight(dd, aa, bb, cc, f3, 0x5C4DD124, 13, 8); 492 lineLeft(c, d, a, b, f2, 0x5A827999, 15, 7); 493 lineLeft(b, c, d, a, f2, 0x5A827999, 3, 15); 494 lineRight(cc, dd, aa, bb, f3, 0x5C4DD124, 5, 9); 495 lineRight(bb, cc, dd, aa, f3, 0x5C4DD124, 10, 11); 496 lineLeft(a, b, c, d, f2, 0x5A827999, 12, 7); 497 lineLeft(d, a, b, c, f2, 0x5A827999, 0, 12); 498 lineRight(aa, bb, cc, dd, f3, 0x5C4DD124, 14, 7); 499 lineRight(dd, aa, bb, cc, f3, 0x5C4DD124, 15, 7); 500 lineLeft(c, d, a, b, f2, 0x5A827999, 9, 15); 501 lineLeft(b, c, d, a, f2, 0x5A827999, 5, 9); 502 lineRight(cc, dd, aa, bb, f3, 0x5C4DD124, 8, 12); 503 lineRight(bb, cc, dd, aa, f3, 0x5C4DD124, 12, 7); 504 lineLeft(a, b, c, d, f2, 0x5A827999, 2, 11); 505 lineLeft(d, a, b, c, f2, 0x5A827999, 14, 7); 506 lineRight(aa, bb, cc, dd, f3, 0x5C4DD124, 4, 6); 507 lineRight(dd, aa, bb, cc, f3, 0x5C4DD124, 9, 15); 508 lineLeft(c, d, a, b, f2, 0x5A827999, 11, 13); 509 lineLeft(b, c, d, a, f2, 0x5A827999, 8, 12); 510 lineRight(cc, dd, aa, bb, f3, 0x5C4DD124, 1, 13); 511 lineRight(bb, cc, dd, aa, f3, 0x5C4DD124, 2, 11); 512 lineLeft(a, b, c, d, f3, 0x6ED9EBA1, 3, 11); 513 lineLeft(d, a, b, c, f3, 0x6ED9EBA1, 10, 13); 514 lineRight(aa, bb, cc, dd, f2, 0x6D703EF3, 15, 9); 515 lineRight(dd, aa, bb, cc, f2, 0x6D703EF3, 5, 7); 516 lineLeft(c, d, a, b, f3, 0x6ED9EBA1, 14, 6); 517 lineLeft(b, c, d, a, f3, 0x6ED9EBA1, 4, 7); 518 lineRight(cc, dd, aa, bb, f2, 0x6D703EF3, 1, 15); 519 lineRight(bb, cc, dd, aa, f2, 0x6D703EF3, 3, 11); 520 lineLeft(a, b, c, d, f3, 0x6ED9EBA1, 9, 14); 521 lineLeft(d, a, b, c, f3, 0x6ED9EBA1, 15, 9); 522 lineRight(aa, bb, cc, dd, f2, 0x6D703EF3, 7, 8); 523 lineRight(dd, aa, bb, cc, f2, 0x6D703EF3, 14, 6); 524 lineLeft(c, d, a, b, f3, 0x6ED9EBA1, 8, 13); 525 lineLeft(b, c, d, a, f3, 0x6ED9EBA1, 1, 15); 526 lineRight(cc, dd, aa, bb, f2, 0x6D703EF3, 6, 6); 527 lineRight(bb, cc, dd, aa, f2, 0x6D703EF3, 9, 14); 528 lineLeft(a, b, c, d, f3, 0x6ED9EBA1, 2, 14); 529 lineLeft(d, a, b, c, f3, 0x6ED9EBA1, 7, 8); 530 lineRight(aa, bb, cc, dd, f2, 0x6D703EF3, 11, 12); 531 lineRight(dd, aa, bb, cc, f2, 0x6D703EF3, 8, 13); 532 lineLeft(c, d, a, b, f3, 0x6ED9EBA1, 0, 13); 533 lineLeft(b, c, d, a, f3, 0x6ED9EBA1, 6, 6); 534 lineRight(cc, dd, aa, bb, f2, 0x6D703EF3, 12, 5); 535 lineRight(bb, cc, dd, aa, f2, 0x6D703EF3, 2, 14); 536 lineLeft(a, b, c, d, f3, 0x6ED9EBA1, 13, 5); 537 lineLeft(d, a, b, c, f3, 0x6ED9EBA1, 11, 12); 538 lineRight(aa, bb, cc, dd, f2, 0x6D703EF3, 10, 13); 539 lineRight(dd, aa, bb, cc, f2, 0x6D703EF3, 0, 13); 540 lineLeft(c, d, a, b, f3, 0x6ED9EBA1, 5, 7); 541 lineLeft(b, c, d, a, f3, 0x6ED9EBA1, 12, 5); 542 lineRight(cc, dd, aa, bb, f2, 0x6D703EF3, 4, 7); 543 lineRight(bb, cc, dd, aa, f2, 0x6D703EF3, 13, 5); 544 lineLeft(a, b, c, d, f4, 0x8F1BBCDC, 1, 11); 545 lineLeft(d, a, b, c, f4, 0x8F1BBCDC, 9, 12); 546 lineRight(aa, bb, cc, dd, f1, 0x00000000, 8, 15); 547 lineRight(dd, aa, bb, cc, f1, 0x00000000, 6, 5); 548 lineLeft(c, d, a, b, f4, 0x8F1BBCDC, 11, 14); 549 lineLeft(b, c, d, a, f4, 0x8F1BBCDC, 10, 15); 550 lineRight(cc, dd, aa, bb, f1, 0x00000000, 4, 8); 551 lineRight(bb, cc, dd, aa, f1, 0x00000000, 1, 11); 552 lineLeft(a, b, c, d, f4, 0x8F1BBCDC, 0, 14); 553 lineLeft(d, a, b, c, f4, 0x8F1BBCDC, 8, 15); 554 lineRight(aa, bb, cc, dd, f1, 0x00000000, 3, 14); 555 lineRight(dd, aa, bb, cc, f1, 0x00000000, 11, 14); 556 lineLeft(c, d, a, b, f4, 0x8F1BBCDC, 12, 9); 557 lineLeft(b, c, d, a, f4, 0x8F1BBCDC, 4, 8); 558 lineRight(cc, dd, aa, bb, f1, 0x00000000, 15, 6); 559 lineRight(bb, cc, dd, aa, f1, 0x00000000, 0, 14); 560 lineLeft(a, b, c, d, f4, 0x8F1BBCDC, 13, 9); 561 lineLeft(d, a, b, c, f4, 0x8F1BBCDC, 3, 14); 562 lineRight(aa, bb, cc, dd, f1, 0x00000000, 5, 6); 563 lineRight(dd, aa, bb, cc, f1, 0x00000000, 12, 9); 564 lineLeft(c, d, a, b, f4, 0x8F1BBCDC, 7, 5); 565 lineLeft(b, c, d, a, f4, 0x8F1BBCDC, 15, 6); 566 lineRight(cc, dd, aa, bb, f1, 0x00000000, 2, 12); 567 lineRight(bb, cc, dd, aa, f1, 0x00000000, 13, 9); 568 lineLeft(a, b, c, d, f4, 0x8F1BBCDC, 14, 8); 569 lineLeft(d, a, b, c, f4, 0x8F1BBCDC, 5, 6); 570 lineRight(aa, bb, cc, dd, f1, 0x00000000, 9, 12); 571 lineRight(dd, aa, bb, cc, f1, 0x00000000, 7, 5); 572 lineLeft(c, d, a, b, f4, 0x8F1BBCDC, 6, 5); 573 lineLeft(b, c, d, a, f4, 0x8F1BBCDC, 2, 12); 574 lineRight(cc, dd, aa, bb, f1, 0x00000000, 10, 15); 575 lineRight(bb, cc, dd, aa, f1, 0x00000000, 14, 8); 576 577 const uint32_t t = m_h[1] + c + dd; 578 m_h[1] = m_h[2] + d + aa; 579 m_h[2] = m_h[3] + a + bb; 580 m_h[3] = m_h[0] + b + cc; 581 m_h[0] = t; 582 } 583 } 584 } 585 } 586 using RIPEMD_128 = Hash::RIPEMD_128_NS::RIPEMD_128; 587 } 588 589 #endif // CHOCOBO1_RIPEMD_128_H 590