summaryrefslogtreecommitdiffstats
path: root/drkonqi/sha1.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drkonqi/sha1.cpp')
-rw-r--r--drkonqi/sha1.cpp344
1 files changed, 344 insertions, 0 deletions
diff --git a/drkonqi/sha1.cpp b/drkonqi/sha1.cpp
new file mode 100644
index 000000000..86dd30a99
--- /dev/null
+++ b/drkonqi/sha1.cpp
@@ -0,0 +1,344 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 George Staikos <staikos@kde.org>
+ Based heavily on SHA1 code from GPG 1.0.3 (C) 1998 FSF
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <config.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h> /* For uintXX_t on OSX */
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h> /* For uintXX_t on Tru64 */
+#endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#include "sha1.h"
+#include <string.h>
+
+// FIXME: this can be optimized to one instruction on most cpus.
+#define rol(x,y) ((x << y) | (x >> (32-y)))
+
+
+#define K1 0x5a827999L
+#define K2 0x6ed9eba1L
+#define K3 0x8f1bbcdcL
+#define K4 0xca62c1d6L
+#define F1(x,y,z) ( z ^ ( x & ( y ^ z ) ) )
+#define F2(x,y,z) ( x ^ y ^ z )
+#define F3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) )
+#define F4(x,y,z) ( x ^ y ^ z )
+
+#define M(i) ( tm = x[i&0x0f] ^ x[(i-14)&0x0f] \
+ ^ x[(i-8)&0x0f] ^ x[(i-3)&0x0f] \
+ , (x[i&0x0f] = (tm << 1) | (tm >> 31)))
+
+#define R(a,b,c,d,e,f,k,m) do { e += rol(a, 5) \
+ + f(b, c, d) \
+ + k \
+ + m; \
+ b = rol(b, 30); \
+ } while(0)
+
+
+SHA1::SHA1() {
+ _hashlen = 160;
+ _init = false;
+ reset();
+}
+
+
+int SHA1::reset() {
+ _h0 = 0x67452301;
+ _h1 = 0xefcdab89;
+ _h2 = 0x98badcfe;
+ _h3 = 0x10325476;
+ _h4 = 0xc3d2e1f0;
+ _nblocks = 0;
+ _count = 0;
+ memset(_buf, 0, 56); // clear the buffer
+
+ _init = true;
+ return 0;
+}
+
+
+int SHA1::size() const {
+ return _hashlen;
+}
+
+
+SHA1::~SHA1() {
+
+}
+
+
+void SHA1::transform(void *data) {
+ unsigned int a, b, c, d, e, tm;
+ unsigned int x[16];
+ unsigned char *_data = (unsigned char *)data;
+
+ a = _h0;
+ b = _h1;
+ c = _h2;
+ d = _h3;
+ e = _h4;
+
+#ifdef WORDS_BIGENDIAN
+ memcpy(x, _data, 64);
+#else
+ int i;
+ unsigned char *p2;
+ for (i = 0, p2 = (unsigned char *)x;
+ i < 16; i++, p2 += 4) {
+ p2[3] = *_data++;
+ p2[2] = *_data++;
+ p2[1] = *_data++;
+ p2[0] = *_data++;
+ }
+#endif
+
+ R(a, b, c, d, e, F1, K1, x[ 0]);
+ R(e, a, b, c, d, F1, K1, x[ 1]);
+ R(d, e, a, b, c, F1, K1, x[ 2]);
+ R(c, d, e, a, b, F1, K1, x[ 3]);
+ R(b, c, d, e, a, F1, K1, x[ 4]);
+ R(a, b, c, d, e, F1, K1, x[ 5]);
+ R(e, a, b, c, d, F1, K1, x[ 6]);
+ R(d, e, a, b, c, F1, K1, x[ 7]);
+ R(c, d, e, a, b, F1, K1, x[ 8]);
+ R(b, c, d, e, a, F1, K1, x[ 9]);
+ R(a, b, c, d, e, F1, K1, x[10]);
+ R(e, a, b, c, d, F1, K1, x[11]);
+ R(d, e, a, b, c, F1, K1, x[12]);
+ R(c, d, e, a, b, F1, K1, x[13]);
+ R(b, c, d, e, a, F1, K1, x[14]);
+ R(a, b, c, d, e, F1, K1, x[15]);
+ R(e, a, b, c, d, F1, K1, M(16));
+ R(d, e, a, b, c, F1, K1, M(17));
+ R(c, d, e, a, b, F1, K1, M(18));
+ R(b, c, d, e, a, F1, K1, M(19));
+ R(a, b, c, d, e, F2, K2, M(20));
+ R(e, a, b, c, d, F2, K2, M(21));
+ R(d, e, a, b, c, F2, K2, M(22));
+ R(c, d, e, a, b, F2, K2, M(23));
+ R(b, c, d, e, a, F2, K2, M(24));
+ R(a, b, c, d, e, F2, K2, M(25));
+ R(e, a, b, c, d, F2, K2, M(26));
+ R(d, e, a, b, c, F2, K2, M(27));
+ R(c, d, e, a, b, F2, K2, M(28));
+ R(b, c, d, e, a, F2, K2, M(29));
+ R(a, b, c, d, e, F2, K2, M(30));
+ R(e, a, b, c, d, F2, K2, M(31));
+ R(d, e, a, b, c, F2, K2, M(32));
+ R(c, d, e, a, b, F2, K2, M(33));
+ R(b, c, d, e, a, F2, K2, M(34));
+ R(a, b, c, d, e, F2, K2, M(35));
+ R(e, a, b, c, d, F2, K2, M(36));
+ R(d, e, a, b, c, F2, K2, M(37));
+ R(c, d, e, a, b, F2, K2, M(38));
+ R(b, c, d, e, a, F2, K2, M(39));
+ R(a, b, c, d, e, F3, K3, M(40));
+ R(e, a, b, c, d, F3, K3, M(41));
+ R(d, e, a, b, c, F3, K3, M(42));
+ R(c, d, e, a, b, F3, K3, M(43));
+ R(b, c, d, e, a, F3, K3, M(44));
+ R(a, b, c, d, e, F3, K3, M(45));
+ R(e, a, b, c, d, F3, K3, M(46));
+ R(d, e, a, b, c, F3, K3, M(47));
+ R(c, d, e, a, b, F3, K3, M(48));
+ R(b, c, d, e, a, F3, K3, M(49));
+ R(a, b, c, d, e, F3, K3, M(50));
+ R(e, a, b, c, d, F3, K3, M(51));
+ R(d, e, a, b, c, F3, K3, M(52));
+ R(c, d, e, a, b, F3, K3, M(53));
+ R(b, c, d, e, a, F3, K3, M(54));
+ R(a, b, c, d, e, F3, K3, M(55));
+ R(e, a, b, c, d, F3, K3, M(56));
+ R(d, e, a, b, c, F3, K3, M(57));
+ R(c, d, e, a, b, F3, K3, M(58));
+ R(b, c, d, e, a, F3, K3, M(59));
+ R(a, b, c, d, e, F4, K4, M(60));
+ R(e, a, b, c, d, F4, K4, M(61));
+ R(d, e, a, b, c, F4, K4, M(62));
+ R(c, d, e, a, b, F4, K4, M(63));
+ R(b, c, d, e, a, F4, K4, M(64));
+ R(a, b, c, d, e, F4, K4, M(65));
+ R(e, a, b, c, d, F4, K4, M(66));
+ R(d, e, a, b, c, F4, K4, M(67));
+ R(c, d, e, a, b, F4, K4, M(68));
+ R(b, c, d, e, a, F4, K4, M(69));
+ R(a, b, c, d, e, F4, K4, M(70));
+ R(e, a, b, c, d, F4, K4, M(71));
+ R(d, e, a, b, c, F4, K4, M(72));
+ R(c, d, e, a, b, F4, K4, M(73));
+ R(b, c, d, e, a, F4, K4, M(74));
+ R(a, b, c, d, e, F4, K4, M(75));
+ R(e, a, b, c, d, F4, K4, M(76));
+ R(d, e, a, b, c, F4, K4, M(77));
+ R(c, d, e, a, b, F4, K4, M(78));
+ R(b, c, d, e, a, F4, K4, M(79));
+
+ _h0 += a;
+ _h1 += b;
+ _h2 += c;
+ _h3 += d;
+ _h4 += e;
+
+}
+
+
+bool SHA1::readyToGo() const {
+ return _init;
+}
+
+
+int SHA1::process(const void *block, int len) {
+ if (!_init) {
+ return -1;
+ }
+
+ unsigned char *_block = (unsigned char *)block;
+
+ int cnt = 0;
+ // Flush the buffer before proceeding
+ if (_count == 64) {
+ transform(_buf);
+ _count = 0;
+ _nblocks++;
+ }
+
+ if (!_block) {
+ return 0;
+ }
+
+ if (_count) {
+ for (; len && _count < 64; len--, cnt++) {
+ _buf[_count++] = *_block++;
+ }
+ process(0, 0); // flush the buffer if necessary
+ if (!len) {
+ return cnt;
+ }
+ }
+
+ while (len >= 64) {
+ transform(_block);
+ _count = 0;
+ _nblocks++;
+ len -= 64;
+ cnt += 64;
+ _block += 64;
+ }
+
+ for (; len && _count < 64; len--, cnt++) {
+ _buf[_count++] = *_block++;
+ }
+
+ return cnt;
+}
+
+
+const unsigned char *SHA1::hash() {
+ unsigned int t, msb, lsb;
+ unsigned char *p;
+
+
+ if (!_init) {
+ return (unsigned char *)_buf;
+ }
+
+ process(0, 0);
+
+ msb = 0;
+ t = _nblocks;
+
+ if ((lsb = t << 6) < t) {
+ msb++;
+ }
+
+ msb += t >> 26;
+ t = lsb;
+
+ if ((lsb = t + _count) < t) {
+ msb++;
+ }
+
+ t = lsb;
+
+ if ((lsb = t << 3) < t) {
+ msb++;
+ }
+
+ msb += t >> 29;
+
+ _buf[_count++] = 0x80;
+
+ if (_count < 56) {
+ while (_count < 56) {
+ _buf[_count++] = 0;
+ }
+ } else {
+ while (_count < 64) {
+ _buf[_count++] = 0;
+ }
+ process(0, 0);
+ memset(_buf, 0, 56);
+ }
+
+ _buf[56] = msb >> 24;
+ _buf[57] = msb >> 16;
+ _buf[58] = msb >> 8;
+ _buf[59] = msb;
+ _buf[60] = lsb >> 24;
+ _buf[61] = lsb >> 16;
+ _buf[62] = lsb >> 8;
+ _buf[63] = lsb;
+
+ transform(_buf);
+
+ p = _buf;
+
+#ifdef WORDS_BIGENDIAN
+#define X( a ) do { *( uint32_t * )p = _h##a; p += 4; } while ( 0 )
+#else
+#define X(a) do { *p++ = _h##a >> 24; *p++ = _h##a >> 16; \
+ *p++ = _h##a >> 8; *p++ = _h##a; } while (0)
+#endif
+
+ X(0);
+ X(1);
+ X(2);
+ X(3);
+ X(4);
+
+#undef X
+
+ _init = false;
+
+ return (unsigned char *)_buf;
+}
+
+
+
+