added rmd160 checksum tool from http://www.nic.com/~cheah/rmd160.tar.gz
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12570 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -125,6 +125,7 @@ SubInclude OBOS_TOP src bin makeudfimage ;
|
|||||||
SubInclude OBOS_TOP src bin mkdos ;
|
SubInclude OBOS_TOP src bin mkdos ;
|
||||||
SubInclude OBOS_TOP src bin patch ;
|
SubInclude OBOS_TOP src bin patch ;
|
||||||
SubInclude OBOS_TOP src bin pc ;
|
SubInclude OBOS_TOP src bin pc ;
|
||||||
|
SubInclude OBOS_TOP src bin rmd160 ;
|
||||||
SubInclude OBOS_TOP src bin sed ;
|
SubInclude OBOS_TOP src bin sed ;
|
||||||
SubInclude OBOS_TOP src bin sharutils ;
|
SubInclude OBOS_TOP src bin sharutils ;
|
||||||
SubInclude OBOS_TOP src bin strace ;
|
SubInclude OBOS_TOP src bin strace ;
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
SubDir OBOS_TOP src bin rmd160 ;
|
||||||
|
|
||||||
|
BinCommand rmd160 :
|
||||||
|
rmd160.c
|
||||||
|
main.c
|
||||||
|
;
|
||||||
@@ -0,0 +1,424 @@
|
|||||||
|
/*
|
||||||
|
rmd.c
|
||||||
|
RIPEMD-160 generate and check utility
|
||||||
|
by Po Shan Cheah, Copyright (c) 1997
|
||||||
|
You may distribute this program freely provided this notice
|
||||||
|
is retained.
|
||||||
|
|
||||||
|
January 5, 1997:
|
||||||
|
Initial release.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rmd160.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define BUFLEN 4096
|
||||||
|
#define RMDBITS 160
|
||||||
|
|
||||||
|
int binary_mode = 0;
|
||||||
|
int verbose_mode = 0;
|
||||||
|
char *progname = "";
|
||||||
|
|
||||||
|
int prog_rc = 0;
|
||||||
|
|
||||||
|
void setrc(int newrc) {
|
||||||
|
|
||||||
|
/* raises but never lowers the program return code to newrc */
|
||||||
|
|
||||||
|
if (newrc > prog_rc)
|
||||||
|
prog_rc = newrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cvthex(char c) {
|
||||||
|
/* convert a hex digit to an integer */
|
||||||
|
|
||||||
|
c = toupper(c);
|
||||||
|
|
||||||
|
if (c >= 'A' && c <= 'F')
|
||||||
|
return c - 'A' + 10;
|
||||||
|
|
||||||
|
return c - '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
int hexdigit(char c) {
|
||||||
|
/* returns true if character is a hexadecimal digit */
|
||||||
|
|
||||||
|
return
|
||||||
|
(c >= '0' && c <= '9') ||
|
||||||
|
(toupper(c) >= 'A' && toupper(c) <= 'F');
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ESCAPE '%'
|
||||||
|
|
||||||
|
char *encodestr(char *instr) {
|
||||||
|
/* replace unprintable characters and % itself with %HH */
|
||||||
|
|
||||||
|
static char buf[BUFLEN];
|
||||||
|
char *outstr = buf;
|
||||||
|
|
||||||
|
for ( ; *instr; ++instr) {
|
||||||
|
if (isprint(*instr) && !isspace(*instr) && *instr != ESCAPE)
|
||||||
|
*outstr++ = *instr;
|
||||||
|
else {
|
||||||
|
sprintf(outstr, "%%%02x", *instr);
|
||||||
|
outstr += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*outstr = '\0';
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *decodestr(char *instr) {
|
||||||
|
/* undo what encodestr did */
|
||||||
|
|
||||||
|
static char buf[BUFLEN];
|
||||||
|
char *outstr = buf;
|
||||||
|
|
||||||
|
while (*instr) {
|
||||||
|
if (*instr == ESCAPE &&
|
||||||
|
hexdigit(instr[1]) &&
|
||||||
|
hexdigit(instr[2])) {
|
||||||
|
*outstr++ = cvthex(instr[1]) << 4 | cvthex(instr[2]);
|
||||||
|
instr += 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*outstr++ = *instr ++;
|
||||||
|
}
|
||||||
|
*outstr = '\0';
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pack_chunk(word *chunk, byte *buf) {
|
||||||
|
/* pack 64 bytes into 16 little-endian 32-bit words */
|
||||||
|
|
||||||
|
int j;
|
||||||
|
|
||||||
|
for (j = 0; j < 16; ++j, buf += 4)
|
||||||
|
*chunk++ = (word) buf[0] | (word) buf[1] << 8 |
|
||||||
|
(word) buf[2] << 16 | (word) buf[3] << 24 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte *rmdfp(char *fname, FILE *fp) {
|
||||||
|
/* calculate the message digest of a file
|
||||||
|
and return it in string form */
|
||||||
|
|
||||||
|
int bytesread;
|
||||||
|
int i;
|
||||||
|
word tmp;
|
||||||
|
word chunk[16];
|
||||||
|
char buf[BUFLEN];
|
||||||
|
word length[2];
|
||||||
|
word mdbuf[RMDBITS / 32];
|
||||||
|
static byte code[RMDBITS / 8];
|
||||||
|
|
||||||
|
length[0] = length[1] = 0;
|
||||||
|
MDinit(mdbuf);
|
||||||
|
|
||||||
|
/* do all full BUFLEN portions */
|
||||||
|
|
||||||
|
while ((bytesread = fread(buf, 1, BUFLEN, fp)) == BUFLEN) {
|
||||||
|
|
||||||
|
for (i = 0; i < BUFLEN; i += 64) {
|
||||||
|
pack_chunk(chunk, buf + i);
|
||||||
|
MDcompress(mdbuf, chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((tmp = length[0] + bytesread) < length[0])
|
||||||
|
++ length[1]; /* overflow */
|
||||||
|
length[0] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ferror(fp)) {
|
||||||
|
fprintf(stderr, "%s: %s\n", fname, strerror(errno));
|
||||||
|
setrc(2);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do all the remaining 64-byte blocks */
|
||||||
|
|
||||||
|
for (i = 0; i < bytesread - 63; i += 64) {
|
||||||
|
pack_chunk(chunk, buf + i);
|
||||||
|
MDcompress(mdbuf, chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((tmp = length[0] + bytesread) < length[0])
|
||||||
|
++ length[1]; /* overflow */
|
||||||
|
length[0] = tmp;
|
||||||
|
|
||||||
|
/* do the last partial or zero length block */
|
||||||
|
|
||||||
|
MDfinish(mdbuf, buf + i, length[0] << 3,
|
||||||
|
length[0] >> 29 | length[1] << 3);
|
||||||
|
|
||||||
|
/* convert to 64-byte string using little-endian conversion */
|
||||||
|
|
||||||
|
for (i = 0; i < RMDBITS / 8; i += 4) {
|
||||||
|
|
||||||
|
word wd = mdbuf[i >> 2];
|
||||||
|
|
||||||
|
code[i] = (byte) (wd);
|
||||||
|
code[i + 1] = (byte) (wd >> 8);
|
||||||
|
code[i + 2] = (byte) (wd >> 16);
|
||||||
|
code[i + 3] = (byte) (wd >> 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printcode(byte *code) {
|
||||||
|
/* print a RIPEMD-160 code */
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < RMDBITS / 8; ++i)
|
||||||
|
printf("%02x", code[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte *rmdfile(char *fname) {
|
||||||
|
/* calculate the message digest of a single file
|
||||||
|
and output the digest followed by the file name */
|
||||||
|
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
fp = fopen(fname, binary_mode ? "rb" : "r");
|
||||||
|
if (fp == NULL) {
|
||||||
|
fprintf(stderr, "%s: %s\n", fname, strerror(errno));
|
||||||
|
setrc(2);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
byte *code = rmdfp(fname, fp);
|
||||||
|
fclose(fp);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int checkdigest(char *digest) {
|
||||||
|
/* returns true if string is a valid message digest string */
|
||||||
|
|
||||||
|
if (strlen(digest) != RMDBITS / 8 * 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for ( ; *digest; ++digest) {
|
||||||
|
if ( ! hexdigit(*digest))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stringtocode(byte *code, char *str) {
|
||||||
|
/* convert message digest string into 20 byte code */
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < RMDBITS / 8; ++i, str += 2)
|
||||||
|
*code++ = cvthex(str[0]) << 4 | cvthex(str[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkfp(char *fname, FILE *fp) {
|
||||||
|
/* check message digests. message digest data comes from
|
||||||
|
the given open file handle. */
|
||||||
|
|
||||||
|
int lineno = 0;
|
||||||
|
int nfail = 0;
|
||||||
|
int nfile = 0;
|
||||||
|
char *filename;
|
||||||
|
byte *code;
|
||||||
|
byte inputcode[RMDBITS / 8];
|
||||||
|
char line[BUFLEN];
|
||||||
|
char digest[BUFLEN];
|
||||||
|
char infilename[BUFLEN];
|
||||||
|
|
||||||
|
while (fgets(line, BUFLEN, fp)) {
|
||||||
|
|
||||||
|
++lineno;
|
||||||
|
|
||||||
|
/* error checking */
|
||||||
|
|
||||||
|
if (sscanf(line, "%s%s", digest, infilename) < 2) {
|
||||||
|
fprintf(stderr, "%s: invalid input on line %d\n",
|
||||||
|
progname, lineno);
|
||||||
|
setrc(2);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!checkdigest(digest)) {
|
||||||
|
fprintf(stderr, "%s: invalid message digest on line %d\n",
|
||||||
|
progname, lineno);
|
||||||
|
setrc(2);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
stringtocode(inputcode, digest);
|
||||||
|
|
||||||
|
/* calculate message digest for file */
|
||||||
|
|
||||||
|
filename = decodestr(infilename);
|
||||||
|
|
||||||
|
code = rmdfile(filename);
|
||||||
|
if (code) {
|
||||||
|
|
||||||
|
++nfile;
|
||||||
|
|
||||||
|
/* compare digests */
|
||||||
|
|
||||||
|
if (memcmp(inputcode, code, RMDBITS / 8) != 0) {
|
||||||
|
++nfail;
|
||||||
|
setrc(1);
|
||||||
|
|
||||||
|
if (verbose_mode)
|
||||||
|
printf("FAILED %s\n", filename);
|
||||||
|
else
|
||||||
|
printf("%s: RIPEMD-160 check failed for `%s'\n",
|
||||||
|
progname, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
if (verbose_mode)
|
||||||
|
printf("GOOD %s\n", filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose_mode && nfail)
|
||||||
|
printf("%s: %d of %d file(s) failed RIPEMD-160 check\n",
|
||||||
|
progname, nfail, nfile);
|
||||||
|
|
||||||
|
if (ferror(fp)) {
|
||||||
|
fprintf(stderr, "%s: %s\n", fname, strerror(errno));
|
||||||
|
setrc(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkfile(char *fname) {
|
||||||
|
/* check message digests. message digest data comes from
|
||||||
|
the named file. */
|
||||||
|
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
fp = fopen(fname, "r");
|
||||||
|
if (fp == NULL) {
|
||||||
|
fprintf(stderr, "%s: %s\n", fname, strerror(errno));
|
||||||
|
setrc(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
checkfp(fname, fp);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
int c;
|
||||||
|
int check_mode = 0;
|
||||||
|
|
||||||
|
progname = argv[0];
|
||||||
|
|
||||||
|
/* parse command line arguments */
|
||||||
|
|
||||||
|
while ((c = getopt(argc, argv, "bcvh")) >= 0) {
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
|
||||||
|
case 'b':
|
||||||
|
binary_mode = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'c':
|
||||||
|
check_mode = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'v':
|
||||||
|
verbose_mode = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
case ':':
|
||||||
|
case '?':
|
||||||
|
printf("Usage: %s [-b] [-c] [-v] [<file>...]\n"
|
||||||
|
"Generates or checks RIPEMD-160 message digests\n"
|
||||||
|
" -b read files in binary mode\n"
|
||||||
|
" -c check message digests\n"
|
||||||
|
" -v verbose, print file names while checking\n\n"
|
||||||
|
"If -c is not specified, then one message digest is "
|
||||||
|
"generated per file\n"
|
||||||
|
"and sent to standard output. If no files are specified "
|
||||||
|
"then input is\n"
|
||||||
|
"taken from standard input and only one message digest "
|
||||||
|
"will be\n"
|
||||||
|
"generated.\n\n"
|
||||||
|
"If -c is specified then message digests for a list of "
|
||||||
|
"files are\n"
|
||||||
|
"checked. The input should be a table in the same format "
|
||||||
|
"as the output\n"
|
||||||
|
"of this program when message digests are generated. If a "
|
||||||
|
"file is\n"
|
||||||
|
"specified then the message digest table is read from that "
|
||||||
|
"file. If no\n"
|
||||||
|
"file is specified, then the message digest table is read "
|
||||||
|
"from standard\n"
|
||||||
|
"input.\n", progname);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_mode) {
|
||||||
|
|
||||||
|
if (optind < argc) {
|
||||||
|
|
||||||
|
/* check using data from file named on command line */
|
||||||
|
|
||||||
|
checkfile(argv[optind]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
|
||||||
|
/* check using data from standard input */
|
||||||
|
|
||||||
|
checkfp("(stdin)", stdin);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
|
||||||
|
if (optind < argc) {
|
||||||
|
|
||||||
|
/* process file arguments */
|
||||||
|
|
||||||
|
for ( ; optind < argc; ++optind) {
|
||||||
|
|
||||||
|
byte *code = rmdfile(argv[optind]);
|
||||||
|
|
||||||
|
if (code) {
|
||||||
|
printcode(code);
|
||||||
|
printf(" %s\n", encodestr(argv[optind]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
|
||||||
|
/* no file arguments so take input from stdin */
|
||||||
|
|
||||||
|
byte *code = rmdfp("(stdin)", stdin);
|
||||||
|
|
||||||
|
if (code) {
|
||||||
|
printcode(code);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return prog_rc;
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
.TH rmd160 1 "4 January 1997" "Linux" "Linux Programmer's Manual"
|
||||||
|
.SH NAME
|
||||||
|
rmd160 \- generate and check RIPEMD-160 message digests
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.BR "rmd160 " [
|
||||||
|
.IR file " ] ..."
|
||||||
|
.br
|
||||||
|
.BR "rmd160 " [ " \-bv " ] " \-c " [
|
||||||
|
.I file
|
||||||
|
.RB ]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fBrmd160\fP generates and checks RIPEMD-160 message digests. These
|
||||||
|
message digests are 160-bit signatures of the input files. \fBrmd160\fP
|
||||||
|
can be used to verify the integrity of binaries posted to usenet
|
||||||
|
newsgroups or files made available for distribution via anonymous ftp.
|
||||||
|
.PP
|
||||||
|
Message digests for a tree of files can be generated with
|
||||||
|
a command similar to the following:
|
||||||
|
.PP
|
||||||
|
find . -type f -print | xargs md5sum
|
||||||
|
.PP
|
||||||
|
The output of this command is suitable as input for the \fB-c\fP
|
||||||
|
option.
|
||||||
|
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.B \-c
|
||||||
|
Check message digests. Input is taken from standard input or from the
|
||||||
|
first file specified on the command line. The input should be in the
|
||||||
|
same format as the message digest output generated by \fBrmd160\fP
|
||||||
|
when this option is not specified.
|
||||||
|
.TP
|
||||||
|
.B \-v
|
||||||
|
Verbose. Print all file names when checking and the result of each
|
||||||
|
message digest check. If this option is not specified then only files
|
||||||
|
that failed the check will be printed.
|
||||||
|
.TP
|
||||||
|
.B \-b
|
||||||
|
Read files in binary mode. This option has no effect on Unix systems.
|
||||||
|
.SH RETURN VALUES
|
||||||
|
Status codes returned by \fBrmd160\fP:
|
||||||
|
.TP
|
||||||
|
.B 2
|
||||||
|
fatal or I/O related errors
|
||||||
|
.TP
|
||||||
|
.B 1
|
||||||
|
one or more files failed the message digest check
|
||||||
|
.TP
|
||||||
|
.B 0
|
||||||
|
no errors and all files passed the message digest check
|
||||||
|
.SH CREDITS
|
||||||
|
The \fBrmd160\fP program was written by Po Shan Cheah and may be
|
||||||
|
freely distributed provided all authorship and copyright notices are
|
||||||
|
retained. The interface for \fBrmd160\fP is based on \fBmd5sum\fP by
|
||||||
|
Branko Lankester.
|
||||||
|
.PP
|
||||||
|
The underlying implementation of RIPEMD-160 was written by
|
||||||
|
Antoon Bosselaers of Katholieke Universiteit Leuven and is available
|
||||||
|
in Dr. Dobb's Journal (January 1997).
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR "sum" "(1), " "cksum" "(1), "
|
||||||
|
.BR "pgp" "(1), " "md5sum" "(1)"
|
||||||
@@ -0,0 +1,285 @@
|
|||||||
|
/********************************************************************\
|
||||||
|
* FILE: rmd160.c
|
||||||
|
* CONTENTS: A sample C-implementation of the RIPEMD-160 hash-function.
|
||||||
|
* TARGET: any computer with an ANSI C compiler
|
||||||
|
* AUTHOR: Antoon Bosselaers, Dept. Electrical Eng.-ESAT/COSIC
|
||||||
|
* DATE: 1 March 1996 VERSION: 1.0
|
||||||
|
**********************************************************************
|
||||||
|
* Copyright (c) Katholieke Universiteit Leuven 1996, All Rights Reserved
|
||||||
|
* The Katholieke Universiteit Leuven makes no representations concerning
|
||||||
|
* either the merchantability of this software or the suitability of this
|
||||||
|
* software for any particular purpose. It is provided "as is" without
|
||||||
|
* express or implied warranty of any kind. These notices must be retained
|
||||||
|
* in any copies of any part of this documentation and/or software.
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
/* header files */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "rmd160.h"
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
void MDinit(word *MDbuf)
|
||||||
|
/* Initialization of the 5-word MDbuf array to the magic
|
||||||
|
initialization constants
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
MDbuf[0] = 0x67452301UL;
|
||||||
|
MDbuf[1] = 0xefcdab89UL;
|
||||||
|
MDbuf[2] = 0x98badcfeUL;
|
||||||
|
MDbuf[3] = 0x10325476UL;
|
||||||
|
MDbuf[4] = 0xc3d2e1f0UL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
void MDcompress(word *MDbuf, word *X)
|
||||||
|
/* The compression function is called for every complete 64-byte
|
||||||
|
message block. The 5-word internal state MDbuf is updated using
|
||||||
|
message words X[0] through X[15]. The conversion from a string
|
||||||
|
of 64 bytes to an array of 16 words using a Little-endian
|
||||||
|
convention is the responsibility of the calling function.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
/* make two copies of the old state */
|
||||||
|
word aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2],
|
||||||
|
dd = MDbuf[3], ee = MDbuf[4];
|
||||||
|
word aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2],
|
||||||
|
ddd = MDbuf[3], eee = MDbuf[4];
|
||||||
|
|
||||||
|
/* round 1 */
|
||||||
|
FF1(aa, bb, cc, dd, ee, X[ 0], 11);
|
||||||
|
FF1(ee, aa, bb, cc, dd, X[ 1], 14);
|
||||||
|
FF1(dd, ee, aa, bb, cc, X[ 2], 15);
|
||||||
|
FF1(cc, dd, ee, aa, bb, X[ 3], 12);
|
||||||
|
FF1(bb, cc, dd, ee, aa, X[ 4], 5);
|
||||||
|
FF1(aa, bb, cc, dd, ee, X[ 5], 8);
|
||||||
|
FF1(ee, aa, bb, cc, dd, X[ 6], 7);
|
||||||
|
FF1(dd, ee, aa, bb, cc, X[ 7], 9);
|
||||||
|
FF1(cc, dd, ee, aa, bb, X[ 8], 11);
|
||||||
|
FF1(bb, cc, dd, ee, aa, X[ 9], 13);
|
||||||
|
FF1(aa, bb, cc, dd, ee, X[10], 14);
|
||||||
|
FF1(ee, aa, bb, cc, dd, X[11], 15);
|
||||||
|
FF1(dd, ee, aa, bb, cc, X[12], 6);
|
||||||
|
FF1(cc, dd, ee, aa, bb, X[13], 7);
|
||||||
|
FF1(bb, cc, dd, ee, aa, X[14], 9);
|
||||||
|
FF1(aa, bb, cc, dd, ee, X[15], 8);
|
||||||
|
|
||||||
|
/* round 2 */
|
||||||
|
FF2(ee, aa, bb, cc, dd, X[ 7], 7);
|
||||||
|
FF2(dd, ee, aa, bb, cc, X[ 4], 6);
|
||||||
|
FF2(cc, dd, ee, aa, bb, X[13], 8);
|
||||||
|
FF2(bb, cc, dd, ee, aa, X[ 1], 13);
|
||||||
|
FF2(aa, bb, cc, dd, ee, X[10], 11);
|
||||||
|
FF2(ee, aa, bb, cc, dd, X[ 6], 9);
|
||||||
|
FF2(dd, ee, aa, bb, cc, X[15], 7);
|
||||||
|
FF2(cc, dd, ee, aa, bb, X[ 3], 15);
|
||||||
|
FF2(bb, cc, dd, ee, aa, X[12], 7);
|
||||||
|
FF2(aa, bb, cc, dd, ee, X[ 0], 12);
|
||||||
|
FF2(ee, aa, bb, cc, dd, X[ 9], 15);
|
||||||
|
FF2(dd, ee, aa, bb, cc, X[ 5], 9);
|
||||||
|
FF2(cc, dd, ee, aa, bb, X[ 2], 11);
|
||||||
|
FF2(bb, cc, dd, ee, aa, X[14], 7);
|
||||||
|
FF2(aa, bb, cc, dd, ee, X[11], 13);
|
||||||
|
FF2(ee, aa, bb, cc, dd, X[ 8], 12);
|
||||||
|
|
||||||
|
/* round 3 */
|
||||||
|
FF3(dd, ee, aa, bb, cc, X[ 3], 11);
|
||||||
|
FF3(cc, dd, ee, aa, bb, X[10], 13);
|
||||||
|
FF3(bb, cc, dd, ee, aa, X[14], 6);
|
||||||
|
FF3(aa, bb, cc, dd, ee, X[ 4], 7);
|
||||||
|
FF3(ee, aa, bb, cc, dd, X[ 9], 14);
|
||||||
|
FF3(dd, ee, aa, bb, cc, X[15], 9);
|
||||||
|
FF3(cc, dd, ee, aa, bb, X[ 8], 13);
|
||||||
|
FF3(bb, cc, dd, ee, aa, X[ 1], 15);
|
||||||
|
FF3(aa, bb, cc, dd, ee, X[ 2], 14);
|
||||||
|
FF3(ee, aa, bb, cc, dd, X[ 7], 8);
|
||||||
|
FF3(dd, ee, aa, bb, cc, X[ 0], 13);
|
||||||
|
FF3(cc, dd, ee, aa, bb, X[ 6], 6);
|
||||||
|
FF3(bb, cc, dd, ee, aa, X[13], 5);
|
||||||
|
FF3(aa, bb, cc, dd, ee, X[11], 12);
|
||||||
|
FF3(ee, aa, bb, cc, dd, X[ 5], 7);
|
||||||
|
FF3(dd, ee, aa, bb, cc, X[12], 5);
|
||||||
|
|
||||||
|
/* round 4 */
|
||||||
|
FF4(cc, dd, ee, aa, bb, X[ 1], 11);
|
||||||
|
FF4(bb, cc, dd, ee, aa, X[ 9], 12);
|
||||||
|
FF4(aa, bb, cc, dd, ee, X[11], 14);
|
||||||
|
FF4(ee, aa, bb, cc, dd, X[10], 15);
|
||||||
|
FF4(dd, ee, aa, bb, cc, X[ 0], 14);
|
||||||
|
FF4(cc, dd, ee, aa, bb, X[ 8], 15);
|
||||||
|
FF4(bb, cc, dd, ee, aa, X[12], 9);
|
||||||
|
FF4(aa, bb, cc, dd, ee, X[ 4], 8);
|
||||||
|
FF4(ee, aa, bb, cc, dd, X[13], 9);
|
||||||
|
FF4(dd, ee, aa, bb, cc, X[ 3], 14);
|
||||||
|
FF4(cc, dd, ee, aa, bb, X[ 7], 5);
|
||||||
|
FF4(bb, cc, dd, ee, aa, X[15], 6);
|
||||||
|
FF4(aa, bb, cc, dd, ee, X[14], 8);
|
||||||
|
FF4(ee, aa, bb, cc, dd, X[ 5], 6);
|
||||||
|
FF4(dd, ee, aa, bb, cc, X[ 6], 5);
|
||||||
|
FF4(cc, dd, ee, aa, bb, X[ 2], 12);
|
||||||
|
|
||||||
|
/* round 5 */
|
||||||
|
FF5(bb, cc, dd, ee, aa, X[ 4], 9);
|
||||||
|
FF5(aa, bb, cc, dd, ee, X[ 0], 15);
|
||||||
|
FF5(ee, aa, bb, cc, dd, X[ 5], 5);
|
||||||
|
FF5(dd, ee, aa, bb, cc, X[ 9], 11);
|
||||||
|
FF5(cc, dd, ee, aa, bb, X[ 7], 6);
|
||||||
|
FF5(bb, cc, dd, ee, aa, X[12], 8);
|
||||||
|
FF5(aa, bb, cc, dd, ee, X[ 2], 13);
|
||||||
|
FF5(ee, aa, bb, cc, dd, X[10], 12);
|
||||||
|
FF5(dd, ee, aa, bb, cc, X[14], 5);
|
||||||
|
FF5(cc, dd, ee, aa, bb, X[ 1], 12);
|
||||||
|
FF5(bb, cc, dd, ee, aa, X[ 3], 13);
|
||||||
|
FF5(aa, bb, cc, dd, ee, X[ 8], 14);
|
||||||
|
FF5(ee, aa, bb, cc, dd, X[11], 11);
|
||||||
|
FF5(dd, ee, aa, bb, cc, X[ 6], 8);
|
||||||
|
FF5(cc, dd, ee, aa, bb, X[15], 5);
|
||||||
|
FF5(bb, cc, dd, ee, aa, X[13], 6);
|
||||||
|
|
||||||
|
/* parallel round 1 */
|
||||||
|
FFF5(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
|
||||||
|
FFF5(eee, aaa, bbb, ccc, ddd, X[14], 9);
|
||||||
|
FFF5(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
|
||||||
|
FFF5(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
|
||||||
|
FFF5(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
|
||||||
|
FFF5(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
|
||||||
|
FFF5(eee, aaa, bbb, ccc, ddd, X[11], 15);
|
||||||
|
FFF5(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
|
||||||
|
FFF5(ccc, ddd, eee, aaa, bbb, X[13], 7);
|
||||||
|
FFF5(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
|
||||||
|
FFF5(aaa, bbb, ccc, ddd, eee, X[15], 8);
|
||||||
|
FFF5(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
|
||||||
|
FFF5(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
|
||||||
|
FFF5(ccc, ddd, eee, aaa, bbb, X[10], 14);
|
||||||
|
FFF5(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
|
||||||
|
FFF5(aaa, bbb, ccc, ddd, eee, X[12], 6);
|
||||||
|
|
||||||
|
/* parallel round 2 */
|
||||||
|
FFF4(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
|
||||||
|
FFF4(ddd, eee, aaa, bbb, ccc, X[11], 13);
|
||||||
|
FFF4(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
|
||||||
|
FFF4(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
|
||||||
|
FFF4(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
|
||||||
|
FFF4(eee, aaa, bbb, ccc, ddd, X[13], 8);
|
||||||
|
FFF4(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
|
||||||
|
FFF4(ccc, ddd, eee, aaa, bbb, X[10], 11);
|
||||||
|
FFF4(bbb, ccc, ddd, eee, aaa, X[14], 7);
|
||||||
|
FFF4(aaa, bbb, ccc, ddd, eee, X[15], 7);
|
||||||
|
FFF4(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
|
||||||
|
FFF4(ddd, eee, aaa, bbb, ccc, X[12], 7);
|
||||||
|
FFF4(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
|
||||||
|
FFF4(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
|
||||||
|
FFF4(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
|
||||||
|
FFF4(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
|
||||||
|
|
||||||
|
/* parallel round 3 */
|
||||||
|
FFF3(ddd, eee, aaa, bbb, ccc, X[15], 9);
|
||||||
|
FFF3(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
|
||||||
|
FFF3(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
|
||||||
|
FFF3(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
|
||||||
|
FFF3(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
|
||||||
|
FFF3(ddd, eee, aaa, bbb, ccc, X[14], 6);
|
||||||
|
FFF3(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
|
||||||
|
FFF3(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
|
||||||
|
FFF3(aaa, bbb, ccc, ddd, eee, X[11], 12);
|
||||||
|
FFF3(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
|
||||||
|
FFF3(ddd, eee, aaa, bbb, ccc, X[12], 5);
|
||||||
|
FFF3(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
|
||||||
|
FFF3(bbb, ccc, ddd, eee, aaa, X[10], 13);
|
||||||
|
FFF3(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
|
||||||
|
FFF3(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
|
||||||
|
FFF3(ddd, eee, aaa, bbb, ccc, X[13], 5);
|
||||||
|
|
||||||
|
/* parallel round 4 */
|
||||||
|
FFF2(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
|
||||||
|
FFF2(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
|
||||||
|
FFF2(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
|
||||||
|
FFF2(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
|
||||||
|
FFF2(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
|
||||||
|
FFF2(ccc, ddd, eee, aaa, bbb, X[11], 14);
|
||||||
|
FFF2(bbb, ccc, ddd, eee, aaa, X[15], 6);
|
||||||
|
FFF2(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
|
||||||
|
FFF2(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
|
||||||
|
FFF2(ddd, eee, aaa, bbb, ccc, X[12], 9);
|
||||||
|
FFF2(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
|
||||||
|
FFF2(bbb, ccc, ddd, eee, aaa, X[13], 9);
|
||||||
|
FFF2(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
|
||||||
|
FFF2(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
|
||||||
|
FFF2(ddd, eee, aaa, bbb, ccc, X[10], 15);
|
||||||
|
FFF2(ccc, ddd, eee, aaa, bbb, X[14], 8);
|
||||||
|
|
||||||
|
/* parallel round 5 */
|
||||||
|
FFF1(bbb, ccc, ddd, eee, aaa, X[12] , 8);
|
||||||
|
FFF1(aaa, bbb, ccc, ddd, eee, X[15] , 5);
|
||||||
|
FFF1(eee, aaa, bbb, ccc, ddd, X[10] , 12);
|
||||||
|
FFF1(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
|
||||||
|
FFF1(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
|
||||||
|
FFF1(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
|
||||||
|
FFF1(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
|
||||||
|
FFF1(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
|
||||||
|
FFF1(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
|
||||||
|
FFF1(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
|
||||||
|
FFF1(bbb, ccc, ddd, eee, aaa, X[13] , 6);
|
||||||
|
FFF1(aaa, bbb, ccc, ddd, eee, X[14] , 5);
|
||||||
|
FFF1(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
|
||||||
|
FFF1(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
|
||||||
|
FFF1(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
|
||||||
|
FFF1(bbb, ccc, ddd, eee, aaa, X[11] , 11);
|
||||||
|
|
||||||
|
/* combine results into new state */
|
||||||
|
ddd += cc + MDbuf[1];
|
||||||
|
MDbuf[1] = MDbuf[2] + dd + eee;
|
||||||
|
MDbuf[2] = MDbuf[3] + ee + aaa;
|
||||||
|
MDbuf[3] = MDbuf[4] + aa + bbb;
|
||||||
|
MDbuf[4] = MDbuf[0] + bb + ccc;
|
||||||
|
MDbuf[0] = ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
void MDfinish(word *MDbuf, byte *string, word lswlen, word mswlen)
|
||||||
|
/* The final value of the 5-word MDbuf array is calculated.
|
||||||
|
lswlen and mswlen contain, respectively, the least and most significant
|
||||||
|
32 bits of the message bit length mod 2^64, and string is an incomplete
|
||||||
|
block containing the (lswlen mod 512) remaining message bits.
|
||||||
|
(In case the message is already a multiple of 512 bits, string
|
||||||
|
is not used.) The conversion of the 5-word final state MDbuf to
|
||||||
|
the 20-byte hash result using a Little-endian convention is the
|
||||||
|
responsibility of the calling function.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
size_t i, length;
|
||||||
|
byte mask;
|
||||||
|
word X[16];
|
||||||
|
|
||||||
|
/* clear 16-word message block */
|
||||||
|
memset(X, 0, 16*sizeof(word));
|
||||||
|
|
||||||
|
/* copy (lswlen mod 512) bits from string into X */
|
||||||
|
length = ((lswlen&511)+7)/8; /* number of bytes */
|
||||||
|
mask = (lswlen&7) ? ((byte)1 << (lswlen&7)) - 1 : 0xff;
|
||||||
|
for (i=0; i<length; i++) {
|
||||||
|
/* byte i goes into word X[i div 4] at bit position 8*(i mod 4) */
|
||||||
|
if (i == length-1)
|
||||||
|
X[i>>2] ^= (word) (*string&mask) << (8*(i&3));
|
||||||
|
else
|
||||||
|
X[i>>2] ^= (word) *string++ << (8*(i&3));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* append a single 1 */
|
||||||
|
X[(lswlen>>5)&15] ^= (word)1 << (8*((lswlen>>3)&3)+7-(lswlen&7));
|
||||||
|
|
||||||
|
if ((lswlen & 511) > 447) {
|
||||||
|
/* length doesn't fit in this block anymore.
|
||||||
|
Compress, and put length in the next block */
|
||||||
|
MDcompress(MDbuf, X);
|
||||||
|
memset(X, 0, 16*sizeof(word));
|
||||||
|
}
|
||||||
|
/* append length in bits*/
|
||||||
|
X[14] = lswlen;
|
||||||
|
X[15] = mswlen;
|
||||||
|
MDcompress(MDbuf, X);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************ end of file rmd160.c **********************/
|
||||||
|
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
/********************************************************************\
|
||||||
|
* FILE: rmd160.h
|
||||||
|
* CONTENTS: Header file for a sample C-implementation of the
|
||||||
|
* RIPEMD-160 hash-function.
|
||||||
|
* AUTHOR: Antoon Bosselaers, Dept. Electrical Eng.-ESAT/COSIC
|
||||||
|
* DATE: 1 March 1996 VERSION: 1.0
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
#ifndef RMD160H /* make sure this file is read only once */
|
||||||
|
#define RMD160H
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
/* Type definitions of an 8 and a 32-bit integer type, respectively.
|
||||||
|
Adapt these, if necessary, for your operating system and compiler
|
||||||
|
*/
|
||||||
|
typedef unsigned char byte; /* unsigned 8-bit integer */
|
||||||
|
typedef unsigned long word; /* unsigned 32-bit integer */
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
/* Macro definitions */
|
||||||
|
|
||||||
|
/* ROL(x, n) cyclically rotates x over n bits to the left
|
||||||
|
x must be of an unsigned 32 bits type and 0 <= n < 32.
|
||||||
|
*/
|
||||||
|
#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||||
|
|
||||||
|
/* The five basic RIPEMD-160 functions F1(), F2(), F3(), F4(), and F5()
|
||||||
|
*/
|
||||||
|
#define F1(x, y, z) ((x) ^ (y) ^ (z))
|
||||||
|
#define F2(x, y, z) (((x) & (y)) | (~(x) & (z)))
|
||||||
|
#define F3(x, y, z) (((x) | ~(y)) ^ (z))
|
||||||
|
#define F4(x, y, z) (((x) & (z)) | ((y) & ~(z)))
|
||||||
|
#define F5(x, y, z) ((x) ^ ((y) | ~(z)))
|
||||||
|
|
||||||
|
/* The ten basic RIPEMD-160 transformations FF1() through FFF5()
|
||||||
|
*/
|
||||||
|
#define FF1(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += F1((b), (c), (d)) + (x);\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
#define FF2(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += F2((b), (c), (d)) + (x) + 0x5a827999UL;\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
#define FF3(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += F3((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
#define FF4(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += F4((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
#define FF5(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += F5((b), (c), (d)) + (x) + 0xa953fd4eUL;\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
#define FFF1(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += F1((b), (c), (d)) + (x);\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
#define FFF2(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += F2((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
#define FFF3(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += F3((b), (c), (d)) + (x) + 0x6d703ef3UL;\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
#define FFF4(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += F4((b), (c), (d)) + (x) + 0x5c4dd124UL;\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
#define FFF5(a, b, c, d, e, x, s) {\
|
||||||
|
(a) += F5((b), (c), (d)) + (x) + 0x50a28be6UL;\
|
||||||
|
(a) = ROL((a), (s)) + (e);\
|
||||||
|
(c) = ROL((c), 10);\
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
/* Function prototypes */
|
||||||
|
|
||||||
|
void MDinit(word *MDbuf);
|
||||||
|
void MDcompress(word *MDbuf, word *X);
|
||||||
|
void MDfinish(word *MDbuf, byte *string, word lswlen, word mswlen);
|
||||||
|
|
||||||
|
#endif /* RMD160H */
|
||||||
|
|
||||||
|
/*********************** end of file rmd160.h ***********************/
|
||||||
|
|
||||||
Reference in New Issue
Block a user