1*8411e6adSJerome Forissier /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2*8411e6adSJerome Forissier /* SPDX-License-Identifier: Unlicense */
35a913ee7SJerome Forissier #include "tomcrypt_private.h"
45a913ee7SJerome Forissier
55a913ee7SJerome Forissier /**
65a913ee7SJerome Forissier @file rmd320.c
75a913ee7SJerome Forissier RMD320 hash function
85a913ee7SJerome Forissier */
95a913ee7SJerome Forissier
105a913ee7SJerome Forissier #ifdef LTC_RIPEMD320
115a913ee7SJerome Forissier
125a913ee7SJerome Forissier const struct ltc_hash_descriptor rmd320_desc =
135a913ee7SJerome Forissier {
145a913ee7SJerome Forissier "rmd320",
155a913ee7SJerome Forissier 14,
165a913ee7SJerome Forissier 40,
175a913ee7SJerome Forissier 64,
185a913ee7SJerome Forissier
195a913ee7SJerome Forissier /* OID ... does not exist
205a913ee7SJerome Forissier * http://oid-info.com/get/1.3.36.3.2 */
215a913ee7SJerome Forissier { 0 },
225a913ee7SJerome Forissier 0,
235a913ee7SJerome Forissier
245a913ee7SJerome Forissier &rmd320_init,
255a913ee7SJerome Forissier &rmd320_process,
265a913ee7SJerome Forissier &rmd320_done,
275a913ee7SJerome Forissier &rmd320_test,
285a913ee7SJerome Forissier NULL
295a913ee7SJerome Forissier };
305a913ee7SJerome Forissier
315a913ee7SJerome Forissier /* the five basic functions F(), G() and H() */
325a913ee7SJerome Forissier #define F(x, y, z) ((x) ^ (y) ^ (z))
335a913ee7SJerome Forissier #define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
345a913ee7SJerome Forissier #define H(x, y, z) (((x) | ~(y)) ^ (z))
355a913ee7SJerome Forissier #define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
365a913ee7SJerome Forissier #define J(x, y, z) ((x) ^ ((y) | ~(z)))
375a913ee7SJerome Forissier
385a913ee7SJerome Forissier /* the ten basic operations FF() through III() */
395a913ee7SJerome Forissier #define FF(a, b, c, d, e, x, s) \
405a913ee7SJerome Forissier (a) += F((b), (c), (d)) + (x);\
415a913ee7SJerome Forissier (a) = ROLc((a), (s)) + (e);\
425a913ee7SJerome Forissier (c) = ROLc((c), 10);
435a913ee7SJerome Forissier
445a913ee7SJerome Forissier #define GG(a, b, c, d, e, x, s) \
455a913ee7SJerome Forissier (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
465a913ee7SJerome Forissier (a) = ROLc((a), (s)) + (e);\
475a913ee7SJerome Forissier (c) = ROLc((c), 10);
485a913ee7SJerome Forissier
495a913ee7SJerome Forissier #define HH(a, b, c, d, e, x, s) \
505a913ee7SJerome Forissier (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
515a913ee7SJerome Forissier (a) = ROLc((a), (s)) + (e);\
525a913ee7SJerome Forissier (c) = ROLc((c), 10);
535a913ee7SJerome Forissier
545a913ee7SJerome Forissier #define II(a, b, c, d, e, x, s) \
555a913ee7SJerome Forissier (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
565a913ee7SJerome Forissier (a) = ROLc((a), (s)) + (e);\
575a913ee7SJerome Forissier (c) = ROLc((c), 10);
585a913ee7SJerome Forissier
595a913ee7SJerome Forissier #define JJ(a, b, c, d, e, x, s) \
605a913ee7SJerome Forissier (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
615a913ee7SJerome Forissier (a) = ROLc((a), (s)) + (e);\
625a913ee7SJerome Forissier (c) = ROLc((c), 10);
635a913ee7SJerome Forissier
645a913ee7SJerome Forissier #define FFF(a, b, c, d, e, x, s) \
655a913ee7SJerome Forissier (a) += F((b), (c), (d)) + (x);\
665a913ee7SJerome Forissier (a) = ROLc((a), (s)) + (e);\
675a913ee7SJerome Forissier (c) = ROLc((c), 10);
685a913ee7SJerome Forissier
695a913ee7SJerome Forissier #define GGG(a, b, c, d, e, x, s) \
705a913ee7SJerome Forissier (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
715a913ee7SJerome Forissier (a) = ROLc((a), (s)) + (e);\
725a913ee7SJerome Forissier (c) = ROLc((c), 10);
735a913ee7SJerome Forissier
745a913ee7SJerome Forissier #define HHH(a, b, c, d, e, x, s) \
755a913ee7SJerome Forissier (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
765a913ee7SJerome Forissier (a) = ROLc((a), (s)) + (e);\
775a913ee7SJerome Forissier (c) = ROLc((c), 10);
785a913ee7SJerome Forissier
795a913ee7SJerome Forissier #define III(a, b, c, d, e, x, s) \
805a913ee7SJerome Forissier (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
815a913ee7SJerome Forissier (a) = ROLc((a), (s)) + (e);\
825a913ee7SJerome Forissier (c) = ROLc((c), 10);
835a913ee7SJerome Forissier
845a913ee7SJerome Forissier #define JJJ(a, b, c, d, e, x, s) \
855a913ee7SJerome Forissier (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
865a913ee7SJerome Forissier (a) = ROLc((a), (s)) + (e);\
875a913ee7SJerome Forissier (c) = ROLc((c), 10);
885a913ee7SJerome Forissier
895a913ee7SJerome Forissier
905a913ee7SJerome Forissier #ifdef LTC_CLEAN_STACK
ss_rmd320_compress(hash_state * md,const unsigned char * buf)91*8411e6adSJerome Forissier static int ss_rmd320_compress(hash_state *md, const unsigned char *buf)
925a913ee7SJerome Forissier #else
93*8411e6adSJerome Forissier static int s_rmd320_compress(hash_state *md, const unsigned char *buf)
945a913ee7SJerome Forissier #endif
955a913ee7SJerome Forissier {
965a913ee7SJerome Forissier ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,tmp,X[16];
975a913ee7SJerome Forissier int i;
985a913ee7SJerome Forissier
995a913ee7SJerome Forissier /* load words X */
1005a913ee7SJerome Forissier for (i = 0; i < 16; i++){
1015a913ee7SJerome Forissier LOAD32L(X[i], buf + (4 * i));
1025a913ee7SJerome Forissier }
1035a913ee7SJerome Forissier
1045a913ee7SJerome Forissier /* load state */
1055a913ee7SJerome Forissier aa = md->rmd320.state[0];
1065a913ee7SJerome Forissier bb = md->rmd320.state[1];
1075a913ee7SJerome Forissier cc = md->rmd320.state[2];
1085a913ee7SJerome Forissier dd = md->rmd320.state[3];
1095a913ee7SJerome Forissier ee = md->rmd320.state[4];
1105a913ee7SJerome Forissier aaa = md->rmd320.state[5];
1115a913ee7SJerome Forissier bbb = md->rmd320.state[6];
1125a913ee7SJerome Forissier ccc = md->rmd320.state[7];
1135a913ee7SJerome Forissier ddd = md->rmd320.state[8];
1145a913ee7SJerome Forissier eee = md->rmd320.state[9];
1155a913ee7SJerome Forissier
1165a913ee7SJerome Forissier /* round 1 */
1175a913ee7SJerome Forissier FF(aa, bb, cc, dd, ee, X[ 0], 11);
1185a913ee7SJerome Forissier FF(ee, aa, bb, cc, dd, X[ 1], 14);
1195a913ee7SJerome Forissier FF(dd, ee, aa, bb, cc, X[ 2], 15);
1205a913ee7SJerome Forissier FF(cc, dd, ee, aa, bb, X[ 3], 12);
1215a913ee7SJerome Forissier FF(bb, cc, dd, ee, aa, X[ 4], 5);
1225a913ee7SJerome Forissier FF(aa, bb, cc, dd, ee, X[ 5], 8);
1235a913ee7SJerome Forissier FF(ee, aa, bb, cc, dd, X[ 6], 7);
1245a913ee7SJerome Forissier FF(dd, ee, aa, bb, cc, X[ 7], 9);
1255a913ee7SJerome Forissier FF(cc, dd, ee, aa, bb, X[ 8], 11);
1265a913ee7SJerome Forissier FF(bb, cc, dd, ee, aa, X[ 9], 13);
1275a913ee7SJerome Forissier FF(aa, bb, cc, dd, ee, X[10], 14);
1285a913ee7SJerome Forissier FF(ee, aa, bb, cc, dd, X[11], 15);
1295a913ee7SJerome Forissier FF(dd, ee, aa, bb, cc, X[12], 6);
1305a913ee7SJerome Forissier FF(cc, dd, ee, aa, bb, X[13], 7);
1315a913ee7SJerome Forissier FF(bb, cc, dd, ee, aa, X[14], 9);
1325a913ee7SJerome Forissier FF(aa, bb, cc, dd, ee, X[15], 8);
1335a913ee7SJerome Forissier
1345a913ee7SJerome Forissier /* parallel round 1 */
1355a913ee7SJerome Forissier JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
1365a913ee7SJerome Forissier JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
1375a913ee7SJerome Forissier JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
1385a913ee7SJerome Forissier JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
1395a913ee7SJerome Forissier JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
1405a913ee7SJerome Forissier JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
1415a913ee7SJerome Forissier JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
1425a913ee7SJerome Forissier JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
1435a913ee7SJerome Forissier JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
1445a913ee7SJerome Forissier JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
1455a913ee7SJerome Forissier JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
1465a913ee7SJerome Forissier JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
1475a913ee7SJerome Forissier JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
1485a913ee7SJerome Forissier JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
1495a913ee7SJerome Forissier JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
1505a913ee7SJerome Forissier JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
1515a913ee7SJerome Forissier
1525a913ee7SJerome Forissier tmp = aa; aa = aaa; aaa = tmp;
1535a913ee7SJerome Forissier
1545a913ee7SJerome Forissier /* round 2 */
1555a913ee7SJerome Forissier GG(ee, aa, bb, cc, dd, X[ 7], 7);
1565a913ee7SJerome Forissier GG(dd, ee, aa, bb, cc, X[ 4], 6);
1575a913ee7SJerome Forissier GG(cc, dd, ee, aa, bb, X[13], 8);
1585a913ee7SJerome Forissier GG(bb, cc, dd, ee, aa, X[ 1], 13);
1595a913ee7SJerome Forissier GG(aa, bb, cc, dd, ee, X[10], 11);
1605a913ee7SJerome Forissier GG(ee, aa, bb, cc, dd, X[ 6], 9);
1615a913ee7SJerome Forissier GG(dd, ee, aa, bb, cc, X[15], 7);
1625a913ee7SJerome Forissier GG(cc, dd, ee, aa, bb, X[ 3], 15);
1635a913ee7SJerome Forissier GG(bb, cc, dd, ee, aa, X[12], 7);
1645a913ee7SJerome Forissier GG(aa, bb, cc, dd, ee, X[ 0], 12);
1655a913ee7SJerome Forissier GG(ee, aa, bb, cc, dd, X[ 9], 15);
1665a913ee7SJerome Forissier GG(dd, ee, aa, bb, cc, X[ 5], 9);
1675a913ee7SJerome Forissier GG(cc, dd, ee, aa, bb, X[ 2], 11);
1685a913ee7SJerome Forissier GG(bb, cc, dd, ee, aa, X[14], 7);
1695a913ee7SJerome Forissier GG(aa, bb, cc, dd, ee, X[11], 13);
1705a913ee7SJerome Forissier GG(ee, aa, bb, cc, dd, X[ 8], 12);
1715a913ee7SJerome Forissier
1725a913ee7SJerome Forissier /* parallel round 2 */
1735a913ee7SJerome Forissier III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
1745a913ee7SJerome Forissier III(ddd, eee, aaa, bbb, ccc, X[11], 13);
1755a913ee7SJerome Forissier III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
1765a913ee7SJerome Forissier III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
1775a913ee7SJerome Forissier III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
1785a913ee7SJerome Forissier III(eee, aaa, bbb, ccc, ddd, X[13], 8);
1795a913ee7SJerome Forissier III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
1805a913ee7SJerome Forissier III(ccc, ddd, eee, aaa, bbb, X[10], 11);
1815a913ee7SJerome Forissier III(bbb, ccc, ddd, eee, aaa, X[14], 7);
1825a913ee7SJerome Forissier III(aaa, bbb, ccc, ddd, eee, X[15], 7);
1835a913ee7SJerome Forissier III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
1845a913ee7SJerome Forissier III(ddd, eee, aaa, bbb, ccc, X[12], 7);
1855a913ee7SJerome Forissier III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
1865a913ee7SJerome Forissier III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
1875a913ee7SJerome Forissier III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
1885a913ee7SJerome Forissier III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
1895a913ee7SJerome Forissier
1905a913ee7SJerome Forissier tmp = bb; bb = bbb; bbb = tmp;
1915a913ee7SJerome Forissier
1925a913ee7SJerome Forissier /* round 3 */
1935a913ee7SJerome Forissier HH(dd, ee, aa, bb, cc, X[ 3], 11);
1945a913ee7SJerome Forissier HH(cc, dd, ee, aa, bb, X[10], 13);
1955a913ee7SJerome Forissier HH(bb, cc, dd, ee, aa, X[14], 6);
1965a913ee7SJerome Forissier HH(aa, bb, cc, dd, ee, X[ 4], 7);
1975a913ee7SJerome Forissier HH(ee, aa, bb, cc, dd, X[ 9], 14);
1985a913ee7SJerome Forissier HH(dd, ee, aa, bb, cc, X[15], 9);
1995a913ee7SJerome Forissier HH(cc, dd, ee, aa, bb, X[ 8], 13);
2005a913ee7SJerome Forissier HH(bb, cc, dd, ee, aa, X[ 1], 15);
2015a913ee7SJerome Forissier HH(aa, bb, cc, dd, ee, X[ 2], 14);
2025a913ee7SJerome Forissier HH(ee, aa, bb, cc, dd, X[ 7], 8);
2035a913ee7SJerome Forissier HH(dd, ee, aa, bb, cc, X[ 0], 13);
2045a913ee7SJerome Forissier HH(cc, dd, ee, aa, bb, X[ 6], 6);
2055a913ee7SJerome Forissier HH(bb, cc, dd, ee, aa, X[13], 5);
2065a913ee7SJerome Forissier HH(aa, bb, cc, dd, ee, X[11], 12);
2075a913ee7SJerome Forissier HH(ee, aa, bb, cc, dd, X[ 5], 7);
2085a913ee7SJerome Forissier HH(dd, ee, aa, bb, cc, X[12], 5);
2095a913ee7SJerome Forissier
2105a913ee7SJerome Forissier /* parallel round 3 */
2115a913ee7SJerome Forissier HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
2125a913ee7SJerome Forissier HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
2135a913ee7SJerome Forissier HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
2145a913ee7SJerome Forissier HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
2155a913ee7SJerome Forissier HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
2165a913ee7SJerome Forissier HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
2175a913ee7SJerome Forissier HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
2185a913ee7SJerome Forissier HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
2195a913ee7SJerome Forissier HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
2205a913ee7SJerome Forissier HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
2215a913ee7SJerome Forissier HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
2225a913ee7SJerome Forissier HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
2235a913ee7SJerome Forissier HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
2245a913ee7SJerome Forissier HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
2255a913ee7SJerome Forissier HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
2265a913ee7SJerome Forissier HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
2275a913ee7SJerome Forissier
2285a913ee7SJerome Forissier tmp = cc; cc = ccc; ccc = tmp;
2295a913ee7SJerome Forissier
2305a913ee7SJerome Forissier /* round 4 */
2315a913ee7SJerome Forissier II(cc, dd, ee, aa, bb, X[ 1], 11);
2325a913ee7SJerome Forissier II(bb, cc, dd, ee, aa, X[ 9], 12);
2335a913ee7SJerome Forissier II(aa, bb, cc, dd, ee, X[11], 14);
2345a913ee7SJerome Forissier II(ee, aa, bb, cc, dd, X[10], 15);
2355a913ee7SJerome Forissier II(dd, ee, aa, bb, cc, X[ 0], 14);
2365a913ee7SJerome Forissier II(cc, dd, ee, aa, bb, X[ 8], 15);
2375a913ee7SJerome Forissier II(bb, cc, dd, ee, aa, X[12], 9);
2385a913ee7SJerome Forissier II(aa, bb, cc, dd, ee, X[ 4], 8);
2395a913ee7SJerome Forissier II(ee, aa, bb, cc, dd, X[13], 9);
2405a913ee7SJerome Forissier II(dd, ee, aa, bb, cc, X[ 3], 14);
2415a913ee7SJerome Forissier II(cc, dd, ee, aa, bb, X[ 7], 5);
2425a913ee7SJerome Forissier II(bb, cc, dd, ee, aa, X[15], 6);
2435a913ee7SJerome Forissier II(aa, bb, cc, dd, ee, X[14], 8);
2445a913ee7SJerome Forissier II(ee, aa, bb, cc, dd, X[ 5], 6);
2455a913ee7SJerome Forissier II(dd, ee, aa, bb, cc, X[ 6], 5);
2465a913ee7SJerome Forissier II(cc, dd, ee, aa, bb, X[ 2], 12);
2475a913ee7SJerome Forissier
2485a913ee7SJerome Forissier /* parallel round 4 */
2495a913ee7SJerome Forissier GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
2505a913ee7SJerome Forissier GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
2515a913ee7SJerome Forissier GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
2525a913ee7SJerome Forissier GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
2535a913ee7SJerome Forissier GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
2545a913ee7SJerome Forissier GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
2555a913ee7SJerome Forissier GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
2565a913ee7SJerome Forissier GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
2575a913ee7SJerome Forissier GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
2585a913ee7SJerome Forissier GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
2595a913ee7SJerome Forissier GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
2605a913ee7SJerome Forissier GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
2615a913ee7SJerome Forissier GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
2625a913ee7SJerome Forissier GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
2635a913ee7SJerome Forissier GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
2645a913ee7SJerome Forissier GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
2655a913ee7SJerome Forissier
2665a913ee7SJerome Forissier tmp = dd; dd = ddd; ddd = tmp;
2675a913ee7SJerome Forissier
2685a913ee7SJerome Forissier /* round 5 */
2695a913ee7SJerome Forissier JJ(bb, cc, dd, ee, aa, X[ 4], 9);
2705a913ee7SJerome Forissier JJ(aa, bb, cc, dd, ee, X[ 0], 15);
2715a913ee7SJerome Forissier JJ(ee, aa, bb, cc, dd, X[ 5], 5);
2725a913ee7SJerome Forissier JJ(dd, ee, aa, bb, cc, X[ 9], 11);
2735a913ee7SJerome Forissier JJ(cc, dd, ee, aa, bb, X[ 7], 6);
2745a913ee7SJerome Forissier JJ(bb, cc, dd, ee, aa, X[12], 8);
2755a913ee7SJerome Forissier JJ(aa, bb, cc, dd, ee, X[ 2], 13);
2765a913ee7SJerome Forissier JJ(ee, aa, bb, cc, dd, X[10], 12);
2775a913ee7SJerome Forissier JJ(dd, ee, aa, bb, cc, X[14], 5);
2785a913ee7SJerome Forissier JJ(cc, dd, ee, aa, bb, X[ 1], 12);
2795a913ee7SJerome Forissier JJ(bb, cc, dd, ee, aa, X[ 3], 13);
2805a913ee7SJerome Forissier JJ(aa, bb, cc, dd, ee, X[ 8], 14);
2815a913ee7SJerome Forissier JJ(ee, aa, bb, cc, dd, X[11], 11);
2825a913ee7SJerome Forissier JJ(dd, ee, aa, bb, cc, X[ 6], 8);
2835a913ee7SJerome Forissier JJ(cc, dd, ee, aa, bb, X[15], 5);
2845a913ee7SJerome Forissier JJ(bb, cc, dd, ee, aa, X[13], 6);
2855a913ee7SJerome Forissier
2865a913ee7SJerome Forissier /* parallel round 5 */
2875a913ee7SJerome Forissier FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
2885a913ee7SJerome Forissier FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
2895a913ee7SJerome Forissier FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
2905a913ee7SJerome Forissier FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
2915a913ee7SJerome Forissier FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
2925a913ee7SJerome Forissier FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
2935a913ee7SJerome Forissier FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
2945a913ee7SJerome Forissier FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
2955a913ee7SJerome Forissier FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
2965a913ee7SJerome Forissier FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
2975a913ee7SJerome Forissier FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
2985a913ee7SJerome Forissier FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
2995a913ee7SJerome Forissier FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
3005a913ee7SJerome Forissier FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
3015a913ee7SJerome Forissier FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
3025a913ee7SJerome Forissier FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
3035a913ee7SJerome Forissier
3045a913ee7SJerome Forissier tmp = ee; ee = eee; eee = tmp;
3055a913ee7SJerome Forissier
3065a913ee7SJerome Forissier /* combine results */
3075a913ee7SJerome Forissier md->rmd320.state[0] += aa;
3085a913ee7SJerome Forissier md->rmd320.state[1] += bb;
3095a913ee7SJerome Forissier md->rmd320.state[2] += cc;
3105a913ee7SJerome Forissier md->rmd320.state[3] += dd;
3115a913ee7SJerome Forissier md->rmd320.state[4] += ee;
3125a913ee7SJerome Forissier md->rmd320.state[5] += aaa;
3135a913ee7SJerome Forissier md->rmd320.state[6] += bbb;
3145a913ee7SJerome Forissier md->rmd320.state[7] += ccc;
3155a913ee7SJerome Forissier md->rmd320.state[8] += ddd;
3165a913ee7SJerome Forissier md->rmd320.state[9] += eee;
3175a913ee7SJerome Forissier
3185a913ee7SJerome Forissier return CRYPT_OK;
3195a913ee7SJerome Forissier }
3205a913ee7SJerome Forissier
3215a913ee7SJerome Forissier #ifdef LTC_CLEAN_STACK
s_rmd320_compress(hash_state * md,const unsigned char * buf)322*8411e6adSJerome Forissier static int s_rmd320_compress(hash_state *md, const unsigned char *buf)
3235a913ee7SJerome Forissier {
3245a913ee7SJerome Forissier int err;
325*8411e6adSJerome Forissier err = ss_rmd320_compress(md, buf);
3265a913ee7SJerome Forissier burn_stack(sizeof(ulong32) * 27 + sizeof(int));
3275a913ee7SJerome Forissier return err;
3285a913ee7SJerome Forissier }
3295a913ee7SJerome Forissier #endif
3305a913ee7SJerome Forissier
3315a913ee7SJerome Forissier /**
3325a913ee7SJerome Forissier Initialize the hash state
3335a913ee7SJerome Forissier @param md The hash state you wish to initialize
3345a913ee7SJerome Forissier @return CRYPT_OK if successful
3355a913ee7SJerome Forissier */
rmd320_init(hash_state * md)3365a913ee7SJerome Forissier int rmd320_init(hash_state * md)
3375a913ee7SJerome Forissier {
3385a913ee7SJerome Forissier LTC_ARGCHK(md != NULL);
3395a913ee7SJerome Forissier md->rmd320.state[0] = 0x67452301UL;
3405a913ee7SJerome Forissier md->rmd320.state[1] = 0xefcdab89UL;
3415a913ee7SJerome Forissier md->rmd320.state[2] = 0x98badcfeUL;
3425a913ee7SJerome Forissier md->rmd320.state[3] = 0x10325476UL;
3435a913ee7SJerome Forissier md->rmd320.state[4] = 0xc3d2e1f0UL;
3445a913ee7SJerome Forissier md->rmd320.state[5] = 0x76543210UL;
3455a913ee7SJerome Forissier md->rmd320.state[6] = 0xfedcba98UL;
3465a913ee7SJerome Forissier md->rmd320.state[7] = 0x89abcdefUL;
3475a913ee7SJerome Forissier md->rmd320.state[8] = 0x01234567UL;
3485a913ee7SJerome Forissier md->rmd320.state[9] = 0x3c2d1e0fUL;
3495a913ee7SJerome Forissier md->rmd320.curlen = 0;
3505a913ee7SJerome Forissier md->rmd320.length = 0;
3515a913ee7SJerome Forissier return CRYPT_OK;
3525a913ee7SJerome Forissier }
3535a913ee7SJerome Forissier
3545a913ee7SJerome Forissier /**
3555a913ee7SJerome Forissier Process a block of memory though the hash
3565a913ee7SJerome Forissier @param md The hash state
3575a913ee7SJerome Forissier @param in The data to hash
3585a913ee7SJerome Forissier @param inlen The length of the data (octets)
3595a913ee7SJerome Forissier @return CRYPT_OK if successful
3605a913ee7SJerome Forissier */
361*8411e6adSJerome Forissier HASH_PROCESS(rmd320_process, s_rmd320_compress, rmd320, 64)
3625a913ee7SJerome Forissier
3635a913ee7SJerome Forissier /**
3645a913ee7SJerome Forissier Terminate the hash to get the digest
3655a913ee7SJerome Forissier @param md The hash state
3665a913ee7SJerome Forissier @param out [out] The destination of the hash (20 bytes)
3675a913ee7SJerome Forissier @return CRYPT_OK if successful
3685a913ee7SJerome Forissier */
rmd320_done(hash_state * md,unsigned char * out)3695a913ee7SJerome Forissier int rmd320_done(hash_state * md, unsigned char *out)
3705a913ee7SJerome Forissier {
3715a913ee7SJerome Forissier int i;
3725a913ee7SJerome Forissier
3735a913ee7SJerome Forissier LTC_ARGCHK(md != NULL);
3745a913ee7SJerome Forissier LTC_ARGCHK(out != NULL);
3755a913ee7SJerome Forissier
3765a913ee7SJerome Forissier if (md->rmd320.curlen >= sizeof(md->rmd320.buf)) {
3775a913ee7SJerome Forissier return CRYPT_INVALID_ARG;
3785a913ee7SJerome Forissier }
3795a913ee7SJerome Forissier
3805a913ee7SJerome Forissier
3815a913ee7SJerome Forissier /* increase the length of the message */
3825a913ee7SJerome Forissier md->rmd320.length += md->rmd320.curlen * 8;
3835a913ee7SJerome Forissier
3845a913ee7SJerome Forissier /* append the '1' bit */
3855a913ee7SJerome Forissier md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0x80;
3865a913ee7SJerome Forissier
3875a913ee7SJerome Forissier /* if the length is currently above 56 bytes we append zeros
3885a913ee7SJerome Forissier * then compress. Then we can fall back to padding zeros and length
3895a913ee7SJerome Forissier * encoding like normal.
3905a913ee7SJerome Forissier */
3915a913ee7SJerome Forissier if (md->rmd320.curlen > 56) {
3925a913ee7SJerome Forissier while (md->rmd320.curlen < 64) {
3935a913ee7SJerome Forissier md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0;
3945a913ee7SJerome Forissier }
395*8411e6adSJerome Forissier s_rmd320_compress(md, md->rmd320.buf);
3965a913ee7SJerome Forissier md->rmd320.curlen = 0;
3975a913ee7SJerome Forissier }
3985a913ee7SJerome Forissier
3995a913ee7SJerome Forissier /* pad upto 56 bytes of zeroes */
4005a913ee7SJerome Forissier while (md->rmd320.curlen < 56) {
4015a913ee7SJerome Forissier md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0;
4025a913ee7SJerome Forissier }
4035a913ee7SJerome Forissier
4045a913ee7SJerome Forissier /* store length */
4055a913ee7SJerome Forissier STORE64L(md->rmd320.length, md->rmd320.buf+56);
406*8411e6adSJerome Forissier s_rmd320_compress(md, md->rmd320.buf);
4075a913ee7SJerome Forissier
4085a913ee7SJerome Forissier /* copy output */
4095a913ee7SJerome Forissier for (i = 0; i < 10; i++) {
4105a913ee7SJerome Forissier STORE32L(md->rmd320.state[i], out+(4*i));
4115a913ee7SJerome Forissier }
4125a913ee7SJerome Forissier #ifdef LTC_CLEAN_STACK
4135a913ee7SJerome Forissier zeromem(md, sizeof(hash_state));
4145a913ee7SJerome Forissier #endif
4155a913ee7SJerome Forissier return CRYPT_OK;
4165a913ee7SJerome Forissier }
4175a913ee7SJerome Forissier
4185a913ee7SJerome Forissier /**
4195a913ee7SJerome Forissier Self-test the hash
4205a913ee7SJerome Forissier @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
4215a913ee7SJerome Forissier */
rmd320_test(void)4225a913ee7SJerome Forissier int rmd320_test(void)
4235a913ee7SJerome Forissier {
4245a913ee7SJerome Forissier #ifndef LTC_TEST
4255a913ee7SJerome Forissier return CRYPT_NOP;
4265a913ee7SJerome Forissier #else
4275a913ee7SJerome Forissier static const struct {
4285a913ee7SJerome Forissier const char *msg;
4295a913ee7SJerome Forissier unsigned char hash[40];
4305a913ee7SJerome Forissier } tests[] = {
4315a913ee7SJerome Forissier { "",
4325a913ee7SJerome Forissier { 0x22, 0xd6, 0x5d, 0x56, 0x61, 0x53, 0x6c, 0xdc, 0x75, 0xc1,
4335a913ee7SJerome Forissier 0xfd, 0xf5, 0xc6, 0xde, 0x7b, 0x41, 0xb9, 0xf2, 0x73, 0x25,
4345a913ee7SJerome Forissier 0xeb, 0xc6, 0x1e, 0x85, 0x57, 0x17, 0x7d, 0x70, 0x5a, 0x0e,
4355a913ee7SJerome Forissier 0xc8, 0x80, 0x15, 0x1c, 0x3a, 0x32, 0xa0, 0x08, 0x99, 0xb8 }
4365a913ee7SJerome Forissier },
4375a913ee7SJerome Forissier { "a",
4385a913ee7SJerome Forissier { 0xce, 0x78, 0x85, 0x06, 0x38, 0xf9, 0x26, 0x58, 0xa5, 0xa5,
4395a913ee7SJerome Forissier 0x85, 0x09, 0x75, 0x79, 0x92, 0x6d, 0xda, 0x66, 0x7a, 0x57,
4405a913ee7SJerome Forissier 0x16, 0x56, 0x2c, 0xfc, 0xf6, 0xfb, 0xe7, 0x7f, 0x63, 0x54,
4415a913ee7SJerome Forissier 0x2f, 0x99, 0xb0, 0x47, 0x05, 0xd6, 0x97, 0x0d, 0xff, 0x5d }
4425a913ee7SJerome Forissier },
4435a913ee7SJerome Forissier { "abc",
4445a913ee7SJerome Forissier { 0xde, 0x4c, 0x01, 0xb3, 0x05, 0x4f, 0x89, 0x30, 0xa7, 0x9d,
4455a913ee7SJerome Forissier 0x09, 0xae, 0x73, 0x8e, 0x92, 0x30, 0x1e, 0x5a, 0x17, 0x08,
4465a913ee7SJerome Forissier 0x5b, 0xef, 0xfd, 0xc1, 0xb8, 0xd1, 0x16, 0x71, 0x3e, 0x74,
4475a913ee7SJerome Forissier 0xf8, 0x2f, 0xa9, 0x42, 0xd6, 0x4c, 0xdb, 0xc4, 0x68, 0x2d }
4485a913ee7SJerome Forissier },
4495a913ee7SJerome Forissier { "message digest",
4505a913ee7SJerome Forissier { 0x3a, 0x8e, 0x28, 0x50, 0x2e, 0xd4, 0x5d, 0x42, 0x2f, 0x68,
4515a913ee7SJerome Forissier 0x84, 0x4f, 0x9d, 0xd3, 0x16, 0xe7, 0xb9, 0x85, 0x33, 0xfa,
4525a913ee7SJerome Forissier 0x3f, 0x2a, 0x91, 0xd2, 0x9f, 0x84, 0xd4, 0x25, 0xc8, 0x8d,
4535a913ee7SJerome Forissier 0x6b, 0x4e, 0xff, 0x72, 0x7d, 0xf6, 0x6a, 0x7c, 0x01, 0x97 }
4545a913ee7SJerome Forissier },
4555a913ee7SJerome Forissier { "abcdefghijklmnopqrstuvwxyz",
4565a913ee7SJerome Forissier { 0xca, 0xbd, 0xb1, 0x81, 0x0b, 0x92, 0x47, 0x0a, 0x20, 0x93,
4575a913ee7SJerome Forissier 0xaa, 0x6b, 0xce, 0x05, 0x95, 0x2c, 0x28, 0x34, 0x8c, 0xf4,
4585a913ee7SJerome Forissier 0x3f, 0xf6, 0x08, 0x41, 0x97, 0x51, 0x66, 0xbb, 0x40, 0xed,
4595a913ee7SJerome Forissier 0x23, 0x40, 0x04, 0xb8, 0x82, 0x44, 0x63, 0xe6, 0xb0, 0x09 }
4605a913ee7SJerome Forissier },
4615a913ee7SJerome Forissier { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
4625a913ee7SJerome Forissier { 0xd0, 0x34, 0xa7, 0x95, 0x0c, 0xf7, 0x22, 0x02, 0x1b, 0xa4,
4635a913ee7SJerome Forissier 0xb8, 0x4d, 0xf7, 0x69, 0xa5, 0xde, 0x20, 0x60, 0xe2, 0x59,
4645a913ee7SJerome Forissier 0xdf, 0x4c, 0x9b, 0xb4, 0xa4, 0x26, 0x8c, 0x0e, 0x93, 0x5b,
4655a913ee7SJerome Forissier 0xbc, 0x74, 0x70, 0xa9, 0x69, 0xc9, 0xd0, 0x72, 0xa1, 0xac }
4665a913ee7SJerome Forissier }
4675a913ee7SJerome Forissier };
4685a913ee7SJerome Forissier
4695a913ee7SJerome Forissier int i;
4705a913ee7SJerome Forissier unsigned char tmp[40];
4715a913ee7SJerome Forissier hash_state md;
4725a913ee7SJerome Forissier
4735a913ee7SJerome Forissier for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
4745a913ee7SJerome Forissier rmd320_init(&md);
475*8411e6adSJerome Forissier rmd320_process(&md, (unsigned char *)tests[i].msg, XSTRLEN(tests[i].msg));
4765a913ee7SJerome Forissier rmd320_done(&md, tmp);
4775a913ee7SJerome Forissier if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "RIPEMD320", i)) {
4785a913ee7SJerome Forissier return CRYPT_FAIL_TESTVECTOR;
4795a913ee7SJerome Forissier }
4805a913ee7SJerome Forissier }
4815a913ee7SJerome Forissier return CRYPT_OK;
4825a913ee7SJerome Forissier #endif
4835a913ee7SJerome Forissier }
4845a913ee7SJerome Forissier
4855a913ee7SJerome Forissier #endif
486