00001
00002
00003
00004
00005
00006
00007
00008 #include <botan/has160.h>
00009 #include <botan/loadstor.h>
00010 #include <botan/rotate.h>
00011
00012 namespace Botan {
00013
00014 namespace HAS_160_F {
00015
00016
00017
00018
00019 inline void F1(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E,
00020 u32bit msg, u32bit rot)
00021 {
00022 E += rotate_left(A, rot) + (D ^ (B & (C ^ D))) + msg;
00023 B = rotate_left(B, 10);
00024 }
00025
00026
00027
00028
00029 inline void F2(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E,
00030 u32bit msg, u32bit rot)
00031 {
00032 E += rotate_left(A, rot) + (B ^ C ^ D) + msg + 0x5A827999;
00033 B = rotate_left(B, 17);
00034 }
00035
00036
00037
00038
00039 inline void F3(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E,
00040 u32bit msg, u32bit rot)
00041 {
00042 E += rotate_left(A, rot) + (C ^ (B | ~D)) + msg + 0x6ED9EBA1;
00043 B = rotate_left(B, 25);
00044 }
00045
00046
00047
00048
00049 inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E,
00050 u32bit msg, u32bit rot)
00051 {
00052 E += rotate_left(A, rot) + (B ^ C ^ D) + msg + 0x8F1BBCDC;
00053 B = rotate_left(B, 30);
00054 }
00055
00056 }
00057
00058
00059
00060
00061 void HAS_160::compress_n(const byte input[], u32bit blocks)
00062 {
00063 using namespace HAS_160_F;
00064
00065 u32bit A = digest[0], B = digest[1], C = digest[2],
00066 D = digest[3], E = digest[4];
00067
00068 for(u32bit i = 0; i != blocks; ++i)
00069 {
00070 load_le(X.begin(), input, 16);
00071
00072 X[16] = X[ 0] ^ X[ 1] ^ X[ 2] ^ X[ 3];
00073 X[17] = X[ 4] ^ X[ 5] ^ X[ 6] ^ X[ 7];
00074 X[18] = X[ 8] ^ X[ 9] ^ X[10] ^ X[11];
00075 X[19] = X[12] ^ X[13] ^ X[14] ^ X[15];
00076 F1(A,B,C,D,E,X[18], 5); F1(E,A,B,C,D,X[ 0],11);
00077 F1(D,E,A,B,C,X[ 1], 7); F1(C,D,E,A,B,X[ 2],15);
00078 F1(B,C,D,E,A,X[ 3], 6); F1(A,B,C,D,E,X[19],13);
00079 F1(E,A,B,C,D,X[ 4], 8); F1(D,E,A,B,C,X[ 5],14);
00080 F1(C,D,E,A,B,X[ 6], 7); F1(B,C,D,E,A,X[ 7],12);
00081 F1(A,B,C,D,E,X[16], 9); F1(E,A,B,C,D,X[ 8],11);
00082 F1(D,E,A,B,C,X[ 9], 8); F1(C,D,E,A,B,X[10],15);
00083 F1(B,C,D,E,A,X[11], 6); F1(A,B,C,D,E,X[17],12);
00084 F1(E,A,B,C,D,X[12], 9); F1(D,E,A,B,C,X[13],14);
00085 F1(C,D,E,A,B,X[14], 5); F1(B,C,D,E,A,X[15],13);
00086
00087 X[16] = X[ 3] ^ X[ 6] ^ X[ 9] ^ X[12];
00088 X[17] = X[ 2] ^ X[ 5] ^ X[ 8] ^ X[15];
00089 X[18] = X[ 1] ^ X[ 4] ^ X[11] ^ X[14];
00090 X[19] = X[ 0] ^ X[ 7] ^ X[10] ^ X[13];
00091 F2(A,B,C,D,E,X[18], 5); F2(E,A,B,C,D,X[ 3],11);
00092 F2(D,E,A,B,C,X[ 6], 7); F2(C,D,E,A,B,X[ 9],15);
00093 F2(B,C,D,E,A,X[12], 6); F2(A,B,C,D,E,X[19],13);
00094 F2(E,A,B,C,D,X[15], 8); F2(D,E,A,B,C,X[ 2],14);
00095 F2(C,D,E,A,B,X[ 5], 7); F2(B,C,D,E,A,X[ 8],12);
00096 F2(A,B,C,D,E,X[16], 9); F2(E,A,B,C,D,X[11],11);
00097 F2(D,E,A,B,C,X[14], 8); F2(C,D,E,A,B,X[ 1],15);
00098 F2(B,C,D,E,A,X[ 4], 6); F2(A,B,C,D,E,X[17],12);
00099 F2(E,A,B,C,D,X[ 7], 9); F2(D,E,A,B,C,X[10],14);
00100 F2(C,D,E,A,B,X[13], 5); F2(B,C,D,E,A,X[ 0],13);
00101
00102 X[16] = X[ 5] ^ X[ 7] ^ X[12] ^ X[14];
00103 X[17] = X[ 0] ^ X[ 2] ^ X[ 9] ^ X[11];
00104 X[18] = X[ 4] ^ X[ 6] ^ X[13] ^ X[15];
00105 X[19] = X[ 1] ^ X[ 3] ^ X[ 8] ^ X[10];
00106 F3(A,B,C,D,E,X[18], 5); F3(E,A,B,C,D,X[12],11);
00107 F3(D,E,A,B,C,X[ 5], 7); F3(C,D,E,A,B,X[14],15);
00108 F3(B,C,D,E,A,X[ 7], 6); F3(A,B,C,D,E,X[19],13);
00109 F3(E,A,B,C,D,X[ 0], 8); F3(D,E,A,B,C,X[ 9],14);
00110 F3(C,D,E,A,B,X[ 2], 7); F3(B,C,D,E,A,X[11],12);
00111 F3(A,B,C,D,E,X[16], 9); F3(E,A,B,C,D,X[ 4],11);
00112 F3(D,E,A,B,C,X[13], 8); F3(C,D,E,A,B,X[ 6],15);
00113 F3(B,C,D,E,A,X[15], 6); F3(A,B,C,D,E,X[17],12);
00114 F3(E,A,B,C,D,X[ 8], 9); F3(D,E,A,B,C,X[ 1],14);
00115 F3(C,D,E,A,B,X[10], 5); F3(B,C,D,E,A,X[ 3],13);
00116
00117 X[16] = X[ 2] ^ X[ 7] ^ X[ 8] ^ X[13];
00118 X[17] = X[ 3] ^ X[ 4] ^ X[ 9] ^ X[14];
00119 X[18] = X[ 0] ^ X[ 5] ^ X[10] ^ X[15];
00120 X[19] = X[ 1] ^ X[ 6] ^ X[11] ^ X[12];
00121 F4(A,B,C,D,E,X[18], 5); F4(E,A,B,C,D,X[ 7],11);
00122 F4(D,E,A,B,C,X[ 2], 7); F4(C,D,E,A,B,X[13],15);
00123 F4(B,C,D,E,A,X[ 8], 6); F4(A,B,C,D,E,X[19],13);
00124 F4(E,A,B,C,D,X[ 3], 8); F4(D,E,A,B,C,X[14],14);
00125 F4(C,D,E,A,B,X[ 9], 7); F4(B,C,D,E,A,X[ 4],12);
00126 F4(A,B,C,D,E,X[16], 9); F4(E,A,B,C,D,X[15],11);
00127 F4(D,E,A,B,C,X[10], 8); F4(C,D,E,A,B,X[ 5],15);
00128 F4(B,C,D,E,A,X[ 0], 6); F4(A,B,C,D,E,X[17],12);
00129 F4(E,A,B,C,D,X[11], 9); F4(D,E,A,B,C,X[ 6],14);
00130 F4(C,D,E,A,B,X[ 1], 5); F4(B,C,D,E,A,X[12],13);
00131
00132 A = (digest[0] += A);
00133 B = (digest[1] += B);
00134 C = (digest[2] += C);
00135 D = (digest[3] += D);
00136 E = (digest[4] += E);
00137
00138 input += HASH_BLOCK_SIZE;
00139 }
00140 }
00141
00142
00143
00144
00145 void HAS_160::copy_out(byte output[])
00146 {
00147 for(u32bit j = 0; j != OUTPUT_LENGTH; j += 4)
00148 store_le(digest[j/4], output + j);
00149 }
00150
00151
00152
00153
00154 void HAS_160::clear()
00155 {
00156 MDx_HashFunction::clear();
00157 X.clear();
00158 digest[0] = 0x67452301;
00159 digest[1] = 0xEFCDAB89;
00160 digest[2] = 0x98BADCFE;
00161 digest[3] = 0x10325476;
00162 digest[4] = 0xC3D2E1F0;
00163 }
00164
00165 }