1020 lines
40 KiB
C
1020 lines
40 KiB
C
/* ripemd.c
|
|
*
|
|
* Copyright (C) 2000,2001 Nikos Mavroyanopoulos
|
|
*
|
|
* This library is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU Library General Public License as published
|
|
* by the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public
|
|
* License along with this library; if not, write to the
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
* Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
|
|
/*
|
|
* RIPEMD-160 is a 160-bit cryptographic hash function, designed by Hans
|
|
* Dobbertin, Antoon Bosselaers, and Bart Preneel. It is intended to be
|
|
* used as a secure replacement for the 128-bit hash functions MD4, MD5,
|
|
* and RIPEMD
|
|
* See also: http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
|
|
*
|
|
* RIPEMD-128 is a plug-in substitute for RIPEMD (or MD4 and MD5, for
|
|
* that matter) with a 128-bit result. 128-bit hash results do not
|
|
* offer sufficient protection for the next ten years, and
|
|
* applications using 128-bit hash functions should consider upgrading
|
|
* to a 160-bit hash function.
|
|
*
|
|
* RIPEMD-256 and RIPEMD-320 are optional extensions of, respectively,
|
|
* RIPEMD-128 and RIPEMD-160, and are intended for applications of
|
|
* hash functions that require a longer hash result without needing a
|
|
* larger security level.
|
|
*/
|
|
|
|
/* Implementation of the RIPE-MD Hash Algorithms.
|
|
* Based on the SHA-1 implementation, (C) by A.M. Kuchling
|
|
*
|
|
* The ripemd160 code was written by Nikos Mavroyanopoulos, the code
|
|
* for ripemd128, ripemd256 and ripemd320 was added by B. Poettering
|
|
* in April 2004.
|
|
*/
|
|
|
|
#include "libdefs.h"
|
|
|
|
#ifdef ENABLE_RIPEMD
|
|
|
|
#include "mhash_ripemd.h"
|
|
|
|
/* 32-bit rotate left - kludged with shifts */
|
|
#define ROTL(n,X) (((X)<<(n))|((X)>>(32-(n))))
|
|
|
|
#define f0(x,y,z) (x^y^z)
|
|
/* #define f16(x,y,z) ((x&y)|(~(x) & z)) */
|
|
#define f16(x,y,z) ((z)^((x)&((y)^(z))))
|
|
#define f32(x,y,z) ((x|~(y))^z)
|
|
/* #define f48(x,y,z) ((x&z)|(y&~(z))) */
|
|
#define f48(x,y,z) ((y)^((z)&((x)^(y))))
|
|
#define f64(x,y,z) (x^(y|(~z)))
|
|
|
|
#define K0 0x00000000
|
|
#define K1 0x5A827999 /* 2^30 * sqrt(2) */
|
|
#define K2 0x6ED9EBA1 /* 2^30 * sqrt(3) */
|
|
#define K3 0x8F1BBCDC /* 2^30 * sqrt(5) */
|
|
#define K4 0xA953FD4E /* 2^30 * sqrt(7) */
|
|
|
|
#define KK0 0x50A28BE6 /* 2^30 * cbrt(2) */
|
|
#define KK1 0x5C4DD124 /* 2^30 * cbrt(3) */
|
|
#define KK2 0x6D703EF3 /* 2^30 * cbrt(5) */
|
|
#define KK3 0x7A6D76E9 /* 2^30 * cbrt(7) */
|
|
#define KK4 0x00000000
|
|
|
|
#define h0init 0x67452301
|
|
#define h1init 0xEFCDAB89
|
|
#define h2init 0x98BADCFE
|
|
#define h3init 0x10325476
|
|
#define h4init 0xC3D2E1F0
|
|
#define h5init 0x76543210
|
|
#define h6init 0xFEDCBA98
|
|
#define h7init 0x89ABCDEF
|
|
#define h8init 0x01234567
|
|
#define h9init 0x3C2D1E0F
|
|
|
|
|
|
/* Initialize the RIPEMD values */
|
|
|
|
void ripemd_init(struct ripemd_ctx *ctx)
|
|
{
|
|
/* Set the h-vars to their initial values */
|
|
ctx->digest[0] = h0init;
|
|
ctx->digest[1] = h1init;
|
|
ctx->digest[2] = h2init;
|
|
ctx->digest[3] = h3init;
|
|
|
|
/* Initialize bit count */
|
|
ctx->bitcount = 0;
|
|
|
|
/* Initialize buffer */
|
|
ctx->index = 0;
|
|
}
|
|
|
|
void ripemd128_init(struct ripemd_ctx *ctx)
|
|
{
|
|
ripemd_init(ctx);
|
|
ctx->digest_len = 8 * RIPEMD128_DIGESTSIZE;
|
|
}
|
|
|
|
void ripemd160_init(struct ripemd_ctx *ctx)
|
|
{
|
|
ripemd_init(ctx);
|
|
ctx->digest[4] = h4init;
|
|
ctx->digest_len = 8 * RIPEMD160_DIGESTSIZE;
|
|
}
|
|
|
|
void ripemd256_init(struct ripemd_ctx *ctx)
|
|
{
|
|
ripemd_init(ctx);
|
|
ctx->digest[4] = h5init;
|
|
ctx->digest[5] = h6init;
|
|
ctx->digest[6] = h7init;
|
|
ctx->digest[7] = h8init;
|
|
ctx->digest_len = 8 * RIPEMD256_DIGESTSIZE;
|
|
}
|
|
|
|
void ripemd320_init(struct ripemd_ctx *ctx)
|
|
{
|
|
ripemd_init(ctx);
|
|
ctx->digest[4] = h4init;
|
|
ctx->digest[5] = h5init;
|
|
ctx->digest[6] = h6init;
|
|
ctx->digest[7] = h7init;
|
|
ctx->digest[8] = h8init;
|
|
ctx->digest[9] = h9init;
|
|
ctx->digest_len = 8 * RIPEMD320_DIGESTSIZE;
|
|
}
|
|
|
|
|
|
/* The RIPEMD core functions */
|
|
|
|
#define subRound128(a, b, c, d, f, k, r, data) \
|
|
( a = ROTL( r, a + f(b,c,d) + data + k))
|
|
|
|
#define subRound160(a, b, c, d, e, f, k, r, data) \
|
|
( a = ROTL( r, a + f(b,c,d) + data + k) + e, c = ROTL(10, c) )
|
|
|
|
static void ripemd128_transform(struct ripemd_ctx *ctx, mutils_word32 * data)
|
|
{
|
|
mutils_word32 A, B, C, D; /* Local vars */
|
|
mutils_word32 AA, BB, CC, DD; /* Local vars */
|
|
mutils_word32 T;
|
|
|
|
/* Set up first buffer and local data buffer */
|
|
A = AA = ctx->digest[0];
|
|
B = BB = ctx->digest[1];
|
|
C = CC = ctx->digest[2];
|
|
D = DD = ctx->digest[3];
|
|
|
|
/* j=0...15 */
|
|
subRound128(A, B, C, D, f0, K0, 11, data[0]);
|
|
subRound128(D, A, B, C, f0, K0, 14, data[1]);
|
|
subRound128(C, D, A, B, f0, K0, 15, data[2]);
|
|
subRound128(B, C, D, A, f0, K0, 12, data[3]);
|
|
subRound128(A, B, C, D, f0, K0, 5, data[4]);
|
|
subRound128(D, A, B, C, f0, K0, 8, data[5]);
|
|
subRound128(C, D, A, B, f0, K0, 7, data[6]);
|
|
subRound128(B, C, D, A, f0, K0, 9, data[7]);
|
|
subRound128(A, B, C, D, f0, K0, 11, data[8]);
|
|
subRound128(D, A, B, C, f0, K0, 13, data[9]);
|
|
subRound128(C, D, A, B, f0, K0, 14, data[10]);
|
|
subRound128(B, C, D, A, f0, K0, 15, data[11]);
|
|
subRound128(A, B, C, D, f0, K0, 6, data[12]);
|
|
subRound128(D, A, B, C, f0, K0, 7, data[13]);
|
|
subRound128(C, D, A, B, f0, K0, 9, data[14]);
|
|
subRound128(B, C, D, A, f0, K0, 8, data[15]);
|
|
|
|
subRound128(AA, BB, CC, DD, f48, KK0, 8, data[5]);
|
|
subRound128(DD, AA, BB, CC, f48, KK0, 9, data[14]);
|
|
subRound128(CC, DD, AA, BB, f48, KK0, 9, data[7]);
|
|
subRound128(BB, CC, DD, AA, f48, KK0, 11, data[0]);
|
|
subRound128(AA, BB, CC, DD, f48, KK0, 13, data[9]);
|
|
subRound128(DD, AA, BB, CC, f48, KK0, 15, data[2]);
|
|
subRound128(CC, DD, AA, BB, f48, KK0, 15, data[11]);
|
|
subRound128(BB, CC, DD, AA, f48, KK0, 5, data[4]);
|
|
subRound128(AA, BB, CC, DD, f48, KK0, 7, data[13]);
|
|
subRound128(DD, AA, BB, CC, f48, KK0, 7, data[6]);
|
|
subRound128(CC, DD, AA, BB, f48, KK0, 8, data[15]);
|
|
subRound128(BB, CC, DD, AA, f48, KK0, 11, data[8]);
|
|
subRound128(AA, BB, CC, DD, f48, KK0, 14, data[1]);
|
|
subRound128(DD, AA, BB, CC, f48, KK0, 14, data[10]);
|
|
subRound128(CC, DD, AA, BB, f48, KK0, 12, data[3]);
|
|
subRound128(BB, CC, DD, AA, f48, KK0, 6, data[12]);
|
|
|
|
/* j=16...31 */
|
|
subRound128(A, B, C, D, f16, K1, 7, data[7]);
|
|
subRound128(D, A, B, C, f16, K1, 6, data[4]);
|
|
subRound128(C, D, A, B, f16, K1, 8, data[13]);
|
|
subRound128(B, C, D, A, f16, K1, 13, data[1]);
|
|
subRound128(A, B, C, D, f16, K1, 11, data[10]);
|
|
subRound128(D, A, B, C, f16, K1, 9, data[6]);
|
|
subRound128(C, D, A, B, f16, K1, 7, data[15]);
|
|
subRound128(B, C, D, A, f16, K1, 15, data[3]);
|
|
subRound128(A, B, C, D, f16, K1, 7, data[12]);
|
|
subRound128(D, A, B, C, f16, K1, 12, data[0]);
|
|
subRound128(C, D, A, B, f16, K1, 15, data[9]);
|
|
subRound128(B, C, D, A, f16, K1, 9, data[5]);
|
|
subRound128(A, B, C, D, f16, K1, 11, data[2]);
|
|
subRound128(D, A, B, C, f16, K1, 7, data[14]);
|
|
subRound128(C, D, A, B, f16, K1, 13, data[11]);
|
|
subRound128(B, C, D, A, f16, K1, 12, data[8]);
|
|
|
|
subRound128(AA, BB, CC, DD, f32, KK1, 9, data[6]);
|
|
subRound128(DD, AA, BB, CC, f32, KK1, 13, data[11]);
|
|
subRound128(CC, DD, AA, BB, f32, KK1, 15, data[3]);
|
|
subRound128(BB, CC, DD, AA, f32, KK1, 7, data[7]);
|
|
subRound128(AA, BB, CC, DD, f32, KK1, 12, data[0]);
|
|
subRound128(DD, AA, BB, CC, f32, KK1, 8, data[13]);
|
|
subRound128(CC, DD, AA, BB, f32, KK1, 9, data[5]);
|
|
subRound128(BB, CC, DD, AA, f32, KK1, 11, data[10]);
|
|
subRound128(AA, BB, CC, DD, f32, KK1, 7, data[14]);
|
|
subRound128(DD, AA, BB, CC, f32, KK1, 7, data[15]);
|
|
subRound128(CC, DD, AA, BB, f32, KK1, 12, data[8]);
|
|
subRound128(BB, CC, DD, AA, f32, KK1, 7, data[12]);
|
|
subRound128(AA, BB, CC, DD, f32, KK1, 6, data[4]);
|
|
subRound128(DD, AA, BB, CC, f32, KK1, 15, data[9]);
|
|
subRound128(CC, DD, AA, BB, f32, KK1, 13, data[1]);
|
|
subRound128(BB, CC, DD, AA, f32, KK1, 11, data[2]);
|
|
|
|
/* j=32...47 */
|
|
subRound128(A, B, C, D, f32, K2, 11, data[3]);
|
|
subRound128(D, A, B, C, f32, K2, 13, data[10]);
|
|
subRound128(C, D, A, B, f32, K2, 6, data[14]);
|
|
subRound128(B, C, D, A, f32, K2, 7, data[4]);
|
|
subRound128(A, B, C, D, f32, K2, 14, data[9]);
|
|
subRound128(D, A, B, C, f32, K2, 9, data[15]);
|
|
subRound128(C, D, A, B, f32, K2, 13, data[8]);
|
|
subRound128(B, C, D, A, f32, K2, 15, data[1]);
|
|
subRound128(A, B, C, D, f32, K2, 14, data[2]);
|
|
subRound128(D, A, B, C, f32, K2, 8, data[7]);
|
|
subRound128(C, D, A, B, f32, K2, 13, data[0]);
|
|
subRound128(B, C, D, A, f32, K2, 6, data[6]);
|
|
subRound128(A, B, C, D, f32, K2, 5, data[13]);
|
|
subRound128(D, A, B, C, f32, K2, 12, data[11]);
|
|
subRound128(C, D, A, B, f32, K2, 7, data[5]);
|
|
subRound128(B, C, D, A, f32, K2, 5, data[12]);
|
|
|
|
subRound128(AA, BB, CC, DD, f16, KK2, 9, data[15]);
|
|
subRound128(DD, AA, BB, CC, f16, KK2, 7, data[5]);
|
|
subRound128(CC, DD, AA, BB, f16, KK2, 15, data[1]);
|
|
subRound128(BB, CC, DD, AA, f16, KK2, 11, data[3]);
|
|
subRound128(AA, BB, CC, DD, f16, KK2, 8, data[7]);
|
|
subRound128(DD, AA, BB, CC, f16, KK2, 6, data[14]);
|
|
subRound128(CC, DD, AA, BB, f16, KK2, 6, data[6]);
|
|
subRound128(BB, CC, DD, AA, f16, KK2, 14, data[9]);
|
|
subRound128(AA, BB, CC, DD, f16, KK2, 12, data[11]);
|
|
subRound128(DD, AA, BB, CC, f16, KK2, 13, data[8]);
|
|
subRound128(CC, DD, AA, BB, f16, KK2, 5, data[12]);
|
|
subRound128(BB, CC, DD, AA, f16, KK2, 14, data[2]);
|
|
subRound128(AA, BB, CC, DD, f16, KK2, 13, data[10]);
|
|
subRound128(DD, AA, BB, CC, f16, KK2, 13, data[0]);
|
|
subRound128(CC, DD, AA, BB, f16, KK2, 7, data[4]);
|
|
subRound128(BB, CC, DD, AA, f16, KK2, 5, data[13]);
|
|
|
|
/* j=48...63 */
|
|
subRound128(A, B, C, D, f48, K3, 11, data[1]);
|
|
subRound128(D, A, B, C, f48, K3, 12, data[9]);
|
|
subRound128(C, D, A, B, f48, K3, 14, data[11]);
|
|
subRound128(B, C, D, A, f48, K3, 15, data[10]);
|
|
subRound128(A, B, C, D, f48, K3, 14, data[0]);
|
|
subRound128(D, A, B, C, f48, K3, 15, data[8]);
|
|
subRound128(C, D, A, B, f48, K3, 9, data[12]);
|
|
subRound128(B, C, D, A, f48, K3, 8, data[4]);
|
|
subRound128(A, B, C, D, f48, K3, 9, data[13]);
|
|
subRound128(D, A, B, C, f48, K3, 14, data[3]);
|
|
subRound128(C, D, A, B, f48, K3, 5, data[7]);
|
|
subRound128(B, C, D, A, f48, K3, 6, data[15]);
|
|
subRound128(A, B, C, D, f48, K3, 8, data[14]);
|
|
subRound128(D, A, B, C, f48, K3, 6, data[5]);
|
|
subRound128(C, D, A, B, f48, K3, 5, data[6]);
|
|
subRound128(B, C, D, A, f48, K3, 12, data[2]);
|
|
|
|
subRound128(AA, BB, CC, DD, f0, KK4, 15, data[8]);
|
|
subRound128(DD, AA, BB, CC, f0, KK4, 5, data[6]);
|
|
subRound128(CC, DD, AA, BB, f0, KK4, 8, data[4]);
|
|
subRound128(BB, CC, DD, AA, f0, KK4, 11, data[1]);
|
|
subRound128(AA, BB, CC, DD, f0, KK4, 14, data[3]);
|
|
subRound128(DD, AA, BB, CC, f0, KK4, 14, data[11]);
|
|
subRound128(CC, DD, AA, BB, f0, KK4, 6, data[15]);
|
|
subRound128(BB, CC, DD, AA, f0, KK4, 14, data[0]);
|
|
subRound128(AA, BB, CC, DD, f0, KK4, 6, data[5]);
|
|
subRound128(DD, AA, BB, CC, f0, KK4, 9, data[12]);
|
|
subRound128(CC, DD, AA, BB, f0, KK4, 12, data[2]);
|
|
subRound128(BB, CC, DD, AA, f0, KK4, 9, data[13]);
|
|
subRound128(AA, BB, CC, DD, f0, KK4, 12, data[9]);
|
|
subRound128(DD, AA, BB, CC, f0, KK4, 5, data[7]);
|
|
subRound128(CC, DD, AA, BB, f0, KK4, 15, data[10]);
|
|
subRound128(BB, CC, DD, AA, f0, KK4, 8, data[14]);
|
|
|
|
T = ctx->digest[1] + DD + C;
|
|
ctx->digest[1] = ctx->digest[2] + AA + D;
|
|
ctx->digest[2] = ctx->digest[3] + BB + A;
|
|
ctx->digest[3] = ctx->digest[0] + CC + B;
|
|
ctx->digest[0] = T;
|
|
}
|
|
|
|
static void ripemd160_transform(struct ripemd_ctx *ctx, mutils_word32 * data)
|
|
{
|
|
mutils_word32 A, B, C, D, E; /* Local vars */
|
|
mutils_word32 AA, BB, CC, DD, EE; /* Local vars */
|
|
mutils_word32 T;
|
|
|
|
/* Set up first buffer and local data buffer */
|
|
A = AA = ctx->digest[0];
|
|
B = BB = ctx->digest[1];
|
|
C = CC = ctx->digest[2];
|
|
D = DD = ctx->digest[3];
|
|
E = EE = ctx->digest[4];
|
|
|
|
/* j=0...15 */
|
|
subRound160(A, B, C, D, E, f0, K0, 11, data[0]);
|
|
subRound160(E, A, B, C, D, f0, K0, 14, data[1]);
|
|
subRound160(D, E, A, B, C, f0, K0, 15, data[2]);
|
|
subRound160(C, D, E, A, B, f0, K0, 12, data[3]);
|
|
subRound160(B, C, D, E, A, f0, K0, 5, data[4]);
|
|
subRound160(A, B, C, D, E, f0, K0, 8, data[5]);
|
|
subRound160(E, A, B, C, D, f0, K0, 7, data[6]);
|
|
subRound160(D, E, A, B, C, f0, K0, 9, data[7]);
|
|
subRound160(C, D, E, A, B, f0, K0, 11, data[8]);
|
|
subRound160(B, C, D, E, A, f0, K0, 13, data[9]);
|
|
subRound160(A, B, C, D, E, f0, K0, 14, data[10]);
|
|
subRound160(E, A, B, C, D, f0, K0, 15, data[11]);
|
|
subRound160(D, E, A, B, C, f0, K0, 6, data[12]);
|
|
subRound160(C, D, E, A, B, f0, K0, 7, data[13]);
|
|
subRound160(B, C, D, E, A, f0, K0, 9, data[14]);
|
|
subRound160(A, B, C, D, E, f0, K0, 8, data[15]);
|
|
|
|
subRound160(AA, BB, CC, DD, EE, f64, KK0, 8, data[5]);
|
|
subRound160(EE, AA, BB, CC, DD, f64, KK0, 9, data[14]);
|
|
subRound160(DD, EE, AA, BB, CC, f64, KK0, 9, data[7]);
|
|
subRound160(CC, DD, EE, AA, BB, f64, KK0, 11, data[0]);
|
|
subRound160(BB, CC, DD, EE, AA, f64, KK0, 13, data[9]);
|
|
subRound160(AA, BB, CC, DD, EE, f64, KK0, 15, data[2]);
|
|
subRound160(EE, AA, BB, CC, DD, f64, KK0, 15, data[11]);
|
|
subRound160(DD, EE, AA, BB, CC, f64, KK0, 5, data[4]);
|
|
subRound160(CC, DD, EE, AA, BB, f64, KK0, 7, data[13]);
|
|
subRound160(BB, CC, DD, EE, AA, f64, KK0, 7, data[6]);
|
|
subRound160(AA, BB, CC, DD, EE, f64, KK0, 8, data[15]);
|
|
subRound160(EE, AA, BB, CC, DD, f64, KK0, 11, data[8]);
|
|
subRound160(DD, EE, AA, BB, CC, f64, KK0, 14, data[1]);
|
|
subRound160(CC, DD, EE, AA, BB, f64, KK0, 14, data[10]);
|
|
subRound160(BB, CC, DD, EE, AA, f64, KK0, 12, data[3]);
|
|
subRound160(AA, BB, CC, DD, EE, f64, KK0, 6, data[12]);
|
|
|
|
/* j=16...31 */
|
|
subRound160(E, A, B, C, D, f16, K1, 7, data[7]);
|
|
subRound160(D, E, A, B, C, f16, K1, 6, data[4]);
|
|
subRound160(C, D, E, A, B, f16, K1, 8, data[13]);
|
|
subRound160(B, C, D, E, A, f16, K1, 13, data[1]);
|
|
subRound160(A, B, C, D, E, f16, K1, 11, data[10]);
|
|
subRound160(E, A, B, C, D, f16, K1, 9, data[6]);
|
|
subRound160(D, E, A, B, C, f16, K1, 7, data[15]);
|
|
subRound160(C, D, E, A, B, f16, K1, 15, data[3]);
|
|
subRound160(B, C, D, E, A, f16, K1, 7, data[12]);
|
|
subRound160(A, B, C, D, E, f16, K1, 12, data[0]);
|
|
subRound160(E, A, B, C, D, f16, K1, 15, data[9]);
|
|
subRound160(D, E, A, B, C, f16, K1, 9, data[5]);
|
|
subRound160(C, D, E, A, B, f16, K1, 11, data[2]);
|
|
subRound160(B, C, D, E, A, f16, K1, 7, data[14]);
|
|
subRound160(A, B, C, D, E, f16, K1, 13, data[11]);
|
|
subRound160(E, A, B, C, D, f16, K1, 12, data[8]);
|
|
|
|
subRound160(EE, AA, BB, CC, DD, f48, KK1, 9, data[6]);
|
|
subRound160(DD, EE, AA, BB, CC, f48, KK1, 13, data[11]);
|
|
subRound160(CC, DD, EE, AA, BB, f48, KK1, 15, data[3]);
|
|
subRound160(BB, CC, DD, EE, AA, f48, KK1, 7, data[7]);
|
|
subRound160(AA, BB, CC, DD, EE, f48, KK1, 12, data[0]);
|
|
subRound160(EE, AA, BB, CC, DD, f48, KK1, 8, data[13]);
|
|
subRound160(DD, EE, AA, BB, CC, f48, KK1, 9, data[5]);
|
|
subRound160(CC, DD, EE, AA, BB, f48, KK1, 11, data[10]);
|
|
subRound160(BB, CC, DD, EE, AA, f48, KK1, 7, data[14]);
|
|
subRound160(AA, BB, CC, DD, EE, f48, KK1, 7, data[15]);
|
|
subRound160(EE, AA, BB, CC, DD, f48, KK1, 12, data[8]);
|
|
subRound160(DD, EE, AA, BB, CC, f48, KK1, 7, data[12]);
|
|
subRound160(CC, DD, EE, AA, BB, f48, KK1, 6, data[4]);
|
|
subRound160(BB, CC, DD, EE, AA, f48, KK1, 15, data[9]);
|
|
subRound160(AA, BB, CC, DD, EE, f48, KK1, 13, data[1]);
|
|
subRound160(EE, AA, BB, CC, DD, f48, KK1, 11, data[2]);
|
|
|
|
/* j=32...47 */
|
|
subRound160(D, E, A, B, C, f32, K2, 11, data[3]);
|
|
subRound160(C, D, E, A, B, f32, K2, 13, data[10]);
|
|
subRound160(B, C, D, E, A, f32, K2, 6, data[14]);
|
|
subRound160(A, B, C, D, E, f32, K2, 7, data[4]);
|
|
subRound160(E, A, B, C, D, f32, K2, 14, data[9]);
|
|
subRound160(D, E, A, B, C, f32, K2, 9, data[15]);
|
|
subRound160(C, D, E, A, B, f32, K2, 13, data[8]);
|
|
subRound160(B, C, D, E, A, f32, K2, 15, data[1]);
|
|
subRound160(A, B, C, D, E, f32, K2, 14, data[2]);
|
|
subRound160(E, A, B, C, D, f32, K2, 8, data[7]);
|
|
subRound160(D, E, A, B, C, f32, K2, 13, data[0]);
|
|
subRound160(C, D, E, A, B, f32, K2, 6, data[6]);
|
|
subRound160(B, C, D, E, A, f32, K2, 5, data[13]);
|
|
subRound160(A, B, C, D, E, f32, K2, 12, data[11]);
|
|
subRound160(E, A, B, C, D, f32, K2, 7, data[5]);
|
|
subRound160(D, E, A, B, C, f32, K2, 5, data[12]);
|
|
|
|
subRound160(DD, EE, AA, BB, CC, f32, KK2, 9, data[15]);
|
|
subRound160(CC, DD, EE, AA, BB, f32, KK2, 7, data[5]);
|
|
subRound160(BB, CC, DD, EE, AA, f32, KK2, 15, data[1]);
|
|
subRound160(AA, BB, CC, DD, EE, f32, KK2, 11, data[3]);
|
|
subRound160(EE, AA, BB, CC, DD, f32, KK2, 8, data[7]);
|
|
subRound160(DD, EE, AA, BB, CC, f32, KK2, 6, data[14]);
|
|
subRound160(CC, DD, EE, AA, BB, f32, KK2, 6, data[6]);
|
|
subRound160(BB, CC, DD, EE, AA, f32, KK2, 14, data[9]);
|
|
subRound160(AA, BB, CC, DD, EE, f32, KK2, 12, data[11]);
|
|
subRound160(EE, AA, BB, CC, DD, f32, KK2, 13, data[8]);
|
|
subRound160(DD, EE, AA, BB, CC, f32, KK2, 5, data[12]);
|
|
subRound160(CC, DD, EE, AA, BB, f32, KK2, 14, data[2]);
|
|
subRound160(BB, CC, DD, EE, AA, f32, KK2, 13, data[10]);
|
|
subRound160(AA, BB, CC, DD, EE, f32, KK2, 13, data[0]);
|
|
subRound160(EE, AA, BB, CC, DD, f32, KK2, 7, data[4]);
|
|
subRound160(DD, EE, AA, BB, CC, f32, KK2, 5, data[13]);
|
|
|
|
/* j=48...63 */
|
|
subRound160(C, D, E, A, B, f48, K3, 11, data[1]);
|
|
subRound160(B, C, D, E, A, f48, K3, 12, data[9]);
|
|
subRound160(A, B, C, D, E, f48, K3, 14, data[11]);
|
|
subRound160(E, A, B, C, D, f48, K3, 15, data[10]);
|
|
subRound160(D, E, A, B, C, f48, K3, 14, data[0]);
|
|
subRound160(C, D, E, A, B, f48, K3, 15, data[8]);
|
|
subRound160(B, C, D, E, A, f48, K3, 9, data[12]);
|
|
subRound160(A, B, C, D, E, f48, K3, 8, data[4]);
|
|
subRound160(E, A, B, C, D, f48, K3, 9, data[13]);
|
|
subRound160(D, E, A, B, C, f48, K3, 14, data[3]);
|
|
subRound160(C, D, E, A, B, f48, K3, 5, data[7]);
|
|
subRound160(B, C, D, E, A, f48, K3, 6, data[15]);
|
|
subRound160(A, B, C, D, E, f48, K3, 8, data[14]);
|
|
subRound160(E, A, B, C, D, f48, K3, 6, data[5]);
|
|
subRound160(D, E, A, B, C, f48, K3, 5, data[6]);
|
|
subRound160(C, D, E, A, B, f48, K3, 12, data[2]);
|
|
|
|
subRound160(CC, DD, EE, AA, BB, f16, KK3, 15, data[8]);
|
|
subRound160(BB, CC, DD, EE, AA, f16, KK3, 5, data[6]);
|
|
subRound160(AA, BB, CC, DD, EE, f16, KK3, 8, data[4]);
|
|
subRound160(EE, AA, BB, CC, DD, f16, KK3, 11, data[1]);
|
|
subRound160(DD, EE, AA, BB, CC, f16, KK3, 14, data[3]);
|
|
subRound160(CC, DD, EE, AA, BB, f16, KK3, 14, data[11]);
|
|
subRound160(BB, CC, DD, EE, AA, f16, KK3, 6, data[15]);
|
|
subRound160(AA, BB, CC, DD, EE, f16, KK3, 14, data[0]);
|
|
subRound160(EE, AA, BB, CC, DD, f16, KK3, 6, data[5]);
|
|
subRound160(DD, EE, AA, BB, CC, f16, KK3, 9, data[12]);
|
|
subRound160(CC, DD, EE, AA, BB, f16, KK3, 12, data[2]);
|
|
subRound160(BB, CC, DD, EE, AA, f16, KK3, 9, data[13]);
|
|
subRound160(AA, BB, CC, DD, EE, f16, KK3, 12, data[9]);
|
|
subRound160(EE, AA, BB, CC, DD, f16, KK3, 5, data[7]);
|
|
subRound160(DD, EE, AA, BB, CC, f16, KK3, 15, data[10]);
|
|
subRound160(CC, DD, EE, AA, BB, f16, KK3, 8, data[14]);
|
|
|
|
/* j=64...79 */
|
|
subRound160(B, C, D, E, A, f64, K4, 9, data[4]);
|
|
subRound160(A, B, C, D, E, f64, K4, 15, data[0]);
|
|
subRound160(E, A, B, C, D, f64, K4, 5, data[5]);
|
|
subRound160(D, E, A, B, C, f64, K4, 11, data[9]);
|
|
subRound160(C, D, E, A, B, f64, K4, 6, data[7]);
|
|
subRound160(B, C, D, E, A, f64, K4, 8, data[12]);
|
|
subRound160(A, B, C, D, E, f64, K4, 13, data[2]);
|
|
subRound160(E, A, B, C, D, f64, K4, 12, data[10]);
|
|
subRound160(D, E, A, B, C, f64, K4, 5, data[14]);
|
|
subRound160(C, D, E, A, B, f64, K4, 12, data[1]);
|
|
subRound160(B, C, D, E, A, f64, K4, 13, data[3]);
|
|
subRound160(A, B, C, D, E, f64, K4, 14, data[8]);
|
|
subRound160(E, A, B, C, D, f64, K4, 11, data[11]);
|
|
subRound160(D, E, A, B, C, f64, K4, 8, data[6]);
|
|
subRound160(C, D, E, A, B, f64, K4, 5, data[15]);
|
|
subRound160(B, C, D, E, A, f64, K4, 6, data[13]);
|
|
|
|
subRound160(BB, CC, DD, EE, AA, f0, KK4, 8, data[12]);
|
|
subRound160(AA, BB, CC, DD, EE, f0, KK4, 5, data[15]);
|
|
subRound160(EE, AA, BB, CC, DD, f0, KK4, 12, data[10]);
|
|
subRound160(DD, EE, AA, BB, CC, f0, KK4, 9, data[4]);
|
|
subRound160(CC, DD, EE, AA, BB, f0, KK4, 12, data[1]);
|
|
subRound160(BB, CC, DD, EE, AA, f0, KK4, 5, data[5]);
|
|
subRound160(AA, BB, CC, DD, EE, f0, KK4, 14, data[8]);
|
|
subRound160(EE, AA, BB, CC, DD, f0, KK4, 6, data[7]);
|
|
subRound160(DD, EE, AA, BB, CC, f0, KK4, 8, data[6]);
|
|
subRound160(CC, DD, EE, AA, BB, f0, KK4, 13, data[2]);
|
|
subRound160(BB, CC, DD, EE, AA, f0, KK4, 6, data[13]);
|
|
subRound160(AA, BB, CC, DD, EE, f0, KK4, 5, data[14]);
|
|
subRound160(EE, AA, BB, CC, DD, f0, KK4, 15, data[0]);
|
|
subRound160(DD, EE, AA, BB, CC, f0, KK4, 13, data[3]);
|
|
subRound160(CC, DD, EE, AA, BB, f0, KK4, 11, data[9]);
|
|
subRound160(BB, CC, DD, EE, AA, f0, KK4, 11, data[11]);
|
|
|
|
|
|
T = ctx->digest[1] + DD + C;
|
|
ctx->digest[1] = ctx->digest[2] + EE + D;
|
|
ctx->digest[2] = ctx->digest[3] + AA + E;
|
|
ctx->digest[3] = ctx->digest[4] + BB + A;
|
|
ctx->digest[4] = ctx->digest[0] + CC + B;
|
|
ctx->digest[0] = T;
|
|
}
|
|
|
|
|
|
static void ripemd256_transform(struct ripemd_ctx *ctx, mutils_word32 * data)
|
|
{
|
|
mutils_word32 A, B, C, D; /* Local vars */
|
|
mutils_word32 AA, BB, CC, DD; /* Local vars */
|
|
mutils_word32 T;
|
|
|
|
/* Set up first buffer and local data buffer */
|
|
A = ctx->digest[0];
|
|
B = ctx->digest[1];
|
|
C = ctx->digest[2];
|
|
D = ctx->digest[3];
|
|
AA = ctx->digest[4];
|
|
BB = ctx->digest[5];
|
|
CC = ctx->digest[6];
|
|
DD = ctx->digest[7];
|
|
|
|
/* j=0...15 */
|
|
subRound128(A, B, C, D, f0, K0, 11, data[0]);
|
|
subRound128(D, A, B, C, f0, K0, 14, data[1]);
|
|
subRound128(C, D, A, B, f0, K0, 15, data[2]);
|
|
subRound128(B, C, D, A, f0, K0, 12, data[3]);
|
|
subRound128(A, B, C, D, f0, K0, 5, data[4]);
|
|
subRound128(D, A, B, C, f0, K0, 8, data[5]);
|
|
subRound128(C, D, A, B, f0, K0, 7, data[6]);
|
|
subRound128(B, C, D, A, f0, K0, 9, data[7]);
|
|
subRound128(A, B, C, D, f0, K0, 11, data[8]);
|
|
subRound128(D, A, B, C, f0, K0, 13, data[9]);
|
|
subRound128(C, D, A, B, f0, K0, 14, data[10]);
|
|
subRound128(B, C, D, A, f0, K0, 15, data[11]);
|
|
subRound128(A, B, C, D, f0, K0, 6, data[12]);
|
|
subRound128(D, A, B, C, f0, K0, 7, data[13]);
|
|
subRound128(C, D, A, B, f0, K0, 9, data[14]);
|
|
subRound128(B, C, D, A, f0, K0, 8, data[15]);
|
|
|
|
subRound128(AA, BB, CC, DD, f48, KK0, 8, data[5]);
|
|
subRound128(DD, AA, BB, CC, f48, KK0, 9, data[14]);
|
|
subRound128(CC, DD, AA, BB, f48, KK0, 9, data[7]);
|
|
subRound128(BB, CC, DD, AA, f48, KK0, 11, data[0]);
|
|
subRound128(AA, BB, CC, DD, f48, KK0, 13, data[9]);
|
|
subRound128(DD, AA, BB, CC, f48, KK0, 15, data[2]);
|
|
subRound128(CC, DD, AA, BB, f48, KK0, 15, data[11]);
|
|
subRound128(BB, CC, DD, AA, f48, KK0, 5, data[4]);
|
|
subRound128(AA, BB, CC, DD, f48, KK0, 7, data[13]);
|
|
subRound128(DD, AA, BB, CC, f48, KK0, 7, data[6]);
|
|
subRound128(CC, DD, AA, BB, f48, KK0, 8, data[15]);
|
|
subRound128(BB, CC, DD, AA, f48, KK0, 11, data[8]);
|
|
subRound128(AA, BB, CC, DD, f48, KK0, 14, data[1]);
|
|
subRound128(DD, AA, BB, CC, f48, KK0, 14, data[10]);
|
|
subRound128(CC, DD, AA, BB, f48, KK0, 12, data[3]);
|
|
subRound128(BB, CC, DD, AA, f48, KK0, 6, data[12]);
|
|
|
|
T = A; A = AA; AA = T;
|
|
|
|
/* j=16...31 */
|
|
subRound128(A, B, C, D, f16, K1, 7, data[7]);
|
|
subRound128(D, A, B, C, f16, K1, 6, data[4]);
|
|
subRound128(C, D, A, B, f16, K1, 8, data[13]);
|
|
subRound128(B, C, D, A, f16, K1, 13, data[1]);
|
|
subRound128(A, B, C, D, f16, K1, 11, data[10]);
|
|
subRound128(D, A, B, C, f16, K1, 9, data[6]);
|
|
subRound128(C, D, A, B, f16, K1, 7, data[15]);
|
|
subRound128(B, C, D, A, f16, K1, 15, data[3]);
|
|
subRound128(A, B, C, D, f16, K1, 7, data[12]);
|
|
subRound128(D, A, B, C, f16, K1, 12, data[0]);
|
|
subRound128(C, D, A, B, f16, K1, 15, data[9]);
|
|
subRound128(B, C, D, A, f16, K1, 9, data[5]);
|
|
subRound128(A, B, C, D, f16, K1, 11, data[2]);
|
|
subRound128(D, A, B, C, f16, K1, 7, data[14]);
|
|
subRound128(C, D, A, B, f16, K1, 13, data[11]);
|
|
subRound128(B, C, D, A, f16, K1, 12, data[8]);
|
|
|
|
subRound128(AA, BB, CC, DD, f32, KK1, 9, data[6]);
|
|
subRound128(DD, AA, BB, CC, f32, KK1, 13, data[11]);
|
|
subRound128(CC, DD, AA, BB, f32, KK1, 15, data[3]);
|
|
subRound128(BB, CC, DD, AA, f32, KK1, 7, data[7]);
|
|
subRound128(AA, BB, CC, DD, f32, KK1, 12, data[0]);
|
|
subRound128(DD, AA, BB, CC, f32, KK1, 8, data[13]);
|
|
subRound128(CC, DD, AA, BB, f32, KK1, 9, data[5]);
|
|
subRound128(BB, CC, DD, AA, f32, KK1, 11, data[10]);
|
|
subRound128(AA, BB, CC, DD, f32, KK1, 7, data[14]);
|
|
subRound128(DD, AA, BB, CC, f32, KK1, 7, data[15]);
|
|
subRound128(CC, DD, AA, BB, f32, KK1, 12, data[8]);
|
|
subRound128(BB, CC, DD, AA, f32, KK1, 7, data[12]);
|
|
subRound128(AA, BB, CC, DD, f32, KK1, 6, data[4]);
|
|
subRound128(DD, AA, BB, CC, f32, KK1, 15, data[9]);
|
|
subRound128(CC, DD, AA, BB, f32, KK1, 13, data[1]);
|
|
subRound128(BB, CC, DD, AA, f32, KK1, 11, data[2]);
|
|
|
|
T = B; B = BB; BB = T;
|
|
|
|
/* j=32...47 */
|
|
subRound128(A, B, C, D, f32, K2, 11, data[3]);
|
|
subRound128(D, A, B, C, f32, K2, 13, data[10]);
|
|
subRound128(C, D, A, B, f32, K2, 6, data[14]);
|
|
subRound128(B, C, D, A, f32, K2, 7, data[4]);
|
|
subRound128(A, B, C, D, f32, K2, 14, data[9]);
|
|
subRound128(D, A, B, C, f32, K2, 9, data[15]);
|
|
subRound128(C, D, A, B, f32, K2, 13, data[8]);
|
|
subRound128(B, C, D, A, f32, K2, 15, data[1]);
|
|
subRound128(A, B, C, D, f32, K2, 14, data[2]);
|
|
subRound128(D, A, B, C, f32, K2, 8, data[7]);
|
|
subRound128(C, D, A, B, f32, K2, 13, data[0]);
|
|
subRound128(B, C, D, A, f32, K2, 6, data[6]);
|
|
subRound128(A, B, C, D, f32, K2, 5, data[13]);
|
|
subRound128(D, A, B, C, f32, K2, 12, data[11]);
|
|
subRound128(C, D, A, B, f32, K2, 7, data[5]);
|
|
subRound128(B, C, D, A, f32, K2, 5, data[12]);
|
|
|
|
subRound128(AA, BB, CC, DD, f16, KK2, 9, data[15]);
|
|
subRound128(DD, AA, BB, CC, f16, KK2, 7, data[5]);
|
|
subRound128(CC, DD, AA, BB, f16, KK2, 15, data[1]);
|
|
subRound128(BB, CC, DD, AA, f16, KK2, 11, data[3]);
|
|
subRound128(AA, BB, CC, DD, f16, KK2, 8, data[7]);
|
|
subRound128(DD, AA, BB, CC, f16, KK2, 6, data[14]);
|
|
subRound128(CC, DD, AA, BB, f16, KK2, 6, data[6]);
|
|
subRound128(BB, CC, DD, AA, f16, KK2, 14, data[9]);
|
|
subRound128(AA, BB, CC, DD, f16, KK2, 12, data[11]);
|
|
subRound128(DD, AA, BB, CC, f16, KK2, 13, data[8]);
|
|
subRound128(CC, DD, AA, BB, f16, KK2, 5, data[12]);
|
|
subRound128(BB, CC, DD, AA, f16, KK2, 14, data[2]);
|
|
subRound128(AA, BB, CC, DD, f16, KK2, 13, data[10]);
|
|
subRound128(DD, AA, BB, CC, f16, KK2, 13, data[0]);
|
|
subRound128(CC, DD, AA, BB, f16, KK2, 7, data[4]);
|
|
subRound128(BB, CC, DD, AA, f16, KK2, 5, data[13]);
|
|
|
|
T = C; C = CC; CC = T;
|
|
|
|
/* j=48...63 */
|
|
subRound128(A, B, C, D, f48, K3, 11, data[1]);
|
|
subRound128(D, A, B, C, f48, K3, 12, data[9]);
|
|
subRound128(C, D, A, B, f48, K3, 14, data[11]);
|
|
subRound128(B, C, D, A, f48, K3, 15, data[10]);
|
|
subRound128(A, B, C, D, f48, K3, 14, data[0]);
|
|
subRound128(D, A, B, C, f48, K3, 15, data[8]);
|
|
subRound128(C, D, A, B, f48, K3, 9, data[12]);
|
|
subRound128(B, C, D, A, f48, K3, 8, data[4]);
|
|
subRound128(A, B, C, D, f48, K3, 9, data[13]);
|
|
subRound128(D, A, B, C, f48, K3, 14, data[3]);
|
|
subRound128(C, D, A, B, f48, K3, 5, data[7]);
|
|
subRound128(B, C, D, A, f48, K3, 6, data[15]);
|
|
subRound128(A, B, C, D, f48, K3, 8, data[14]);
|
|
subRound128(D, A, B, C, f48, K3, 6, data[5]);
|
|
subRound128(C, D, A, B, f48, K3, 5, data[6]);
|
|
subRound128(B, C, D, A, f48, K3, 12, data[2]);
|
|
|
|
subRound128(AA, BB, CC, DD, f0, KK4, 15, data[8]);
|
|
subRound128(DD, AA, BB, CC, f0, KK4, 5, data[6]);
|
|
subRound128(CC, DD, AA, BB, f0, KK4, 8, data[4]);
|
|
subRound128(BB, CC, DD, AA, f0, KK4, 11, data[1]);
|
|
subRound128(AA, BB, CC, DD, f0, KK4, 14, data[3]);
|
|
subRound128(DD, AA, BB, CC, f0, KK4, 14, data[11]);
|
|
subRound128(CC, DD, AA, BB, f0, KK4, 6, data[15]);
|
|
subRound128(BB, CC, DD, AA, f0, KK4, 14, data[0]);
|
|
subRound128(AA, BB, CC, DD, f0, KK4, 6, data[5]);
|
|
subRound128(DD, AA, BB, CC, f0, KK4, 9, data[12]);
|
|
subRound128(CC, DD, AA, BB, f0, KK4, 12, data[2]);
|
|
subRound128(BB, CC, DD, AA, f0, KK4, 9, data[13]);
|
|
subRound128(AA, BB, CC, DD, f0, KK4, 12, data[9]);
|
|
subRound128(DD, AA, BB, CC, f0, KK4, 5, data[7]);
|
|
subRound128(CC, DD, AA, BB, f0, KK4, 15, data[10]);
|
|
subRound128(BB, CC, DD, AA, f0, KK4, 8, data[14]);
|
|
|
|
/* T = D; D = DD; DD = T; */
|
|
|
|
ctx->digest[0] += A;
|
|
ctx->digest[1] += B;
|
|
ctx->digest[2] += C;
|
|
ctx->digest[3] += DD;
|
|
ctx->digest[4] += AA;
|
|
ctx->digest[5] += BB;
|
|
ctx->digest[6] += CC;
|
|
ctx->digest[7] += D;
|
|
}
|
|
|
|
static void ripemd320_transform(struct ripemd_ctx *ctx, mutils_word32 * data)
|
|
{
|
|
mutils_word32 A, B, C, D, E; /* Local vars */
|
|
mutils_word32 AA, BB, CC, DD, EE; /* Local vars */
|
|
mutils_word32 T;
|
|
|
|
/* Set up first buffer and local data buffer */
|
|
A = ctx->digest[0];
|
|
B = ctx->digest[1];
|
|
C = ctx->digest[2];
|
|
D = ctx->digest[3];
|
|
E = ctx->digest[4];
|
|
AA = ctx->digest[5];
|
|
BB = ctx->digest[6];
|
|
CC = ctx->digest[7];
|
|
DD = ctx->digest[8];
|
|
EE = ctx->digest[9];
|
|
|
|
/* j=0...15 */
|
|
subRound160(A, B, C, D, E, f0, K0, 11, data[0]);
|
|
subRound160(E, A, B, C, D, f0, K0, 14, data[1]);
|
|
subRound160(D, E, A, B, C, f0, K0, 15, data[2]);
|
|
subRound160(C, D, E, A, B, f0, K0, 12, data[3]);
|
|
subRound160(B, C, D, E, A, f0, K0, 5, data[4]);
|
|
subRound160(A, B, C, D, E, f0, K0, 8, data[5]);
|
|
subRound160(E, A, B, C, D, f0, K0, 7, data[6]);
|
|
subRound160(D, E, A, B, C, f0, K0, 9, data[7]);
|
|
subRound160(C, D, E, A, B, f0, K0, 11, data[8]);
|
|
subRound160(B, C, D, E, A, f0, K0, 13, data[9]);
|
|
subRound160(A, B, C, D, E, f0, K0, 14, data[10]);
|
|
subRound160(E, A, B, C, D, f0, K0, 15, data[11]);
|
|
subRound160(D, E, A, B, C, f0, K0, 6, data[12]);
|
|
subRound160(C, D, E, A, B, f0, K0, 7, data[13]);
|
|
subRound160(B, C, D, E, A, f0, K0, 9, data[14]);
|
|
subRound160(A, B, C, D, E, f0, K0, 8, data[15]);
|
|
|
|
subRound160(AA, BB, CC, DD, EE, f64, KK0, 8, data[5]);
|
|
subRound160(EE, AA, BB, CC, DD, f64, KK0, 9, data[14]);
|
|
subRound160(DD, EE, AA, BB, CC, f64, KK0, 9, data[7]);
|
|
subRound160(CC, DD, EE, AA, BB, f64, KK0, 11, data[0]);
|
|
subRound160(BB, CC, DD, EE, AA, f64, KK0, 13, data[9]);
|
|
subRound160(AA, BB, CC, DD, EE, f64, KK0, 15, data[2]);
|
|
subRound160(EE, AA, BB, CC, DD, f64, KK0, 15, data[11]);
|
|
subRound160(DD, EE, AA, BB, CC, f64, KK0, 5, data[4]);
|
|
subRound160(CC, DD, EE, AA, BB, f64, KK0, 7, data[13]);
|
|
subRound160(BB, CC, DD, EE, AA, f64, KK0, 7, data[6]);
|
|
subRound160(AA, BB, CC, DD, EE, f64, KK0, 8, data[15]);
|
|
subRound160(EE, AA, BB, CC, DD, f64, KK0, 11, data[8]);
|
|
subRound160(DD, EE, AA, BB, CC, f64, KK0, 14, data[1]);
|
|
subRound160(CC, DD, EE, AA, BB, f64, KK0, 14, data[10]);
|
|
subRound160(BB, CC, DD, EE, AA, f64, KK0, 12, data[3]);
|
|
subRound160(AA, BB, CC, DD, EE, f64, KK0, 6, data[12]);
|
|
|
|
T = A; A = AA; AA = T;
|
|
|
|
/* j=16...31 */
|
|
subRound160(E, A, B, C, D, f16, K1, 7, data[7]);
|
|
subRound160(D, E, A, B, C, f16, K1, 6, data[4]);
|
|
subRound160(C, D, E, A, B, f16, K1, 8, data[13]);
|
|
subRound160(B, C, D, E, A, f16, K1, 13, data[1]);
|
|
subRound160(A, B, C, D, E, f16, K1, 11, data[10]);
|
|
subRound160(E, A, B, C, D, f16, K1, 9, data[6]);
|
|
subRound160(D, E, A, B, C, f16, K1, 7, data[15]);
|
|
subRound160(C, D, E, A, B, f16, K1, 15, data[3]);
|
|
subRound160(B, C, D, E, A, f16, K1, 7, data[12]);
|
|
subRound160(A, B, C, D, E, f16, K1, 12, data[0]);
|
|
subRound160(E, A, B, C, D, f16, K1, 15, data[9]);
|
|
subRound160(D, E, A, B, C, f16, K1, 9, data[5]);
|
|
subRound160(C, D, E, A, B, f16, K1, 11, data[2]);
|
|
subRound160(B, C, D, E, A, f16, K1, 7, data[14]);
|
|
subRound160(A, B, C, D, E, f16, K1, 13, data[11]);
|
|
subRound160(E, A, B, C, D, f16, K1, 12, data[8]);
|
|
|
|
subRound160(EE, AA, BB, CC, DD, f48, KK1, 9, data[6]);
|
|
subRound160(DD, EE, AA, BB, CC, f48, KK1, 13, data[11]);
|
|
subRound160(CC, DD, EE, AA, BB, f48, KK1, 15, data[3]);
|
|
subRound160(BB, CC, DD, EE, AA, f48, KK1, 7, data[7]);
|
|
subRound160(AA, BB, CC, DD, EE, f48, KK1, 12, data[0]);
|
|
subRound160(EE, AA, BB, CC, DD, f48, KK1, 8, data[13]);
|
|
subRound160(DD, EE, AA, BB, CC, f48, KK1, 9, data[5]);
|
|
subRound160(CC, DD, EE, AA, BB, f48, KK1, 11, data[10]);
|
|
subRound160(BB, CC, DD, EE, AA, f48, KK1, 7, data[14]);
|
|
subRound160(AA, BB, CC, DD, EE, f48, KK1, 7, data[15]);
|
|
subRound160(EE, AA, BB, CC, DD, f48, KK1, 12, data[8]);
|
|
subRound160(DD, EE, AA, BB, CC, f48, KK1, 7, data[12]);
|
|
subRound160(CC, DD, EE, AA, BB, f48, KK1, 6, data[4]);
|
|
subRound160(BB, CC, DD, EE, AA, f48, KK1, 15, data[9]);
|
|
subRound160(AA, BB, CC, DD, EE, f48, KK1, 13, data[1]);
|
|
subRound160(EE, AA, BB, CC, DD, f48, KK1, 11, data[2]);
|
|
|
|
T = B; B = BB; BB = T;
|
|
|
|
/* j=32...47 */
|
|
subRound160(D, E, A, B, C, f32, K2, 11, data[3]);
|
|
subRound160(C, D, E, A, B, f32, K2, 13, data[10]);
|
|
subRound160(B, C, D, E, A, f32, K2, 6, data[14]);
|
|
subRound160(A, B, C, D, E, f32, K2, 7, data[4]);
|
|
subRound160(E, A, B, C, D, f32, K2, 14, data[9]);
|
|
subRound160(D, E, A, B, C, f32, K2, 9, data[15]);
|
|
subRound160(C, D, E, A, B, f32, K2, 13, data[8]);
|
|
subRound160(B, C, D, E, A, f32, K2, 15, data[1]);
|
|
subRound160(A, B, C, D, E, f32, K2, 14, data[2]);
|
|
subRound160(E, A, B, C, D, f32, K2, 8, data[7]);
|
|
subRound160(D, E, A, B, C, f32, K2, 13, data[0]);
|
|
subRound160(C, D, E, A, B, f32, K2, 6, data[6]);
|
|
subRound160(B, C, D, E, A, f32, K2, 5, data[13]);
|
|
subRound160(A, B, C, D, E, f32, K2, 12, data[11]);
|
|
subRound160(E, A, B, C, D, f32, K2, 7, data[5]);
|
|
subRound160(D, E, A, B, C, f32, K2, 5, data[12]);
|
|
|
|
subRound160(DD, EE, AA, BB, CC, f32, KK2, 9, data[15]);
|
|
subRound160(CC, DD, EE, AA, BB, f32, KK2, 7, data[5]);
|
|
subRound160(BB, CC, DD, EE, AA, f32, KK2, 15, data[1]);
|
|
subRound160(AA, BB, CC, DD, EE, f32, KK2, 11, data[3]);
|
|
subRound160(EE, AA, BB, CC, DD, f32, KK2, 8, data[7]);
|
|
subRound160(DD, EE, AA, BB, CC, f32, KK2, 6, data[14]);
|
|
subRound160(CC, DD, EE, AA, BB, f32, KK2, 6, data[6]);
|
|
subRound160(BB, CC, DD, EE, AA, f32, KK2, 14, data[9]);
|
|
subRound160(AA, BB, CC, DD, EE, f32, KK2, 12, data[11]);
|
|
subRound160(EE, AA, BB, CC, DD, f32, KK2, 13, data[8]);
|
|
subRound160(DD, EE, AA, BB, CC, f32, KK2, 5, data[12]);
|
|
subRound160(CC, DD, EE, AA, BB, f32, KK2, 14, data[2]);
|
|
subRound160(BB, CC, DD, EE, AA, f32, KK2, 13, data[10]);
|
|
subRound160(AA, BB, CC, DD, EE, f32, KK2, 13, data[0]);
|
|
subRound160(EE, AA, BB, CC, DD, f32, KK2, 7, data[4]);
|
|
subRound160(DD, EE, AA, BB, CC, f32, KK2, 5, data[13]);
|
|
|
|
T = C; C = CC; CC = T;
|
|
|
|
/* j=48...63 */
|
|
subRound160(C, D, E, A, B, f48, K3, 11, data[1]);
|
|
subRound160(B, C, D, E, A, f48, K3, 12, data[9]);
|
|
subRound160(A, B, C, D, E, f48, K3, 14, data[11]);
|
|
subRound160(E, A, B, C, D, f48, K3, 15, data[10]);
|
|
subRound160(D, E, A, B, C, f48, K3, 14, data[0]);
|
|
subRound160(C, D, E, A, B, f48, K3, 15, data[8]);
|
|
subRound160(B, C, D, E, A, f48, K3, 9, data[12]);
|
|
subRound160(A, B, C, D, E, f48, K3, 8, data[4]);
|
|
subRound160(E, A, B, C, D, f48, K3, 9, data[13]);
|
|
subRound160(D, E, A, B, C, f48, K3, 14, data[3]);
|
|
subRound160(C, D, E, A, B, f48, K3, 5, data[7]);
|
|
subRound160(B, C, D, E, A, f48, K3, 6, data[15]);
|
|
subRound160(A, B, C, D, E, f48, K3, 8, data[14]);
|
|
subRound160(E, A, B, C, D, f48, K3, 6, data[5]);
|
|
subRound160(D, E, A, B, C, f48, K3, 5, data[6]);
|
|
subRound160(C, D, E, A, B, f48, K3, 12, data[2]);
|
|
|
|
subRound160(CC, DD, EE, AA, BB, f16, KK3, 15, data[8]);
|
|
subRound160(BB, CC, DD, EE, AA, f16, KK3, 5, data[6]);
|
|
subRound160(AA, BB, CC, DD, EE, f16, KK3, 8, data[4]);
|
|
subRound160(EE, AA, BB, CC, DD, f16, KK3, 11, data[1]);
|
|
subRound160(DD, EE, AA, BB, CC, f16, KK3, 14, data[3]);
|
|
subRound160(CC, DD, EE, AA, BB, f16, KK3, 14, data[11]);
|
|
subRound160(BB, CC, DD, EE, AA, f16, KK3, 6, data[15]);
|
|
subRound160(AA, BB, CC, DD, EE, f16, KK3, 14, data[0]);
|
|
subRound160(EE, AA, BB, CC, DD, f16, KK3, 6, data[5]);
|
|
subRound160(DD, EE, AA, BB, CC, f16, KK3, 9, data[12]);
|
|
subRound160(CC, DD, EE, AA, BB, f16, KK3, 12, data[2]);
|
|
subRound160(BB, CC, DD, EE, AA, f16, KK3, 9, data[13]);
|
|
subRound160(AA, BB, CC, DD, EE, f16, KK3, 12, data[9]);
|
|
subRound160(EE, AA, BB, CC, DD, f16, KK3, 5, data[7]);
|
|
subRound160(DD, EE, AA, BB, CC, f16, KK3, 15, data[10]);
|
|
subRound160(CC, DD, EE, AA, BB, f16, KK3, 8, data[14]);
|
|
|
|
T = D; D = DD; DD = T;
|
|
|
|
/* j=64...79 */
|
|
subRound160(B, C, D, E, A, f64, K4, 9, data[4]);
|
|
subRound160(A, B, C, D, E, f64, K4, 15, data[0]);
|
|
subRound160(E, A, B, C, D, f64, K4, 5, data[5]);
|
|
subRound160(D, E, A, B, C, f64, K4, 11, data[9]);
|
|
subRound160(C, D, E, A, B, f64, K4, 6, data[7]);
|
|
subRound160(B, C, D, E, A, f64, K4, 8, data[12]);
|
|
subRound160(A, B, C, D, E, f64, K4, 13, data[2]);
|
|
subRound160(E, A, B, C, D, f64, K4, 12, data[10]);
|
|
subRound160(D, E, A, B, C, f64, K4, 5, data[14]);
|
|
subRound160(C, D, E, A, B, f64, K4, 12, data[1]);
|
|
subRound160(B, C, D, E, A, f64, K4, 13, data[3]);
|
|
subRound160(A, B, C, D, E, f64, K4, 14, data[8]);
|
|
subRound160(E, A, B, C, D, f64, K4, 11, data[11]);
|
|
subRound160(D, E, A, B, C, f64, K4, 8, data[6]);
|
|
subRound160(C, D, E, A, B, f64, K4, 5, data[15]);
|
|
subRound160(B, C, D, E, A, f64, K4, 6, data[13]);
|
|
|
|
subRound160(BB, CC, DD, EE, AA, f0, KK4, 8, data[12]);
|
|
subRound160(AA, BB, CC, DD, EE, f0, KK4, 5, data[15]);
|
|
subRound160(EE, AA, BB, CC, DD, f0, KK4, 12, data[10]);
|
|
subRound160(DD, EE, AA, BB, CC, f0, KK4, 9, data[4]);
|
|
subRound160(CC, DD, EE, AA, BB, f0, KK4, 12, data[1]);
|
|
subRound160(BB, CC, DD, EE, AA, f0, KK4, 5, data[5]);
|
|
subRound160(AA, BB, CC, DD, EE, f0, KK4, 14, data[8]);
|
|
subRound160(EE, AA, BB, CC, DD, f0, KK4, 6, data[7]);
|
|
subRound160(DD, EE, AA, BB, CC, f0, KK4, 8, data[6]);
|
|
subRound160(CC, DD, EE, AA, BB, f0, KK4, 13, data[2]);
|
|
subRound160(BB, CC, DD, EE, AA, f0, KK4, 6, data[13]);
|
|
subRound160(AA, BB, CC, DD, EE, f0, KK4, 5, data[14]);
|
|
subRound160(EE, AA, BB, CC, DD, f0, KK4, 15, data[0]);
|
|
subRound160(DD, EE, AA, BB, CC, f0, KK4, 13, data[3]);
|
|
subRound160(CC, DD, EE, AA, BB, f0, KK4, 11, data[9]);
|
|
subRound160(BB, CC, DD, EE, AA, f0, KK4, 11, data[11]);
|
|
|
|
/* T = E; E = EE; EE = T; */
|
|
|
|
ctx->digest[0] += A;
|
|
ctx->digest[1] += B;
|
|
ctx->digest[2] += C;
|
|
ctx->digest[3] += D;
|
|
ctx->digest[4] += EE;
|
|
ctx->digest[5] += AA;
|
|
ctx->digest[6] += BB;
|
|
ctx->digest[7] += CC;
|
|
ctx->digest[8] += DD;
|
|
ctx->digest[9] += E;
|
|
}
|
|
|
|
static void ripemd_transform(struct ripemd_ctx *ctx, mutils_word32 * data)
|
|
{
|
|
switch(ctx->digest_len) /* select the right compression function */
|
|
{
|
|
case 8 * RIPEMD128_DIGESTSIZE:
|
|
ripemd128_transform(ctx, data); break;
|
|
case 8 * RIPEMD160_DIGESTSIZE:
|
|
ripemd160_transform(ctx, data); break;
|
|
case 8 * RIPEMD256_DIGESTSIZE:
|
|
ripemd256_transform(ctx, data); break;
|
|
case 8 * RIPEMD320_DIGESTSIZE:
|
|
ripemd320_transform(ctx, data); break;
|
|
}
|
|
}
|
|
|
|
#ifndef EXTRACT_UCHAR
|
|
#define EXTRACT_UCHAR(p) (*(mutils_word8 *)(p))
|
|
#endif
|
|
|
|
#define STRING2INT(s) ((((((EXTRACT_UCHAR(s+3) << 8) \
|
|
| EXTRACT_UCHAR(s+2)) << 8) \
|
|
| EXTRACT_UCHAR(s+1)) << 8) \
|
|
| EXTRACT_UCHAR(s))
|
|
|
|
static void ripemd_block(struct ripemd_ctx *ctx, mutils_word8 *block)
|
|
{
|
|
mutils_word32 data[RIPEMD_DATALEN];
|
|
mutils_word32 i;
|
|
|
|
/* Update bit count */
|
|
ctx->bitcount += RIPEMD_DATASIZE * 8;
|
|
|
|
/* Endian independent conversion */
|
|
for (i = 0; i < RIPEMD_DATALEN; i++, block += 4)
|
|
data[i] = STRING2INT(block);
|
|
|
|
ripemd_transform(ctx, data);
|
|
}
|
|
|
|
void ripemd_update(struct ripemd_ctx *ctx, mutils_word8 *buffer, mutils_word32 len)
|
|
{
|
|
if (ctx->index) { /* Try to fill partial block */
|
|
unsigned left = RIPEMD_DATASIZE - ctx->index;
|
|
if (len < left) {
|
|
mutils_memcpy(ctx->block + ctx->index, buffer, len);
|
|
ctx->index += len;
|
|
return; /* Finished */
|
|
} else {
|
|
mutils_memcpy(ctx->block + ctx->index, buffer, left);
|
|
ripemd_block(ctx, ctx->block);
|
|
buffer += left;
|
|
len -= left;
|
|
}
|
|
}
|
|
while (len >= RIPEMD_DATASIZE) {
|
|
ripemd_block(ctx, buffer);
|
|
buffer += RIPEMD_DATASIZE;
|
|
len -= RIPEMD_DATASIZE;
|
|
}
|
|
if ((ctx->index = len))
|
|
/* This assignment is intended */
|
|
/* Buffer leftovers */
|
|
mutils_memcpy(ctx->block, buffer, len);
|
|
}
|
|
|
|
/* Final wrapup - pad to RIPEMD_DATASIZE-byte boundary with the bit pattern
|
|
1 0* (64-bit count of bits processed, LSB-first) */
|
|
|
|
void ripemd_final(struct ripemd_ctx *ctx)
|
|
{
|
|
mutils_word32 data[RIPEMD_DATALEN];
|
|
mutils_word32 i;
|
|
mutils_word32 words;
|
|
|
|
i = ctx->index;
|
|
/* Set the first char of padding to 0x80. This is safe since there is
|
|
always at least one byte free */
|
|
ctx->block[i++] = 0x80;
|
|
|
|
/* Fill rest of word */
|
|
for (; i & 3; i++)
|
|
ctx->block[i] = 0;
|
|
|
|
/* i is now a multiple of the word size 4 */
|
|
words = i >> 2;
|
|
for (i = 0; i < words; i++)
|
|
data[i] = STRING2INT(ctx->block + 4 * i);
|
|
|
|
if (words > (RIPEMD_DATALEN - 2)) { /* No room for length in this block.
|
|
* Process it and pad with another one */
|
|
for (i = words; i < RIPEMD_DATALEN; i++)
|
|
data[i] = 0;
|
|
ripemd_transform(ctx, data);
|
|
for (i = 0; i < (RIPEMD_DATALEN - 2); i++)
|
|
data[i] = 0;
|
|
} else
|
|
for (i = words; i < RIPEMD_DATALEN - 2; i++)
|
|
data[i] = 0;
|
|
|
|
/* add length padding */
|
|
ctx->bitcount += 8 * ctx->index;
|
|
data[RIPEMD_DATALEN - 2] =
|
|
ctx->bitcount & ((1LL << 32) - 1);
|
|
data[RIPEMD_DATALEN - 1] =
|
|
ctx->bitcount >> 32;
|
|
|
|
ripemd_transform(ctx, data);
|
|
}
|
|
|
|
void ripemd_digest(struct ripemd_ctx *ctx, mutils_word8 * s)
|
|
{
|
|
mutils_word32 i;
|
|
|
|
if (s!=NULL)
|
|
for (i = 0; i < ctx->digest_len / 32; i++) {
|
|
*s++ = 0xff & ctx->digest[i];
|
|
*s++ = 0xff & (ctx->digest[i] >> 8);
|
|
*s++ = 0xff & (ctx->digest[i] >> 16);
|
|
*s++ = 0xff & (ctx->digest[i] >> 24);
|
|
}
|
|
}
|
|
|
|
#endif /* ENABLE_RIPEMD */
|