Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
whirlpool.c
Go to the documentation of this file.
00001 /** 00002 * @file whirlpool.c 00003 * @brief Whirlpool hash function 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneCrypto Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @section Description 00026 * 00027 * Whirlpool is a hash function that operates on messages less than 2^256 bits 00028 * in length, and produces a message digest of 512 bits 00029 * 00030 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00031 * @version 1.7.6 00032 **/ 00033 00034 //Switch to the appropriate trace level 00035 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL 00036 00037 //Dependencies 00038 #include <string.h> 00039 #include "crypto.h" 00040 #include "whirlpool.h" 00041 00042 //Check crypto library configuration 00043 #if (WHIRLPOOL_SUPPORT == ENABLED) 00044 00045 //Round function 00046 #define RHO(b, a, n, c) \ 00047 { \ 00048 b = t[(a[n] >> 56) & 0xFF]; \ 00049 b ^= ROR64(t[(a[(n + 7) % 8] >> 48) & 0xFF], 8); \ 00050 b ^= ROR64(t[(a[(n + 6) % 8] >> 40) & 0xFF], 16); \ 00051 b ^= ROR64(t[(a[(n + 5) % 8] >> 32) & 0xFF], 24); \ 00052 b ^= ROR64(t[(a[(n + 4) % 8] >> 24) & 0xFF], 32); \ 00053 b ^= ROR64(t[(a[(n + 3) % 8] >> 16) & 0xFF], 40); \ 00054 b ^= ROR64(t[(a[(n + 2) % 8] >> 8) & 0xFF], 48); \ 00055 b ^= ROR64(t[a[(n + 1) % 8] & 0xFF], 56); \ 00056 b ^= c; \ 00057 } 00058 00059 //Whirlpool padding 00060 static const uint8_t padding[64] = 00061 { 00062 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00063 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00064 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00065 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 00066 }; 00067 00068 //Whirlpool constants 00069 static const uint64_t rc[10] = 00070 { 00071 0x1823C6E887B8014F, 00072 0x36A6D2F5796F9152, 00073 0x60BC9B8EA30C7B35, 00074 0x1DE0D7C22E4BFE57, 00075 0x157737E59FF04ADA, 00076 0x58C9290AB1A06B85, 00077 0xBD5D10F4CB3E0567, 00078 0xE427418BA77D95D8, 00079 0xFBEE7C66DD17479E, 00080 0xCA2DBF07AD5A8333 00081 }; 00082 00083 //Whirlpool look-up table 00084 static const uint64_t t[256] = 00085 { 00086 0x18186018C07830D8, 0x23238C2305AF4626, 0xC6C63FC67EF991B8, 0xE8E887E8136FCDFB, 00087 0x878726874CA113CB, 0xB8B8DAB8A9626D11, 0x0101040108050209, 0x4F4F214F426E9E0D, 00088 0x3636D836ADEE6C9B, 0xA6A6A2A6590451FF, 0xD2D26FD2DEBDB90C, 0xF5F5F3F5FB06F70E, 00089 0x7979F979EF80F296, 0x6F6FA16F5FCEDE30, 0x91917E91FCEF3F6D, 0x52525552AA07A4F8, 00090 0x60609D6027FDC047, 0xBCBCCABC89766535, 0x9B9B569BACCD2B37, 0x8E8E028E048C018A, 00091 0xA3A3B6A371155BD2, 0x0C0C300C603C186C, 0x7B7BF17BFF8AF684, 0x3535D435B5E16A80, 00092 0x1D1D741DE8693AF5, 0xE0E0A7E05347DDB3, 0xD7D77BD7F6ACB321, 0xC2C22FC25EED999C, 00093 0x2E2EB82E6D965C43, 0x4B4B314B627A9629, 0xFEFEDFFEA321E15D, 0x575741578216AED5, 00094 0x15155415A8412ABD, 0x7777C1779FB6EEE8, 0x3737DC37A5EB6E92, 0xE5E5B3E57B56D79E, 00095 0x9F9F469F8CD92313, 0xF0F0E7F0D317FD23, 0x4A4A354A6A7F9420, 0xDADA4FDA9E95A944, 00096 0x58587D58FA25B0A2, 0xC9C903C906CA8FCF, 0x2929A429558D527C, 0x0A0A280A5022145A, 00097 0xB1B1FEB1E14F7F50, 0xA0A0BAA0691A5DC9, 0x6B6BB16B7FDAD614, 0x85852E855CAB17D9, 00098 0xBDBDCEBD8173673C, 0x5D5D695DD234BA8F, 0x1010401080502090, 0xF4F4F7F4F303F507, 00099 0xCBCB0BCB16C08BDD, 0x3E3EF83EEDC67CD3, 0x0505140528110A2D, 0x676781671FE6CE78, 00100 0xE4E4B7E47353D597, 0x27279C2725BB4E02, 0x4141194132588273, 0x8B8B168B2C9D0BA7, 00101 0xA7A7A6A7510153F6, 0x7D7DE97DCF94FAB2, 0x95956E95DCFB3749, 0xD8D847D88E9FAD56, 00102 0xFBFBCBFB8B30EB70, 0xEEEE9FEE2371C1CD, 0x7C7CED7CC791F8BB, 0x6666856617E3CC71, 00103 0xDDDD53DDA68EA77B, 0x17175C17B84B2EAF, 0x4747014702468E45, 0x9E9E429E84DC211A, 00104 0xCACA0FCA1EC589D4, 0x2D2DB42D75995A58, 0xBFBFC6BF9179632E, 0x07071C07381B0E3F, 00105 0xADAD8EAD012347AC, 0x5A5A755AEA2FB4B0, 0x838336836CB51BEF, 0x3333CC3385FF66B6, 00106 0x636391633FF2C65C, 0x02020802100A0412, 0xAAAA92AA39384993, 0x7171D971AFA8E2DE, 00107 0xC8C807C80ECF8DC6, 0x19196419C87D32D1, 0x494939497270923B, 0xD9D943D9869AAF5F, 00108 0xF2F2EFF2C31DF931, 0xE3E3ABE34B48DBA8, 0x5B5B715BE22AB6B9, 0x88881A8834920DBC, 00109 0x9A9A529AA4C8293E, 0x262698262DBE4C0B, 0x3232C8328DFA64BF, 0xB0B0FAB0E94A7D59, 00110 0xE9E983E91B6ACFF2, 0x0F0F3C0F78331E77, 0xD5D573D5E6A6B733, 0x80803A8074BA1DF4, 00111 0xBEBEC2BE997C6127, 0xCDCD13CD26DE87EB, 0x3434D034BDE46889, 0x48483D487A759032, 00112 0xFFFFDBFFAB24E354, 0x7A7AF57AF78FF48D, 0x90907A90F4EA3D64, 0x5F5F615FC23EBE9D, 00113 0x202080201DA0403D, 0x6868BD6867D5D00F, 0x1A1A681AD07234CA, 0xAEAE82AE192C41B7, 00114 0xB4B4EAB4C95E757D, 0x54544D549A19A8CE, 0x93937693ECE53B7F, 0x222288220DAA442F, 00115 0x64648D6407E9C863, 0xF1F1E3F1DB12FF2A, 0x7373D173BFA2E6CC, 0x12124812905A2482, 00116 0x40401D403A5D807A, 0x0808200840281048, 0xC3C32BC356E89B95, 0xECEC97EC337BC5DF, 00117 0xDBDB4BDB9690AB4D, 0xA1A1BEA1611F5FC0, 0x8D8D0E8D1C830791, 0x3D3DF43DF5C97AC8, 00118 0x97976697CCF1335B, 0x0000000000000000, 0xCFCF1BCF36D483F9, 0x2B2BAC2B4587566E, 00119 0x7676C57697B3ECE1, 0x8282328264B019E6, 0xD6D67FD6FEA9B128, 0x1B1B6C1BD87736C3, 00120 0xB5B5EEB5C15B7774, 0xAFAF86AF112943BE, 0x6A6AB56A77DFD41D, 0x50505D50BA0DA0EA, 00121 0x45450945124C8A57, 0xF3F3EBF3CB18FB38, 0x3030C0309DF060AD, 0xEFEF9BEF2B74C3C4, 00122 0x3F3FFC3FE5C37EDA, 0x55554955921CAAC7, 0xA2A2B2A2791059DB, 0xEAEA8FEA0365C9E9, 00123 0x656589650FECCA6A, 0xBABAD2BAB9686903, 0x2F2FBC2F65935E4A, 0xC0C027C04EE79D8E, 00124 0xDEDE5FDEBE81A160, 0x1C1C701CE06C38FC, 0xFDFDD3FDBB2EE746, 0x4D4D294D52649A1F, 00125 0x92927292E4E03976, 0x7575C9758FBCEAFA, 0x06061806301E0C36, 0x8A8A128A249809AE, 00126 0xB2B2F2B2F940794B, 0xE6E6BFE66359D185, 0x0E0E380E70361C7E, 0x1F1F7C1FF8633EE7, 00127 0x6262956237F7C455, 0xD4D477D4EEA3B53A, 0xA8A89AA829324D81, 0x96966296C4F43152, 00128 0xF9F9C3F99B3AEF62, 0xC5C533C566F697A3, 0x2525942535B14A10, 0x59597959F220B2AB, 00129 0x84842A8454AE15D0, 0x7272D572B7A7E4C5, 0x3939E439D5DD72EC, 0x4C4C2D4C5A619816, 00130 0x5E5E655ECA3BBC94, 0x7878FD78E785F09F, 0x3838E038DDD870E5, 0x8C8C0A8C14860598, 00131 0xD1D163D1C6B2BF17, 0xA5A5AEA5410B57E4, 0xE2E2AFE2434DD9A1, 0x616199612FF8C24E, 00132 0xB3B3F6B3F1457B42, 0x2121842115A54234, 0x9C9C4A9C94D62508, 0x1E1E781EF0663CEE, 00133 0x4343114322528661, 0xC7C73BC776FC93B1, 0xFCFCD7FCB32BE54F, 0x0404100420140824, 00134 0x51515951B208A2E3, 0x99995E99BCC72F25, 0x6D6DA96D4FC4DA22, 0x0D0D340D68391A65, 00135 0xFAFACFFA8335E979, 0xDFDF5BDFB684A369, 0x7E7EE57ED79BFCA9, 0x242490243DB44819, 00136 0x3B3BEC3BC5D776FE, 0xABAB96AB313D4B9A, 0xCECE1FCE3ED181F0, 0x1111441188552299, 00137 0x8F8F068F0C890383, 0x4E4E254E4A6B9C04, 0xB7B7E6B7D1517366, 0xEBEB8BEB0B60CBE0, 00138 0x3C3CF03CFDCC78C1, 0x81813E817CBF1FFD, 0x94946A94D4FE3540, 0xF7F7FBF7EB0CF31C, 00139 0xB9B9DEB9A1676F18, 0x13134C13985F268B, 0x2C2CB02C7D9C5851, 0xD3D36BD3D6B8BB05, 00140 0xE7E7BBE76B5CD38C, 0x6E6EA56E57CBDC39, 0xC4C437C46EF395AA, 0x03030C03180F061B, 00141 0x565645568A13ACDC, 0x44440D441A49885E, 0x7F7FE17FDF9EFEA0, 0xA9A99EA921374F88, 00142 0x2A2AA82A4D825467, 0xBBBBD6BBB16D6B0A, 0xC1C123C146E29F87, 0x53535153A202A6F1, 00143 0xDCDC57DCAE8BA572, 0x0B0B2C0B58271653, 0x9D9D4E9D9CD32701, 0x6C6CAD6C47C1D82B, 00144 0x3131C43195F562A4, 0x7474CD7487B9E8F3, 0xF6F6FFF6E309F115, 0x464605460A438C4C, 00145 0xACAC8AAC092645A5, 0x89891E893C970FB5, 0x14145014A04428B4, 0xE1E1A3E15B42DFBA, 00146 0x16165816B04E2CA6, 0x3A3AE83ACDD274F7, 0x6969B9696FD0D206, 0x09092409482D1241, 00147 0x7070DD70A7ADE0D7, 0xB6B6E2B6D954716F, 0xD0D067D0CEB7BD1E, 0xEDED93ED3B7EC7D6, 00148 0xCCCC17CC2EDB85E2, 0x424215422A578468, 0x98985A98B4C22D2C, 0xA4A4AAA4490E55ED, 00149 0x2828A0285D885075, 0x5C5C6D5CDA31B886, 0xF8F8C7F8933FED6B, 0x8686228644A411C2 00150 }; 00151 00152 //Whirlpool object identifier (1.0.10118.3.0.55) 00153 static const uint8_t whirlpoolOid[] = {0x28, 0xCF, 0x06, 0x03, 0x00, 0x37}; 00154 00155 //Common interface for hash algorithms 00156 const HashAlgo whirlpoolHashAlgo = 00157 { 00158 "WHIRLPOOL", 00159 whirlpoolOid, 00160 sizeof(whirlpoolOid), 00161 sizeof(WhirlpoolContext), 00162 WHIRLPOOL_BLOCK_SIZE, 00163 WHIRLPOOL_DIGEST_SIZE, 00164 (HashAlgoCompute) whirlpoolCompute, 00165 (HashAlgoInit) whirlpoolInit, 00166 (HashAlgoUpdate) whirlpoolUpdate, 00167 (HashAlgoFinal) whirlpoolFinal 00168 }; 00169 00170 00171 /** 00172 * @brief Digest a message using Whirlpool 00173 * @param[in] data Pointer to the message being hashed 00174 * @param[in] length Length of the message 00175 * @param[out] digest Pointer to the calculated digest 00176 * @return Error code 00177 **/ 00178 00179 error_t whirlpoolCompute(const void *data, size_t length, uint8_t *digest) 00180 { 00181 //Allocate a memory buffer to hold the Whirlpool context 00182 WhirlpoolContext *context = cryptoAllocMem(sizeof(WhirlpoolContext)); 00183 //Failed to allocate memory? 00184 if(context == NULL) 00185 return ERROR_OUT_OF_MEMORY; 00186 00187 //Initialize the Whirlpool context 00188 whirlpoolInit(context); 00189 //Digest the message 00190 whirlpoolUpdate(context, data, length); 00191 //Finalize the Whirlpool message digest 00192 whirlpoolFinal(context, digest); 00193 00194 //Free previously allocated memory 00195 cryptoFreeMem(context); 00196 //Successful processing 00197 return NO_ERROR; 00198 } 00199 00200 00201 /** 00202 * @brief Initialize Whirlpool message digest context 00203 * @param[in] context Pointer to the Whirlpool context to initialize 00204 **/ 00205 00206 void whirlpoolInit(WhirlpoolContext *context) 00207 { 00208 uint_t i; 00209 00210 //Set initial hash value 00211 for(i = 0; i < 8; i++) 00212 context->h[i] = 0; 00213 00214 //Number of bytes in the buffer 00215 context->size = 0; 00216 //Total length of the message 00217 context->totalSize = 0; 00218 } 00219 00220 00221 /** 00222 * @brief Update the Whirlpool context with a portion of the message being hashed 00223 * @param[in] context Pointer to the Whirlpool context 00224 * @param[in] data Pointer to the buffer being hashed 00225 * @param[in] length Length of the buffer 00226 **/ 00227 00228 void whirlpoolUpdate(WhirlpoolContext *context, const void *data, size_t length) 00229 { 00230 size_t n; 00231 00232 //Process the incoming data 00233 while(length > 0) 00234 { 00235 //The buffer can hold at most 64 bytes 00236 n = MIN(length, 64 - context->size); 00237 00238 //Copy the data to the buffer 00239 memcpy(context->buffer + context->size, data, n); 00240 00241 //Update the Whirlpool context 00242 context->size += n; 00243 context->totalSize += n; 00244 //Advance the data pointer 00245 data = (uint8_t *) data + n; 00246 //Remaining bytes to process 00247 length -= n; 00248 00249 //Process message in 8-word blocks 00250 if(context->size == 64) 00251 { 00252 //Transform the 8-word block 00253 whirlpoolProcessBlock(context); 00254 //Empty the buffer 00255 context->size = 0; 00256 } 00257 } 00258 } 00259 00260 00261 /** 00262 * @brief Finish the Whirlpool message digest 00263 * @param[in] context Pointer to the Whirlpool context 00264 * @param[out] digest Calculated digest (optional parameter) 00265 **/ 00266 00267 void whirlpoolFinal(WhirlpoolContext *context, uint8_t *digest) 00268 { 00269 uint_t i; 00270 size_t paddingSize; 00271 uint64_t totalSize; 00272 00273 //Length of the original message (before padding) 00274 totalSize = context->totalSize * 8; 00275 00276 //Pad the message so that its length is congruent to 32 modulo 64 00277 if(context->size < 32) 00278 paddingSize = 32 - context->size; 00279 else 00280 paddingSize = 64 + 32 - context->size; 00281 00282 //Append padding 00283 whirlpoolUpdate(context, padding, paddingSize); 00284 00285 //Append the length of the original message 00286 context->x[4] = 0; 00287 context->x[5] = 0; 00288 context->x[6] = 0; 00289 context->x[7] = htobe64(totalSize); 00290 00291 //Calculate the message digest 00292 whirlpoolProcessBlock(context); 00293 00294 //Convert from host byte order to big-endian byte order 00295 for(i = 0; i < 8; i++) 00296 context->h[i] = htobe64(context->h[i]); 00297 00298 //Copy the resulting digest 00299 if(digest != NULL) 00300 memcpy(digest, context->digest, WHIRLPOOL_DIGEST_SIZE); 00301 } 00302 00303 00304 /** 00305 * @brief Process message in 16-word blocks 00306 * @param[in] context Pointer to the Whirlpool context 00307 **/ 00308 00309 void whirlpoolProcessBlock(WhirlpoolContext *context) 00310 { 00311 uint_t i; 00312 00313 uint64_t *x = context->x; 00314 uint64_t *k = context->k; 00315 uint64_t *l = context->l; 00316 uint64_t *state = context->state; 00317 00318 //Convert from big-endian byte order to host byte order 00319 for(i = 0; i < 8; i++) 00320 x[i] = betoh64(x[i]); 00321 00322 k[0] = context->h[0]; 00323 k[1] = context->h[1]; 00324 k[2] = context->h[2]; 00325 k[3] = context->h[3]; 00326 k[4] = context->h[4]; 00327 k[5] = context->h[5]; 00328 k[6] = context->h[6]; 00329 k[7] = context->h[7]; 00330 00331 state[0] = x[0] ^ k[0]; 00332 state[1] = x[1] ^ k[1]; 00333 state[2] = x[2] ^ k[2]; 00334 state[3] = x[3] ^ k[3]; 00335 state[4] = x[4] ^ k[4]; 00336 state[5] = x[5] ^ k[5]; 00337 state[6] = x[6] ^ k[6]; 00338 state[7] = x[7] ^ k[7]; 00339 00340 //Iterate over all rounds 00341 for(i = 0; i < 10; i++) 00342 { 00343 //Key schedule 00344 RHO(l[0], k, 0, rc[i]); 00345 RHO(l[1], k, 1, 0); 00346 RHO(l[2], k, 2, 0); 00347 RHO(l[3], k, 3, 0); 00348 RHO(l[4], k, 4, 0); 00349 RHO(l[5], k, 5, 0); 00350 RHO(l[6], k, 6, 0); 00351 RHO(l[7], k, 7, 0); 00352 00353 k[0] = l[0]; 00354 k[1] = l[1]; 00355 k[2] = l[2]; 00356 k[3] = l[3]; 00357 k[4] = l[4]; 00358 k[5] = l[5]; 00359 k[6] = l[6]; 00360 k[7] = l[7]; 00361 00362 //Apply the round function 00363 RHO(l[0], state, 0, k[0]); 00364 RHO(l[1], state, 1, k[1]); 00365 RHO(l[2], state, 2, k[2]); 00366 RHO(l[3], state, 3, k[3]); 00367 RHO(l[4], state, 4, k[4]); 00368 RHO(l[5], state, 5, k[5]); 00369 RHO(l[6], state, 6, k[6]); 00370 RHO(l[7], state, 7, k[7]); 00371 00372 state[0] = l[0]; 00373 state[1] = l[1]; 00374 state[2] = l[2]; 00375 state[3] = l[3]; 00376 state[4] = l[4]; 00377 state[5] = l[5]; 00378 state[6] = l[6]; 00379 state[7] = l[7]; 00380 } 00381 00382 //Update the hash value 00383 context->h[0] ^= state[0] ^ x[0]; 00384 context->h[1] ^= state[1] ^ x[1]; 00385 context->h[2] ^= state[2] ^ x[2]; 00386 context->h[3] ^= state[3] ^ x[3]; 00387 context->h[4] ^= state[4] ^ x[4]; 00388 context->h[5] ^= state[5] ^ x[5]; 00389 context->h[6] ^= state[6] ^ x[6]; 00390 context->h[7] ^= state[7] ^ x[7]; 00391 } 00392 00393 #endif 00394
Generated on Tue Jul 12 2022 17:10:17 by
