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