xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/netpgpverify/rmd160.c (revision dd98b26d9b747061a6a9c2243c42b44a36f58989)
1*dd98b26dSagc /* 	$NetBSD: rmd160.c,v 1.2 2016/06/14 20:47:08 agc Exp $ */
225f78d91Sagc /*	$KAME: rmd160.c,v 1.2 2003/07/25 09:37:55 itojun Exp $	*/
325f78d91Sagc /*	$OpenBSD: rmd160.c,v 1.3 2001/09/26 21:40:13 markus Exp $	*/
425f78d91Sagc /*
525f78d91Sagc  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
625f78d91Sagc  *
725f78d91Sagc  * Redistribution and use in source and binary forms, with or without
825f78d91Sagc  * modification, are permitted provided that the following conditions
925f78d91Sagc  * are met:
1025f78d91Sagc  * 1. Redistributions of source code must retain the above copyright
1125f78d91Sagc  *    notice, this list of conditions and the following disclaimer.
1225f78d91Sagc  * 2. Redistributions in binary form must reproduce the above copyright
1325f78d91Sagc  *    notice, this list of conditions and the following disclaimer in the
1425f78d91Sagc  *    documentation and/or other materials provided with the distribution.
1525f78d91Sagc  *
1625f78d91Sagc  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1725f78d91Sagc  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1825f78d91Sagc  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1925f78d91Sagc  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2025f78d91Sagc  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2125f78d91Sagc  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2225f78d91Sagc  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2325f78d91Sagc  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2425f78d91Sagc  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2525f78d91Sagc  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2625f78d91Sagc  */
2725f78d91Sagc /*
2825f78d91Sagc  * Preneel, Bosselaers, Dobbertin, "The Cryptographic Hash Function RIPEMD-160",
2925f78d91Sagc  * RSA Laboratories, CryptoBytes, Volume 3, Number 2, Autumn 1997,
3025f78d91Sagc  * ftp://ftp.rsasecurity.com/pub/cryptobytes/crypto3n2.pdf
3125f78d91Sagc  */
3225f78d91Sagc 
3325f78d91Sagc #include <string.h>
3425f78d91Sagc 
3525f78d91Sagc #include <sys/types.h>
3625f78d91Sagc #include <sys/param.h>
3725f78d91Sagc 
3825f78d91Sagc #include "rmd160.h"
3925f78d91Sagc 
4025f78d91Sagc #define PUT_64BIT_LE(cp, value) do { \
4125f78d91Sagc 	(cp)[7] = (u_char)((value) >> 56); \
4225f78d91Sagc 	(cp)[6] = (u_char)((value) >> 48); \
4325f78d91Sagc 	(cp)[5] = (u_char)((value) >> 40); \
4425f78d91Sagc 	(cp)[4] = (u_char)((value) >> 32); \
4525f78d91Sagc 	(cp)[3] = (u_char)((value) >> 24); \
4625f78d91Sagc 	(cp)[2] = (u_char)((value) >> 16); \
4725f78d91Sagc 	(cp)[1] = (u_char)((value) >> 8); \
4825f78d91Sagc 	(cp)[0] = (u_char)((value)); } while (/*CONSTCOND*/0)
4925f78d91Sagc 
5025f78d91Sagc #define PUT_32BIT_LE(cp, value) do { \
5125f78d91Sagc 	(cp)[3] = (value) >> 24; \
5225f78d91Sagc 	(cp)[2] = (value) >> 16; \
5325f78d91Sagc 	(cp)[1] = (value) >> 8; \
5425f78d91Sagc 	(cp)[0] = (value); } while (/*CONSTCOND*/0)
5525f78d91Sagc 
5625f78d91Sagc #define	H0	0x67452301U
5725f78d91Sagc #define	H1	0xEFCDAB89U
5825f78d91Sagc #define	H2	0x98BADCFEU
5925f78d91Sagc #define	H3	0x10325476U
6025f78d91Sagc #define	H4	0xC3D2E1F0U
6125f78d91Sagc 
6225f78d91Sagc #define	K0	0x00000000U
6325f78d91Sagc #define	K1	0x5A827999U
6425f78d91Sagc #define	K2	0x6ED9EBA1U
6525f78d91Sagc #define	K3	0x8F1BBCDCU
6625f78d91Sagc #define	K4	0xA953FD4EU
6725f78d91Sagc 
6825f78d91Sagc #define	KK0	0x50A28BE6U
6925f78d91Sagc #define	KK1	0x5C4DD124U
7025f78d91Sagc #define	KK2	0x6D703EF3U
7125f78d91Sagc #define	KK3	0x7A6D76E9U
7225f78d91Sagc #define	KK4	0x00000000U
7325f78d91Sagc 
7425f78d91Sagc /* rotate x left n bits.  */
7525f78d91Sagc #define ROL(n, x) (((x) << (n)) | ((x) >> (32-(n))))
7625f78d91Sagc 
7725f78d91Sagc #define F0(x, y, z) ((x) ^ (y) ^ (z))
7825f78d91Sagc #define F1(x, y, z) (((x) & (y)) | ((~x) & (z)))
7925f78d91Sagc #define F2(x, y, z) (((x) | (~y)) ^ (z))
8025f78d91Sagc #define F3(x, y, z) (((x) & (z)) | ((y) & (~z)))
8125f78d91Sagc #define F4(x, y, z) ((x) ^ ((y) | (~z)))
8225f78d91Sagc 
8325f78d91Sagc #define R(a, b, c, d, e, Fj, Kj, sj, rj) \
8425f78d91Sagc 	do { \
8525f78d91Sagc 		a = ROL(sj, a + Fj(b,c,d) + X(rj) + Kj) + e; \
8625f78d91Sagc 		c = ROL(10, c); \
8725f78d91Sagc 	} while(/*CONSTCOND*/0)
8825f78d91Sagc 
8925f78d91Sagc #define X(i)	x[i]
9025f78d91Sagc 
9125f78d91Sagc static const u_char PADDING[64] = {
9225f78d91Sagc 	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9325f78d91Sagc 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9425f78d91Sagc 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
9525f78d91Sagc };
9625f78d91Sagc 
9725f78d91Sagc void
netpgpv_RMD160Init(NETPGPV_RMD160_CTX * ctx)98*dd98b26dSagc netpgpv_RMD160Init(NETPGPV_RMD160_CTX *ctx)
9925f78d91Sagc {
10025f78d91Sagc 	ctx->count = 0;
10125f78d91Sagc 	ctx->state[0] = H0;
10225f78d91Sagc 	ctx->state[1] = H1;
10325f78d91Sagc 	ctx->state[2] = H2;
10425f78d91Sagc 	ctx->state[3] = H3;
10525f78d91Sagc 	ctx->state[4] = H4;
10625f78d91Sagc }
10725f78d91Sagc 
10825f78d91Sagc void
netpgpv_RMD160Update(NETPGPV_RMD160_CTX * ctx,const u_char * input,uint32_t len)109*dd98b26dSagc netpgpv_RMD160Update(NETPGPV_RMD160_CTX *ctx, const u_char *input, uint32_t len)
11025f78d91Sagc {
11125f78d91Sagc 	uint32_t have, off, need;
11225f78d91Sagc 
11325f78d91Sagc 	have = (uint32_t)((ctx->count/8) % 64);
11425f78d91Sagc 	need = 64 - have;
11525f78d91Sagc 	ctx->count += 8 * len;
11625f78d91Sagc 	off = 0;
11725f78d91Sagc 
11825f78d91Sagc 	if (len >= need) {
11925f78d91Sagc 		if (have) {
12025f78d91Sagc 			memcpy(ctx->buffer + have, input, (size_t)need);
121*dd98b26dSagc 			netpgpv_RMD160Transform(ctx->state, ctx->buffer);
12225f78d91Sagc 			off = need;
12325f78d91Sagc 			have = 0;
12425f78d91Sagc 		}
12525f78d91Sagc 		/* now the buffer is empty */
12625f78d91Sagc 		while (off + 64 <= len) {
127*dd98b26dSagc 			netpgpv_RMD160Transform(ctx->state, input+off);
12825f78d91Sagc 			off += 64;
12925f78d91Sagc 		}
13025f78d91Sagc 	}
13125f78d91Sagc 	if (off < len)
13225f78d91Sagc 		memcpy(ctx->buffer + have, input+off, (size_t)len-off);
13325f78d91Sagc }
13425f78d91Sagc 
13525f78d91Sagc void
netpgpv_RMD160Final(u_char digest[20],NETPGPV_RMD160_CTX * ctx)136*dd98b26dSagc netpgpv_RMD160Final(u_char digest[20], NETPGPV_RMD160_CTX *ctx)
13725f78d91Sagc {
13825f78d91Sagc 	int i;
13925f78d91Sagc 	u_char size[8];
14025f78d91Sagc 	uint32_t padlen;
14125f78d91Sagc 
14225f78d91Sagc 	PUT_64BIT_LE(size, ctx->count);
14325f78d91Sagc 
14425f78d91Sagc 	/*
14525f78d91Sagc 	 * pad to 64 byte blocks, at least one byte from PADDING plus 8 bytes
14625f78d91Sagc 	 * for the size
14725f78d91Sagc 	 */
14825f78d91Sagc 	padlen = (uint32_t)(64 - ((ctx->count/8) % 64));
14925f78d91Sagc 	if (padlen < 1 + 8)
15025f78d91Sagc 		padlen += 64;
151*dd98b26dSagc 	netpgpv_RMD160Update(ctx, PADDING, padlen - 8);		/* padlen - 8 <= 64 */
152*dd98b26dSagc 	netpgpv_RMD160Update(ctx, size, 8);
15325f78d91Sagc 
15425f78d91Sagc 	if (digest != NULL)
15525f78d91Sagc 		for (i = 0; i < 5; i++)
15625f78d91Sagc 			PUT_32BIT_LE(digest + i*4, ctx->state[i]);
15725f78d91Sagc 
15825f78d91Sagc 	memset(ctx, 0, sizeof (*ctx));
15925f78d91Sagc }
16025f78d91Sagc 
16125f78d91Sagc void
netpgpv_RMD160Transform(uint32_t state[5],const u_char block[64])162*dd98b26dSagc netpgpv_RMD160Transform(uint32_t state[5], const u_char block[64])
16325f78d91Sagc {
16425f78d91Sagc 	uint32_t a, b, c, d, e, aa, bb, cc, dd, ee, t, x[16];
16525f78d91Sagc 
16625f78d91Sagc #if BYTE_ORDER == LITTLE_ENDIAN
16725f78d91Sagc 	memcpy(x, block, (size_t)64);
16825f78d91Sagc #else
16925f78d91Sagc 	int i;
17025f78d91Sagc 
171*dd98b26dSagc 	for (i = 0; i < 16; i++) {
172*dd98b26dSagc 		x[i] = (uint32_t)(
173*dd98b26dSagc 		    (uint32_t)(block[i*4 + 0]) |
174*dd98b26dSagc 		    (uint32_t)(block[i*4 + 1]) <<  8 |
175*dd98b26dSagc 		    (uint32_t)(block[i*4 + 2]) << 16 |
176*dd98b26dSagc 		    (uint32_t)(block[i*4 + 3]) << 24);
177*dd98b26dSagc 	}
17825f78d91Sagc #endif
17925f78d91Sagc 
18025f78d91Sagc 	a = state[0];
18125f78d91Sagc 	b = state[1];
18225f78d91Sagc 	c = state[2];
18325f78d91Sagc 	d = state[3];
18425f78d91Sagc 	e = state[4];
18525f78d91Sagc 
18625f78d91Sagc 	/* Round 1 */
18725f78d91Sagc 	R(a, b, c, d, e, F0, K0, 11,  0);
18825f78d91Sagc 	R(e, a, b, c, d, F0, K0, 14,  1);
18925f78d91Sagc 	R(d, e, a, b, c, F0, K0, 15,  2);
19025f78d91Sagc 	R(c, d, e, a, b, F0, K0, 12,  3);
19125f78d91Sagc 	R(b, c, d, e, a, F0, K0,  5,  4);
19225f78d91Sagc 	R(a, b, c, d, e, F0, K0,  8,  5);
19325f78d91Sagc 	R(e, a, b, c, d, F0, K0,  7,  6);
19425f78d91Sagc 	R(d, e, a, b, c, F0, K0,  9,  7);
19525f78d91Sagc 	R(c, d, e, a, b, F0, K0, 11,  8);
19625f78d91Sagc 	R(b, c, d, e, a, F0, K0, 13,  9);
19725f78d91Sagc 	R(a, b, c, d, e, F0, K0, 14, 10);
19825f78d91Sagc 	R(e, a, b, c, d, F0, K0, 15, 11);
19925f78d91Sagc 	R(d, e, a, b, c, F0, K0,  6, 12);
20025f78d91Sagc 	R(c, d, e, a, b, F0, K0,  7, 13);
20125f78d91Sagc 	R(b, c, d, e, a, F0, K0,  9, 14);
20225f78d91Sagc 	R(a, b, c, d, e, F0, K0,  8, 15); /* #15 */
20325f78d91Sagc 	/* Round 2 */
20425f78d91Sagc 	R(e, a, b, c, d, F1, K1,  7,  7);
20525f78d91Sagc 	R(d, e, a, b, c, F1, K1,  6,  4);
20625f78d91Sagc 	R(c, d, e, a, b, F1, K1,  8, 13);
20725f78d91Sagc 	R(b, c, d, e, a, F1, K1, 13,  1);
20825f78d91Sagc 	R(a, b, c, d, e, F1, K1, 11, 10);
20925f78d91Sagc 	R(e, a, b, c, d, F1, K1,  9,  6);
21025f78d91Sagc 	R(d, e, a, b, c, F1, K1,  7, 15);
21125f78d91Sagc 	R(c, d, e, a, b, F1, K1, 15,  3);
21225f78d91Sagc 	R(b, c, d, e, a, F1, K1,  7, 12);
21325f78d91Sagc 	R(a, b, c, d, e, F1, K1, 12,  0);
21425f78d91Sagc 	R(e, a, b, c, d, F1, K1, 15,  9);
21525f78d91Sagc 	R(d, e, a, b, c, F1, K1,  9,  5);
21625f78d91Sagc 	R(c, d, e, a, b, F1, K1, 11,  2);
21725f78d91Sagc 	R(b, c, d, e, a, F1, K1,  7, 14);
21825f78d91Sagc 	R(a, b, c, d, e, F1, K1, 13, 11);
21925f78d91Sagc 	R(e, a, b, c, d, F1, K1, 12,  8); /* #31 */
22025f78d91Sagc 	/* Round 3 */
22125f78d91Sagc 	R(d, e, a, b, c, F2, K2, 11,  3);
22225f78d91Sagc 	R(c, d, e, a, b, F2, K2, 13, 10);
22325f78d91Sagc 	R(b, c, d, e, a, F2, K2,  6, 14);
22425f78d91Sagc 	R(a, b, c, d, e, F2, K2,  7,  4);
22525f78d91Sagc 	R(e, a, b, c, d, F2, K2, 14,  9);
22625f78d91Sagc 	R(d, e, a, b, c, F2, K2,  9, 15);
22725f78d91Sagc 	R(c, d, e, a, b, F2, K2, 13,  8);
22825f78d91Sagc 	R(b, c, d, e, a, F2, K2, 15,  1);
22925f78d91Sagc 	R(a, b, c, d, e, F2, K2, 14,  2);
23025f78d91Sagc 	R(e, a, b, c, d, F2, K2,  8,  7);
23125f78d91Sagc 	R(d, e, a, b, c, F2, K2, 13,  0);
23225f78d91Sagc 	R(c, d, e, a, b, F2, K2,  6,  6);
23325f78d91Sagc 	R(b, c, d, e, a, F2, K2,  5, 13);
23425f78d91Sagc 	R(a, b, c, d, e, F2, K2, 12, 11);
23525f78d91Sagc 	R(e, a, b, c, d, F2, K2,  7,  5);
23625f78d91Sagc 	R(d, e, a, b, c, F2, K2,  5, 12); /* #47 */
23725f78d91Sagc 	/* Round 4 */
23825f78d91Sagc 	R(c, d, e, a, b, F3, K3, 11,  1);
23925f78d91Sagc 	R(b, c, d, e, a, F3, K3, 12,  9);
24025f78d91Sagc 	R(a, b, c, d, e, F3, K3, 14, 11);
24125f78d91Sagc 	R(e, a, b, c, d, F3, K3, 15, 10);
24225f78d91Sagc 	R(d, e, a, b, c, F3, K3, 14,  0);
24325f78d91Sagc 	R(c, d, e, a, b, F3, K3, 15,  8);
24425f78d91Sagc 	R(b, c, d, e, a, F3, K3,  9, 12);
24525f78d91Sagc 	R(a, b, c, d, e, F3, K3,  8,  4);
24625f78d91Sagc 	R(e, a, b, c, d, F3, K3,  9, 13);
24725f78d91Sagc 	R(d, e, a, b, c, F3, K3, 14,  3);
24825f78d91Sagc 	R(c, d, e, a, b, F3, K3,  5,  7);
24925f78d91Sagc 	R(b, c, d, e, a, F3, K3,  6, 15);
25025f78d91Sagc 	R(a, b, c, d, e, F3, K3,  8, 14);
25125f78d91Sagc 	R(e, a, b, c, d, F3, K3,  6,  5);
25225f78d91Sagc 	R(d, e, a, b, c, F3, K3,  5,  6);
25325f78d91Sagc 	R(c, d, e, a, b, F3, K3, 12,  2); /* #63 */
25425f78d91Sagc 	/* Round 5 */
25525f78d91Sagc 	R(b, c, d, e, a, F4, K4,  9,  4);
25625f78d91Sagc 	R(a, b, c, d, e, F4, K4, 15,  0);
25725f78d91Sagc 	R(e, a, b, c, d, F4, K4,  5,  5);
25825f78d91Sagc 	R(d, e, a, b, c, F4, K4, 11,  9);
25925f78d91Sagc 	R(c, d, e, a, b, F4, K4,  6,  7);
26025f78d91Sagc 	R(b, c, d, e, a, F4, K4,  8, 12);
26125f78d91Sagc 	R(a, b, c, d, e, F4, K4, 13,  2);
26225f78d91Sagc 	R(e, a, b, c, d, F4, K4, 12, 10);
26325f78d91Sagc 	R(d, e, a, b, c, F4, K4,  5, 14);
26425f78d91Sagc 	R(c, d, e, a, b, F4, K4, 12,  1);
26525f78d91Sagc 	R(b, c, d, e, a, F4, K4, 13,  3);
26625f78d91Sagc 	R(a, b, c, d, e, F4, K4, 14,  8);
26725f78d91Sagc 	R(e, a, b, c, d, F4, K4, 11, 11);
26825f78d91Sagc 	R(d, e, a, b, c, F4, K4,  8,  6);
26925f78d91Sagc 	R(c, d, e, a, b, F4, K4,  5, 15);
27025f78d91Sagc 	R(b, c, d, e, a, F4, K4,  6, 13); /* #79 */
27125f78d91Sagc 
27225f78d91Sagc 	aa = a ; bb = b; cc = c; dd = d; ee = e;
27325f78d91Sagc 
27425f78d91Sagc 	a = state[0];
27525f78d91Sagc 	b = state[1];
27625f78d91Sagc 	c = state[2];
27725f78d91Sagc 	d = state[3];
27825f78d91Sagc 	e = state[4];
27925f78d91Sagc 
28025f78d91Sagc 	/* Parallel round 1 */
28125f78d91Sagc 	R(a, b, c, d, e, F4, KK0,  8,  5);
28225f78d91Sagc 	R(e, a, b, c, d, F4, KK0,  9, 14);
28325f78d91Sagc 	R(d, e, a, b, c, F4, KK0,  9,  7);
28425f78d91Sagc 	R(c, d, e, a, b, F4, KK0, 11,  0);
28525f78d91Sagc 	R(b, c, d, e, a, F4, KK0, 13,  9);
28625f78d91Sagc 	R(a, b, c, d, e, F4, KK0, 15,  2);
28725f78d91Sagc 	R(e, a, b, c, d, F4, KK0, 15, 11);
28825f78d91Sagc 	R(d, e, a, b, c, F4, KK0,  5,  4);
28925f78d91Sagc 	R(c, d, e, a, b, F4, KK0,  7, 13);
29025f78d91Sagc 	R(b, c, d, e, a, F4, KK0,  7,  6);
29125f78d91Sagc 	R(a, b, c, d, e, F4, KK0,  8, 15);
29225f78d91Sagc 	R(e, a, b, c, d, F4, KK0, 11,  8);
29325f78d91Sagc 	R(d, e, a, b, c, F4, KK0, 14,  1);
29425f78d91Sagc 	R(c, d, e, a, b, F4, KK0, 14, 10);
29525f78d91Sagc 	R(b, c, d, e, a, F4, KK0, 12,  3);
29625f78d91Sagc 	R(a, b, c, d, e, F4, KK0,  6, 12); /* #15 */
29725f78d91Sagc 	/* Parallel round 2 */
29825f78d91Sagc 	R(e, a, b, c, d, F3, KK1,  9,  6);
29925f78d91Sagc 	R(d, e, a, b, c, F3, KK1, 13, 11);
30025f78d91Sagc 	R(c, d, e, a, b, F3, KK1, 15,  3);
30125f78d91Sagc 	R(b, c, d, e, a, F3, KK1,  7,  7);
30225f78d91Sagc 	R(a, b, c, d, e, F3, KK1, 12,  0);
30325f78d91Sagc 	R(e, a, b, c, d, F3, KK1,  8, 13);
30425f78d91Sagc 	R(d, e, a, b, c, F3, KK1,  9,  5);
30525f78d91Sagc 	R(c, d, e, a, b, F3, KK1, 11, 10);
30625f78d91Sagc 	R(b, c, d, e, a, F3, KK1,  7, 14);
30725f78d91Sagc 	R(a, b, c, d, e, F3, KK1,  7, 15);
30825f78d91Sagc 	R(e, a, b, c, d, F3, KK1, 12,  8);
30925f78d91Sagc 	R(d, e, a, b, c, F3, KK1,  7, 12);
31025f78d91Sagc 	R(c, d, e, a, b, F3, KK1,  6,  4);
31125f78d91Sagc 	R(b, c, d, e, a, F3, KK1, 15,  9);
31225f78d91Sagc 	R(a, b, c, d, e, F3, KK1, 13,  1);
31325f78d91Sagc 	R(e, a, b, c, d, F3, KK1, 11,  2); /* #31 */
31425f78d91Sagc 	/* Parallel round 3 */
31525f78d91Sagc 	R(d, e, a, b, c, F2, KK2,  9, 15);
31625f78d91Sagc 	R(c, d, e, a, b, F2, KK2,  7,  5);
31725f78d91Sagc 	R(b, c, d, e, a, F2, KK2, 15,  1);
31825f78d91Sagc 	R(a, b, c, d, e, F2, KK2, 11,  3);
31925f78d91Sagc 	R(e, a, b, c, d, F2, KK2,  8,  7);
32025f78d91Sagc 	R(d, e, a, b, c, F2, KK2,  6, 14);
32125f78d91Sagc 	R(c, d, e, a, b, F2, KK2,  6,  6);
32225f78d91Sagc 	R(b, c, d, e, a, F2, KK2, 14,  9);
32325f78d91Sagc 	R(a, b, c, d, e, F2, KK2, 12, 11);
32425f78d91Sagc 	R(e, a, b, c, d, F2, KK2, 13,  8);
32525f78d91Sagc 	R(d, e, a, b, c, F2, KK2,  5, 12);
32625f78d91Sagc 	R(c, d, e, a, b, F2, KK2, 14,  2);
32725f78d91Sagc 	R(b, c, d, e, a, F2, KK2, 13, 10);
32825f78d91Sagc 	R(a, b, c, d, e, F2, KK2, 13,  0);
32925f78d91Sagc 	R(e, a, b, c, d, F2, KK2,  7,  4);
33025f78d91Sagc 	R(d, e, a, b, c, F2, KK2,  5, 13); /* #47 */
33125f78d91Sagc 	/* Parallel round 4 */
33225f78d91Sagc 	R(c, d, e, a, b, F1, KK3, 15,  8);
33325f78d91Sagc 	R(b, c, d, e, a, F1, KK3,  5,  6);
33425f78d91Sagc 	R(a, b, c, d, e, F1, KK3,  8,  4);
33525f78d91Sagc 	R(e, a, b, c, d, F1, KK3, 11,  1);
33625f78d91Sagc 	R(d, e, a, b, c, F1, KK3, 14,  3);
33725f78d91Sagc 	R(c, d, e, a, b, F1, KK3, 14, 11);
33825f78d91Sagc 	R(b, c, d, e, a, F1, KK3,  6, 15);
33925f78d91Sagc 	R(a, b, c, d, e, F1, KK3, 14,  0);
34025f78d91Sagc 	R(e, a, b, c, d, F1, KK3,  6,  5);
34125f78d91Sagc 	R(d, e, a, b, c, F1, KK3,  9, 12);
34225f78d91Sagc 	R(c, d, e, a, b, F1, KK3, 12,  2);
34325f78d91Sagc 	R(b, c, d, e, a, F1, KK3,  9, 13);
34425f78d91Sagc 	R(a, b, c, d, e, F1, KK3, 12,  9);
34525f78d91Sagc 	R(e, a, b, c, d, F1, KK3,  5,  7);
34625f78d91Sagc 	R(d, e, a, b, c, F1, KK3, 15, 10);
34725f78d91Sagc 	R(c, d, e, a, b, F1, KK3,  8, 14); /* #63 */
34825f78d91Sagc 	/* Parallel round 5 */
34925f78d91Sagc 	R(b, c, d, e, a, F0, KK4,  8, 12);
35025f78d91Sagc 	R(a, b, c, d, e, F0, KK4,  5, 15);
35125f78d91Sagc 	R(e, a, b, c, d, F0, KK4, 12, 10);
35225f78d91Sagc 	R(d, e, a, b, c, F0, KK4,  9,  4);
35325f78d91Sagc 	R(c, d, e, a, b, F0, KK4, 12,  1);
35425f78d91Sagc 	R(b, c, d, e, a, F0, KK4,  5,  5);
35525f78d91Sagc 	R(a, b, c, d, e, F0, KK4, 14,  8);
35625f78d91Sagc 	R(e, a, b, c, d, F0, KK4,  6,  7);
35725f78d91Sagc 	R(d, e, a, b, c, F0, KK4,  8,  6);
35825f78d91Sagc 	R(c, d, e, a, b, F0, KK4, 13,  2);
35925f78d91Sagc 	R(b, c, d, e, a, F0, KK4,  6, 13);
36025f78d91Sagc 	R(a, b, c, d, e, F0, KK4,  5, 14);
36125f78d91Sagc 	R(e, a, b, c, d, F0, KK4, 15,  0);
36225f78d91Sagc 	R(d, e, a, b, c, F0, KK4, 13,  3);
36325f78d91Sagc 	R(c, d, e, a, b, F0, KK4, 11,  9);
36425f78d91Sagc 	R(b, c, d, e, a, F0, KK4, 11, 11); /* #79 */
36525f78d91Sagc 
36625f78d91Sagc 	t =        state[1] + cc + d;
36725f78d91Sagc 	state[1] = state[2] + dd + e;
36825f78d91Sagc 	state[2] = state[3] + ee + a;
36925f78d91Sagc 	state[3] = state[4] + aa + b;
37025f78d91Sagc 	state[4] = state[0] + bb + c;
37125f78d91Sagc 	state[0] = t;
37225f78d91Sagc }
373