add PIDigest with SHA and MD series
This commit is contained in:
98
libs/main/digest/pidigest_sha1_p.cpp
Normal file
98
libs/main/digest/pidigest_sha1_p.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Digest algorithms
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pidigest_sha1_p.h"
|
||||
|
||||
template<typename T>
|
||||
inline T rotate_u(T v, int bits) {
|
||||
return (v << bits) | (v >> ((sizeof(T) * 8) - bits));
|
||||
}
|
||||
template<typename T>
|
||||
inline T shift_u(T v, int bits) {
|
||||
return v << bits;
|
||||
}
|
||||
|
||||
PIByteArray SHA1::sha1(const PIByteArray & in) {
|
||||
constexpr int part_size = 64;
|
||||
constexpr int rounds = 80;
|
||||
|
||||
uint32_t h0 = 0x67452301u;
|
||||
uint32_t h1 = 0xEFCDAB89u;
|
||||
uint32_t h2 = 0x98BADCFEu;
|
||||
uint32_t h3 = 0x10325476u;
|
||||
uint32_t h4 = 0xC3D2E1F0u;
|
||||
|
||||
uint64_t l = in.size() * 8;
|
||||
PIByteArray msg = in;
|
||||
int add_l = (part_size - 8) - (msg.size() % (part_size));
|
||||
if (add_l <= 0) add_l += part_size;
|
||||
msg.append(0x80);
|
||||
for (int i = 1; i < add_l; ++i)
|
||||
msg.append(0x0);
|
||||
msg << piChangedEndian(l);
|
||||
int parts = msg.size_s() / part_size;
|
||||
// piCout << l << "add" << add_l << "=" << (in.size() + add_l + sizeof(l)) << msg.size() << parts;
|
||||
uint32_t w[80];
|
||||
for (int p = 0; p < parts; ++p) {
|
||||
uint32_t * mw = (uint32_t *)msg.data(p * part_size);
|
||||
for (int i = 0; i < 16; ++i)
|
||||
w[i] = piChangedEndian(mw[i]);
|
||||
for (int i = 16; i < 80; ++i) {
|
||||
w[i] = rotate_u((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1);
|
||||
}
|
||||
uint32_t a = h0;
|
||||
uint32_t b = h1;
|
||||
uint32_t c = h2;
|
||||
uint32_t d = h3;
|
||||
uint32_t e = h4;
|
||||
uint32_t f = 0;
|
||||
uint32_t k = 0;
|
||||
uint32_t t = 0;
|
||||
for (int i = 0; i < rounds; ++i) {
|
||||
if (i >= 0 && i <= 19) {
|
||||
f = (b & c) | ((~b) & d);
|
||||
k = 0x5A827999;
|
||||
} else if (i >= 20 && i <= 39) {
|
||||
f = b ^ c ^ d;
|
||||
k = 0x6ED9EBA1;
|
||||
} else if (i >= 40 && i <= 59) {
|
||||
f = (b & c) | (b & d) | (c & d);
|
||||
k = 0x8F1BBCDC;
|
||||
} else if (i >= 60 && i <= 79) {
|
||||
f = b ^ c ^ d;
|
||||
k = 0xCA62C1D6;
|
||||
}
|
||||
|
||||
t = rotate_u(a, 5) + f + e + k + w[i];
|
||||
e = d;
|
||||
d = c;
|
||||
c = rotate_u(b, 30);
|
||||
b = a;
|
||||
a = t;
|
||||
}
|
||||
h0 += a;
|
||||
h1 += b;
|
||||
h2 += c;
|
||||
h3 += d;
|
||||
h4 += e;
|
||||
}
|
||||
PIByteArray ret;
|
||||
ret << piChangedEndian(h0) << piChangedEndian(h1) << piChangedEndian(h2) << piChangedEndian(h3) << piChangedEndian(h4);
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user