Re-organized, added Tiger, added RMD128, 160, 256, and 320, added MD2 and MD4.

This commit is contained in:
GRMrGecko 2013-08-09 22:54:43 -05:00
parent 0be24c7fdf
commit 296586842f
35 changed files with 4695 additions and 640 deletions

View File

@ -7,6 +7,8 @@
//
#import <Foundation/Foundation.h>
#import "MGMTypes.h"
#import "MGMMD2.h"
#import "MGMMD5.h"
#import "MGMSHA1.h"
#import "MGMSHA224.h"
@ -16,17 +18,18 @@
typedef enum {
MDNULL = -1,
MDMD5 = 0,
MDSHA1 = 1,
MDSHA224 = 2,
MDSHA256 = 3,
MDSHA384 = 4,
MDSHA512 = 5,
MDMD2 = 0,
MDMD5 = 1,
MDSHA1 = 2,
MDSHA224 = 3,
MDSHA256 = 4,
MDSHA384 = 5,
MDSHA512 = 6,
} MGMMDType;
@interface MGMMD : NSObject {
MGMMDType algorithm;
int algorithmLength;
struct MGMHashDescription description;
void *context;
NSData *finalData;
}

View File

@ -7,7 +7,6 @@
//
#import "MGMMD.h"
#import "MGMTypes.h"
@implementation MGMMD
+ (NSString *)stringHash:(NSString *)theString usingAlgorithm:(NSString *)theAlgorithm {
@ -28,6 +27,9 @@
+ (NSArray *)supportedAlgorithms {
NSMutableArray *algorithms = [NSMutableArray array];
#ifdef _MD_MD2
[algorithms addObject:MDNMD2];
#endif
#ifdef _MD_MD5
[algorithms addObject:MDNMD5];
#endif
@ -57,58 +59,55 @@
theAlgorithm = [theAlgorithm lowercaseString];
algorithm = MDNULL;
context = NULL;
#ifdef _MD_MD2
if ([theAlgorithm isEqual:MDNMD2]) {
algorithm = MDMD2;
description = MD2Desc;
}
#endif
#ifdef _MD_MD5
if ([theAlgorithm isEqual:MDNMD5]) {
algorithm = MDMD5;
context = malloc(sizeof(struct MD5Context));
MD5Init(context);
algorithmLength = MD5Length;
description = MD5Desc;
}
#endif
#ifdef _MD_SHA1
if ([theAlgorithm isEqual:MDNSHA1]) {
algorithm = MDSHA1;
context = malloc(sizeof(struct SHA1Context));
SHA1Init(context);
algorithmLength = SHA1Length;
description = SHA1Desc;
}
#endif
#ifdef _MD_SHA224
if ([theAlgorithm isEqual:MDNSHA224]) {
algorithm = MDSHA224;
context = malloc(sizeof(struct SHA224Context));
SHA224Init(context);
algorithmLength = SHA224Length;
description = SHA224Desc;
}
#endif
#ifdef _MD_SHA256
if ([theAlgorithm isEqual:MDNSHA256]) {
algorithm = MDSHA256;
context = malloc(sizeof(struct SHA256Context));
SHA256Init(context);
algorithmLength = SHA256Length;
description = SHA256Desc;
}
#endif
#ifdef _MD_SHA384
if ([theAlgorithm isEqual:MDNSHA384]) {
algorithm = MDSHA384;
context = malloc(sizeof(struct SHA384Context));
SHA384Init(context);
algorithmLength = SHA384Length;
description = SHA384Desc;
}
#endif
#ifdef _MD_SHA512
if ([theAlgorithm isEqual:MDNSHA512]) {
algorithm = MDSHA512;
context = malloc(sizeof(struct SHA512Context));
SHA512Init(context);
algorithmLength = SHA512Length;
description = SHA512Desc;
}
#endif
if (algorithm==MDNULL) {
NSLog(@"The alorithm \"%@\" is not supported.", theAlgorithm);
[self release];
self = nil;
} else {
context = malloc(description.contextSize);
description.init(context);
}
}
return self;
@ -144,61 +143,15 @@
}
- (BOOL)updateWithBytes:(const char *)theBytes length:(int)theLength {
if (finalData!=nil) return NO;
#ifdef _MD_MD5
if (algorithm==MDMD5)
MD5Update(context, (const unsigned char *)theBytes, theLength);
#endif
#ifdef _MD_SHA1
if (algorithm==MDSHA1)
SHA1Update(context, (const unsigned char *)theBytes, theLength);
#endif
#ifdef _MD_SHA224
if (algorithm==MDSHA224)
SHA224Update(context, (const unsigned char *)theBytes, theLength);
#endif
#ifdef _MD_SHA256
if (algorithm==MDSHA256)
SHA256Update(context, (const unsigned char *)theBytes, theLength);
#endif
#ifdef _MD_SHA384
if (algorithm==MDSHA384)
SHA384Update(context, (const unsigned char *)theBytes, theLength);
#endif
#ifdef _MD_SHA512
if (algorithm==MDSHA512)
SHA512Update(context, (const unsigned char *)theBytes, theLength);
#endif
description.update(context, (const unsigned char *)theBytes, theLength);
return YES;
}
- (NSData *)finalData {
if (finalData==nil) {
unsigned char MDDigest[algorithmLength];
#ifdef _MD_MD5
if (algorithm==MDMD5)
MD5Final(MDDigest, context);
#endif
#ifdef _MD_SHA1
if (algorithm==MDSHA1)
SHA1Final(MDDigest, context);
#endif
#ifdef _MD_SHA224
if (algorithm==MDSHA224)
SHA224Final(MDDigest, context);
#endif
#ifdef _MD_SHA256
if (algorithm==MDSHA256)
SHA256Final(MDDigest, context);
#endif
#ifdef _MD_SHA384
if (algorithm==MDSHA384)
SHA384Final(MDDigest, context);
#endif
#ifdef _MD_SHA512
if (algorithm==MDSHA512)
SHA512Final(MDDigest, context);
#endif
finalData = [[NSData dataWithBytes:MDDigest length:algorithmLength] retain];
unsigned char MDDigest[description.length];
description.final(MDDigest, context);
finalData = [[NSData dataWithBytes:MDDigest length:description.length] retain];
}
return finalData;
}
@ -217,7 +170,7 @@
bytes++;
}
*hexBuffer = '\0';
return [[NSData dataWithBytesNoCopy:stringBuffer length:algorithmLength*2] bytes];
return [[NSData dataWithBytesNoCopy:stringBuffer length:description.length*2] bytes];
}
- (NSString *)finalHash {
return [NSString stringWithUTF8String:[self finalStringHash]];

50
Classes/MD/MGMMD2.h Normal file
View File

@ -0,0 +1,50 @@
//
// MGMMD2.h
//
// Created by Mr. Gecko <GRMrGecko@gmail.com> on 5/27/11.
// No Copyright Claimed. Public Domain.
//
#ifndef _MD_MD2
#define _MD_MD2
#ifdef __NEXT_RUNTIME__
#import <Foundation/Foundation.h>
extern NSString * const MDNMD2;
@interface NSString (MGMMD2)
- (NSString *)MD2;
- (NSString *)pathMD2;
@end
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern const struct MGMHashDescription MD2Desc;
char *MD2String(const char *string, int length);
char *MD2File(const char *path);
#define MD2Length 16
struct MD2Context {
unsigned char checksum[MD2Length], X[48], buf[MD2Length];
unsigned long curlen;
};
void MD2Init(struct MD2Context *context);
void MD2Update(struct MD2Context *context, const unsigned char *buf, unsigned len);
void MD2Final(unsigned char digest[MD2Length], struct MD2Context *context);
void MD2UpdateCheckSum(struct MD2Context *context);
void MD2Transform(struct MD2Context *context);
int MD2Test();
#ifdef __cplusplus
}
#endif
#endif

274
Classes/MD/MGMMD2.m Normal file
View File

@ -0,0 +1,274 @@
//
// MGMMD2.m
//
// Created by Mr. Gecko <GRMrGecko@gmail.com> on 5/27/11.
// No Copyright Claimed. Public Domain.
// C Algorithm created by Tom St Denis <tomstdenis@gmail.com> <http://libtom.org>
//
#ifdef __NEXT_RUNTIME__
#import "MGMMD2.h"
#import "MGMTypes.h"
NSString * const MDNMD2 = @"md2";
@implementation NSString (MGMMD2)
- (NSString *)MD2 {
NSData *MDData = [self dataUsingEncoding:NSUTF8StringEncoding];
struct MD2Context MDContext;
unsigned char MDDigest[MD2Length];
MD2Init(&MDContext);
MD2Update(&MDContext, [MDData bytes], [MDData length]);
MD2Final(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(MD2Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<MD2Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
NSString *hash = [NSString stringWithUTF8String:stringBuffer];
free(stringBuffer);
return hash;
}
- (NSString *)pathMD2 {
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:self];
if (file==nil)
return nil;
struct MD2Context MDContext;
unsigned char MDDigest[MD2Length];
MD2Init(&MDContext);
int length;
do {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSData *MDData = [file readDataOfLength:MDFileReadLength];
length = [MDData length];
MD2Update(&MDContext, [MDData bytes], length);
[pool release];
} while (length>0);
MD2Final(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(MD2Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<MD2Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
NSString *hash = [NSString stringWithUTF8String:stringBuffer];
free(stringBuffer);
return hash;
}
@end
#else
#include <stdio.h>
#include <string.h>
#include "MGMMD2.h"
#include "MGMTypes.h"
#endif
const struct MGMHashDescription MD2Desc = {
"md2",
sizeof(struct MD2Context),
(void(*)(void *))&MD2Init,
(void(*)(void *, const unsigned char *, unsigned))&MD2Update,
(void(*)(unsigned char *, void *))&MD2Final,
MD2Length
};
char *MD2String(const char *string, int length) {
struct MD2Context MDContext;
unsigned char MDDigest[MD2Length];
MD2Init(&MDContext);
MD2Update(&MDContext, (const unsigned char *)string, length);
MD2Final(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(MD2Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<MD2Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
return stringBuffer;
}
char *MD2File(const char *path) {
FILE *file = fopen(path, "r");
if (file==NULL)
return NULL;
struct MD2Context MDContext;
unsigned char MDDigest[MD2Length];
MD2Init(&MDContext);
int length;
do {
unsigned char MDData[MDFileReadLength];
length = fread(&MDData, 1, MDFileReadLength, file);
MD2Update(&MDContext, MDData, length);
} while (length>0);
MD2Final(MDDigest, &MDContext);
fclose(file);
char *stringBuffer = (char *)malloc(MD2Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<MD2Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
return stringBuffer;
}
void MD2Init(struct MD2Context *context) {
memset(context->X, 0, sizeof(context->X));
memset(context->checksum, 0, sizeof(context->checksum));
memset(context->buf, 0, sizeof(context->buf));
context->curlen = 0;
}
static const unsigned char MD2PI_SUBST[256] = {
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
31, 26, 219, 153, 141, 51, 159, 17, 131, 20
};
void MD2Update(struct MD2Context *context, const unsigned char *buf, unsigned len) {
if (buf==NULL)
return;
unsigned long n;
if (context->curlen > sizeof(context->buf))
return;
while (len>0) {
n = MIN(len, (16 - context->curlen));
memcpy(context->buf + context->curlen, buf, (size_t)n);
context->curlen += n;
buf += n;
len -= n;
if (context->curlen == MD2Length) {
MD2Transform(context);
MD2UpdateCheckSum(context);
context->curlen = 0;
}
}
}
void MD2Final(unsigned char digest[MD2Length], struct MD2Context *context) {
if (context->curlen >= sizeof(context->buf))
return;
/* pad the message */
unsigned long k = MD2Length - context->curlen;
for (unsigned long i=context->curlen; i<MD2Length; i++) {
context->buf[i] = (unsigned char)k;
}
/* hash and update */
MD2Transform(context);
MD2UpdateCheckSum(context);
/* hash checksum */
memcpy(context->buf, context->checksum, MD2Length);
MD2Transform(context);
memcpy(digest, context->X, MD2Length);
memset(context, 0, sizeof(struct MD2Context));
}
void MD2UpdateCheckSum(struct MD2Context *context) {
unsigned char L = context->checksum[15];
for (int j=0; j<MD2Length; j++) {
L = (context->checksum[j] ^= MD2PI_SUBST[(int)(context->buf[j] ^ L)] & 255);
}
}
void MD2Transform(struct MD2Context *context) {
for (int j=0; j<MD2Length; j++) {
context->X[16+j] = context->buf[j];
context->X[32+j] = context->X[j] ^ context->X[16+j];
}
unsigned char t = 0;
for (int j=0; j<18; j++) {
for (int k=0; k<48; k++) {
t = (context->X[k] ^= MD2PI_SUBST[(int)(t & 255)]);
}
t = (t + (unsigned char)j) & 255;
}
}
int MD2Test() {
static const struct {
char *msg;
unsigned char hash[MD2Length];
} tests[] = {
{
"",
{0x83,0x50,0xe5,0xa3,0xe2,0x4c,0x15,0x3d,0xf2,0x27,0x5c,0x9f,0x80,0x69,0x27,0x73}
},
{
"a",
{0x32,0xec,0x01,0xec,0x4a,0x6d,0xac,0x72,0xc0,0xab,0x96,0xfb,0x34,0xc0,0xb5,0xd1}
},
{
"message digest",
{0xab,0x4f,0x49,0x6b,0xfb,0x2a,0x53,0x0b,0x21,0x9f,0xf3,0x30,0x31,0xfe,0x06,0xb0}
},
{
"abcdefghijklmnopqrstuvwxyz",
{0x4e,0x8d,0xdf,0xf3,0x65,0x02,0x92,0xab,0x5a,0x41,0x08,0xc3,0xaa,0x47,0x94,0x0b}
},
{
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
{0xda,0x33,0xde,0xf2,0xa4,0x2d,0xf1,0x39,0x75,0x35,0x28,0x46,0xc3,0x03,0x38,0xcd}
},
{
"12345678901234567890123456789012345678901234567890123456789012345678901234567890",
{0xd5,0x97,0x6f,0x79,0xd8,0x3d,0x3a,0x0d,0xc9,0x80,0x6c,0x3c,0x66,0xf3,0xef,0xd8}
},
{NULL, {0}}
};
struct MD2Context MDContext;
unsigned char MDDigest[MD2Length];
for (int i=0; tests[i].msg!=NULL; i++) {
MD2Init(&MDContext);
MD2Update(&MDContext, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
MD2Final(MDDigest, &MDContext);
if (memcmp(MDDigest, tests[i].hash, MD2Length))
return 0;
}
return 1;
}

51
Classes/MD/MGMMD4.h Normal file
View File

@ -0,0 +1,51 @@
//
// MGMMD4.h
//
// Created by Mr. Gecko <GRMrGecko@gmail.com> on 5/27/11.
// No Copyright Claimed. Public Domain.
//
#ifndef _MD_MD4
#define _MD_MD4
#ifdef __NEXT_RUNTIME__
#import <Foundation/Foundation.h>
extern NSString * const MDNMD4;
@interface NSString (MGMMD4)
- (NSString *)MD4;
- (NSString *)pathMD4;
@end
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern const struct MGMHashDescription MD4Desc;
char *MD4String(const char *string, int length);
char *MD4File(const char *path);
#define MD4Length 16
#define MD4BufferSize 64
struct MD4Context {
uint64_t length;
uint32_t state[4], curlen;
unsigned char buf[MD4BufferSize];
};
void MD4Init(struct MD4Context *context);
void MD4Update(struct MD4Context *context, const unsigned char *buf, unsigned len);
void MD4Final(unsigned char digest[MD4Length], struct MD4Context *context);
void MD4Transform(struct MD4Context *context, unsigned char *buf);
int MD4Test();
#ifdef __cplusplus
}
#endif
#endif

325
Classes/MD/MGMMD4.m Normal file
View File

@ -0,0 +1,325 @@
//
// MGMMD4.m
//
// Created by Mr. Gecko <GRMrGecko@gmail.com> on 5/27/11.
// No Copyright Claimed. Public Domain.
// C Algorithm created by Tom St Denis <tomstdenis@gmail.com> <http://libtom.org>
//
#ifdef __NEXT_RUNTIME__
#import "MGMMD4.h"
#import "MGMTypes.h"
NSString * const MDNMD4 = @"md4";
@implementation NSString (MGMMD4)
- (NSString *)MD4 {
NSData *MDData = [self dataUsingEncoding:NSUTF8StringEncoding];
struct MD4Context MDContext;
unsigned char MDDigest[MD4Length];
MD4Init(&MDContext);
MD4Update(&MDContext, [MDData bytes], [MDData length]);
MD4Final(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(MD4Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<MD4Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
NSString *hash = [NSString stringWithUTF8String:stringBuffer];
free(stringBuffer);
return hash;
}
- (NSString *)pathMD4 {
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:self];
if (file==nil)
return nil;
struct MD4Context MDContext;
unsigned char MDDigest[MD4Length];
MD4Init(&MDContext);
int length;
do {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSData *MDData = [file readDataOfLength:MDFileReadLength];
length = [MDData length];
MD4Update(&MDContext, [MDData bytes], length);
[pool release];
} while (length>0);
MD4Final(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(MD4Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<MD4Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
NSString *hash = [NSString stringWithUTF8String:stringBuffer];
free(stringBuffer);
return hash;
}
@end
#else
#include <stdio.h>
#include <string.h>
#include "MGMMD4.h"
#include "MGMTypes.h"
#endif
const struct MGMHashDescription MD4Desc = {
"md4",
sizeof(struct MD4Context),
(void(*)(void *))&MD4Init,
(void(*)(void *, const unsigned char *, unsigned))&MD4Update,
(void(*)(unsigned char *, void *))&MD4Final,
MD4Length
};
char *MD4String(const char *string, int length) {
struct MD4Context MDContext;
unsigned char MDDigest[MD4Length];
MD4Init(&MDContext);
MD4Update(&MDContext, (const unsigned char *)string, length);
MD4Final(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(MD4Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<MD4Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
return stringBuffer;
}
char *MD4File(const char *path) {
FILE *file = fopen(path, "r");
if (file==NULL)
return NULL;
struct MD4Context MDContext;
unsigned char MDDigest[MD4Length];
MD4Init(&MDContext);
int length;
do {
unsigned char MDData[MDFileReadLength];
length = fread(&MDData, 1, MDFileReadLength, file);
MD4Update(&MDContext, MDData, length);
} while (length>0);
MD4Final(MDDigest, &MDContext);
fclose(file);
char *stringBuffer = (char *)malloc(MD4Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<MD4Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
return stringBuffer;
}
void MD4Init(struct MD4Context *context) {
context->state[0] = INT32(0x67452301);
context->state[1] = INT32(0xefcdab89);
context->state[2] = INT32(0x98badcfe);
context->state[3] = INT32(0x10325476);
context->length = 0;
context->curlen = 0;
}
void MD4Update(struct MD4Context *context, const unsigned char *buf, unsigned len) {
if (buf==NULL)
return;
unsigned long n;
while (len>0) {
if (context->curlen == 0 && len>=MD4BufferSize) {
MD4Transform(context, (unsigned char *)buf);
context->length += MD4BufferSize * 8;
buf += MD4BufferSize;
len -= MD4BufferSize;
} else {
n = MIN(len, (MD4BufferSize-context->curlen));
memcpy(context->buf+context->curlen, buf, (size_t)n);
context->curlen += n;
buf += n;
len -= n;
if (context->curlen == MD4BufferSize) {
MD4Transform(context, context->buf);
context->length += 8*MD4BufferSize;
context->curlen = 0;
}
}
}
}
void MD4Final(unsigned char digest[MD4Length], struct MD4Context *context) {
context->length += context->curlen * 8;
context->buf[context->curlen++] = (unsigned char)0x80;
if (context->curlen > 56) {
while (context->curlen < MD4BufferSize) {
context->buf[context->curlen++] = (unsigned char)0;
}
MD4Transform(context, context->buf);
context->curlen = 0;
}
while (context->curlen < 56) {
context->buf[context->curlen++] = (unsigned char)0;
}
putu64l(context->length, context->buf+56);
MD4Transform(context, context->buf);
for (int i=0; i<4; i++) {
putu32l(context->state[i], digest+(4*i));
}
memset(context, 0, sizeof(struct MD4Context));
}
#define MD4_S1 0
#define MD4_S2 INT32(0x5a827999)
#define MD4_S3 INT32(0x6ed9eba1)
#define MD4_F1(x, y, z) (z ^ (x & (y ^ z)))
#define MD4_F2(x, y, z) ((x & y) | (z & (x | y)))
#define MD4_F3(x, y, z) ((x) ^ (y) ^ (z))
#define MD4STEP(a, b, c, d, e, f, g, h) \
(c) += a((d), (e), (f)) + (g) + b; (c) = ROL32((c), (h));
void MD4Transform(struct MD4Context *context, unsigned char *buf) {
uint32_t x[16];
uint32_t a = context->state[0];
uint32_t b = context->state[1];
uint32_t c = context->state[2];
uint32_t d = context->state[3];
for (int i=0; i<16; i++) {
x[i] = getu32l(buf+(4*i));
}
/* Round 1 */
MD4STEP(MD4_F1, MD4_S1, a, b, c, d, x[0], 3);
MD4STEP(MD4_F1, MD4_S1, d, a, b, c, x[1], 7);
MD4STEP(MD4_F1, MD4_S1, c, d, a, b, x[2], 11);
MD4STEP(MD4_F1, MD4_S1, b, c, d, a, x[3], 19);
MD4STEP(MD4_F1, MD4_S1, a, b, c, d, x[4], 3);
MD4STEP(MD4_F1, MD4_S1, d, a, b, c, x[5], 7);
MD4STEP(MD4_F1, MD4_S1, c, d, a, b, x[6], 11);
MD4STEP(MD4_F1, MD4_S1, b, c, d, a, x[7], 19);
MD4STEP(MD4_F1, MD4_S1, a, b, c, d, x[8], 3);
MD4STEP(MD4_F1, MD4_S1, d, a, b, c, x[9], 7);
MD4STEP(MD4_F1, MD4_S1, c, d, a, b, x[10], 11);
MD4STEP(MD4_F1, MD4_S1, b, c, d, a, x[11], 19);
MD4STEP(MD4_F1, MD4_S1, a, b, c, d, x[12], 3);
MD4STEP(MD4_F1, MD4_S1, d, a, b, c, x[13], 7);
MD4STEP(MD4_F1, MD4_S1, c, d, a, b, x[14], 11);
MD4STEP(MD4_F1, MD4_S1, b, c, d, a, x[15], 19);
/* Round 2 */
MD4STEP(MD4_F2, MD4_S2, a, b, c, d, x[0], 3);
MD4STEP(MD4_F2, MD4_S2, d, a, b, c, x[4], 5);
MD4STEP(MD4_F2, MD4_S2, c, d, a, b, x[8], 9);
MD4STEP(MD4_F2, MD4_S2, b, c, d, a, x[12], 13);
MD4STEP(MD4_F2, MD4_S2, a, b, c, d, x[1], 3);
MD4STEP(MD4_F2, MD4_S2, d, a, b, c, x[5], 5);
MD4STEP(MD4_F2, MD4_S2, c, d, a, b, x[9], 9);
MD4STEP(MD4_F2, MD4_S2, b, c, d, a, x[13], 13);
MD4STEP(MD4_F2, MD4_S2, a, b, c, d, x[2], 3);
MD4STEP(MD4_F2, MD4_S2, d, a, b, c, x[6], 5);
MD4STEP(MD4_F2, MD4_S2, c, d, a, b, x[10], 9);
MD4STEP(MD4_F2, MD4_S2, b, c, d, a, x[14], 13);
MD4STEP(MD4_F2, MD4_S2, a, b, c, d, x[3], 3);
MD4STEP(MD4_F2, MD4_S2, d, a, b, c, x[7], 5);
MD4STEP(MD4_F2, MD4_S2, c, d, a, b, x[11], 9);
MD4STEP(MD4_F2, MD4_S2, b, c, d, a, x[15], 13);
/* Round 3 */
MD4STEP(MD4_F3, MD4_S3, a, b, c, d, x[0], 3);
MD4STEP(MD4_F3, MD4_S3, d, a, b, c, x[8], 9);
MD4STEP(MD4_F3, MD4_S3, c, d, a, b, x[4], 11);
MD4STEP(MD4_F3, MD4_S3, b, c, d, a, x[12], 15);
MD4STEP(MD4_F3, MD4_S3, a, b, c, d, x[2], 3);
MD4STEP(MD4_F3, MD4_S3, d, a, b, c, x[10], 9);
MD4STEP(MD4_F3, MD4_S3, c, d, a, b, x[6], 11);
MD4STEP(MD4_F3, MD4_S3, b, c, d, a, x[14], 15);
MD4STEP(MD4_F3, MD4_S3, a, b, c, d, x[1], 3);
MD4STEP(MD4_F3, MD4_S3, d, a, b, c, x[9], 9);
MD4STEP(MD4_F3, MD4_S3, c, d, a, b, x[5], 11);
MD4STEP(MD4_F3, MD4_S3, b, c, d, a, x[13], 15);
MD4STEP(MD4_F3, MD4_S3, a, b, c, d, x[3], 3);
MD4STEP(MD4_F3, MD4_S3, d, a, b, c, x[11], 9);
MD4STEP(MD4_F3, MD4_S3, c, d, a, b, x[7], 11);
MD4STEP(MD4_F3, MD4_S3, b, c, d, a, x[15], 15);
context->state[0] = context->state[0] + a;
context->state[1] = context->state[1] + b;
context->state[2] = context->state[2] + c;
context->state[3] = context->state[3] + d;
}
int MD4Test() {
static const struct {
char *msg;
unsigned char hash[MD4Length];
} tests[] = {
{
"",
{0x31,0xd6,0xcf,0xe0,0xd1,0x6a,0xe9,0x31,0xb7,0x3c,0x59,0xd7,0xe0,0xc0,0x89,0xc0}
},
{
"a",
{0xbd,0xe5,0x2c,0xb3,0x1d,0xe3,0x3e,0x46,0x24,0x5e,0x05,0xfb,0xdb,0xd6,0xfb,0x24}
},
{
"abc",
{0xa4,0x48,0x01,0x7a,0xaf,0x21,0xd8,0x52,0x5f,0xc1,0x0a,0xe8,0x7a,0xa6,0x72,0x9d}
},
{
"message digest",
{0xd9,0x13,0x0a,0x81,0x64,0x54,0x9f,0xe8,0x18,0x87,0x48,0x06,0xe1,0xc7,0x01,0x4b}
},
{
"abcdefghijklmnopqrstuvwxyz",
{0xd7,0x9e,0x1c,0x30,0x8a,0xa5,0xbb,0xcd,0xee,0xa8,0xed,0x63,0xdf,0x41,0x2d,0xa9}
},
{
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
{0x04,0x3f,0x85,0x82,0xf2,0x41,0xdb,0x35,0x1c,0xe6,0x27,0xe1,0x53,0xe7,0xf0,0xe4}
},
{
"12345678901234567890123456789012345678901234567890123456789012345678901234567890",
{0xe3,0x3b,0x4d,0xdc,0x9c,0x38,0xf2,0x19,0x9c,0x3e,0x7b,0x16,0x4f,0xcc,0x05,0x36}
},
{NULL, {0}}
};
struct MD4Context MDContext;
unsigned char MDDigest[MD4Length];
for (int i=0; tests[i].msg!=NULL; i++) {
MD4Init(&MDContext);
MD4Update(&MDContext, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
MD4Final(MDDigest, &MDContext);
if (memcmp(MDDigest, tests[i].hash, MD4Length))
return 0;
}
return 1;
}

View File

@ -24,22 +24,25 @@ extern NSString * const MDNMD5;
extern "C" {
#endif
extern const struct MGMHashDescription MD5Desc;
char *MD5String(const char *string, int length);
char *MD5File(const char *path);
#define MD5Length 16
#define MD5BufferSize 4
#define MD5BufferSize 64
struct MD5Context {
uint32_t buf[MD5BufferSize];
uint32_t bits[2];
unsigned char in[64];
uint32_t length;
uint32_t state[4], curlen;
unsigned char buf[MD5BufferSize];
};
void MD5Init(struct MD5Context *context);
void MD5Update(struct MD5Context *context, const unsigned char *buf, unsigned len);
void MD5Final(unsigned char digest[MD5Length], struct MD5Context *context);
void MD5Transform(uint32_t buf[MD5BufferSize], const unsigned char inraw[64]);
void MD5Transform(struct MD5Context *context, unsigned char *buf);
int MD5Test();
#ifdef __cplusplus
}

View File

@ -3,14 +3,13 @@
//
// Created by Mr. Gecko <GRMrGecko@gmail.com> on 1/6/10.
// No Copyright Claimed. Public Domain.
// C Algorithm created by Colin Plumb
// C Algorithm created by Tom St Denis <tomstdenis@gmail.com> <http://libtom.org>
//
#ifdef __NEXT_RUNTIME__
#import "MGMMD5.h"
#import "MGMTypes.h"
NSString * const MDNMD5 = @"md5";
@implementation NSString (MGMMD5)
@ -73,6 +72,15 @@ NSString * const MDNMD5 = @"md5";
#include "MGMTypes.h"
#endif
const struct MGMHashDescription MD5Desc = {
"md5",
sizeof(struct MD5Context),
(void(*)(void *))&MD5Init,
(void(*)(void *, const unsigned char *, unsigned))&MD5Update,
(void(*)(unsigned char *, void *))&MD5Final,
MD5Length
};
char *MD5String(const char *string, int length) {
struct MD5Context MDContext;
unsigned char MDDigest[MD5Length];
@ -123,77 +131,63 @@ char *MD5File(const char *path) {
}
void MD5Init(struct MD5Context *context) {
context->buf[0] = 0x67452301;
context->buf[1] = 0xefcdab89;
context->buf[2] = 0x98badcfe;
context->buf[3] = 0x10325476;
context->bits[0] = 0;
context->bits[1] = 0;
context->state[0] = INT32(0x67452301);
context->state[1] = INT32(0xefcdab89);
context->state[2] = INT32(0x98badcfe);
context->state[3] = INT32(0x10325476);
context->curlen = 0;
context->length = 0;
}
void MD5Update(struct MD5Context *context, const unsigned char *buf, unsigned len) {
uint32_t t;
t = context->bits[0];
if ((context->bits[0] = (t + ((uint32_t)len << 3))) < t)
context->bits[1]++;
context->bits[1] += len >> 29;
t = (t >> 3) & 0x3f;
if (t!=0) {
unsigned char *p = context->in + t;
t = 64-t;
if (len < t) {
memcpy(p, buf, len);
if (buf==NULL)
return;
unsigned long n;
while (len>0) {
if (context->curlen == 0 && len>=MD5BufferSize) {
MD5Transform(context, (unsigned char *)buf);
context->length += MD5BufferSize * 8;
buf += MD5BufferSize;
len -= MD5BufferSize;
} else {
n = MIN(len, (MD5BufferSize-context->curlen));
memcpy(context->buf+context->curlen, buf, (size_t)n);
context->curlen += n;
buf += n;
len -= n;
if (context->curlen == MD5BufferSize) {
MD5Transform(context, context->buf);
context->length += 8*MD5BufferSize;
context->curlen = 0;
}
memcpy(p, buf, t);
MD5Transform(context->buf, context->in);
buf += t;
len -= t;
}
while (len >= 64) {
memcpy(context->in, buf, 64);
MD5Transform(context->buf, context->in);
buf += 64;
len -= 64;
}
memcpy(context->in, buf, len);
}
void MD5Final(unsigned char digest[MD5Length], struct MD5Context *context) {
unsigned count;
unsigned char *p;
context->length += context->curlen * 8;
context->buf[context->curlen++] = (unsigned char)0x80;
count = (context->bits[0] >> 3) & 0x3F;
p = context->in + count;
*p++ = MDPadding[0];
count = 64 - 1 - count;
if (count < 8) {
memset(p, MDPadding[1], count);
MD5Transform(context->buf, context->in);
memset(context->in, MDPadding[1], 56);
} else {
memset(p, MDPadding[1], count-8);
if (context->curlen > 56) {
while (context->curlen < 64) {
context->buf[context->curlen++] = (unsigned char)0;
}
MD5Transform(context, context->buf);
context->curlen = 0;
}
putu32l(context->bits[0], context->in + 56);
putu32l(context->bits[1], context->in + 60);
while (context->curlen < 56) {
context->buf[context->curlen++] = (unsigned char)0;
}
MD5Transform(context->buf, context->in);
for (int i=0; i<4; i++)
putu32l(context->buf[i], digest + (4 * i));
putu64l(context->length, context->buf+56);
MD5Transform(context, context->buf);
memset(context, 0, sizeof(context));
for (int i=0; i<4; i++) {
putu32l(context->state[i], digest+(4*i));
}
memset(context, 0, sizeof(struct MD5Context));
}
/* #define MD5_F1(x, y, z) (x & y | ~x & z) */
@ -203,95 +197,146 @@ void MD5Final(unsigned char digest[MD5Length], struct MD5Context *context) {
#define MD5_F4(x, y, z) (y ^ (x | ~z))
#define MD5STEP(f, w, x, y, z, data, s) \
( w += f(x, y, z) + data, w &= 0xffffffff, w = w<<s | w>>(32-s), w += x )
( w += f(x, y, z) + data, w &= INT32(0xffffffff), w = w<<s | w>>(32-s), w += x )
void MD5Transform(uint32_t buf[MD5BufferSize], const unsigned char inraw[64]) {
uint32_t in[16];
void MD5Transform(struct MD5Context *context, unsigned char *buf) {
uint32_t x[16];
int i;
for (i = 0; i < 16; ++i) {
in[i] = getu32l(inraw+4*i);
x[i] = getu32l(buf+(4*i));
}
uint32_t a = buf[0];
uint32_t b = buf[1];
uint32_t c = buf[2];
uint32_t d = buf[3];
uint32_t a = context->state[0];
uint32_t b = context->state[1];
uint32_t c = context->state[2];
uint32_t d = context->state[3];
// Round 1
MD5STEP(MD5_F1, a, b, c, d, in[ 0]+0xd76aa478, 7);
MD5STEP(MD5_F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
MD5STEP(MD5_F1, c, d, a, b, in[ 2]+0x242070db, 17);
MD5STEP(MD5_F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
MD5STEP(MD5_F1, a, b, c, d, in[ 4]+0xf57c0faf, 7);
MD5STEP(MD5_F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
MD5STEP(MD5_F1, c, d, a, b, in[ 6]+0xa8304613, 17);
MD5STEP(MD5_F1, b, c, d, a, in[ 7]+0xfd469501, 22);
MD5STEP(MD5_F1, a, b, c, d, in[ 8]+0x698098d8, 7);
MD5STEP(MD5_F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
MD5STEP(MD5_F1, c, d, a, b, in[10]+0xffff5bb1, 17);
MD5STEP(MD5_F1, b, c, d, a, in[11]+0x895cd7be, 22);
MD5STEP(MD5_F1, a, b, c, d, in[12]+0x6b901122, 7);
MD5STEP(MD5_F1, d, a, b, c, in[13]+0xfd987193, 12);
MD5STEP(MD5_F1, c, d, a, b, in[14]+0xa679438e, 17);
MD5STEP(MD5_F1, b, c, d, a, in[15]+0x49b40821, 22);
MD5STEP(MD5_F1, a, b, c, d, x[0]+INT32(0xd76aa478), 7);
MD5STEP(MD5_F1, d, a, b, c, x[1]+INT32(0xe8c7b756), 12);
MD5STEP(MD5_F1, c, d, a, b, x[2]+INT32(0x242070db), 17);
MD5STEP(MD5_F1, b, c, d, a, x[3]+INT32(0xc1bdceee), 22);
MD5STEP(MD5_F1, a, b, c, d, x[4]+INT32(0xf57c0faf), 7);
MD5STEP(MD5_F1, d, a, b, c, x[5]+INT32(0x4787c62a), 12);
MD5STEP(MD5_F1, c, d, a, b, x[6]+INT32(0xa8304613), 17);
MD5STEP(MD5_F1, b, c, d, a, x[7]+INT32(0xfd469501), 22);
MD5STEP(MD5_F1, a, b, c, d, x[8]+INT32(0x698098d8), 7);
MD5STEP(MD5_F1, d, a, b, c, x[9]+INT32(0x8b44f7af), 12);
MD5STEP(MD5_F1, c, d, a, b, x[10]+INT32(0xffff5bb1), 17);
MD5STEP(MD5_F1, b, c, d, a, x[11]+INT32(0x895cd7be), 22);
MD5STEP(MD5_F1, a, b, c, d, x[12]+INT32(0x6b901122), 7);
MD5STEP(MD5_F1, d, a, b, c, x[13]+INT32(0xfd987193), 12);
MD5STEP(MD5_F1, c, d, a, b, x[14]+INT32(0xa679438e), 17);
MD5STEP(MD5_F1, b, c, d, a, x[15]+INT32(0x49b40821), 22);
// Round 2
MD5STEP(MD5_F2, a, b, c, d, in[ 1]+0xf61e2562, 5);
MD5STEP(MD5_F2, d, a, b, c, in[ 6]+0xc040b340, 9);
MD5STEP(MD5_F2, c, d, a, b, in[11]+0x265e5a51, 14);
MD5STEP(MD5_F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
MD5STEP(MD5_F2, a, b, c, d, in[ 5]+0xd62f105d, 5);
MD5STEP(MD5_F2, d, a, b, c, in[10]+0x02441453, 9);
MD5STEP(MD5_F2, c, d, a, b, in[15]+0xd8a1e681, 14);
MD5STEP(MD5_F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
MD5STEP(MD5_F2, a, b, c, d, in[ 9]+0x21e1cde6, 5);
MD5STEP(MD5_F2, d, a, b, c, in[14]+0xc33707d6, 9);
MD5STEP(MD5_F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
MD5STEP(MD5_F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
MD5STEP(MD5_F2, a, b, c, d, in[13]+0xa9e3e905, 5);
MD5STEP(MD5_F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9);
MD5STEP(MD5_F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
MD5STEP(MD5_F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
MD5STEP(MD5_F2, a, b, c, d, x[1]+INT32(0xf61e2562), 5);
MD5STEP(MD5_F2, d, a, b, c, x[6]+INT32(0xc040b340), 9);
MD5STEP(MD5_F2, c, d, a, b, x[11]+INT32(0x265e5a51), 14);
MD5STEP(MD5_F2, b, c, d, a, x[0]+INT32(0xe9b6c7aa), 20);
MD5STEP(MD5_F2, a, b, c, d, x[5]+INT32(0xd62f105d), 5);
MD5STEP(MD5_F2, d, a, b, c, x[10]+INT32(0x02441453), 9);
MD5STEP(MD5_F2, c, d, a, b, x[15]+INT32(0xd8a1e681), 14);
MD5STEP(MD5_F2, b, c, d, a, x[4]+INT32(0xe7d3fbc8), 20);
MD5STEP(MD5_F2, a, b, c, d, x[9]+INT32(0x21e1cde6), 5);
MD5STEP(MD5_F2, d, a, b, c, x[14]+INT32(0xc33707d6), 9);
MD5STEP(MD5_F2, c, d, a, b, x[3]+INT32(0xf4d50d87), 14);
MD5STEP(MD5_F2, b, c, d, a, x[8]+INT32(0x455a14ed), 20);
MD5STEP(MD5_F2, a, b, c, d, x[13]+INT32(0xa9e3e905), 5);
MD5STEP(MD5_F2, d, a, b, c, x[2]+INT32(0xfcefa3f8), 9);
MD5STEP(MD5_F2, c, d, a, b, x[7]+INT32(0x676f02d9), 14);
MD5STEP(MD5_F2, b, c, d, a, x[12]+INT32(0x8d2a4c8a), 20);
// Round 3
MD5STEP(MD5_F3, a, b, c, d, in[ 5]+0xfffa3942, 4);
MD5STEP(MD5_F3, d, a, b, c, in[ 8]+0x8771f681, 11);
MD5STEP(MD5_F3, c, d, a, b, in[11]+0x6d9d6122, 16);
MD5STEP(MD5_F3, b, c, d, a, in[14]+0xfde5380c, 23);
MD5STEP(MD5_F3, a, b, c, d, in[ 1]+0xa4beea44, 4);
MD5STEP(MD5_F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
MD5STEP(MD5_F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
MD5STEP(MD5_F3, b, c, d, a, in[10]+0xbebfbc70, 23);
MD5STEP(MD5_F3, a, b, c, d, in[13]+0x289b7ec6, 4);
MD5STEP(MD5_F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
MD5STEP(MD5_F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
MD5STEP(MD5_F3, b, c, d, a, in[ 6]+0x04881d05, 23);
MD5STEP(MD5_F3, a, b, c, d, in[ 9]+0xd9d4d039, 4);
MD5STEP(MD5_F3, d, a, b, c, in[12]+0xe6db99e5, 11);
MD5STEP(MD5_F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
MD5STEP(MD5_F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
MD5STEP(MD5_F3, a, b, c, d, x[5]+INT32(0xfffa3942), 4);
MD5STEP(MD5_F3, d, a, b, c, x[8]+INT32(0x8771f681), 11);
MD5STEP(MD5_F3, c, d, a, b, x[11]+INT32(0x6d9d6122), 16);
MD5STEP(MD5_F3, b, c, d, a, x[14]+INT32(0xfde5380c), 23);
MD5STEP(MD5_F3, a, b, c, d, x[1]+INT32(0xa4beea44), 4);
MD5STEP(MD5_F3, d, a, b, c, x[4]+INT32(0x4bdecfa9), 11);
MD5STEP(MD5_F3, c, d, a, b, x[7]+INT32(0xf6bb4b60), 16);
MD5STEP(MD5_F3, b, c, d, a, x[10]+INT32(0xbebfbc70), 23);
MD5STEP(MD5_F3, a, b, c, d, x[13]+INT32(0x289b7ec6), 4);
MD5STEP(MD5_F3, d, a, b, c, x[0]+INT32(0xeaa127fa), 11);
MD5STEP(MD5_F3, c, d, a, b, x[3]+INT32(0xd4ef3085), 16);
MD5STEP(MD5_F3, b, c, d, a, x[6]+INT32(0x04881d05), 23);
MD5STEP(MD5_F3, a, b, c, d, x[9]+INT32(0xd9d4d039), 4);
MD5STEP(MD5_F3, d, a, b, c, x[12]+INT32(0xe6db99e5), 11);
MD5STEP(MD5_F3, c, d, a, b, x[15]+INT32(0x1fa27cf8), 16);
MD5STEP(MD5_F3, b, c, d, a, x[2]+INT32(0xc4ac5665), 23);
// Round 4
MD5STEP(MD5_F4, a, b, c, d, in[ 0]+0xf4292244, 6);
MD5STEP(MD5_F4, d, a, b, c, in[ 7]+0x432aff97, 10);
MD5STEP(MD5_F4, c, d, a, b, in[14]+0xab9423a7, 15);
MD5STEP(MD5_F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
MD5STEP(MD5_F4, a, b, c, d, in[12]+0x655b59c3, 6);
MD5STEP(MD5_F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
MD5STEP(MD5_F4, c, d, a, b, in[10]+0xffeff47d, 15);
MD5STEP(MD5_F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
MD5STEP(MD5_F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6);
MD5STEP(MD5_F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
MD5STEP(MD5_F4, c, d, a, b, in[ 6]+0xa3014314, 15);
MD5STEP(MD5_F4, b, c, d, a, in[13]+0x4e0811a1, 21);
MD5STEP(MD5_F4, a, b, c, d, in[ 4]+0xf7537e82, 6);
MD5STEP(MD5_F4, d, a, b, c, in[11]+0xbd3af235, 10);
MD5STEP(MD5_F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
MD5STEP(MD5_F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
MD5STEP(MD5_F4, a, b, c, d, x[0]+INT32(0xf4292244), 6);
MD5STEP(MD5_F4, d, a, b, c, x[7]+INT32(0x432aff97), 10);
MD5STEP(MD5_F4, c, d, a, b, x[14]+INT32(0xab9423a7), 15);
MD5STEP(MD5_F4, b, c, d, a, x[5]+INT32(0xfc93a039), 21);
MD5STEP(MD5_F4, a, b, c, d, x[12]+INT32(0x655b59c3), 6);
MD5STEP(MD5_F4, d, a, b, c, x[3]+INT32(0x8f0ccc92), 10);
MD5STEP(MD5_F4, c, d, a, b, x[10]+INT32(0xffeff47d), 15);
MD5STEP(MD5_F4, b, c, d, a, x[1]+INT32(0x85845dd1), 21);
MD5STEP(MD5_F4, a, b, c, d, x[8]+INT32(0x6fa87e4f), 6);
MD5STEP(MD5_F4, d, a, b, c, x[15]+INT32(0xfe2ce6e0), 10);
MD5STEP(MD5_F4, c, d, a, b, x[6]+INT32(0xa3014314), 15);
MD5STEP(MD5_F4, b, c, d, a, x[13]+INT32(0x4e0811a1), 21);
MD5STEP(MD5_F4, a, b, c, d, x[4]+INT32(0xf7537e82), 6);
MD5STEP(MD5_F4, d, a, b, c, x[11]+INT32(0xbd3af235), 10);
MD5STEP(MD5_F4, c, d, a, b, x[2]+INT32(0x2ad7d2bb), 15);
MD5STEP(MD5_F4, b, c, d, a, x[9]+INT32(0xeb86d391), 21);
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
context->state[0] += a;
context->state[1] += b;
context->state[2] += c;
context->state[3] += d;
}
int MD5Test() {
static const struct {
char *msg;
unsigned char hash[MD5Length];
} tests[] = {
{
"",
{0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,0x7e}
},
{
"a",
{0x0c,0xc1,0x75,0xb9,0xc0,0xf1,0xb6,0xa8,0x31,0xc3,0x99,0xe2,0x69,0x77,0x26,0x61}
},
{
"abc",
{0x90,0x01,0x50,0x98,0x3c,0xd2,0x4f,0xb0,0xd6,0x96,0x3f,0x7d,0x28,0xe1,0x7f,0x72}
},
{
"message digest",
{0xf9,0x6b,0x69,0x7d,0x7c,0xb7,0x93,0x8d,0x52,0x5a,0x2f,0x31,0xaa,0xf1,0x61,0xd0}
},
{
"abcdefghijklmnopqrstuvwxyz",
{0xc3,0xfc,0xd3,0xd7,0x61,0x92,0xe4,0x00,0x7d,0xfb,0x49,0x6c,0xca,0x67,0xe1,0x3b}
},
{
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
{0xd1,0x74,0xab,0x98,0xd2,0x77,0xd9,0xf5,0xa5,0x61,0x1c,0x2c,0x9f,0x41,0x9d,0x9f}
},
{
"12345678901234567890123456789012345678901234567890123456789012345678901234567890",
{0x57,0xed,0xf4,0xa2,0x2b,0xe3,0xc9,0x55,0xac,0x49,0xda,0x2e,0x21,0x07,0xb6,0x7a}
},
{NULL, {0}}
};
struct MD5Context MDContext;
unsigned char MDDigest[MD5Length];
for (int i=0; tests[i].msg!=NULL; i++) {
MD5Init(&MDContext);
MD5Update(&MDContext, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
MD5Final(MDDigest, &MDContext);
if (memcmp(MDDigest, tests[i].hash, MD5Length))
return 0;
}
return 1;
}

51
Classes/MD/MGMRMD128.h Normal file
View File

@ -0,0 +1,51 @@
//
// MGMRMD128.h
//
// Created by Mr. Gecko <GRMrGecko@gmail.com> on 5/31/11.
// No Copyright Claimed. Public Domain.
//
#ifndef _MD_RMD128
#define _MD_RMD128
#ifdef __NEXT_RUNTIME__
#import <Foundation/Foundation.h>
extern NSString * const MDNRMD128;
@interface NSString (MGMRMD128)
- (NSString *)RMD128;
- (NSString *)pathRMD128;
@end
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern const struct MGMHashDescription RMD128Desc;
char *RMD128String(const char *string, int length);
char *RMD128File(const char *path);
#define RMD128Length 16
#define RMD128BufferSize 64
struct RMD128Context {
uint64_t length;
unsigned char buf[RMD128BufferSize];
uint32_t curlen, state[4];
};
void RMD128Init(struct RMD128Context *context);
void RMD128Update(struct RMD128Context *context, const unsigned char *buf, unsigned len);
void RMD128Final(unsigned char digest[RMD128Length], struct RMD128Context *context);
void RMD128Transform(struct RMD128Context *context, unsigned char *buf);
int RMD128Test();
#ifdef __cplusplus
}
#endif
#endif

419
Classes/MD/MGMRMD128.m Normal file
View File

@ -0,0 +1,419 @@
//
// MGMRMD128.m
//
// Created by Mr. Gecko <GRMrGecko@gmail.com> on 5/31/11.
// No Copyright Claimed. Public Domain.
// C Algorithm created by Tom St Denis <tomstdenis@gmail.com> <http://libtom.org>
//
#ifdef __NEXT_RUNTIME__
#import "MGMRMD128.h"
#import "MGMTypes.h"
NSString * const MDNRMD128 = @"rmd128";
@implementation NSString (MGMRMD128)
- (NSString *)RMD128 {
NSData *MDData = [self dataUsingEncoding:NSUTF8StringEncoding];
struct RMD128Context MDContext;
unsigned char MDDigest[RMD128Length];
RMD128Init(&MDContext);
RMD128Update(&MDContext, [MDData bytes], [MDData length]);
RMD128Final(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(RMD128Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<RMD128Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
NSString *hash = [NSString stringWithUTF8String:stringBuffer];
free(stringBuffer);
return hash;
}
- (NSString *)pathRMD128 {
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:self];
if (file==nil)
return nil;
struct RMD128Context MDContext;
unsigned char MDDigest[RMD128Length];
RMD128Init(&MDContext);
int length;
do {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSData *MDData = [file readDataOfLength:MDFileReadLength];
length = [MDData length];
RMD128Update(&MDContext, [MDData bytes], length);
[pool release];
} while (length>0);
RMD128Final(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(RMD128Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<RMD128Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
NSString *hash = [NSString stringWithUTF8String:stringBuffer];
free(stringBuffer);
return hash;
}
@end
#else
#include <stdio.h>
#include <string.h>
#include "MGMRMD128.h"
#include "MGMTypes.h"
#endif
const struct MGMHashDescription RMD128Desc = {
"rmd128",
sizeof(struct RMD128Context),
(void(*)(void *))&RMD128Init,
(void(*)(void *, const unsigned char *, unsigned))&RMD128Update,
(void(*)(unsigned char *, void *))&RMD128Final,
RMD128Length
};
char *RMD128String(const char *string, int length) {
struct RMD128Context MDContext;
unsigned char MDDigest[RMD128Length];
RMD128Init(&MDContext);
RMD128Update(&MDContext, (const unsigned char *)string, length);
RMD128Final(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(RMD128Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<RMD128Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
return stringBuffer;
}
char *RMD128File(const char *path) {
FILE *file = fopen(path, "r");
if (file==NULL)
return NULL;
struct RMD128Context MDContext;
unsigned char MDDigest[RMD128Length];
RMD128Init(&MDContext);
int length;
do {
unsigned char MDData[MDFileReadLength];
length = fread(&MDData, 1, MDFileReadLength, file);
RMD128Update(&MDContext, MDData, length);
} while (length>0);
RMD128Final(MDDigest, &MDContext);
fclose(file);
char *stringBuffer = (char *)malloc(RMD128Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<RMD128Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
return stringBuffer;
}
void RMD128Init(struct RMD128Context *context) {
context->state[0] = INT32(0x67452301);
context->state[1] = INT32(0xefcdab89);
context->state[2] = INT32(0x98badcfe);
context->state[3] = INT32(0x10325476);
context->curlen = 0;
context->length = 0;
}
void RMD128Update(struct RMD128Context *context, const unsigned char *buf, unsigned len) {
if (buf==NULL)
return;
unsigned long n;
while (len>0) {
if (context->curlen == 0 && len>=RMD128BufferSize) {
RMD128Transform(context, (unsigned char *)buf);
context->length += RMD128BufferSize * 8;
buf += RMD128BufferSize;
len -= RMD128BufferSize;
} else {
n = MIN(len, (RMD128BufferSize-context->curlen));
memcpy(context->buf+context->curlen, buf, (size_t)n);
context->curlen += n;
buf += n;
len -= n;
if (context->curlen == RMD128BufferSize) {
RMD128Transform(context, context->buf);
context->length += 8*RMD128BufferSize;
context->curlen = 0;
}
}
}
}
void RMD128Final(unsigned char digest[RMD128Length], struct RMD128Context *context) {
context->length += context->curlen * 8;
context->buf[context->curlen++] = (unsigned char)0x80;
if (context->curlen > 56) {
while (context->curlen < 64) {
context->buf[context->curlen++] = (unsigned char)0;
}
RMD128Transform(context, context->buf);
context->curlen = 0;
}
while (context->curlen < 56) {
context->buf[context->curlen++] = (unsigned char)0;
}
putu64l(context->length, context->buf+56);
RMD128Transform(context, context->buf);
for (int i=0; i<4; i++) {
putu32l(context->state[i], digest+(4*i));
}
memset(context, 0, sizeof(struct RMD128Context));
}
#define RMD128_S1 0
#define RMD128_S2 INT32(0x5a827999)
#define RMD128_S3 INT32(0x6ed9eba1)
#define RMD128_S4 INT32(0x8f1bbcdc)
#define RMD128_S8 0
#define RMD128_S7 INT32(0x6d703ef3)
#define RMD128_S6 INT32(0x5c4dd124)
#define RMD128_S5 INT32(0x50a28be6)
#define RMD128_F1(x, y, z) ((x) ^ (y) ^ (z))
#define RMD128_F2(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define RMD128_F3(x, y, z) (((x) | ~(y)) ^ (z))
#define RMD128_F4(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define RMD128STEP(a, b, c, d, e, f, g, h) \
(c) += a((d), (e), (f)) + (g) + b; (c) = ROL32((c), (h));
void RMD128Transform(struct RMD128Context *context, unsigned char *buf) {
uint32_t x[16];
uint32_t a = context->state[0], aa = a;
uint32_t b = context->state[1], bb = b;
uint32_t c = context->state[2], cc = c;
uint32_t d = context->state[3], dd = d;
for (int i=0; i<16; i++) {
x[i] = getu32l(buf+(4*i));
}
/* round 1 */
RMD128STEP(RMD128_F1, RMD128_S1, a, b, c, d, x[0], 11);
RMD128STEP(RMD128_F1, RMD128_S1, d, a, b, c, x[1], 14);
RMD128STEP(RMD128_F1, RMD128_S1, c, d, a, b, x[2], 15);
RMD128STEP(RMD128_F1, RMD128_S1, b, c, d, a, x[3], 12);
RMD128STEP(RMD128_F1, RMD128_S1, a, b, c, d, x[4], 5);
RMD128STEP(RMD128_F1, RMD128_S1, d, a, b, c, x[5], 8);
RMD128STEP(RMD128_F1, RMD128_S1, c, d, a, b, x[6], 7);
RMD128STEP(RMD128_F1, RMD128_S1, b, c, d, a, x[7], 9);
RMD128STEP(RMD128_F1, RMD128_S1, a, b, c, d, x[8], 11);
RMD128STEP(RMD128_F1, RMD128_S1, d, a, b, c, x[9], 13);
RMD128STEP(RMD128_F1, RMD128_S1, c, d, a, b, x[10], 14);
RMD128STEP(RMD128_F1, RMD128_S1, b, c, d, a, x[11], 15);
RMD128STEP(RMD128_F1, RMD128_S1, a, b, c, d, x[12], 6);
RMD128STEP(RMD128_F1, RMD128_S1, d, a, b, c, x[13], 7);
RMD128STEP(RMD128_F1, RMD128_S1, c, d, a, b, x[14], 9);
RMD128STEP(RMD128_F1, RMD128_S1, b, c, d, a, x[15], 8);
/* round 2 */
RMD128STEP(RMD128_F2, RMD128_S2, a, b, c, d, x[7], 7);
RMD128STEP(RMD128_F2, RMD128_S2, d, a, b, c, x[4], 6);
RMD128STEP(RMD128_F2, RMD128_S2, c, d, a, b, x[13], 8);
RMD128STEP(RMD128_F2, RMD128_S2, b, c, d, a, x[1], 13);
RMD128STEP(RMD128_F2, RMD128_S2, a, b, c, d, x[10], 11);
RMD128STEP(RMD128_F2, RMD128_S2, d, a, b, c, x[6], 9);
RMD128STEP(RMD128_F2, RMD128_S2, c, d, a, b, x[15], 7);
RMD128STEP(RMD128_F2, RMD128_S2, b, c, d, a, x[3], 15);
RMD128STEP(RMD128_F2, RMD128_S2, a, b, c, d, x[12], 7);
RMD128STEP(RMD128_F2, RMD128_S2, d, a, b, c, x[0], 12);
RMD128STEP(RMD128_F2, RMD128_S2, c, d, a, b, x[9], 15);
RMD128STEP(RMD128_F2, RMD128_S2, b, c, d, a, x[5], 9);
RMD128STEP(RMD128_F2, RMD128_S2, a, b, c, d, x[2], 11);
RMD128STEP(RMD128_F2, RMD128_S2, d, a, b, c, x[14], 7);
RMD128STEP(RMD128_F2, RMD128_S2, c, d, a, b, x[11], 13);
RMD128STEP(RMD128_F2, RMD128_S2, b, c, d, a, x[8], 12);
/* round 3 */
RMD128STEP(RMD128_F3, RMD128_S3, a, b, c, d, x[3], 11);
RMD128STEP(RMD128_F3, RMD128_S3, d, a, b, c, x[10], 13);
RMD128STEP(RMD128_F3, RMD128_S3, c, d, a, b, x[14], 6);
RMD128STEP(RMD128_F3, RMD128_S3, b, c, d, a, x[4], 7);
RMD128STEP(RMD128_F3, RMD128_S3, a, b, c, d, x[9], 14);
RMD128STEP(RMD128_F3, RMD128_S3, d, a, b, c, x[15], 9);
RMD128STEP(RMD128_F3, RMD128_S3, c, d, a, b, x[8], 13);
RMD128STEP(RMD128_F3, RMD128_S3, b, c, d, a, x[1], 15);
RMD128STEP(RMD128_F3, RMD128_S3, a, b, c, d, x[2], 14);
RMD128STEP(RMD128_F3, RMD128_S3, d, a, b, c, x[7], 8);
RMD128STEP(RMD128_F3, RMD128_S3, c, d, a, b, x[0], 13);
RMD128STEP(RMD128_F3, RMD128_S3, b, c, d, a, x[6], 6);
RMD128STEP(RMD128_F3, RMD128_S3, a, b, c, d, x[13], 5);
RMD128STEP(RMD128_F3, RMD128_S3, d, a, b, c, x[11], 12);
RMD128STEP(RMD128_F3, RMD128_S3, c, d, a, b, x[5], 7);
RMD128STEP(RMD128_F3, RMD128_S3, b, c, d, a, x[12], 5);
/* round 4 */
RMD128STEP(RMD128_F4, RMD128_S4, a, b, c, d, x[1], 11);
RMD128STEP(RMD128_F4, RMD128_S4, d, a, b, c, x[9], 12);
RMD128STEP(RMD128_F4, RMD128_S4, c, d, a, b, x[11], 14);
RMD128STEP(RMD128_F4, RMD128_S4, b, c, d, a, x[10], 15);
RMD128STEP(RMD128_F4, RMD128_S4, a, b, c, d, x[0], 14);
RMD128STEP(RMD128_F4, RMD128_S4, d, a, b, c, x[8], 15);
RMD128STEP(RMD128_F4, RMD128_S4, c, d, a, b, x[12], 9);
RMD128STEP(RMD128_F4, RMD128_S4, b, c, d, a, x[4], 8);
RMD128STEP(RMD128_F4, RMD128_S4, a, b, c, d, x[13], 9);
RMD128STEP(RMD128_F4, RMD128_S4, d, a, b, c, x[3], 14);
RMD128STEP(RMD128_F4, RMD128_S4, c, d, a, b, x[7], 5);
RMD128STEP(RMD128_F4, RMD128_S4, b, c, d, a, x[15], 6);
RMD128STEP(RMD128_F4, RMD128_S4, a, b, c, d, x[14], 8);
RMD128STEP(RMD128_F4, RMD128_S4, d, a, b, c, x[5], 6);
RMD128STEP(RMD128_F4, RMD128_S4, c, d, a, b, x[6], 5);
RMD128STEP(RMD128_F4, RMD128_S4, b, c, d, a, x[2], 12);
/* parallel round 1 */
RMD128STEP(RMD128_F4, RMD128_S5, aa, bb, cc, dd, x[5], 8);
RMD128STEP(RMD128_F4, RMD128_S5, dd, aa, bb, cc, x[14], 9);
RMD128STEP(RMD128_F4, RMD128_S5, cc, dd, aa, bb, x[7], 9);
RMD128STEP(RMD128_F4, RMD128_S5, bb, cc, dd, aa, x[0], 11);
RMD128STEP(RMD128_F4, RMD128_S5, aa, bb, cc, dd, x[9], 13);
RMD128STEP(RMD128_F4, RMD128_S5, dd, aa, bb, cc, x[2], 15);
RMD128STEP(RMD128_F4, RMD128_S5, cc, dd, aa, bb, x[11], 15);
RMD128STEP(RMD128_F4, RMD128_S5, bb, cc, dd, aa, x[4], 5);
RMD128STEP(RMD128_F4, RMD128_S5, aa, bb, cc, dd, x[13], 7);
RMD128STEP(RMD128_F4, RMD128_S5, dd, aa, bb, cc, x[6], 7);
RMD128STEP(RMD128_F4, RMD128_S5, cc, dd, aa, bb, x[15], 8);
RMD128STEP(RMD128_F4, RMD128_S5, bb, cc, dd, aa, x[8], 11);
RMD128STEP(RMD128_F4, RMD128_S5, aa, bb, cc, dd, x[1], 14);
RMD128STEP(RMD128_F4, RMD128_S5, dd, aa, bb, cc, x[10], 14);
RMD128STEP(RMD128_F4, RMD128_S5, cc, dd, aa, bb, x[3], 12);
RMD128STEP(RMD128_F4, RMD128_S5, bb, cc, dd, aa, x[12], 6);
/* parallel round 2 */
RMD128STEP(RMD128_F3, RMD128_S6, aa, bb, cc, dd, x[6], 9);
RMD128STEP(RMD128_F3, RMD128_S6, dd, aa, bb, cc, x[11], 13);
RMD128STEP(RMD128_F3, RMD128_S6, cc, dd, aa, bb, x[3], 15);
RMD128STEP(RMD128_F3, RMD128_S6, bb, cc, dd, aa, x[7], 7);
RMD128STEP(RMD128_F3, RMD128_S6, aa, bb, cc, dd, x[0], 12);
RMD128STEP(RMD128_F3, RMD128_S6, dd, aa, bb, cc, x[13], 8);
RMD128STEP(RMD128_F3, RMD128_S6, cc, dd, aa, bb, x[5], 9);
RMD128STEP(RMD128_F3, RMD128_S6, bb, cc, dd, aa, x[10], 11);
RMD128STEP(RMD128_F3, RMD128_S6, aa, bb, cc, dd, x[14], 7);
RMD128STEP(RMD128_F3, RMD128_S6, dd, aa, bb, cc, x[15], 7);
RMD128STEP(RMD128_F3, RMD128_S6, cc, dd, aa, bb, x[8], 12);
RMD128STEP(RMD128_F3, RMD128_S6, bb, cc, dd, aa, x[12], 7);
RMD128STEP(RMD128_F3, RMD128_S6, aa, bb, cc, dd, x[4], 6);
RMD128STEP(RMD128_F3, RMD128_S6, dd, aa, bb, cc, x[9], 15);
RMD128STEP(RMD128_F3, RMD128_S6, cc, dd, aa, bb, x[1], 13);
RMD128STEP(RMD128_F3, RMD128_S6, bb, cc, dd, aa, x[2], 11);
/* parallel round 3 */
RMD128STEP(RMD128_F2, RMD128_S7, aa, bb, cc, dd, x[15], 9);
RMD128STEP(RMD128_F2, RMD128_S7, dd, aa, bb, cc, x[5], 7);
RMD128STEP(RMD128_F2, RMD128_S7, cc, dd, aa, bb, x[1], 15);
RMD128STEP(RMD128_F2, RMD128_S7, bb, cc, dd, aa, x[3], 11);
RMD128STEP(RMD128_F2, RMD128_S7, aa, bb, cc, dd, x[7], 8);
RMD128STEP(RMD128_F2, RMD128_S7, dd, aa, bb, cc, x[14], 6);
RMD128STEP(RMD128_F2, RMD128_S7, cc, dd, aa, bb, x[6], 6);
RMD128STEP(RMD128_F2, RMD128_S7, bb, cc, dd, aa, x[9], 14);
RMD128STEP(RMD128_F2, RMD128_S7, aa, bb, cc, dd, x[11], 12);
RMD128STEP(RMD128_F2, RMD128_S7, dd, aa, bb, cc, x[8], 13);
RMD128STEP(RMD128_F2, RMD128_S7, cc, dd, aa, bb, x[12], 5);
RMD128STEP(RMD128_F2, RMD128_S7, bb, cc, dd, aa, x[2], 14);
RMD128STEP(RMD128_F2, RMD128_S7, aa, bb, cc, dd, x[10], 13);
RMD128STEP(RMD128_F2, RMD128_S7, dd, aa, bb, cc, x[0], 13);
RMD128STEP(RMD128_F2, RMD128_S7, cc, dd, aa, bb, x[4], 7);
RMD128STEP(RMD128_F2, RMD128_S7, bb, cc, dd, aa, x[13], 5);
/* parallel round 4 */
RMD128STEP(RMD128_F1, RMD128_S8, aa, bb, cc, dd, x[8], 15);
RMD128STEP(RMD128_F1, RMD128_S8, dd, aa, bb, cc, x[6], 5);
RMD128STEP(RMD128_F1, RMD128_S8, cc, dd, aa, bb, x[4], 8);
RMD128STEP(RMD128_F1, RMD128_S8, bb, cc, dd, aa, x[1], 11);
RMD128STEP(RMD128_F1, RMD128_S8, aa, bb, cc, dd, x[3], 14);
RMD128STEP(RMD128_F1, RMD128_S8, dd, aa, bb, cc, x[11], 14);
RMD128STEP(RMD128_F1, RMD128_S8, cc, dd, aa, bb, x[15], 6);
RMD128STEP(RMD128_F1, RMD128_S8, bb, cc, dd, aa, x[0], 14);
RMD128STEP(RMD128_F1, RMD128_S8, aa, bb, cc, dd, x[5], 6);
RMD128STEP(RMD128_F1, RMD128_S8, dd, aa, bb, cc, x[12], 9);
RMD128STEP(RMD128_F1, RMD128_S8, cc, dd, aa, bb, x[2], 12);
RMD128STEP(RMD128_F1, RMD128_S8, bb, cc, dd, aa, x[13], 9);
RMD128STEP(RMD128_F1, RMD128_S8, aa, bb, cc, dd, x[9], 12);
RMD128STEP(RMD128_F1, RMD128_S8, dd, aa, bb, cc, x[7], 5);
RMD128STEP(RMD128_F1, RMD128_S8, cc, dd, aa, bb, x[10], 15);
RMD128STEP(RMD128_F1, RMD128_S8, bb, cc, dd, aa, x[14], 8);
dd += c + context->state[1];
context->state[1] = context->state[2] + d + aa;
context->state[2] = context->state[3] + a + bb;
context->state[3] = context->state[0] + b + cc;
context->state[0] = dd;
}
int RMD128Test() {
static const struct {
char *msg;
unsigned char hash[RMD128Length];
} tests[] = {
{
"",
{0xcd,0xf2,0x62,0x13,0xa1,0x50,0xdc,0x3e,0xcb,0x61,0x0f,0x18,0xf6,0xb3,0x8b,0x46}
},
{
"a",
{0x86,0xbe,0x7a,0xfa,0x33,0x9d,0x0f,0xc7,0xcf,0xc7,0x85,0xe7,0x2f,0x57,0x8d,0x33}
},
{
"abc",
{0xc1,0x4a,0x12,0x19,0x9c,0x66,0xe4,0xba,0x84,0x63,0x6b,0x0f,0x69,0x14,0x4c,0x77}
},
{
"message digest",
{0x9e,0x32,0x7b,0x3d,0x6e,0x52,0x30,0x62,0xaf,0xc1,0x13,0x2d,0x7d,0xf9,0xd1,0xb8}
},
{
"abcdefghijklmnopqrstuvwxyz",
{0xfd,0x2a,0xa6,0x07,0xf7,0x1d,0xc8,0xf5,0x10,0x71,0x49,0x22,0xb3,0x71,0x83,0x4e}
},
{
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
{0xd1,0xe9,0x59,0xeb,0x17,0x9c,0x91,0x1f,0xae,0xa4,0x62,0x4c,0x60,0xc5,0xc7,0x02}
},
{NULL, {0}}
};
struct RMD128Context MDContext;
unsigned char MDDigest[RMD128Length];
for (int i=0; tests[i].msg!=NULL; i++) {
RMD128Init(&MDContext);
RMD128Update(&MDContext, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
RMD128Final(MDDigest, &MDContext);
if (memcmp(MDDigest, tests[i].hash, RMD128Length))
return 0;
}
return 1;
}

51
Classes/MD/MGMRMD160.h Normal file
View File

@ -0,0 +1,51 @@
//
// MGMRMD160.h
//
// Created by Mr. Gecko <GRMrGecko@gmail.com> on 5/31/11.
// No Copyright Claimed. Public Domain.
//
#ifndef _MD_RMD160
#define _MD_RMD160
#ifdef __NEXT_RUNTIME__
#import <Foundation/Foundation.h>
extern NSString * const MDNRMD160;
@interface NSString (MGMRMD160)
- (NSString *)RMD160;
- (NSString *)pathRMD160;
@end
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern const struct MGMHashDescription RMD160Desc;
char *RMD160String(const char *string, int length);
char *RMD160File(const char *path);
#define RMD160Length 20
#define RMD160BufferSize 64
struct RMD160Context {
uint64_t length;
unsigned char buf[RMD160BufferSize];
uint32_t curlen, state[5];
};
void RMD160Init(struct RMD160Context *context);
void RMD160Update(struct RMD160Context *context, const unsigned char *buf, unsigned len);
void RMD160Final(unsigned char digest[RMD160Length], struct RMD160Context *context);
void RMD160Transform(struct RMD160Context *context, unsigned char *buf);
int RMD160Test();
#ifdef __cplusplus
}
#endif
#endif

461
Classes/MD/MGMRMD160.m Normal file
View File

@ -0,0 +1,461 @@
//
// MGMRMD160.m
//
// Created by Mr. Gecko <GRMrGecko@gmail.com> on 5/31/11.
// No Copyright Claimed. Public Domain.
// C Algorithm created by Tom St Denis <tomstdenis@gmail.com> <http://libtom.org>
//
#ifdef __NEXT_RUNTIME__
#import "MGMRMD160.h"
#import "MGMTypes.h"
NSString * const MDNRMD160 = @"rmd160";
@implementation NSString (MGMRMD160)
- (NSString *)RMD160 {
NSData *MDData = [self dataUsingEncoding:NSUTF8StringEncoding];
struct RMD160Context MDContext;
unsigned char MDDigest[RMD160Length];
RMD160Init(&MDContext);
RMD160Update(&MDContext, [MDData bytes], [MDData length]);
RMD160Final(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(RMD160Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<RMD160Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
NSString *hash = [NSString stringWithUTF8String:stringBuffer];
free(stringBuffer);
return hash;
}
- (NSString *)pathRMD160 {
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:self];
if (file==nil)
return nil;
struct RMD160Context MDContext;
unsigned char MDDigest[RMD160Length];
RMD160Init(&MDContext);
int length;
do {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSData *MDData = [file readDataOfLength:MDFileReadLength];
length = [MDData length];
RMD160Update(&MDContext, [MDData bytes], length);
[pool release];
} while (length>0);
RMD160Final(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(RMD160Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<RMD160Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
NSString *hash = [NSString stringWithUTF8String:stringBuffer];
free(stringBuffer);
return hash;
}
@end
#else
#include <stdio.h>
#include <string.h>
#include "MGMRMD160.h"
#include "MGMTypes.h"
#endif
const struct MGMHashDescription RMD160Desc = {
"rmd160",
sizeof(struct RMD160Context),
(void(*)(void *))&RMD160Init,
(void(*)(void *, const unsigned char *, unsigned))&RMD160Update,
(void(*)(unsigned char *, void *))&RMD160Final,
RMD160Length
};
char *RMD160String(const char *string, int length) {
struct RMD160Context MDContext;
unsigned char MDDigest[RMD160Length];
RMD160Init(&MDContext);
RMD160Update(&MDContext, (const unsigned char *)string, length);
RMD160Final(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(RMD160Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<RMD160Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
return stringBuffer;
}
char *RMD160File(const char *path) {
FILE *file = fopen(path, "r");
if (file==NULL)
return NULL;
struct RMD160Context MDContext;
unsigned char MDDigest[RMD160Length];
RMD160Init(&MDContext);
int length;
do {
unsigned char MDData[MDFileReadLength];
length = fread(&MDData, 1, MDFileReadLength, file);
RMD160Update(&MDContext, MDData, length);
} while (length>0);
RMD160Final(MDDigest, &MDContext);
fclose(file);
char *stringBuffer = (char *)malloc(RMD160Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<RMD160Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
return stringBuffer;
}
void RMD160Init(struct RMD160Context *context) {
context->state[0] = INT32(0x67452301);
context->state[1] = INT32(0xefcdab89);
context->state[2] = INT32(0x98badcfe);
context->state[3] = INT32(0x10325476);
context->state[4] = INT32(0xc3d2e1f0);
context->curlen = 0;
context->length = 0;
}
void RMD160Update(struct RMD160Context *context, const unsigned char *buf, unsigned len) {
if (buf==NULL)
return;
unsigned long n;
while (len>0) {
if (context->curlen == 0 && len>=RMD160BufferSize) {
RMD160Transform(context, (unsigned char *)buf);
context->length += RMD160BufferSize * 8;
buf += RMD160BufferSize;
len -= RMD160BufferSize;
} else {
n = MIN(len, (RMD160BufferSize-context->curlen));
memcpy(context->buf+context->curlen, buf, (size_t)n);
context->curlen += n;
buf += n;
len -= n;
if (context->curlen == RMD160BufferSize) {
RMD160Transform(context, context->buf);
context->length += 8*RMD160BufferSize;
context->curlen = 0;
}
}
}
}
void RMD160Final(unsigned char digest[RMD160Length], struct RMD160Context *context) {
context->length += context->curlen * 8;
context->buf[context->curlen++] = (unsigned char)0x80;
if (context->curlen > 56) {
while (context->curlen < 64) {
context->buf[context->curlen++] = (unsigned char)0;
}
RMD160Transform(context, context->buf);
context->curlen = 0;
}
while (context->curlen < 56) {
context->buf[context->curlen++] = (unsigned char)0;
}
putu64l(context->length, context->buf+56);
RMD160Transform(context, context->buf);
for (int i=0; i<5; i++) {
putu32l(context->state[i], digest+(4*i));
}
memset(context, 0, sizeof(struct RMD160Context));
}
#define RMD160_S1 0
#define RMD160_S2 INT32(0x5a827999)
#define RMD160_S3 INT32(0x6ed9eba1)
#define RMD160_S4 INT32(0x8f1bbcdc)
#define RMD160_S5 INT32(0xa953fd4e)
#define RMD160_S10 0
#define RMD160_S9 INT32(0x7a6d76e9)
#define RMD160_S8 INT32(0x6d703ef3)
#define RMD160_S7 INT32(0x5c4dd124)
#define RMD160_S6 INT32(0x50a28be6)
#define RMD160_F1(x, y, z) ((x) ^ (y) ^ (z))
#define RMD160_F2(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define RMD160_F3(x, y, z) (((x) | ~(y)) ^ (z))
#define RMD160_F4(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define RMD160_F5(x, y, z) ((x) ^ ((y) | ~(z)))
#define RMD160STEP(a, b, c, d, e, f, g, h, i) \
(c) += a((d), (e), (f)) + (h) + b; (c) = ROL32((c), (i)) + (g); (e) = ROL32((e), 10);
void RMD160Transform(struct RMD160Context *context, unsigned char *buf) {
uint32_t x[16];
uint32_t a = context->state[0], aa = a;
uint32_t b = context->state[1], bb = b;
uint32_t c = context->state[2], cc = c;
uint32_t d = context->state[3], dd = d;
uint32_t e = context->state[4], ee = e;
for (int i=0; i<16; i++) {
x[i] = getu32l(buf+(4*i));
}
/* round 1 */
RMD160STEP(RMD160_F1, RMD160_S1, a, b, c, d, e, x[0], 11);
RMD160STEP(RMD160_F1, RMD160_S1, e, a, b, c, d, x[1], 14);
RMD160STEP(RMD160_F1, RMD160_S1, d, e, a, b, c, x[2], 15);
RMD160STEP(RMD160_F1, RMD160_S1, c, d, e, a, b, x[3], 12);
RMD160STEP(RMD160_F1, RMD160_S1, b, c, d, e, a, x[4], 5);
RMD160STEP(RMD160_F1, RMD160_S1, a, b, c, d, e, x[5], 8);
RMD160STEP(RMD160_F1, RMD160_S1, e, a, b, c, d, x[6], 7);
RMD160STEP(RMD160_F1, RMD160_S1, d, e, a, b, c, x[7], 9);
RMD160STEP(RMD160_F1, RMD160_S1, c, d, e, a, b, x[8], 11);
RMD160STEP(RMD160_F1, RMD160_S1, b, c, d, e, a, x[9], 13);
RMD160STEP(RMD160_F1, RMD160_S1, a, b, c, d, e, x[10], 14);
RMD160STEP(RMD160_F1, RMD160_S1, e, a, b, c, d, x[11], 15);
RMD160STEP(RMD160_F1, RMD160_S1, d, e, a, b, c, x[12], 6);
RMD160STEP(RMD160_F1, RMD160_S1, c, d, e, a, b, x[13], 7);
RMD160STEP(RMD160_F1, RMD160_S1, b, c, d, e, a, x[14], 9);
RMD160STEP(RMD160_F1, RMD160_S1, a, b, c, d, e, x[15], 8);
/* round 2 */
RMD160STEP(RMD160_F2, RMD160_S2, e, a, b, c, d, x[7], 7);
RMD160STEP(RMD160_F2, RMD160_S2, d, e, a, b, c, x[4], 6);
RMD160STEP(RMD160_F2, RMD160_S2, c, d, e, a, b, x[13], 8);
RMD160STEP(RMD160_F2, RMD160_S2, b, c, d, e, a, x[1], 13);
RMD160STEP(RMD160_F2, RMD160_S2, a, b, c, d, e, x[10], 11);
RMD160STEP(RMD160_F2, RMD160_S2, e, a, b, c, d, x[6], 9);
RMD160STEP(RMD160_F2, RMD160_S2, d, e, a, b, c, x[15], 7);
RMD160STEP(RMD160_F2, RMD160_S2, c, d, e, a, b, x[3], 15);
RMD160STEP(RMD160_F2, RMD160_S2, b, c, d, e, a, x[12], 7);
RMD160STEP(RMD160_F2, RMD160_S2, a, b, c, d, e, x[0], 12);
RMD160STEP(RMD160_F2, RMD160_S2, e, a, b, c, d, x[9], 15);
RMD160STEP(RMD160_F2, RMD160_S2, d, e, a, b, c, x[5], 9);
RMD160STEP(RMD160_F2, RMD160_S2, c, d, e, a, b, x[2], 11);
RMD160STEP(RMD160_F2, RMD160_S2, b, c, d, e, a, x[14], 7);
RMD160STEP(RMD160_F2, RMD160_S2, a, b, c, d, e, x[11], 13);
RMD160STEP(RMD160_F2, RMD160_S2, e, a, b, c, d, x[8], 12);
/* round 3 */
RMD160STEP(RMD160_F3, RMD160_S3, d, e, a, b, c, x[3], 11);
RMD160STEP(RMD160_F3, RMD160_S3, c, d, e, a, b, x[10], 13);
RMD160STEP(RMD160_F3, RMD160_S3, b, c, d, e, a, x[14], 6);
RMD160STEP(RMD160_F3, RMD160_S3, a, b, c, d, e, x[4], 7);
RMD160STEP(RMD160_F3, RMD160_S3, e, a, b, c, d, x[9], 14);
RMD160STEP(RMD160_F3, RMD160_S3, d, e, a, b, c, x[15], 9);
RMD160STEP(RMD160_F3, RMD160_S3, c, d, e, a, b, x[8], 13);
RMD160STEP(RMD160_F3, RMD160_S3, b, c, d, e, a, x[1], 15);
RMD160STEP(RMD160_F3, RMD160_S3, a, b, c, d, e, x[2], 14);
RMD160STEP(RMD160_F3, RMD160_S3, e, a, b, c, d, x[7], 8);
RMD160STEP(RMD160_F3, RMD160_S3, d, e, a, b, c, x[0], 13);
RMD160STEP(RMD160_F3, RMD160_S3, c, d, e, a, b, x[6], 6);
RMD160STEP(RMD160_F3, RMD160_S3, b, c, d, e, a, x[13], 5);
RMD160STEP(RMD160_F3, RMD160_S3, a, b, c, d, e, x[11], 12);
RMD160STEP(RMD160_F3, RMD160_S3, e, a, b, c, d, x[5], 7);
RMD160STEP(RMD160_F3, RMD160_S3, d, e, a, b, c, x[12], 5);
/* round 4 */
RMD160STEP(RMD160_F4, RMD160_S4, c, d, e, a, b, x[1], 11);
RMD160STEP(RMD160_F4, RMD160_S4, b, c, d, e, a, x[9], 12);
RMD160STEP(RMD160_F4, RMD160_S4, a, b, c, d, e, x[11], 14);
RMD160STEP(RMD160_F4, RMD160_S4, e, a, b, c, d, x[10], 15);
RMD160STEP(RMD160_F4, RMD160_S4, d, e, a, b, c, x[0], 14);
RMD160STEP(RMD160_F4, RMD160_S4, c, d, e, a, b, x[8], 15);
RMD160STEP(RMD160_F4, RMD160_S4, b, c, d, e, a, x[12], 9);
RMD160STEP(RMD160_F4, RMD160_S4, a, b, c, d, e, x[4], 8);
RMD160STEP(RMD160_F4, RMD160_S4, e, a, b, c, d, x[13], 9);
RMD160STEP(RMD160_F4, RMD160_S4, d, e, a, b, c, x[3], 14);
RMD160STEP(RMD160_F4, RMD160_S4, c, d, e, a, b, x[7], 5);
RMD160STEP(RMD160_F4, RMD160_S4, b, c, d, e, a, x[15], 6);
RMD160STEP(RMD160_F4, RMD160_S4, a, b, c, d, e, x[14], 8);
RMD160STEP(RMD160_F4, RMD160_S4, e, a, b, c, d, x[5], 6);
RMD160STEP(RMD160_F4, RMD160_S4, d, e, a, b, c, x[6], 5);
RMD160STEP(RMD160_F4, RMD160_S4, c, d, e, a, b, x[2], 12);
/* round 5 */
RMD160STEP(RMD160_F5, RMD160_S5, b, c, d, e, a, x[4], 9);
RMD160STEP(RMD160_F5, RMD160_S5, a, b, c, d, e, x[0], 15);
RMD160STEP(RMD160_F5, RMD160_S5, e, a, b, c, d, x[5], 5);
RMD160STEP(RMD160_F5, RMD160_S5, d, e, a, b, c, x[9], 11);
RMD160STEP(RMD160_F5, RMD160_S5, c, d, e, a, b, x[7], 6);
RMD160STEP(RMD160_F5, RMD160_S5, b, c, d, e, a, x[12], 8);
RMD160STEP(RMD160_F5, RMD160_S5, a, b, c, d, e, x[2], 13);
RMD160STEP(RMD160_F5, RMD160_S5, e, a, b, c, d, x[10], 12);
RMD160STEP(RMD160_F5, RMD160_S5, d, e, a, b, c, x[14], 5);
RMD160STEP(RMD160_F5, RMD160_S5, c, d, e, a, b, x[1], 12);
RMD160STEP(RMD160_F5, RMD160_S5, b, c, d, e, a, x[3], 13);
RMD160STEP(RMD160_F5, RMD160_S5, a, b, c, d, e, x[8], 14);
RMD160STEP(RMD160_F5, RMD160_S5, e, a, b, c, d, x[11], 11);
RMD160STEP(RMD160_F5, RMD160_S5, d, e, a, b, c, x[6], 8);
RMD160STEP(RMD160_F5, RMD160_S5, c, d, e, a, b, x[15], 5);
RMD160STEP(RMD160_F5, RMD160_S5, b, c, d, e, a, x[13], 6);
/* parallel round 1 */
RMD160STEP(RMD160_F5, RMD160_S6, aa, bb, cc, dd, ee, x[5], 8);
RMD160STEP(RMD160_F5, RMD160_S6, ee, aa, bb, cc, dd, x[14], 9);
RMD160STEP(RMD160_F5, RMD160_S6, dd, ee, aa, bb, cc, x[7], 9);
RMD160STEP(RMD160_F5, RMD160_S6, cc, dd, ee, aa, bb, x[0], 11);
RMD160STEP(RMD160_F5, RMD160_S6, bb, cc, dd, ee, aa, x[9], 13);
RMD160STEP(RMD160_F5, RMD160_S6, aa, bb, cc, dd, ee, x[2], 15);
RMD160STEP(RMD160_F5, RMD160_S6, ee, aa, bb, cc, dd, x[11], 15);
RMD160STEP(RMD160_F5, RMD160_S6, dd, ee, aa, bb, cc, x[4], 5);
RMD160STEP(RMD160_F5, RMD160_S6, cc, dd, ee, aa, bb, x[13], 7);
RMD160STEP(RMD160_F5, RMD160_S6, bb, cc, dd, ee, aa, x[6], 7);
RMD160STEP(RMD160_F5, RMD160_S6, aa, bb, cc, dd, ee, x[15], 8);
RMD160STEP(RMD160_F5, RMD160_S6, ee, aa, bb, cc, dd, x[8], 11);
RMD160STEP(RMD160_F5, RMD160_S6, dd, ee, aa, bb, cc, x[1], 14);
RMD160STEP(RMD160_F5, RMD160_S6, cc, dd, ee, aa, bb, x[10], 14);
RMD160STEP(RMD160_F5, RMD160_S6, bb, cc, dd, ee, aa, x[3], 12);
RMD160STEP(RMD160_F5, RMD160_S6, aa, bb, cc, dd, ee, x[12], 6);
/* parallel round 2 */
RMD160STEP(RMD160_F4, RMD160_S7, ee, aa, bb, cc, dd, x[6], 9);
RMD160STEP(RMD160_F4, RMD160_S7, dd, ee, aa, bb, cc, x[11], 13);
RMD160STEP(RMD160_F4, RMD160_S7, cc, dd, ee, aa, bb, x[3], 15);
RMD160STEP(RMD160_F4, RMD160_S7, bb, cc, dd, ee, aa, x[7], 7);
RMD160STEP(RMD160_F4, RMD160_S7, aa, bb, cc, dd, ee, x[0], 12);
RMD160STEP(RMD160_F4, RMD160_S7, ee, aa, bb, cc, dd, x[13], 8);
RMD160STEP(RMD160_F4, RMD160_S7, dd, ee, aa, bb, cc, x[5], 9);
RMD160STEP(RMD160_F4, RMD160_S7, cc, dd, ee, aa, bb, x[10], 11);
RMD160STEP(RMD160_F4, RMD160_S7, bb, cc, dd, ee, aa, x[14], 7);
RMD160STEP(RMD160_F4, RMD160_S7, aa, bb, cc, dd, ee, x[15], 7);
RMD160STEP(RMD160_F4, RMD160_S7, ee, aa, bb, cc, dd, x[8], 12);
RMD160STEP(RMD160_F4, RMD160_S7, dd, ee, aa, bb, cc, x[12], 7);
RMD160STEP(RMD160_F4, RMD160_S7, cc, dd, ee, aa, bb, x[4], 6);
RMD160STEP(RMD160_F4, RMD160_S7, bb, cc, dd, ee, aa, x[9], 15);
RMD160STEP(RMD160_F4, RMD160_S7, aa, bb, cc, dd, ee, x[1], 13);
RMD160STEP(RMD160_F4, RMD160_S7, ee, aa, bb, cc, dd, x[2], 11);
/* parallel round 3 */
RMD160STEP(RMD160_F3, RMD160_S8, dd, ee, aa, bb, cc, x[15], 9);
RMD160STEP(RMD160_F3, RMD160_S8, cc, dd, ee, aa, bb, x[5], 7);
RMD160STEP(RMD160_F3, RMD160_S8, bb, cc, dd, ee, aa, x[1], 15);
RMD160STEP(RMD160_F3, RMD160_S8, aa, bb, cc, dd, ee, x[3], 11);
RMD160STEP(RMD160_F3, RMD160_S8, ee, aa, bb, cc, dd, x[7], 8);
RMD160STEP(RMD160_F3, RMD160_S8, dd, ee, aa, bb, cc, x[14], 6);
RMD160STEP(RMD160_F3, RMD160_S8, cc, dd, ee, aa, bb, x[6], 6);
RMD160STEP(RMD160_F3, RMD160_S8, bb, cc, dd, ee, aa, x[9], 14);
RMD160STEP(RMD160_F3, RMD160_S8, aa, bb, cc, dd, ee, x[11], 12);
RMD160STEP(RMD160_F3, RMD160_S8, ee, aa, bb, cc, dd, x[8], 13);
RMD160STEP(RMD160_F3, RMD160_S8, dd, ee, aa, bb, cc, x[12], 5);
RMD160STEP(RMD160_F3, RMD160_S8, cc, dd, ee, aa, bb, x[2], 14);
RMD160STEP(RMD160_F3, RMD160_S8, bb, cc, dd, ee, aa, x[10], 13);
RMD160STEP(RMD160_F3, RMD160_S8, aa, bb, cc, dd, ee, x[0], 13);
RMD160STEP(RMD160_F3, RMD160_S8, ee, aa, bb, cc, dd, x[4], 7);
RMD160STEP(RMD160_F3, RMD160_S8, dd, ee, aa, bb, cc, x[13], 5);
/* parallel round 4 */
RMD160STEP(RMD160_F2, RMD160_S9, cc, dd, ee, aa, bb, x[8], 15);
RMD160STEP(RMD160_F2, RMD160_S9, bb, cc, dd, ee, aa, x[6], 5);
RMD160STEP(RMD160_F2, RMD160_S9, aa, bb, cc, dd, ee, x[4], 8);
RMD160STEP(RMD160_F2, RMD160_S9, ee, aa, bb, cc, dd, x[1], 11);
RMD160STEP(RMD160_F2, RMD160_S9, dd, ee, aa, bb, cc, x[3], 14);
RMD160STEP(RMD160_F2, RMD160_S9, cc, dd, ee, aa, bb, x[11], 14);
RMD160STEP(RMD160_F2, RMD160_S9, bb, cc, dd, ee, aa, x[15], 6);
RMD160STEP(RMD160_F2, RMD160_S9, aa, bb, cc, dd, ee, x[0], 14);
RMD160STEP(RMD160_F2, RMD160_S9, ee, aa, bb, cc, dd, x[5], 6);
RMD160STEP(RMD160_F2, RMD160_S9, dd, ee, aa, bb, cc, x[12], 9);
RMD160STEP(RMD160_F2, RMD160_S9, cc, dd, ee, aa, bb, x[2], 12);
RMD160STEP(RMD160_F2, RMD160_S9, bb, cc, dd, ee, aa, x[13], 9);
RMD160STEP(RMD160_F2, RMD160_S9, aa, bb, cc, dd, ee, x[9], 12);
RMD160STEP(RMD160_F2, RMD160_S9, ee, aa, bb, cc, dd, x[7], 5);
RMD160STEP(RMD160_F2, RMD160_S9, dd, ee, aa, bb, cc, x[10], 15);
RMD160STEP(RMD160_F2, RMD160_S9, cc, dd, ee, aa, bb, x[14], 8);
/* parallel round 5 */
RMD160STEP(RMD160_F1, RMD160_S10, bb, cc, dd, ee, aa, x[12], 8);
RMD160STEP(RMD160_F1, RMD160_S10, aa, bb, cc, dd, ee, x[15], 5);
RMD160STEP(RMD160_F1, RMD160_S10, ee, aa, bb, cc, dd, x[10], 12);
RMD160STEP(RMD160_F1, RMD160_S10, dd, ee, aa, bb, cc, x[4], 9);
RMD160STEP(RMD160_F1, RMD160_S10, cc, dd, ee, aa, bb, x[1], 12);
RMD160STEP(RMD160_F1, RMD160_S10, bb, cc, dd, ee, aa, x[5], 5);
RMD160STEP(RMD160_F1, RMD160_S10, aa, bb, cc, dd, ee, x[8], 14);
RMD160STEP(RMD160_F1, RMD160_S10, ee, aa, bb, cc, dd, x[7], 6);
RMD160STEP(RMD160_F1, RMD160_S10, dd, ee, aa, bb, cc, x[6], 8);
RMD160STEP(RMD160_F1, RMD160_S10, cc, dd, ee, aa, bb, x[2], 13);
RMD160STEP(RMD160_F1, RMD160_S10, bb, cc, dd, ee, aa, x[13], 6);
RMD160STEP(RMD160_F1, RMD160_S10, aa, bb, cc, dd, ee, x[14], 5);
RMD160STEP(RMD160_F1, RMD160_S10, ee, aa, bb, cc, dd, x[0], 15);
RMD160STEP(RMD160_F1, RMD160_S10, dd, ee, aa, bb, cc, x[3], 13);
RMD160STEP(RMD160_F1, RMD160_S10, cc, dd, ee, aa, bb, x[9], 11);
RMD160STEP(RMD160_F1, RMD160_S10, bb, cc, dd, ee, aa, x[11], 11);
dd += c + context->state[1];
context->state[1] = context->state[2] + d + ee;
context->state[2] = context->state[3] + e + aa;
context->state[3] = context->state[4] + a + bb;
context->state[4] = context->state[0] + b + cc;
context->state[0] = dd;
}
int RMD160Test() {
static const struct {
char *msg;
unsigned char hash[RMD160Length];
} tests[] = {
{
"",
{0x9c,0x11,0x85,0xa5,0xc5,0xe9,0xfc,0x54,0x61,0x28,0x08,0x97,0x7e,0xe8,0xf5,0x48,0xb2,0x25,0x8d,0x31}
},
{
"a",
{0x0b,0xdc,0x9d,0x2d,0x25,0x6b,0x3e,0xe9,0xda,0xae,0x34,0x7b,0xe6,0xf4,0xdc,0x83,0x5a,0x46,0x7f,0xfe}
},
{
"abc",
{0x8e,0xb2,0x08,0xf7,0xe0,0x5d,0x98,0x7a,0x9b,0x04,0x4a,0x8e,0x98,0xc6,0xb0,0x87,0xf1,0x5a,0x0b,0xfc}
},
{
"message digest",
{0x5d,0x06,0x89,0xef,0x49,0xd2,0xfa,0xe5,0x72,0xb8,0x81,0xb1,0x23,0xa8,0x5f,0xfa,0x21,0x59,0x5f,0x36}
},
{
"abcdefghijklmnopqrstuvwxyz",
{0xf7,0x1c,0x27,0x10,0x9c,0x69,0x2c,0x1b,0x56,0xbb,0xdc,0xeb,0x5b,0x9d,0x28,0x65,0xb3,0x70,0x8d,0xbc}
},
{
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{0x12,0xa0,0x53,0x38,0x4a,0x9c,0x0c,0x88,0xe4,0x05,0xa0,0x6c,0x27,0xdc,0xf4,0x9a,0xda,0x62,0xeb,0x2b}
},
{NULL, {0}}
};
struct RMD160Context MDContext;
unsigned char MDDigest[RMD160Length];
for (int i=0; tests[i].msg!=NULL; i++) {
RMD160Init(&MDContext);
RMD160Update(&MDContext, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
RMD160Final(MDDigest, &MDContext);
if (memcmp(MDDigest, tests[i].hash, RMD160Length))
return 0;
}
return 1;
}

51
Classes/MD/MGMRMD256.h Normal file
View File

@ -0,0 +1,51 @@
//
// MGMRMD256.h
//
// Created by Mr. Gecko <GRMrGecko@gmail.com> on 5/31/11.
// No Copyright Claimed. Public Domain.
//
#ifndef _MD_RMD256
#define _MD_RMD256
#ifdef __NEXT_RUNTIME__
#import <Foundation/Foundation.h>
extern NSString * const MDNRMD256;
@interface NSString (MGMRMD256)
- (NSString *)RMD256;
- (NSString *)pathRMD256;
@end
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern const struct MGMHashDescription RMD256Desc;
char *RMD256String(const char *string, int length);
char *RMD256File(const char *path);
#define RMD256Length 32
#define RMD256BufferSize 64
struct RMD256Context {
uint64_t length;
unsigned char buf[RMD256BufferSize];
uint32_t curlen, state[8];
};
void RMD256Init(struct RMD256Context *context);
void RMD256Update(struct RMD256Context *context, const unsigned char *buf, unsigned len);
void RMD256Final(unsigned char digest[RMD256Length], struct RMD256Context *context);
void RMD256Transform(struct RMD256Context *context, unsigned char *buf);
int RMD256Test();
#ifdef __cplusplus
}
#endif
#endif

439
Classes/MD/MGMRMD256.m Normal file
View File

@ -0,0 +1,439 @@
//
// MGMRMD256.m
//
// Created by Mr. Gecko <GRMrGecko@gmail.com> on 5/31/11.
// No Copyright Claimed. Public Domain.
// C Algorithm created by Tom St Denis <tomstdenis@gmail.com> <http://libtom.org>
//
#ifdef __NEXT_RUNTIME__
#import "MGMRMD256.h"
#import "MGMTypes.h"
NSString * const MDNRMD256 = @"rmd256";
@implementation NSString (MGMRMD256)
- (NSString *)RMD256 {
NSData *MDData = [self dataUsingEncoding:NSUTF8StringEncoding];
struct RMD256Context MDContext;
unsigned char MDDigest[RMD256Length];
RMD256Init(&MDContext);
RMD256Update(&MDContext, [MDData bytes], [MDData length]);
RMD256Final(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(RMD256Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<RMD256Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
NSString *hash = [NSString stringWithUTF8String:stringBuffer];
free(stringBuffer);
return hash;
}
- (NSString *)pathRMD256 {
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:self];
if (file==nil)
return nil;
struct RMD256Context MDContext;
unsigned char MDDigest[RMD256Length];
RMD256Init(&MDContext);
int length;
do {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSData *MDData = [file readDataOfLength:MDFileReadLength];
length = [MDData length];
RMD256Update(&MDContext, [MDData bytes], length);
[pool release];
} while (length>0);
RMD256Final(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(RMD256Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<RMD256Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
NSString *hash = [NSString stringWithUTF8String:stringBuffer];
free(stringBuffer);
return hash;
}
@end
#else
#include <stdio.h>
#include <string.h>
#include "MGMRMD256.h"
#include "MGMTypes.h"
#endif
const struct MGMHashDescription RMD256Desc = {
"rmd256",
sizeof(struct RMD256Context),
(void(*)(void *))&RMD256Init,
(void(*)(void *, const unsigned char *, unsigned))&RMD256Update,
(void(*)(unsigned char *, void *))&RMD256Final,
RMD256Length
};
char *RMD256String(const char *string, int length) {
struct RMD256Context MDContext;
unsigned char MDDigest[RMD256Length];
RMD256Init(&MDContext);
RMD256Update(&MDContext, (const unsigned char *)string, length);
RMD256Final(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(RMD256Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<RMD256Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
return stringBuffer;
}
char *RMD256File(const char *path) {
FILE *file = fopen(path, "r");
if (file==NULL)
return NULL;
struct RMD256Context MDContext;
unsigned char MDDigest[RMD256Length];
RMD256Init(&MDContext);
int length;
do {
unsigned char MDData[MDFileReadLength];
length = fread(&MDData, 1, MDFileReadLength, file);
RMD256Update(&MDContext, MDData, length);
} while (length>0);
RMD256Final(MDDigest, &MDContext);
fclose(file);
char *stringBuffer = (char *)malloc(RMD256Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<RMD256Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
return stringBuffer;
}
void RMD256Init(struct RMD256Context *context) {
context->state[0] = INT32(0x67452301);
context->state[1] = INT32(0xefcdab89);
context->state[2] = INT32(0x98badcfe);
context->state[3] = INT32(0x10325476);
context->state[4] = INT32(0x76543210);
context->state[5] = INT32(0xfedcba98);
context->state[6] = INT32(0x89abcdef);
context->state[7] = INT32(0x01234567);
context->curlen = 0;
context->length = 0;
}
void RMD256Update(struct RMD256Context *context, const unsigned char *buf, unsigned len) {
if (buf==NULL)
return;
unsigned long n;
while (len>0) {
if (context->curlen == 0 && len>=RMD256BufferSize) {
RMD256Transform(context, (unsigned char *)buf);
context->length += RMD256BufferSize * 8;
buf += RMD256BufferSize;
len -= RMD256BufferSize;
} else {
n = MIN(len, (RMD256BufferSize-context->curlen));
memcpy(context->buf+context->curlen, buf, (size_t)n);
context->curlen += n;
buf += n;
len -= n;
if (context->curlen == RMD256BufferSize) {
RMD256Transform(context, context->buf);
context->length += 8*RMD256BufferSize;
context->curlen = 0;
}
}
}
}
void RMD256Final(unsigned char digest[RMD256Length], struct RMD256Context *context) {
context->length += context->curlen * 8;
context->buf[context->curlen++] = (unsigned char)0x80;
if (context->curlen > 56) {
while (context->curlen < 64) {
context->buf[context->curlen++] = (unsigned char)0;
}
RMD256Transform(context, context->buf);
context->curlen = 0;
}
while (context->curlen < 56) {
context->buf[context->curlen++] = (unsigned char)0;
}
putu64l(context->length, context->buf+56);
RMD256Transform(context, context->buf);
for (int i=0; i<8; i++) {
putu32l(context->state[i], digest+(4*i));
}
memset(context, 0, sizeof(struct RMD256Context));
}
#define RMD256_S1 0
#define RMD256_S2 INT32(0x5a827999)
#define RMD256_S3 INT32(0x6ed9eba1)
#define RMD256_S4 INT32(0x8f1bbcdc)
#define RMD256_S8 0
#define RMD256_S7 INT32(0x6d703ef3)
#define RMD256_S6 INT32(0x5c4dd124)
#define RMD256_S5 INT32(0x50a28be6)
#define RMD256_F1(x, y, z) ((x) ^ (y) ^ (z))
#define RMD256_F2(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define RMD256_F3(x, y, z) (((x) | ~(y)) ^ (z))
#define RMD256_F4(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define RMD256STEP(a, b, c, d, e, f, g, h) \
(c) += a((d), (e), (f)) + (g) + b; (c) = ROL32((c), (h));
void RMD256Transform(struct RMD256Context *context, unsigned char *buf) {
uint32_t x[16], tmp;
uint32_t a = context->state[0];
uint32_t b = context->state[1];
uint32_t c = context->state[2];
uint32_t d = context->state[3];
uint32_t aa = context->state[4];
uint32_t bb = context->state[5];
uint32_t cc = context->state[6];
uint32_t dd = context->state[7];
for (int i=0; i<16; i++) {
x[i] = getu32l(buf+(4*i));
}
/* round 1 */
RMD256STEP(RMD256_F1, RMD256_S1, a, b, c, d, x[0], 11);
RMD256STEP(RMD256_F1, RMD256_S1, d, a, b, c, x[1], 14);
RMD256STEP(RMD256_F1, RMD256_S1, c, d, a, b, x[2], 15);
RMD256STEP(RMD256_F1, RMD256_S1, b, c, d, a, x[3], 12);
RMD256STEP(RMD256_F1, RMD256_S1, a, b, c, d, x[4], 5);
RMD256STEP(RMD256_F1, RMD256_S1, d, a, b, c, x[5], 8);
RMD256STEP(RMD256_F1, RMD256_S1, c, d, a, b, x[6], 7);
RMD256STEP(RMD256_F1, RMD256_S1, b, c, d, a, x[7], 9);
RMD256STEP(RMD256_F1, RMD256_S1, a, b, c, d, x[8], 11);
RMD256STEP(RMD256_F1, RMD256_S1, d, a, b, c, x[9], 13);
RMD256STEP(RMD256_F1, RMD256_S1, c, d, a, b, x[10], 14);
RMD256STEP(RMD256_F1, RMD256_S1, b, c, d, a, x[11], 15);
RMD256STEP(RMD256_F1, RMD256_S1, a, b, c, d, x[12], 6);
RMD256STEP(RMD256_F1, RMD256_S1, d, a, b, c, x[13], 7);
RMD256STEP(RMD256_F1, RMD256_S1, c, d, a, b, x[14], 9);
RMD256STEP(RMD256_F1, RMD256_S1, b, c, d, a, x[15], 8);
/* parallel round 1 */
RMD256STEP(RMD256_F4, RMD256_S5, aa, bb, cc, dd, x[5], 8);
RMD256STEP(RMD256_F4, RMD256_S5, dd, aa, bb, cc, x[14], 9);
RMD256STEP(RMD256_F4, RMD256_S5, cc, dd, aa, bb, x[7], 9);
RMD256STEP(RMD256_F4, RMD256_S5, bb, cc, dd, aa, x[0], 11);
RMD256STEP(RMD256_F4, RMD256_S5, aa, bb, cc, dd, x[9], 13);
RMD256STEP(RMD256_F4, RMD256_S5, dd, aa, bb, cc, x[2], 15);
RMD256STEP(RMD256_F4, RMD256_S5, cc, dd, aa, bb, x[11], 15);
RMD256STEP(RMD256_F4, RMD256_S5, bb, cc, dd, aa, x[4], 5);
RMD256STEP(RMD256_F4, RMD256_S5, aa, bb, cc, dd, x[13], 7);
RMD256STEP(RMD256_F4, RMD256_S5, dd, aa, bb, cc, x[6], 7);
RMD256STEP(RMD256_F4, RMD256_S5, cc, dd, aa, bb, x[15], 8);
RMD256STEP(RMD256_F4, RMD256_S5, bb, cc, dd, aa, x[8], 11);
RMD256STEP(RMD256_F4, RMD256_S5, aa, bb, cc, dd, x[1], 14);
RMD256STEP(RMD256_F4, RMD256_S5, dd, aa, bb, cc, x[10], 14);
RMD256STEP(RMD256_F4, RMD256_S5, cc, dd, aa, bb, x[3], 12);
RMD256STEP(RMD256_F4, RMD256_S5, bb, cc, dd, aa, x[12], 6);
tmp = a; a = aa; aa = tmp;
/* round 2 */
RMD256STEP(RMD256_F2, RMD256_S2, a, b, c, d, x[7], 7);
RMD256STEP(RMD256_F2, RMD256_S2, d, a, b, c, x[4], 6);
RMD256STEP(RMD256_F2, RMD256_S2, c, d, a, b, x[13], 8);
RMD256STEP(RMD256_F2, RMD256_S2, b, c, d, a, x[1], 13);
RMD256STEP(RMD256_F2, RMD256_S2, a, b, c, d, x[10], 11);
RMD256STEP(RMD256_F2, RMD256_S2, d, a, b, c, x[6], 9);
RMD256STEP(RMD256_F2, RMD256_S2, c, d, a, b, x[15], 7);
RMD256STEP(RMD256_F2, RMD256_S2, b, c, d, a, x[3], 15);
RMD256STEP(RMD256_F2, RMD256_S2, a, b, c, d, x[12], 7);
RMD256STEP(RMD256_F2, RMD256_S2, d, a, b, c, x[0], 12);
RMD256STEP(RMD256_F2, RMD256_S2, c, d, a, b, x[9], 15);
RMD256STEP(RMD256_F2, RMD256_S2, b, c, d, a, x[5], 9);
RMD256STEP(RMD256_F2, RMD256_S2, a, b, c, d, x[2], 11);
RMD256STEP(RMD256_F2, RMD256_S2, d, a, b, c, x[14], 7);
RMD256STEP(RMD256_F2, RMD256_S2, c, d, a, b, x[11], 13);
RMD256STEP(RMD256_F2, RMD256_S2, b, c, d, a, x[8], 12);
/* parallel round 2 */
RMD256STEP(RMD256_F3, RMD256_S6, aa, bb, cc, dd, x[6], 9);
RMD256STEP(RMD256_F3, RMD256_S6, dd, aa, bb, cc, x[11], 13);
RMD256STEP(RMD256_F3, RMD256_S6, cc, dd, aa, bb, x[3], 15);
RMD256STEP(RMD256_F3, RMD256_S6, bb, cc, dd, aa, x[7], 7);
RMD256STEP(RMD256_F3, RMD256_S6, aa, bb, cc, dd, x[0], 12);
RMD256STEP(RMD256_F3, RMD256_S6, dd, aa, bb, cc, x[13], 8);
RMD256STEP(RMD256_F3, RMD256_S6, cc, dd, aa, bb, x[5], 9);
RMD256STEP(RMD256_F3, RMD256_S6, bb, cc, dd, aa, x[10], 11);
RMD256STEP(RMD256_F3, RMD256_S6, aa, bb, cc, dd, x[14], 7);
RMD256STEP(RMD256_F3, RMD256_S6, dd, aa, bb, cc, x[15], 7);
RMD256STEP(RMD256_F3, RMD256_S6, cc, dd, aa, bb, x[8], 12);
RMD256STEP(RMD256_F3, RMD256_S6, bb, cc, dd, aa, x[12], 7);
RMD256STEP(RMD256_F3, RMD256_S6, aa, bb, cc, dd, x[4], 6);
RMD256STEP(RMD256_F3, RMD256_S6, dd, aa, bb, cc, x[9], 15);
RMD256STEP(RMD256_F3, RMD256_S6, cc, dd, aa, bb, x[1], 13);
RMD256STEP(RMD256_F3, RMD256_S6, bb, cc, dd, aa, x[2], 11);
tmp = b; b = bb; bb = tmp;
/* round 3 */
RMD256STEP(RMD256_F3, RMD256_S3, a, b, c, d, x[3], 11);
RMD256STEP(RMD256_F3, RMD256_S3, d, a, b, c, x[10], 13);
RMD256STEP(RMD256_F3, RMD256_S3, c, d, a, b, x[14], 6);
RMD256STEP(RMD256_F3, RMD256_S3, b, c, d, a, x[4], 7);
RMD256STEP(RMD256_F3, RMD256_S3, a, b, c, d, x[9], 14);
RMD256STEP(RMD256_F3, RMD256_S3, d, a, b, c, x[15], 9);
RMD256STEP(RMD256_F3, RMD256_S3, c, d, a, b, x[8], 13);
RMD256STEP(RMD256_F3, RMD256_S3, b, c, d, a, x[1], 15);
RMD256STEP(RMD256_F3, RMD256_S3, a, b, c, d, x[2], 14);
RMD256STEP(RMD256_F3, RMD256_S3, d, a, b, c, x[7], 8);
RMD256STEP(RMD256_F3, RMD256_S3, c, d, a, b, x[0], 13);
RMD256STEP(RMD256_F3, RMD256_S3, b, c, d, a, x[6], 6);
RMD256STEP(RMD256_F3, RMD256_S3, a, b, c, d, x[13], 5);
RMD256STEP(RMD256_F3, RMD256_S3, d, a, b, c, x[11], 12);
RMD256STEP(RMD256_F3, RMD256_S3, c, d, a, b, x[5], 7);
RMD256STEP(RMD256_F3, RMD256_S3, b, c, d, a, x[12], 5);
/* parallel round 3 */
RMD256STEP(RMD256_F2, RMD256_S7, aa, bb, cc, dd, x[15], 9);
RMD256STEP(RMD256_F2, RMD256_S7, dd, aa, bb, cc, x[5], 7);
RMD256STEP(RMD256_F2, RMD256_S7, cc, dd, aa, bb, x[1], 15);
RMD256STEP(RMD256_F2, RMD256_S7, bb, cc, dd, aa, x[3], 11);
RMD256STEP(RMD256_F2, RMD256_S7, aa, bb, cc, dd, x[7], 8);
RMD256STEP(RMD256_F2, RMD256_S7, dd, aa, bb, cc, x[14], 6);
RMD256STEP(RMD256_F2, RMD256_S7, cc, dd, aa, bb, x[6], 6);
RMD256STEP(RMD256_F2, RMD256_S7, bb, cc, dd, aa, x[9], 14);
RMD256STEP(RMD256_F2, RMD256_S7, aa, bb, cc, dd, x[11], 12);
RMD256STEP(RMD256_F2, RMD256_S7, dd, aa, bb, cc, x[8], 13);
RMD256STEP(RMD256_F2, RMD256_S7, cc, dd, aa, bb, x[12], 5);
RMD256STEP(RMD256_F2, RMD256_S7, bb, cc, dd, aa, x[2], 14);
RMD256STEP(RMD256_F2, RMD256_S7, aa, bb, cc, dd, x[10], 13);
RMD256STEP(RMD256_F2, RMD256_S7, dd, aa, bb, cc, x[0], 13);
RMD256STEP(RMD256_F2, RMD256_S7, cc, dd, aa, bb, x[4], 7);
RMD256STEP(RMD256_F2, RMD256_S7, bb, cc, dd, aa, x[13], 5);
tmp = c; c = cc; cc = tmp;
/* round 4 */
RMD256STEP(RMD256_F4, RMD256_S4, a, b, c, d, x[1], 11);
RMD256STEP(RMD256_F4, RMD256_S4, d, a, b, c, x[9], 12);
RMD256STEP(RMD256_F4, RMD256_S4, c, d, a, b, x[11], 14);
RMD256STEP(RMD256_F4, RMD256_S4, b, c, d, a, x[10], 15);
RMD256STEP(RMD256_F4, RMD256_S4, a, b, c, d, x[0], 14);
RMD256STEP(RMD256_F4, RMD256_S4, d, a, b, c, x[8], 15);
RMD256STEP(RMD256_F4, RMD256_S4, c, d, a, b, x[12], 9);
RMD256STEP(RMD256_F4, RMD256_S4, b, c, d, a, x[4], 8);
RMD256STEP(RMD256_F4, RMD256_S4, a, b, c, d, x[13], 9);
RMD256STEP(RMD256_F4, RMD256_S4, d, a, b, c, x[3], 14);
RMD256STEP(RMD256_F4, RMD256_S4, c, d, a, b, x[7], 5);
RMD256STEP(RMD256_F4, RMD256_S4, b, c, d, a, x[15], 6);
RMD256STEP(RMD256_F4, RMD256_S4, a, b, c, d, x[14], 8);
RMD256STEP(RMD256_F4, RMD256_S4, d, a, b, c, x[5], 6);
RMD256STEP(RMD256_F4, RMD256_S4, c, d, a, b, x[6], 5);
RMD256STEP(RMD256_F4, RMD256_S4, b, c, d, a, x[2], 12);
/* parallel round 4 */
RMD256STEP(RMD256_F1, RMD256_S8, aa, bb, cc, dd, x[8], 15);
RMD256STEP(RMD256_F1, RMD256_S8, dd, aa, bb, cc, x[6], 5);
RMD256STEP(RMD256_F1, RMD256_S8, cc, dd, aa, bb, x[4], 8);
RMD256STEP(RMD256_F1, RMD256_S8, bb, cc, dd, aa, x[1], 11);
RMD256STEP(RMD256_F1, RMD256_S8, aa, bb, cc, dd, x[3], 14);
RMD256STEP(RMD256_F1, RMD256_S8, dd, aa, bb, cc, x[11], 14);
RMD256STEP(RMD256_F1, RMD256_S8, cc, dd, aa, bb, x[15], 6);
RMD256STEP(RMD256_F1, RMD256_S8, bb, cc, dd, aa, x[0], 14);
RMD256STEP(RMD256_F1, RMD256_S8, aa, bb, cc, dd, x[5], 6);
RMD256STEP(RMD256_F1, RMD256_S8, dd, aa, bb, cc, x[12], 9);
RMD256STEP(RMD256_F1, RMD256_S8, cc, dd, aa, bb, x[2], 12);
RMD256STEP(RMD256_F1, RMD256_S8, bb, cc, dd, aa, x[13], 9);
RMD256STEP(RMD256_F1, RMD256_S8, aa, bb, cc, dd, x[9], 12);
RMD256STEP(RMD256_F1, RMD256_S8, dd, aa, bb, cc, x[7], 5);
RMD256STEP(RMD256_F1, RMD256_S8, cc, dd, aa, bb, x[10], 15);
RMD256STEP(RMD256_F1, RMD256_S8, bb, cc, dd, aa, x[14], 8);
tmp = d; d = dd; dd = tmp;
/* combine results */
context->state[0] += a;
context->state[1] += b;
context->state[2] += c;
context->state[3] += d;
context->state[4] += aa;
context->state[5] += bb;
context->state[6] += cc;
context->state[7] += dd;
}
int RMD256Test() {
static const struct {
char *msg;
unsigned char hash[RMD256Length];
} tests[] = {
{
"",
{0x02,0xba,0x4c,0x4e,0x5f,0x8e,0xcd,0x18,0x77,0xfc,0x52,0xd6,0x4d,0x30,0xe3,0x7a,0x2d,0x97,0x74,0xfb,0x1e,0x5d,0x02,0x63,0x80,0xae,0x01,0x68,0xe3,0xc5,0x52,0x2d}
},
{
"a",
{0xf9,0x33,0x3e,0x45,0xd8,0x57,0xf5,0xd9,0x0a,0x91,0xba,0xb7,0x0a,0x1e,0xba,0x0c,0xfb,0x1b,0xe4,0xb0,0x78,0x3c,0x9a,0xcf,0xcd,0x88,0x3a,0x91,0x34,0x69,0x29,0x25}
},
{
"abc",
{0xaf,0xbd,0x6e,0x22,0x8b,0x9d,0x8c,0xbb,0xce,0xf5,0xca,0x2d,0x03,0xe6,0xdb,0xa1,0x0a,0xc0,0xbc,0x7d,0xcb,0xe4,0x68,0x0e,0x1e,0x42,0xd2,0xe9,0x75,0x45,0x9b,0x65}
},
{
"message digest",
{0x87,0xe9,0x71,0x75,0x9a,0x1c,0xe4,0x7a,0x51,0x4d,0x5c,0x91,0x4c,0x39,0x2c,0x90,0x18,0xc7,0xc4,0x6b,0xc1,0x44,0x65,0x55,0x4a,0xfc,0xdf,0x54,0xa5,0x07,0x0c,0x0e}
},
{
"abcdefghijklmnopqrstuvwxyz",
{0x64,0x9d,0x30,0x34,0x75,0x1e,0xa2,0x16,0x77,0x6b,0xf9,0xa1,0x8a,0xcc,0x81,0xbc,0x78,0x96,0x11,0x8a,0x51,0x97,0x96,0x87,0x82,0xdd,0x1f,0xd9,0x7d,0x8d,0x51,0x33}
},
{
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
{0x57,0x40,0xa4,0x08,0xac,0x16,0xb7,0x20,0xb8,0x44,0x24,0xae,0x93,0x1c,0xbb,0x1f,0xe3,0x63,0xd1,0xd0,0xbf,0x40,0x17,0xf1,0xa8,0x9f,0x7e,0xa6,0xde,0x77,0xa0,0xb8}
},
{NULL, {0}}
};
struct RMD256Context MDContext;
unsigned char MDDigest[RMD256Length];
for (int i=0; tests[i].msg!=NULL; i++) {
RMD256Init(&MDContext);
RMD256Update(&MDContext, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
RMD256Final(MDDigest, &MDContext);
if (memcmp(MDDigest, tests[i].hash, RMD256Length))
return 0;
}
return 1;
}

51
Classes/MD/MGMRMD320.h Normal file
View File

@ -0,0 +1,51 @@
//
// MGMRMD320.h
//
// Created by Mr. Gecko <GRMrGecko@gmail.com> on 5/31/11.
// No Copyright Claimed. Public Domain.
//
#ifndef _MD_RMD320
#define _MD_RMD320
#ifdef __NEXT_RUNTIME__
#import <Foundation/Foundation.h>
extern NSString * const MDNRMD320;
@interface NSString (MGMRMD320)
- (NSString *)RMD320;
- (NSString *)pathRMD320;
@end
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern const struct MGMHashDescription RMD320Desc;
char *RMD320String(const char *string, int length);
char *RMD320File(const char *path);
#define RMD320Length 40
#define RMD320BufferSize 64
struct RMD320Context {
uint64_t length;
unsigned char buf[RMD320BufferSize];
uint32_t curlen, state[10];
};
void RMD320Init(struct RMD320Context *context);
void RMD320Update(struct RMD320Context *context, const unsigned char *buf, unsigned len);
void RMD320Final(unsigned char digest[RMD320Length], struct RMD320Context *context);
void RMD320Transform(struct RMD320Context *context, unsigned char *buf);
int RMD320Test();
#ifdef __cplusplus
}
#endif
#endif

485
Classes/MD/MGMRMD320.m Normal file
View File

@ -0,0 +1,485 @@
//
// MGMRMD320.m
//
// Created by Mr. Gecko <GRMrGecko@gmail.com> on 5/31/11.
// No Copyright Claimed. Public Domain.
// C Algorithm created by Tom St Denis <tomstdenis@gmail.com> <http://libtom.org>
//
#ifdef __NEXT_RUNTIME__
#import "MGMRMD320.h"
#import "MGMTypes.h"
NSString * const MDNRMD320 = @"rmd320";
@implementation NSString (MGMRMD320)
- (NSString *)RMD320 {
NSData *MDData = [self dataUsingEncoding:NSUTF8StringEncoding];
struct RMD320Context MDContext;
unsigned char MDDigest[RMD320Length];
RMD320Init(&MDContext);
RMD320Update(&MDContext, [MDData bytes], [MDData length]);
RMD320Final(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(RMD320Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<RMD320Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
NSString *hash = [NSString stringWithUTF8String:stringBuffer];
free(stringBuffer);
return hash;
}
- (NSString *)pathRMD320 {
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:self];
if (file==nil)
return nil;
struct RMD320Context MDContext;
unsigned char MDDigest[RMD320Length];
RMD320Init(&MDContext);
int length;
do {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSData *MDData = [file readDataOfLength:MDFileReadLength];
length = [MDData length];
RMD320Update(&MDContext, [MDData bytes], length);
[pool release];
} while (length>0);
RMD320Final(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(RMD320Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<RMD320Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
NSString *hash = [NSString stringWithUTF8String:stringBuffer];
free(stringBuffer);
return hash;
}
@end
#else
#include <stdio.h>
#include <string.h>
#include "MGMRMD320.h"
#include "MGMTypes.h"
#endif
const struct MGMHashDescription RMD320Desc = {
"rmd320",
sizeof(struct RMD320Context),
(void(*)(void *))&RMD320Init,
(void(*)(void *, const unsigned char *, unsigned))&RMD320Update,
(void(*)(unsigned char *, void *))&RMD320Final,
RMD320Length
};
char *RMD320String(const char *string, int length) {
struct RMD320Context MDContext;
unsigned char MDDigest[RMD320Length];
RMD320Init(&MDContext);
RMD320Update(&MDContext, (const unsigned char *)string, length);
RMD320Final(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(RMD320Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<RMD320Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
return stringBuffer;
}
char *RMD320File(const char *path) {
FILE *file = fopen(path, "r");
if (file==NULL)
return NULL;
struct RMD320Context MDContext;
unsigned char MDDigest[RMD320Length];
RMD320Init(&MDContext);
int length;
do {
unsigned char MDData[MDFileReadLength];
length = fread(&MDData, 1, MDFileReadLength, file);
RMD320Update(&MDContext, MDData, length);
} while (length>0);
RMD320Final(MDDigest, &MDContext);
fclose(file);
char *stringBuffer = (char *)malloc(RMD320Length * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<RMD320Length; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
return stringBuffer;
}
void RMD320Init(struct RMD320Context *context) {
context->state[0] = INT32(0x67452301);
context->state[1] = INT32(0xefcdab89);
context->state[2] = INT32(0x98badcfe);
context->state[3] = INT32(0x10325476);
context->state[4] = INT32(0xc3d2e1f0);
context->state[5] = INT32(0x76543210);
context->state[6] = INT32(0xfedcba98);
context->state[7] = INT32(0x89abcdef);
context->state[8] = INT32(0x01234567);
context->state[9] = INT32(0x3c2d1e0f);
context->curlen = 0;
context->length = 0;
}
void RMD320Update(struct RMD320Context *context, const unsigned char *buf, unsigned len) {
if (buf==NULL)
return;
unsigned long n;
while (len>0) {
if (context->curlen == 0 && len>=RMD320BufferSize) {
RMD320Transform(context, (unsigned char *)buf);
context->length += RMD320BufferSize * 8;
buf += RMD320BufferSize;
len -= RMD320BufferSize;
} else {
n = MIN(len, (RMD320BufferSize-context->curlen));
memcpy(context->buf+context->curlen, buf, (size_t)n);
context->curlen += n;
buf += n;
len -= n;
if (context->curlen == RMD320BufferSize) {
RMD320Transform(context, context->buf);
context->length += 8*RMD320BufferSize;
context->curlen = 0;
}
}
}
}
void RMD320Final(unsigned char digest[RMD320Length], struct RMD320Context *context) {
context->length += context->curlen * 8;
context->buf[context->curlen++] = (unsigned char)0x80;
if (context->curlen > 56) {
while (context->curlen < 64) {
context->buf[context->curlen++] = (unsigned char)0;
}
RMD320Transform(context, context->buf);
context->curlen = 0;
}
while (context->curlen < 56) {
context->buf[context->curlen++] = (unsigned char)0;
}
putu64l(context->length, context->buf+56);
RMD320Transform(context, context->buf);
for (int i=0; i<10; i++) {
putu32l(context->state[i], digest+(4*i));
}
memset(context, 0, sizeof(struct RMD320Context));
}
#define RMD320_S1 0
#define RMD320_S2 INT32(0x5a827999)
#define RMD320_S3 INT32(0x6ed9eba1)
#define RMD320_S4 INT32(0x8f1bbcdc)
#define RMD320_S5 INT32(0xa953fd4e)
#define RMD320_S10 0
#define RMD320_S9 INT32(0x7a6d76e9)
#define RMD320_S8 INT32(0x6d703ef3)
#define RMD320_S7 INT32(0x5c4dd124)
#define RMD320_S6 INT32(0x50a28be6)
#define RMD320_F1(x, y, z) ((x) ^ (y) ^ (z))
#define RMD320_F2(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define RMD320_F3(x, y, z) (((x) | ~(y)) ^ (z))
#define RMD320_F4(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define RMD320_F5(x, y, z) ((x) ^ ((y) | ~(z)))
#define RMD320STEP(a, b, c, d, e, f, g, h, i) \
(c) += a((d), (e), (f)) + (h) + b; (c) = ROL32((c), (i)) + (g); (e) = ROL32((e), 10);
void RMD320Transform(struct RMD320Context *context, unsigned char *buf) {
uint32_t x[16], tmp;
uint32_t a = context->state[0];
uint32_t b = context->state[1];
uint32_t c = context->state[2];
uint32_t d = context->state[3];
uint32_t e = context->state[4];
uint32_t aa = context->state[5];
uint32_t bb = context->state[6];
uint32_t cc = context->state[7];
uint32_t dd = context->state[8];
uint32_t ee = context->state[9];
for (int i=0; i<16; i++) {
x[i] = getu32l(buf+(4*i));
}
/* round 1 */
RMD320STEP(RMD320_F1, RMD320_S1, a, b, c, d, e, x[0], 11);
RMD320STEP(RMD320_F1, RMD320_S1, e, a, b, c, d, x[1], 14);
RMD320STEP(RMD320_F1, RMD320_S1, d, e, a, b, c, x[2], 15);
RMD320STEP(RMD320_F1, RMD320_S1, c, d, e, a, b, x[3], 12);
RMD320STEP(RMD320_F1, RMD320_S1, b, c, d, e, a, x[4], 5);
RMD320STEP(RMD320_F1, RMD320_S1, a, b, c, d, e, x[5], 8);
RMD320STEP(RMD320_F1, RMD320_S1, e, a, b, c, d, x[6], 7);
RMD320STEP(RMD320_F1, RMD320_S1, d, e, a, b, c, x[7], 9);
RMD320STEP(RMD320_F1, RMD320_S1, c, d, e, a, b, x[8], 11);
RMD320STEP(RMD320_F1, RMD320_S1, b, c, d, e, a, x[9], 13);
RMD320STEP(RMD320_F1, RMD320_S1, a, b, c, d, e, x[10], 14);
RMD320STEP(RMD320_F1, RMD320_S1, e, a, b, c, d, x[11], 15);
RMD320STEP(RMD320_F1, RMD320_S1, d, e, a, b, c, x[12], 6);
RMD320STEP(RMD320_F1, RMD320_S1, c, d, e, a, b, x[13], 7);
RMD320STEP(RMD320_F1, RMD320_S1, b, c, d, e, a, x[14], 9);
RMD320STEP(RMD320_F1, RMD320_S1, a, b, c, d, e, x[15], 8);
/* parallel round 1 */
RMD320STEP(RMD320_F5, RMD320_S6, aa, bb, cc, dd, ee, x[5], 8);
RMD320STEP(RMD320_F5, RMD320_S6, ee, aa, bb, cc, dd, x[14], 9);
RMD320STEP(RMD320_F5, RMD320_S6, dd, ee, aa, bb, cc, x[7], 9);
RMD320STEP(RMD320_F5, RMD320_S6, cc, dd, ee, aa, bb, x[0], 11);
RMD320STEP(RMD320_F5, RMD320_S6, bb, cc, dd, ee, aa, x[9], 13);
RMD320STEP(RMD320_F5, RMD320_S6, aa, bb, cc, dd, ee, x[2], 15);
RMD320STEP(RMD320_F5, RMD320_S6, ee, aa, bb, cc, dd, x[11], 15);
RMD320STEP(RMD320_F5, RMD320_S6, dd, ee, aa, bb, cc, x[4], 5);
RMD320STEP(RMD320_F5, RMD320_S6, cc, dd, ee, aa, bb, x[13], 7);
RMD320STEP(RMD320_F5, RMD320_S6, bb, cc, dd, ee, aa, x[6], 7);
RMD320STEP(RMD320_F5, RMD320_S6, aa, bb, cc, dd, ee, x[15], 8);
RMD320STEP(RMD320_F5, RMD320_S6, ee, aa, bb, cc, dd, x[8], 11);
RMD320STEP(RMD320_F5, RMD320_S6, dd, ee, aa, bb, cc, x[1], 14);
RMD320STEP(RMD320_F5, RMD320_S6, cc, dd, ee, aa, bb, x[10], 14);
RMD320STEP(RMD320_F5, RMD320_S6, bb, cc, dd, ee, aa, x[3], 12);
RMD320STEP(RMD320_F5, RMD320_S6, aa, bb, cc, dd, ee, x[12], 6);
tmp = a; a = aa; aa = tmp;
/* round 2 */
RMD320STEP(RMD320_F2, RMD320_S2, e, a, b, c, d, x[7], 7);
RMD320STEP(RMD320_F2, RMD320_S2, d, e, a, b, c, x[4], 6);
RMD320STEP(RMD320_F2, RMD320_S2, c, d, e, a, b, x[13], 8);
RMD320STEP(RMD320_F2, RMD320_S2, b, c, d, e, a, x[1], 13);
RMD320STEP(RMD320_F2, RMD320_S2, a, b, c, d, e, x[10], 11);
RMD320STEP(RMD320_F2, RMD320_S2, e, a, b, c, d, x[6], 9);
RMD320STEP(RMD320_F2, RMD320_S2, d, e, a, b, c, x[15], 7);
RMD320STEP(RMD320_F2, RMD320_S2, c, d, e, a, b, x[3], 15);
RMD320STEP(RMD320_F2, RMD320_S2, b, c, d, e, a, x[12], 7);
RMD320STEP(RMD320_F2, RMD320_S2, a, b, c, d, e, x[0], 12);
RMD320STEP(RMD320_F2, RMD320_S2, e, a, b, c, d, x[9], 15);
RMD320STEP(RMD320_F2, RMD320_S2, d, e, a, b, c, x[5], 9);
RMD320STEP(RMD320_F2, RMD320_S2, c, d, e, a, b, x[2], 11);
RMD320STEP(RMD320_F2, RMD320_S2, b, c, d, e, a, x[14], 7);
RMD320STEP(RMD320_F2, RMD320_S2, a, b, c, d, e, x[11], 13);
RMD320STEP(RMD320_F2, RMD320_S2, e, a, b, c, d, x[8], 12);
/* parallel round 2 */
RMD320STEP(RMD320_F4, RMD320_S7, ee, aa, bb, cc, dd, x[6], 9);
RMD320STEP(RMD320_F4, RMD320_S7, dd, ee, aa, bb, cc, x[11], 13);
RMD320STEP(RMD320_F4, RMD320_S7, cc, dd, ee, aa, bb, x[3], 15);
RMD320STEP(RMD320_F4, RMD320_S7, bb, cc, dd, ee, aa, x[7], 7);
RMD320STEP(RMD320_F4, RMD320_S7, aa, bb, cc, dd, ee, x[0], 12);
RMD320STEP(RMD320_F4, RMD320_S7, ee, aa, bb, cc, dd, x[13], 8);
RMD320STEP(RMD320_F4, RMD320_S7, dd, ee, aa, bb, cc, x[5], 9);
RMD320STEP(RMD320_F4, RMD320_S7, cc, dd, ee, aa, bb, x[10], 11);
RMD320STEP(RMD320_F4, RMD320_S7, bb, cc, dd, ee, aa, x[14], 7);
RMD320STEP(RMD320_F4, RMD320_S7, aa, bb, cc, dd, ee, x[15], 7);
RMD320STEP(RMD320_F4, RMD320_S7, ee, aa, bb, cc, dd, x[8], 12);
RMD320STEP(RMD320_F4, RMD320_S7, dd, ee, aa, bb, cc, x[12], 7);
RMD320STEP(RMD320_F4, RMD320_S7, cc, dd, ee, aa, bb, x[4], 6);
RMD320STEP(RMD320_F4, RMD320_S7, bb, cc, dd, ee, aa, x[9], 15);
RMD320STEP(RMD320_F4, RMD320_S7, aa, bb, cc, dd, ee, x[1], 13);
RMD320STEP(RMD320_F4, RMD320_S7, ee, aa, bb, cc, dd, x[2], 11);
tmp = b; b = bb; bb = tmp;
/* round 3 */
RMD320STEP(RMD320_F3, RMD320_S3, d, e, a, b, c, x[3], 11);
RMD320STEP(RMD320_F3, RMD320_S3, c, d, e, a, b, x[10], 13);
RMD320STEP(RMD320_F3, RMD320_S3, b, c, d, e, a, x[14], 6);
RMD320STEP(RMD320_F3, RMD320_S3, a, b, c, d, e, x[4], 7);
RMD320STEP(RMD320_F3, RMD320_S3, e, a, b, c, d, x[9], 14);
RMD320STEP(RMD320_F3, RMD320_S3, d, e, a, b, c, x[15], 9);
RMD320STEP(RMD320_F3, RMD320_S3, c, d, e, a, b, x[8], 13);
RMD320STEP(RMD320_F3, RMD320_S3, b, c, d, e, a, x[1], 15);
RMD320STEP(RMD320_F3, RMD320_S3, a, b, c, d, e, x[2], 14);
RMD320STEP(RMD320_F3, RMD320_S3, e, a, b, c, d, x[7], 8);
RMD320STEP(RMD320_F3, RMD320_S3, d, e, a, b, c, x[0], 13);
RMD320STEP(RMD320_F3, RMD320_S3, c, d, e, a, b, x[6], 6);
RMD320STEP(RMD320_F3, RMD320_S3, b, c, d, e, a, x[13], 5);
RMD320STEP(RMD320_F3, RMD320_S3, a, b, c, d, e, x[11], 12);
RMD320STEP(RMD320_F3, RMD320_S3, e, a, b, c, d, x[5], 7);
RMD320STEP(RMD320_F3, RMD320_S3, d, e, a, b, c, x[12], 5);
/* parallel round 3 */
RMD320STEP(RMD320_F3, RMD320_S8, dd, ee, aa, bb, cc, x[15], 9);
RMD320STEP(RMD320_F3, RMD320_S8, cc, dd, ee, aa, bb, x[5], 7);
RMD320STEP(RMD320_F3, RMD320_S8, bb, cc, dd, ee, aa, x[1], 15);
RMD320STEP(RMD320_F3, RMD320_S8, aa, bb, cc, dd, ee, x[3], 11);
RMD320STEP(RMD320_F3, RMD320_S8, ee, aa, bb, cc, dd, x[7], 8);
RMD320STEP(RMD320_F3, RMD320_S8, dd, ee, aa, bb, cc, x[14], 6);
RMD320STEP(RMD320_F3, RMD320_S8, cc, dd, ee, aa, bb, x[6], 6);
RMD320STEP(RMD320_F3, RMD320_S8, bb, cc, dd, ee, aa, x[9], 14);
RMD320STEP(RMD320_F3, RMD320_S8, aa, bb, cc, dd, ee, x[11], 12);
RMD320STEP(RMD320_F3, RMD320_S8, ee, aa, bb, cc, dd, x[8], 13);
RMD320STEP(RMD320_F3, RMD320_S8, dd, ee, aa, bb, cc, x[12], 5);
RMD320STEP(RMD320_F3, RMD320_S8, cc, dd, ee, aa, bb, x[2], 14);
RMD320STEP(RMD320_F3, RMD320_S8, bb, cc, dd, ee, aa, x[10], 13);
RMD320STEP(RMD320_F3, RMD320_S8, aa, bb, cc, dd, ee, x[0], 13);
RMD320STEP(RMD320_F3, RMD320_S8, ee, aa, bb, cc, dd, x[4], 7);
RMD320STEP(RMD320_F3, RMD320_S8, dd, ee, aa, bb, cc, x[13], 5);
tmp = c; c = cc; cc = tmp;
/* round 4 */
RMD320STEP(RMD320_F4, RMD320_S4, c, d, e, a, b, x[1], 11);
RMD320STEP(RMD320_F4, RMD320_S4, b, c, d, e, a, x[9], 12);
RMD320STEP(RMD320_F4, RMD320_S4, a, b, c, d, e, x[11], 14);
RMD320STEP(RMD320_F4, RMD320_S4, e, a, b, c, d, x[10], 15);
RMD320STEP(RMD320_F4, RMD320_S4, d, e, a, b, c, x[0], 14);
RMD320STEP(RMD320_F4, RMD320_S4, c, d, e, a, b, x[8], 15);
RMD320STEP(RMD320_F4, RMD320_S4, b, c, d, e, a, x[12], 9);
RMD320STEP(RMD320_F4, RMD320_S4, a, b, c, d, e, x[4], 8);
RMD320STEP(RMD320_F4, RMD320_S4, e, a, b, c, d, x[13], 9);
RMD320STEP(RMD320_F4, RMD320_S4, d, e, a, b, c, x[3], 14);
RMD320STEP(RMD320_F4, RMD320_S4, c, d, e, a, b, x[7], 5);
RMD320STEP(RMD320_F4, RMD320_S4, b, c, d, e, a, x[15], 6);
RMD320STEP(RMD320_F4, RMD320_S4, a, b, c, d, e, x[14], 8);
RMD320STEP(RMD320_F4, RMD320_S4, e, a, b, c, d, x[5], 6);
RMD320STEP(RMD320_F4, RMD320_S4, d, e, a, b, c, x[6], 5);
RMD320STEP(RMD320_F4, RMD320_S4, c, d, e, a, b, x[2], 12);
/* parallel round 4 */
RMD320STEP(RMD320_F2, RMD320_S9, cc, dd, ee, aa, bb, x[8], 15);
RMD320STEP(RMD320_F2, RMD320_S9, bb, cc, dd, ee, aa, x[6], 5);
RMD320STEP(RMD320_F2, RMD320_S9, aa, bb, cc, dd, ee, x[4], 8);
RMD320STEP(RMD320_F2, RMD320_S9, ee, aa, bb, cc, dd, x[1], 11);
RMD320STEP(RMD320_F2, RMD320_S9, dd, ee, aa, bb, cc, x[3], 14);
RMD320STEP(RMD320_F2, RMD320_S9, cc, dd, ee, aa, bb, x[11], 14);
RMD320STEP(RMD320_F2, RMD320_S9, bb, cc, dd, ee, aa, x[15], 6);
RMD320STEP(RMD320_F2, RMD320_S9, aa, bb, cc, dd, ee, x[0], 14);
RMD320STEP(RMD320_F2, RMD320_S9, ee, aa, bb, cc, dd, x[5], 6);
RMD320STEP(RMD320_F2, RMD320_S9, dd, ee, aa, bb, cc, x[12], 9);
RMD320STEP(RMD320_F2, RMD320_S9, cc, dd, ee, aa, bb, x[2], 12);
RMD320STEP(RMD320_F2, RMD320_S9, bb, cc, dd, ee, aa, x[13], 9);
RMD320STEP(RMD320_F2, RMD320_S9, aa, bb, cc, dd, ee, x[9], 12);
RMD320STEP(RMD320_F2, RMD320_S9, ee, aa, bb, cc, dd, x[7], 5);
RMD320STEP(RMD320_F2, RMD320_S9, dd, ee, aa, bb, cc, x[10], 15);
RMD320STEP(RMD320_F2, RMD320_S9, cc, dd, ee, aa, bb, x[14], 8);
tmp = d; d = dd; dd = tmp;
/* round 5 */
RMD320STEP(RMD320_F5, RMD320_S5, b, c, d, e, a, x[4], 9);
RMD320STEP(RMD320_F5, RMD320_S5, a, b, c, d, e, x[0], 15);
RMD320STEP(RMD320_F5, RMD320_S5, e, a, b, c, d, x[5], 5);
RMD320STEP(RMD320_F5, RMD320_S5, d, e, a, b, c, x[9], 11);
RMD320STEP(RMD320_F5, RMD320_S5, c, d, e, a, b, x[7], 6);
RMD320STEP(RMD320_F5, RMD320_S5, b, c, d, e, a, x[12], 8);
RMD320STEP(RMD320_F5, RMD320_S5, a, b, c, d, e, x[2], 13);
RMD320STEP(RMD320_F5, RMD320_S5, e, a, b, c, d, x[10], 12);
RMD320STEP(RMD320_F5, RMD320_S5, d, e, a, b, c, x[14], 5);
RMD320STEP(RMD320_F5, RMD320_S5, c, d, e, a, b, x[1], 12);
RMD320STEP(RMD320_F5, RMD320_S5, b, c, d, e, a, x[3], 13);
RMD320STEP(RMD320_F5, RMD320_S5, a, b, c, d, e, x[8], 14);
RMD320STEP(RMD320_F5, RMD320_S5, e, a, b, c, d, x[11], 11);
RMD320STEP(RMD320_F5, RMD320_S5, d, e, a, b, c, x[6], 8);
RMD320STEP(RMD320_F5, RMD320_S5, c, d, e, a, b, x[15], 5);
RMD320STEP(RMD320_F5, RMD320_S5, b, c, d, e, a, x[13], 6);
/* parallel round 5 */
RMD320STEP(RMD320_F1, RMD320_S10, bb, cc, dd, ee, aa, x[12], 8);
RMD320STEP(RMD320_F1, RMD320_S10, aa, bb, cc, dd, ee, x[15], 5);
RMD320STEP(RMD320_F1, RMD320_S10, ee, aa, bb, cc, dd, x[10], 12);
RMD320STEP(RMD320_F1, RMD320_S10, dd, ee, aa, bb, cc, x[4], 9);
RMD320STEP(RMD320_F1, RMD320_S10, cc, dd, ee, aa, bb, x[1], 12);
RMD320STEP(RMD320_F1, RMD320_S10, bb, cc, dd, ee, aa, x[5], 5);
RMD320STEP(RMD320_F1, RMD320_S10, aa, bb, cc, dd, ee, x[8], 14);
RMD320STEP(RMD320_F1, RMD320_S10, ee, aa, bb, cc, dd, x[7], 6);
RMD320STEP(RMD320_F1, RMD320_S10, dd, ee, aa, bb, cc, x[6], 8);
RMD320STEP(RMD320_F1, RMD320_S10, cc, dd, ee, aa, bb, x[2], 13);
RMD320STEP(RMD320_F1, RMD320_S10, bb, cc, dd, ee, aa, x[13], 6);
RMD320STEP(RMD320_F1, RMD320_S10, aa, bb, cc, dd, ee, x[14], 5);
RMD320STEP(RMD320_F1, RMD320_S10, ee, aa, bb, cc, dd, x[0], 15);
RMD320STEP(RMD320_F1, RMD320_S10, dd, ee, aa, bb, cc, x[3], 13);
RMD320STEP(RMD320_F1, RMD320_S10, cc, dd, ee, aa, bb, x[9], 11);
RMD320STEP(RMD320_F1, RMD320_S10, bb, cc, dd, ee, aa, x[11], 11);
tmp = e; e = ee; ee = tmp;
context->state[0] += a;
context->state[1] += b;
context->state[2] += c;
context->state[3] += d;
context->state[4] += e;
context->state[5] += aa;
context->state[6] += bb;
context->state[7] += cc;
context->state[8] += dd;
context->state[9] += ee;
}
int RMD320Test() {
static const struct {
char *msg;
unsigned char hash[RMD320Length];
} tests[] = {
{
"",
{0x22,0xd6,0x5d,0x56,0x61,0x53,0x6c,0xdc,0x75,0xc1,0xfd,0xf5,0xc6,0xde,0x7b,0x41,0xb9,0xf2,0x73,0x25,0xeb,0xc6,0x1e,0x85,0x57,0x17,0x7d,0x70,0x5a,0x0e,0xc8,0x80,0x15,0x1c,0x3a,0x32,0xa0,0x08,0x99,0xb8}
},
{
"a",
{0xce,0x78,0x85,0x06,0x38,0xf9,0x26,0x58,0xa5,0xa5,0x85,0x09,0x75,0x79,0x92,0x6d,0xda,0x66,0x7a,0x57,0x16,0x56,0x2c,0xfc,0xf6,0xfb,0xe7,0x7f,0x63,0x54,0x2f,0x99,0xb0,0x47,0x05,0xd6,0x97,0x0d,0xff,0x5d}
},
{
"abc",
{0xde,0x4c,0x01,0xb3,0x05,0x4f,0x89,0x30,0xa7,0x9d,0x09,0xae,0x73,0x8e,0x92,0x30,0x1e,0x5a,0x17,0x08,0x5b,0xef,0xfd,0xc1,0xb8,0xd1,0x16,0x71,0x3e,0x74,0xf8,0x2f,0xa9,0x42,0xd6,0x4c,0xdb,0xc4,0x68,0x2d}
},
{
"message digest",
{0x3a,0x8e,0x28,0x50,0x2e,0xd4,0x5d,0x42,0x2f,0x68,0x84,0x4f,0x9d,0xd3,0x16,0xe7,0xb9,0x85,0x33,0xfa,0x3f,0x2a,0x91,0xd2,0x9f,0x84,0xd4,0x25,0xc8,0x8d,0x6b,0x4e,0xff,0x72,0x7d,0xf6,0x6a,0x7c,0x01,0x97}
},
{
"abcdefghijklmnopqrstuvwxyz",
{0xca,0xbd,0xb1,0x81,0x0b,0x92,0x47,0x0a,0x20,0x93,0xaa,0x6b,0xce,0x05,0x95,0x2c,0x28,0x34,0x8c,0xf4,0x3f,0xf6,0x08,0x41,0x97,0x51,0x66,0xbb,0x40,0xed,0x23,0x40,0x04,0xb8,0x82,0x44,0x63,0xe6,0xb0,0x09}
},
{
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{0xd0,0x34,0xa7,0x95,0x0c,0xf7,0x22,0x02,0x1b,0xa4,0xb8,0x4d,0xf7,0x69,0xa5,0xde,0x20,0x60,0xe2,0x59,0xdf,0x4c,0x9b,0xb4,0xa4,0x26,0x8c,0x0e,0x93,0x5b,0xbc,0x74,0x70,0xa9,0x69,0xc9,0xd0,0x72,0xa1,0xac}
},
{NULL, {0}}
};
struct RMD320Context MDContext;
unsigned char MDDigest[RMD320Length];
for (int i=0; tests[i].msg!=NULL; i++) {
RMD320Init(&MDContext);
RMD320Update(&MDContext, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
RMD320Final(MDDigest, &MDContext);
if (memcmp(MDDigest, tests[i].hash, RMD320Length))
return 0;
}
return 1;
}

View File

@ -24,22 +24,25 @@ extern NSString * const MDNSHA1;
extern "C" {
#endif
extern const struct MGMHashDescription SHA1Desc;
char *SHA1String(const char *string, int length);
char *SHA1File(const char *path);
#define SHA1Length 20
#define SHA1BufferSize 5
#define SHA1BufferSize 64
struct SHA1Context {
uint32_t buf[SHA1BufferSize];
uint32_t bits[2];
unsigned char in[64];
u_int64_t length;
u_int32_t state[5], curlen;
unsigned char buf[SHA1BufferSize];
};
void SHA1Init(struct SHA1Context *context);
void SHA1Update(struct SHA1Context *context, const unsigned char *buf, unsigned len);
void SHA1Final(unsigned char digest[SHA1Length], struct SHA1Context *context);
void SHA1Transform(uint32_t buf[SHA1BufferSize], const unsigned char inraw[64]);
void SHA1Transform(struct SHA1Context *context, unsigned char *buf);
int SHA1Test();
#ifdef __cplusplus
}

View File

@ -69,10 +69,19 @@ NSString * const MDNSHA1 = @"sha1";
#else
#include <stdio.h>
#include <string.h>
#include "MGMMD5.h"
#include "MGMSHA1.h"
#include "MGMTypes.h"
#endif
const struct MGMHashDescription SHA1Desc = {
"sha1",
sizeof(struct SHA1Context),
(void(*)(void *))&SHA1Init,
(void(*)(void *, const unsigned char *, unsigned))&SHA1Update,
(void(*)(unsigned char *, void *))&SHA1Final,
SHA1Length
};
char *SHA1String(const char *string, int length) {
struct SHA1Context MDContext;
unsigned char MDDigest[SHA1Length];
@ -123,59 +132,71 @@ char *SHA1File(const char *path) {
}
void SHA1Init(struct SHA1Context *context) {
context->buf[0] = 0x67452301;
context->buf[1] = 0xEFCDAB89;
context->buf[2] = 0x98BADCFE;
context->buf[3] = 0x10325476;
context->buf[4] = 0xC3D2E1F0;
context->state[0] = INT32(0x67452301);
context->state[1] = INT32(0xEFCDAB89);
context->state[2] = INT32(0x98BADCFE);
context->state[3] = INT32(0x10325476);
context->state[4] = INT32(0xC3D2E1F0);
context->bits[0] = 0;
context->bits[1] = 0;
context->curlen = 0;
context->length = 0;
}
void SHA1Update(struct SHA1Context *context, const unsigned char *buf, unsigned len) {
u_int32_t i, j;
j = context->bits[0];
if ((context->bits[0] += len << 3) < j)
context->bits[1]++;
context->bits[1] += (len>>29);
j = (j >> 3) & 63;
if ((j + len) > 63) {
memcpy(&context->in[j], buf, (i = 64-j));
SHA1Transform(context->buf, context->in);
for ( ; i + 63 < len; i += 64) {
SHA1Transform(context->buf, &buf[i]);
if (buf==NULL)
return;
unsigned long n;
while (len>0) {
if (context->curlen == 0 && len>=SHA1BufferSize) {
SHA1Transform(context, (unsigned char *)buf);
context->length += SHA1BufferSize * 8;
buf += SHA1BufferSize;
len -= SHA1BufferSize;
} else {
n = MIN(len, (SHA1BufferSize-context->curlen));
memcpy(context->buf+context->curlen, buf, (size_t)n);
context->curlen += n;
buf += n;
len -= n;
if (context->curlen == SHA1BufferSize) {
SHA1Transform(context, context->buf);
context->length += 8*SHA1BufferSize;
context->curlen = 0;
}
}
j = 0;
}
else i = 0;
memcpy(&context->in[j], &buf[i], len - i);
}
void SHA1Final(unsigned char digest[SHA1Length], struct SHA1Context *context) {
unsigned char bits[8];
unsigned int count;
context->length += context->curlen * 8;
context->buf[context->curlen++] = (unsigned char)0x80;
putu32(context->bits[1], bits);
putu32(context->bits[0], bits + 4);
if (context->curlen > 56) {
while (context->curlen < 64) {
context->buf[context->curlen++] = (unsigned char)0;
}
SHA1Transform(context, context->buf);
context->curlen = 0;
}
count = (context->bits[0] >> 3) & 0x3f;
count = (count < 56) ? (56 - count) : (120 - count);
SHA1Update(context, MDPadding, count);
while (context->curlen < 56) {
context->buf[context->curlen++] = (unsigned char)0;
}
SHA1Update(context, bits, 8);
putu64(context->length, context->buf+56);
SHA1Transform(context, context->buf);
for (int i=0; i<5; i++)
putu32(context->buf[i], digest + (4 * i));
for (int i=0; i<5; i++) {
putu32(context->state[i], digest+(4*i));
}
memset(context, 0, sizeof(context));
memset(context, 0, sizeof(struct SHA1Context));
}
#define SHA1_rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
#if BYTE_ORDER == LITTLE_ENDIAN
#define SHA1_blk0(i) (block->l[i] = (SHA1_rol(block->l[i], 24)&0xFF00FF00) |(SHA1_rol(block->l[i], 8)&0x00FF00FF))
#define SHA1_blk0(i) (block->l[i] = (SHA1_rol(block->l[i], 24)&INT32(0xFF00FF00)) |(SHA1_rol(block->l[i], 8)&INT32(0x00FF00FF)))
#elif BYTE_ORDER == BIG_ENDIAN
#define SHA1_blk0(i) block->l[i]
#else
@ -183,11 +204,11 @@ void SHA1Final(unsigned char digest[SHA1Length], struct SHA1Context *context) {
#endif
#define SHA1_blk(i) (block->l[i&15] = SHA1_rol(block->l[(i+13)&15]^block->l[(i+8)&15] ^block->l[(i+2)&15]^block->l[i&15], 1))
#define SHA1_R0(v, w, x, y, z, i) z+=((w&(x^y))^y)+SHA1_blk0(i)+0x5A827999+SHA1_rol(v, 5);w=SHA1_rol(w, 30);
#define SHA1_R1(v, w, x, y, z, i) z+=((w&(x^y))^y)+SHA1_blk(i)+0x5A827999+SHA1_rol(v, 5);w=SHA1_rol(w, 30);
#define SHA1_R2(v, w, x, y, z, i) z+=(w^x^y)+SHA1_blk(i)+0x6ED9EBA1+SHA1_rol(v, 5);w=SHA1_rol(w, 30);
#define SHA1_R3(v, w, x, y, z, i) z+=(((w|x)&y)|(w&x))+SHA1_blk(i)+0x8F1BBCDC+SHA1_rol(v, 5);w=SHA1_rol(w, 30);
#define SHA1_R4(v, w, x, y, z, i) z+=(w^x^y)+SHA1_blk(i)+0xCA62C1D6+SHA1_rol(v, 5);w=SHA1_rol(w, 30);
#define SHA1_R0(v, w, x, y, z, i) z+=((w&(x^y))^y)+SHA1_blk0(i)+INT32(0x5A827999)+SHA1_rol(v, 5);w=SHA1_rol(w, 30);
#define SHA1_R1(v, w, x, y, z, i) z+=((w&(x^y))^y)+SHA1_blk(i)+INT32(0x5A827999)+SHA1_rol(v, 5);w=SHA1_rol(w, 30);
#define SHA1_R2(v, w, x, y, z, i) z+=(w^x^y)+SHA1_blk(i)+INT32(0x6ED9EBA1)+SHA1_rol(v, 5);w=SHA1_rol(w, 30);
#define SHA1_R3(v, w, x, y, z, i) z+=(((w|x)&y)|(w&x))+SHA1_blk(i)+INT32(0x8F1BBCDC)+SHA1_rol(v, 5);w=SHA1_rol(w, 30);
#define SHA1_R4(v, w, x, y, z, i) z+=(w^x^y)+SHA1_blk(i)+INT32(0xCA62C1D6)+SHA1_rol(v, 5);w=SHA1_rol(w, 30);
#define SHA1STEP(v, w, x, y, z, i) \
if (i<16) {SHA1_R0(v, w, x, y, z, i);} else \
@ -196,18 +217,18 @@ void SHA1Final(unsigned char digest[SHA1Length], struct SHA1Context *context) {
if (i<60) {SHA1_R3(v, w, x, y, z, i);} else \
if (i<80) {SHA1_R4(v, w, x, y, z, i);}
void SHA1Transform(uint32_t buf[SHA1BufferSize], const unsigned char inraw[64]) {
void SHA1Transform(struct SHA1Context *context, unsigned char *buf) {
typedef union {
char c[64];
u_int32_t l[16];
} SHA1LONG;
SHA1LONG *block = (SHA1LONG *)inraw;
SHA1LONG *block = (SHA1LONG *)buf;
u_int32_t a = buf[0];
u_int32_t b = buf[1];
u_int32_t c = buf[2];
u_int32_t d = buf[3];
u_int32_t e = buf[4];
u_int32_t a = context->state[0];
u_int32_t b = context->state[1];
u_int32_t c = context->state[2];
u_int32_t d = context->state[3];
u_int32_t e = context->state[4];
for (int i=0; i<79; i = i+5) {
SHA1STEP(a, b, c, d, e, i);
@ -217,9 +238,40 @@ void SHA1Transform(uint32_t buf[SHA1BufferSize], const unsigned char inraw[64])
SHA1STEP(b, c, d, e, a, i + 4);
}
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
buf[4] += e;
context->state[0] += a;
context->state[1] += b;
context->state[2] += c;
context->state[3] += d;
context->state[4] += e;
}
int SHA1Test() {
static const struct {
char *msg;
unsigned char hash[SHA1Length];
} tests[] = {
{
"abc",
{0xa9,0x99,0x3e,0x36,0x47,0x06,0x81,0x6a,0xba,0x3e,0x25,0x71,0x78,0x50,0xc2,0x6c,0x9c,0xd0,0xd8,0x9d}
},
{
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{0x84,0x98,0x3E,0x44,0x1C,0x3B,0xD2,0x6E,0xBA,0xAE,0x4A,0xA1,0xF9,0x51,0x29,0xE5,0xE5,0x46,0x70,0xF1}
},
{NULL, {0}}
};
struct SHA1Context MDContext;
unsigned char MDDigest[SHA1Length];
for (int i=0; tests[i].msg!=NULL; i++) {
SHA1Init(&MDContext);
SHA1Update(&MDContext, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
SHA1Final(MDDigest, &MDContext);
if (memcmp(MDDigest, tests[i].hash, SHA1Length))
return 0;
}
return 1;
}

View File

@ -23,22 +23,25 @@ extern NSString * const MDNSHA224;
extern "C" {
#endif
extern const struct MGMHashDescription SHA224Desc;
char *SHA224String(const char *string, int length);
char *SHA224File(const char *path);
#define SHA224Length 28
#define SHA224BufferSize 8
#define SHA224BufferSize 64
struct SHA224Context {
uint32_t buf[SHA224BufferSize];
uint32_t bits[2];
unsigned char in[64];
uint64_t length;
uint32_t state[8], curlen;
unsigned char buf[SHA224BufferSize];
};
void SHA224Init(struct SHA224Context *context);
void SHA224Update(struct SHA224Context *context, const unsigned char *buf, unsigned int len);
void SHA224Final(unsigned char digest[SHA224Length], struct SHA224Context *context);
void SHA224Transform(uint32_t buf[SHA224BufferSize], const unsigned char inraw[64]);
void SHA224Transform(struct SHA224Context *context, unsigned char *buf);
int SHA224Test();
#ifdef __cplusplus
}

View File

@ -68,10 +68,19 @@ NSString * const MDNSHA224 = @"sha224";
#else
#include <stdio.h>
#include <string.h>
#include "MGMMD5.h"
#include "MGMSHA224.h"
#include "MGMTypes.h"
#endif
const struct MGMHashDescription SHA224Desc = {
"sha224",
sizeof(struct SHA224Context),
(void(*)(void *))&SHA224Init,
(void(*)(void *, const unsigned char *, unsigned))&SHA224Update,
(void(*)(unsigned char *, void *))&SHA224Final,
SHA224Length
};
char *SHA224String(const char *string, int length) {
struct SHA224Context MDContext;
unsigned char MDDigest[SHA224Length];
@ -122,70 +131,68 @@ char *SHA224File(const char *path) {
}
void SHA224Init(struct SHA224Context *context) {
context->buf[0] = 0xc1059ed8;
context->buf[1] = 0x367cd507;
context->buf[2] = 0x3070dd17;
context->buf[3] = 0xf70e5939;
context->buf[4] = 0xffc00b31;
context->buf[5] = 0x68581511;
context->buf[6] = 0x64f98fa7;
context->buf[7] = 0xbefa4fa4;
context->state[0] = INT32(0xc1059ed8);
context->state[1] = INT32(0x367cd507);
context->state[2] = INT32(0x3070dd17);
context->state[3] = INT32(0xf70e5939);
context->state[4] = INT32(0xffc00b31);
context->state[5] = INT32(0x68581511);
context->state[6] = INT32(0x64f98fa7);
context->state[7] = INT32(0xbefa4fa4);
context->bits[0] = 0;
context->bits[1] = 0;
context->curlen = 0;
context->length = 0;
}
void SHA224Update(struct SHA224Context *context, const unsigned char *buf, unsigned int len) {
uint32_t t;
t = context->bits[0];
if ((context->bits[0] = (t + ((uint32_t)len << 3))) < t)
context->bits[1]++;
context->bits[1] += len >> 29;
t = (t >> 3) & 0x3f;
if (t!=0) {
unsigned char *p = context->in + t;
t = 64-t;
if (len < t) {
memcpy(p, buf, len);
if (buf==NULL)
return;
unsigned long n;
while (len>0) {
if (context->curlen == 0 && len>=SHA224BufferSize) {
SHA224Transform(context, (unsigned char *)buf);
context->length += SHA224BufferSize * 8;
buf += SHA224BufferSize;
len -= SHA224BufferSize;
} else {
n = MIN(len, (SHA224BufferSize-context->curlen));
memcpy(context->buf+context->curlen, buf, (size_t)n);
context->curlen += n;
buf += n;
len -= n;
if (context->curlen == SHA224BufferSize) {
SHA224Transform(context, context->buf);
context->length += 8*SHA224BufferSize;
context->curlen = 0;
}
memcpy(p, buf, t);
SHA224Transform(context->buf, context->in);
buf += t;
len -= t;
}
while (len >= 64) {
memcpy(context->in, buf, 64);
SHA224Transform(context->buf, context->in);
buf += 64;
len -= 64;
}
memcpy(context->in, buf, len);
}
void SHA224Final(unsigned char digest[SHA224Length], struct SHA224Context *context) {
unsigned char bits[8];
unsigned int count;
context->length += context->curlen * 8;
context->buf[context->curlen++] = (unsigned char)0x80;
putu32(context->bits[1], bits);
putu32(context->bits[0], bits + 4);
if (context->curlen > 56) {
while (context->curlen < 64) {
context->buf[context->curlen++] = (unsigned char)0;
}
SHA224Transform(context, context->buf);
context->curlen = 0;
}
count = (context->bits[0] >> 3) & 0x3f;
count = (count < 56) ? (56 - count) : (120 - count);
SHA224Update(context, MDPadding, count);
while (context->curlen < 56) {
context->buf[context->curlen++] = (unsigned char)0;
}
SHA224Update(context, bits, 8);
putu64(context->length, context->buf+56);
SHA224Transform(context, context->buf);
for (int i=0; i<7; i++)
putu32(context->buf[i], digest + (4 * i));
for (int i=0; i<8; i++) {
putu32(context->state[i], digest+(4*i));
}
memset(context, 0, sizeof(context));
memset(context, 0, sizeof(struct SHA224Context));
}
/* #define SHA224_F1(x, y, z) (x & y | ~x & z) */
@ -201,40 +208,40 @@ void SHA224Final(unsigned char digest[SHA224Length], struct SHA224Context *conte
#define SHA224_F6(x) (ROR32(x, 17) ^ ROR32(x, 19) ^ SHR(x, 10))
static const uint32_t SHA224_Key[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
INT32(0x428a2f98), INT32(0x71374491), INT32(0xb5c0fbcf), INT32(0xe9b5dba5), INT32(0x3956c25b), INT32(0x59f111f1), INT32(0x923f82a4), INT32(0xab1c5ed5),
INT32(0xd807aa98), INT32(0x12835b01), INT32(0x243185be), INT32(0x550c7dc3), INT32(0x72be5d74), INT32(0x80deb1fe), INT32(0x9bdc06a7), INT32(0xc19bf174),
INT32(0xe49b69c1), INT32(0xefbe4786), INT32(0x0fc19dc6), INT32(0x240ca1cc), INT32(0x2de92c6f), INT32(0x4a7484aa), INT32(0x5cb0a9dc), INT32(0x76f988da),
INT32(0x983e5152), INT32(0xa831c66d), INT32(0xb00327c8), INT32(0xbf597fc7), INT32(0xc6e00bf3), INT32(0xd5a79147), INT32(0x06ca6351), INT32(0x14292967),
INT32(0x27b70a85), INT32(0x2e1b2138), INT32(0x4d2c6dfc), INT32(0x53380d13), INT32(0x650a7354), INT32(0x766a0abb), INT32(0x81c2c92e), INT32(0x92722c85),
INT32(0xa2bfe8a1), INT32(0xa81a664b), INT32(0xc24b8b70), INT32(0xc76c51a3), INT32(0xd192e819), INT32(0xd6990624), INT32(0xf40e3585), INT32(0x106aa070),
INT32(0x19a4c116), INT32(0x1e376c08), INT32(0x2748774c), INT32(0x34b0bcb5), INT32(0x391c0cb3), INT32(0x4ed8aa4a), INT32(0x5b9cca4f), INT32(0x682e6ff3),
INT32(0x748f82ee), INT32(0x78a5636f), INT32(0x84c87814), INT32(0x8cc70208), INT32(0x90befffa), INT32(0xa4506ceb), INT32(0xbef9a3f7), INT32(0xc67178f2)
};
#define SHA224STEP(a, b, c, d, e, f, g, h, s) \
t1 = h + SHA224_F4(e) + SHA224_F1(e, f, g) + SHA224_Key[s] + in[s]; \
t1 = h + SHA224_F4(e) + SHA224_F1(e, f, g) + SHA224_Key[s] + x[s]; \
t2 = SHA224_F3(a) + SHA224_F2(a, b, c); \
d += t1; \
h = t1 + t2;
void SHA224Transform(uint32_t buf[SHA224BufferSize], const unsigned char inraw[64]) {
uint32_t in[64], t1, t2;
void SHA224Transform(struct SHA224Context *context, unsigned char *buf) {
uint32_t x[64], t1, t2;
int i;
uint32_t a = buf[0];
uint32_t b = buf[1];
uint32_t c = buf[2];
uint32_t d = buf[3];
uint32_t e = buf[4];
uint32_t f = buf[5];
uint32_t g = buf[6];
uint32_t h = buf[7];
uint32_t a = context->state[0];
uint32_t b = context->state[1];
uint32_t c = context->state[2];
uint32_t d = context->state[3];
uint32_t e = context->state[4];
uint32_t f = context->state[5];
uint32_t g = context->state[6];
uint32_t h = context->state[7];
for (i = 0; i < 16; i++)
in[i] = getu32(inraw+4*i);
x[i] = getu32(buf+(4*i));
for (i = 16; i < 64; i++)
in[i] = SHA224_F6(in[i - 2]) + in[i - 7] + SHA224_F5(in[i - 15]) + in[i - 16];
x[i] = SHA224_F6(x[i - 2]) + x[i - 7] + SHA224_F5(x[i - 15]) + x[i - 16];
for (int i=0; i<64; i = i+8) {
SHA224STEP(a, b, c, d, e, f, g, h, i);
@ -247,12 +254,43 @@ void SHA224Transform(uint32_t buf[SHA224BufferSize], const unsigned char inraw[6
SHA224STEP(b, c, d, e, f, g, h, a, i + 7);
}
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
buf[4] += e;
buf[5] += f;
buf[6] += g;
buf[7] += h;
context->state[0] += a;
context->state[1] += b;
context->state[2] += c;
context->state[3] += d;
context->state[4] += e;
context->state[5] += f;
context->state[6] += g;
context->state[7] += h;
}
int SHA224Test() {
static const struct {
char *msg;
unsigned char hash[SHA224Length];
} tests[] = {
{
"abc",
{0x23,0x09,0x7d,0x22,0x34,0x05,0xd8,0x22,0x86,0x42,0xa4,0x77,0xbd,0xa2,0x55,0xb3,0x2a,0xad,0xbc,0xe4,0xbd,0xa0,0xb3,0xf7,0xe3,0x6c,0x9d,0xa7}
},
{
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{0x75,0x38,0x8b,0x16,0x51,0x27,0x76,0xcc,0x5d,0xba,0x5d,0xa1,0xfd,0x89,0x01,0x50,0xb0,0xc6,0x45,0x5c,0xb4,0xf5,0x8b,0x19,0x52,0x52,0x25,0x25}
},
{NULL, {0}}
};
struct SHA224Context MDContext;
unsigned char MDDigest[SHA224Length];
for (int i=0; tests[i].msg!=NULL; i++) {
SHA224Init(&MDContext);
SHA224Update(&MDContext, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
SHA224Final(MDDigest, &MDContext);
if (memcmp(MDDigest, tests[i].hash, SHA224Length))
return 0;
}
return 1;
}

View File

@ -23,22 +23,25 @@ extern NSString * const MDNSHA256;
extern "C" {
#endif
extern const struct MGMHashDescription SHA256Desc;
char *SHA256String(const char *string, int length);
char *SHA256File(const char *path);
#define SHA256Length 32
#define SHA256BufferSize 8
#define SHA256BufferSize 64
struct SHA256Context {
uint32_t buf[SHA256BufferSize];
uint32_t bits[2];
unsigned char in[64];
uint64_t length;
uint32_t state[8], curlen;
unsigned char buf[SHA256BufferSize];
};
void SHA256Init(struct SHA256Context *context);
void SHA256Update(struct SHA256Context *context, const unsigned char *buf, unsigned int len);
void SHA256Final(unsigned char digest[SHA256Length], struct SHA256Context *context);
void SHA256Transform(uint32_t buf[SHA256BufferSize], const unsigned char inraw[64]);
void SHA256Transform(struct SHA256Context *context, unsigned char *buf);
int SHA256Test();
#ifdef __cplusplus
}

View File

@ -68,10 +68,19 @@ NSString * const MDNSHA256 = @"sha256";
#else
#include <stdio.h>
#include <string.h>
#include "MGMMD5.h"
#include "MGMSHA256.h"
#include "MGMTypes.h"
#endif
const struct MGMHashDescription SHA256Desc = {
"sha256",
sizeof(struct SHA256Context),
(void(*)(void *))&SHA256Init,
(void(*)(void *, const unsigned char *, unsigned))&SHA256Update,
(void(*)(unsigned char *, void *))&SHA256Final,
SHA256Length
};
char *SHA256String(const char *string, int length) {
struct SHA256Context MDContext;
unsigned char MDDigest[SHA256Length];
@ -122,70 +131,68 @@ char *SHA256File(const char *path) {
}
void SHA256Init(struct SHA256Context *context) {
context->buf[0] = 0x6a09e667;
context->buf[1] = 0xbb67ae85;
context->buf[2] = 0x3c6ef372;
context->buf[3] = 0xa54ff53a;
context->buf[4] = 0x510e527f;
context->buf[5] = 0x9b05688c;
context->buf[6] = 0x1f83d9ab;
context->buf[7] = 0x5be0cd19;
context->state[0] = INT32(0x6a09e667);
context->state[1] = INT32(0xbb67ae85);
context->state[2] = INT32(0x3c6ef372);
context->state[3] = INT32(0xa54ff53a);
context->state[4] = INT32(0x510e527f);
context->state[5] = INT32(0x9b05688c);
context->state[6] = INT32(0x1f83d9ab);
context->state[7] = INT32(0x5be0cd19);
context->bits[0] = 0;
context->bits[1] = 0;
context->curlen = 0;
context->length = 0;
}
void SHA256Update(struct SHA256Context *context, const unsigned char *buf, unsigned int len) {
uint32_t t;
t = context->bits[0];
if ((context->bits[0] = (t + ((uint32_t)len << 3))) < t)
context->bits[1]++;
context->bits[1] += len >> 29;
t = (t >> 3) & 0x3f;
if (t!=0) {
unsigned char *p = context->in + t;
t = 64-t;
if (len < t) {
memcpy(p, buf, len);
if (buf==NULL)
return;
unsigned long n;
while (len>0) {
if (context->curlen == 0 && len>=SHA256BufferSize) {
SHA256Transform(context, (unsigned char *)buf);
context->length += SHA256BufferSize * 8;
buf += SHA256BufferSize;
len -= SHA256BufferSize;
} else {
n = MIN(len, (SHA256BufferSize-context->curlen));
memcpy(context->buf+context->curlen, buf, (size_t)n);
context->curlen += n;
buf += n;
len -= n;
if (context->curlen == SHA256BufferSize) {
SHA256Transform(context, context->buf);
context->length += 8*SHA256BufferSize;
context->curlen = 0;
}
memcpy(p, buf, t);
SHA256Transform(context->buf, context->in);
buf += t;
len -= t;
}
while (len >= 64) {
memcpy(context->in, buf, 64);
SHA256Transform(context->buf, context->in);
buf += 64;
len -= 64;
}
memcpy(context->in, buf, len);
}
void SHA256Final(unsigned char digest[SHA256Length], struct SHA256Context *context) {
unsigned char bits[8];
unsigned int count;
context->length += context->curlen * 8;
context->buf[context->curlen++] = (unsigned char)0x80;
putu32(context->bits[1], bits);
putu32(context->bits[0], bits + 4);
if (context->curlen > 56) {
while (context->curlen < 64) {
context->buf[context->curlen++] = (unsigned char)0;
}
SHA256Transform(context, context->buf);
context->curlen = 0;
}
count = (context->bits[0] >> 3) & 0x3f;
count = (count < 56) ? (56 - count) : (120 - count);
SHA256Update(context, MDPadding, count);
while (context->curlen < 56) {
context->buf[context->curlen++] = (unsigned char)0;
}
SHA256Update(context, bits, 8);
putu64(context->length, context->buf+56);
SHA256Transform(context, context->buf);
for (int i=0; i<8; i++)
putu32(context->buf[i], digest + (4 * i));
for (int i=0; i<8; i++) {
putu32(context->state[i], digest+(4*i));
}
memset(context, 0, sizeof(context));
memset(context, 0, sizeof(struct SHA256Context));
}
/* #define SHA256_F1(x, y, z) (x & y | ~x & z) */
@ -201,40 +208,40 @@ void SHA256Final(unsigned char digest[SHA256Length], struct SHA256Context *conte
#define SHA256_F6(x) (ROR32(x, 17) ^ ROR32(x, 19) ^ SHR(x, 10))
static const uint32_t SHA256_Key[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
INT32(0x428a2f98), INT32(0x71374491), INT32(0xb5c0fbcf), INT32(0xe9b5dba5), INT32(0x3956c25b), INT32(0x59f111f1), INT32(0x923f82a4), INT32(0xab1c5ed5),
INT32(0xd807aa98), INT32(0x12835b01), INT32(0x243185be), INT32(0x550c7dc3), INT32(0x72be5d74), INT32(0x80deb1fe), INT32(0x9bdc06a7), INT32(0xc19bf174),
INT32(0xe49b69c1), INT32(0xefbe4786), INT32(0x0fc19dc6), INT32(0x240ca1cc), INT32(0x2de92c6f), INT32(0x4a7484aa), INT32(0x5cb0a9dc), INT32(0x76f988da),
INT32(0x983e5152), INT32(0xa831c66d), INT32(0xb00327c8), INT32(0xbf597fc7), INT32(0xc6e00bf3), INT32(0xd5a79147), INT32(0x06ca6351), INT32(0x14292967),
INT32(0x27b70a85), INT32(0x2e1b2138), INT32(0x4d2c6dfc), INT32(0x53380d13), INT32(0x650a7354), INT32(0x766a0abb), INT32(0x81c2c92e), INT32(0x92722c85),
INT32(0xa2bfe8a1), INT32(0xa81a664b), INT32(0xc24b8b70), INT32(0xc76c51a3), INT32(0xd192e819), INT32(0xd6990624), INT32(0xf40e3585), INT32(0x106aa070),
INT32(0x19a4c116), INT32(0x1e376c08), INT32(0x2748774c), INT32(0x34b0bcb5), INT32(0x391c0cb3), INT32(0x4ed8aa4a), INT32(0x5b9cca4f), INT32(0x682e6ff3),
INT32(0x748f82ee), INT32(0x78a5636f), INT32(0x84c87814), INT32(0x8cc70208), INT32(0x90befffa), INT32(0xa4506ceb), INT32(0xbef9a3f7), INT32(0xc67178f2)
};
#define SHA256STEP(a, b, c, d, e, f, g, h, s) \
t1 = h + SHA256_F4(e) + SHA256_F1(e, f, g) + SHA256_Key[s] + in[s]; \
t1 = h + SHA256_F4(e) + SHA256_F1(e, f, g) + SHA256_Key[s] + x[s]; \
t2 = SHA256_F3(a) + SHA256_F2(a, b, c); \
d += t1; \
h = t1 + t2;
void SHA256Transform(uint32_t buf[SHA256BufferSize], const unsigned char inraw[64]) {
uint32_t in[64], t1, t2;
void SHA256Transform(struct SHA256Context *context, unsigned char *buf) {
uint32_t x[64], t1, t2;
int i;
uint32_t a = buf[0];
uint32_t b = buf[1];
uint32_t c = buf[2];
uint32_t d = buf[3];
uint32_t e = buf[4];
uint32_t f = buf[5];
uint32_t g = buf[6];
uint32_t h = buf[7];
uint32_t a = context->state[0];
uint32_t b = context->state[1];
uint32_t c = context->state[2];
uint32_t d = context->state[3];
uint32_t e = context->state[4];
uint32_t f = context->state[5];
uint32_t g = context->state[6];
uint32_t h = context->state[7];
for (i = 0; i < 16; i++)
in[i] = getu32(inraw+4*i);
x[i] = getu32(buf+(4*i));
for (i = 16; i < 64; i++)
in[i] = SHA256_F6(in[i - 2]) + in[i - 7] + SHA256_F5(in[i - 15]) + in[i - 16];
x[i] = SHA256_F6(x[i - 2]) + x[i - 7] + SHA256_F5(x[i - 15]) + x[i - 16];
for (int i=0; i<64; i = i + 8) {
SHA256STEP(a, b, c, d, e, f, g, h, i);
@ -247,12 +254,43 @@ void SHA256Transform(uint32_t buf[SHA256BufferSize], const unsigned char inraw[6
SHA256STEP(b, c, d, e, f, g, h, a, i + 7);
}
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
buf[4] += e;
buf[5] += f;
buf[6] += g;
buf[7] += h;
context->state[0] += a;
context->state[1] += b;
context->state[2] += c;
context->state[3] += d;
context->state[4] += e;
context->state[5] += f;
context->state[6] += g;
context->state[7] += h;
}
int SHA256Test() {
static const struct {
char *msg;
unsigned char hash[SHA256Length];
} tests[] = {
{
"abc",
{0xba,0x78,0x16,0xbf,0x8f,0x01,0xcf,0xea,0x41,0x41,0x40,0xde,0x5d,0xae,0x22,0x23,0xb0,0x03,0x61,0xa3,0x96,0x17,0x7a,0x9c,0xb4,0x10,0xff,0x61,0xf2,0x00,0x15,0xad}
},
{
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{0x24,0x8d,0x6a,0x61,0xd2,0x06,0x38,0xb8,0xe5,0xc0,0x26,0x93,0x0c,0x3e,0x60,0x39,0xa3,0x3c,0xe4,0x59,0x64,0xff,0x21,0x67,0xf6,0xec,0xed,0xd4,0x19,0xdb,0x06,0xc1}
},
{NULL, {0}}
};
struct SHA256Context MDContext;
unsigned char MDDigest[SHA256Length];
for (int i=0; tests[i].msg!=NULL; i++) {
SHA256Init(&MDContext);
SHA256Update(&MDContext, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
SHA256Final(MDDigest, &MDContext);
if (memcmp(MDDigest, tests[i].hash, SHA256Length))
return 0;
}
return 1;
}

View File

@ -23,22 +23,25 @@ extern NSString * const MDNSHA384;
extern "C" {
#endif
extern const struct MGMHashDescription SHA384Desc;
char *SHA384String(const char *string, int length);
char *SHA384File(const char *path);
#define SHA384Length 48
#define SHA384BufferSize 8
#define SHA384BufferSize 128
struct SHA384Context {
uint64_t buf[SHA384BufferSize];
uint64_t bits[2];
unsigned char in[128];
uint64_t length, state[8];
unsigned long curlen;
unsigned char buf[SHA384BufferSize];
};
void SHA384Init(struct SHA384Context *context);
void SHA384Update(struct SHA384Context *context, const unsigned char *buf, uint64_t len);
void SHA384Final(unsigned char digest[SHA384Length], struct SHA384Context *context);
void SHA384Transform(uint64_t buf[SHA384BufferSize], const unsigned char inraw[80]);
void SHA384Transform(struct SHA384Context *context, unsigned char *buf);
int SHA384Test();
#ifdef __cplusplus
}

View File

@ -68,10 +68,19 @@ NSString * const MDNSHA384 = @"sha384";
#else
#include <stdio.h>
#include <string.h>
#include "MGMMD5.h"
#include "MGMSHA384.h"
#include "MGMTypes.h"
#endif
const struct MGMHashDescription SHA384Desc = {
"sha384",
sizeof(struct SHA384Context),
(void(*)(void *))&SHA384Init,
(void(*)(void *, const unsigned char *, unsigned))&SHA384Update,
(void(*)(unsigned char *, void *))&SHA384Final,
SHA384Length
};
char *SHA384String(const char *string, int length) {
struct SHA384Context MDContext;
unsigned char MDDigest[SHA384Length];
@ -122,70 +131,69 @@ char *SHA384File(const char *path) {
}
void SHA384Init(struct SHA384Context *context) {
context->buf[0] = INT64(0xcbbb9d5dc1059ed8);
context->buf[1] = INT64(0x629a292a367cd507);
context->buf[2] = INT64(0x9159015a3070dd17);
context->buf[3] = INT64(0x152fecd8f70e5939);
context->buf[4] = INT64(0x67332667ffc00b31);
context->buf[5] = INT64(0x8eb44a8768581511);
context->buf[6] = INT64(0xdb0c2e0d64f98fa7);
context->buf[7] = INT64(0x47b5481dbefa4fa4);
context->state[0] = INT64(0xcbbb9d5dc1059ed8);
context->state[1] = INT64(0x629a292a367cd507);
context->state[2] = INT64(0x9159015a3070dd17);
context->state[3] = INT64(0x152fecd8f70e5939);
context->state[4] = INT64(0x67332667ffc00b31);
context->state[5] = INT64(0x8eb44a8768581511);
context->state[6] = INT64(0xdb0c2e0d64f98fa7);
context->state[7] = INT64(0x47b5481dbefa4fa4);
context->bits[0] = 0;
context->bits[1] = 0;
context->curlen = 0;
context->length = 0;
}
void SHA384Update(struct SHA384Context *context, const unsigned char *buf, uint64_t len) {
uint64_t t;
t = context->bits[0];
if ((context->bits[0] = (t + ((uint64_t)len << 3))) < t)
context->bits[1]++;
context->bits[1] += len >> 61;
t = (t >> 3) & 0x7f;
if (t!=0) {
unsigned char *p = context->in + t;
t = 128-t;
if (len < t) {
memcpy(p, buf, len);
if (buf==NULL)
return;
}
memcpy(p, buf, t);
SHA384Transform(context->buf, context->in);
buf += t;
len -= t;
}
while (len >= 128) {
memcpy(context->in, buf, 128);
SHA384Transform(context->buf, context->in);
buf += 128;
len -= 128;
unsigned long n;
while (len>0) {
if (context->curlen == 0 && len>=SHA384BufferSize) {
SHA384Transform(context, (unsigned char *)buf);
context->length += SHA384BufferSize * 8;
buf += SHA384BufferSize;
len -= SHA384BufferSize;
} else {
n = MIN(len, (SHA384BufferSize-context->curlen));
memcpy(context->buf+context->curlen, buf, (size_t)n);
context->curlen += n;
buf += n;
len -= n;
if (context->curlen == SHA384BufferSize) {
SHA384Transform(context, context->buf);
context->length += 8*SHA384BufferSize;
context->curlen = 0;
}
}
}
memcpy(context->in, buf, len);
}
void SHA384Final(unsigned char digest[SHA384Length], struct SHA384Context *context) {
unsigned char bits[16];
unsigned int count;
context->length += context->curlen * INT64(8);
context->buf[context->curlen++] = (unsigned char)0x80;
putu64(context->bits[1], bits);
putu64(context->bits[0], bits + 8);
if (context->curlen > 112) {
while (context->curlen < 128) {
context->buf[context->curlen++] = (unsigned char)0;
}
SHA384Transform(context, context->buf);
context->curlen = 0;
}
count = (context->bits[0] >> 3) & 0x7f;
count = (count < 112) ? (112 - count) : (240 - count);
SHA384Update(context, MDPadding, count);
while (context->curlen < 120) {
context->buf[context->curlen++] = (unsigned char)0;
}
SHA384Update(context, bits, 16);
putu64(context->length, context->buf+120);
SHA384Transform(context, context->buf);
for (int i=0; i<6; i++)
putu64(context->buf[i], digest + (8 * i));
for (int i=0; i<8; i++) {
putu64(context->state[i], digest+(8*i));
}
memset(context, 0, sizeof(context));
memset(context, 0, sizeof(struct SHA384Context));
}
/* #define SHA384_F1(x, y, z) (x & y | ~x & z) */
@ -224,29 +232,29 @@ static const uint64_t SHA384_Key[128] = {
};
#define SHA384STEP(a, b, c, d, e, f, g, h, s) \
t1 = h + SHA384_F4(e) + SHA384_F1(e, f, g) + SHA384_Key[s] + in[s]; \
t1 = h + SHA384_F4(e) + SHA384_F1(e, f, g) + SHA384_Key[s] + x[s]; \
t2 = SHA384_F3(a) + SHA384_F2(a, b, c); \
d += t1; \
h = t1 + t2;
void SHA384Transform(uint64_t buf[SHA384BufferSize], const unsigned char inraw[80]) {
uint64_t in[80], t1, t2;
void SHA384Transform(struct SHA384Context *context, unsigned char *buf) {
uint64_t x[80], t1, t2;
int i;
uint64_t a = buf[0];
uint64_t b = buf[1];
uint64_t c = buf[2];
uint64_t d = buf[3];
uint64_t e = buf[4];
uint64_t f = buf[5];
uint64_t g = buf[6];
uint64_t h = buf[7];
uint64_t a = context->state[0];
uint64_t b = context->state[1];
uint64_t c = context->state[2];
uint64_t d = context->state[3];
uint64_t e = context->state[4];
uint64_t f = context->state[5];
uint64_t g = context->state[6];
uint64_t h = context->state[7];
for (i = 0; i < 16; i++)
in[i] = getu64(inraw+8*i);
x[i] = getu64(buf+(8*i));
for (i = 16; i < 80; i++)
in[i] = SHA384_F6(in[i - 2]) + in[i - 7] + SHA384_F5(in[i - 15]) + in[i - 16];
x[i] = SHA384_F6(x[i - 2]) + x[i - 7] + SHA384_F5(x[i - 15]) + x[i - 16];
for (int i=0; i<80; i = i + 8) {
SHA384STEP(a, b, c, d, e, f, g, h, i);
@ -259,12 +267,43 @@ void SHA384Transform(uint64_t buf[SHA384BufferSize], const unsigned char inraw[8
SHA384STEP(b, c, d, e, f, g, h, a, i + 7);
}
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
buf[4] += e;
buf[5] += f;
buf[6] += g;
buf[7] += h;
context->state[0] += a;
context->state[1] += b;
context->state[2] += c;
context->state[3] += d;
context->state[4] += e;
context->state[5] += f;
context->state[6] += g;
context->state[7] += h;
}
int SHA384Test() {
static const struct {
char *msg;
unsigned char hash[SHA384Length];
} tests[] = {
{
"abc",
{0xcb,0x00,0x75,0x3f,0x45,0xa3,0x5e,0x8b,0xb5,0xa0,0x3d,0x69,0x9a,0xc6,0x50,0x07,0x27,0x2c,0x32,0xab,0x0e,0xde,0xd1,0x63,0x1a,0x8b,0x60,0x5a,0x43,0xff,0x5b,0xed,0x80,0x86,0x07,0x2b,0xa1,0xe7,0xcc,0x23,0x58,0xba,0xec,0xa1,0x34,0xc8,0x25,0xa7}
},
{
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
{0x09,0x33,0x0c,0x33,0xf7,0x11,0x47,0xe8,0x3d,0x19,0x2f,0xc7,0x82,0xcd,0x1b,0x47,0x53,0x11,0x1b,0x17,0x3b,0x3b,0x05,0xd2,0x2f,0xa0,0x80,0x86,0xe3,0xb0,0xf7,0x12,0xfc,0xc7,0xc7,0x1a,0x55,0x7e,0x2d,0xb9,0x66,0xc3,0xe9,0xfa,0x91,0x74,0x60,0x39}
},
{NULL, {0}}
};
struct SHA384Context MDContext;
unsigned char MDDigest[SHA384Length];
for (int i=0; tests[i].msg!=NULL; i++) {
SHA384Init(&MDContext);
SHA384Update(&MDContext, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
SHA384Final(MDDigest, &MDContext);
if (memcmp(MDDigest, tests[i].hash, SHA384Length))
return 0;
}
return 1;
}

View File

@ -23,22 +23,25 @@ extern NSString * const MDNSHA512;
extern "C" {
#endif
extern const struct MGMHashDescription SHA512Desc;
char *SHA512String(const char *string, int length);
char *SHA512File(const char *path);
#define SHA512Length 64
#define SHA512BufferSize 8
#define SHA512BufferSize 128
struct SHA512Context {
uint64_t buf[SHA512BufferSize];
uint64_t bits[2];
unsigned char in[128];
uint64_t length, state[8];
unsigned long curlen;
unsigned char buf[SHA512BufferSize];
};
void SHA512Init(struct SHA512Context *context);
void SHA512Update(struct SHA512Context *context, const unsigned char *buf, uint64_t len);
void SHA512Final(unsigned char digest[SHA512Length], struct SHA512Context *context);
void SHA512Transform(uint64_t buf[SHA512BufferSize], const unsigned char inraw[80]);
void SHA512Transform(struct SHA512Context *context, unsigned char *buf);
int SHA512Test();
#ifdef __cplusplus
}

View File

@ -68,10 +68,19 @@ NSString * const MDNSHA512 = @"sha512";
#else
#include <stdio.h>
#include <string.h>
#include "MGMMD5.h"
#include "MGMSHA512.h"
#include "MGMTypes.h"
#endif
const struct MGMHashDescription SHA512Desc = {
"sha512",
sizeof(struct SHA512Context),
(void(*)(void *))&SHA512Init,
(void(*)(void *, const unsigned char *, unsigned))&SHA512Update,
(void(*)(unsigned char *, void *))&SHA512Final,
SHA512Length
};
char *SHA512String(const char *string, int length) {
struct SHA512Context MDContext;
unsigned char MDDigest[SHA512Length];
@ -122,70 +131,68 @@ char *SHA512File(const char *path) {
}
void SHA512Init(struct SHA512Context *context) {
context->buf[0] = INT64(0x6a09e667f3bcc908);
context->buf[1] = INT64(0xbb67ae8584caa73b);
context->buf[2] = INT64(0x3c6ef372fe94f82b);
context->buf[3] = INT64(0xa54ff53a5f1d36f1);
context->buf[4] = INT64(0x510e527fade682d1);
context->buf[5] = INT64(0x9b05688c2b3e6c1f);
context->buf[6] = INT64(0x1f83d9abfb41bd6b);
context->buf[7] = INT64(0x5be0cd19137e2179);
context->state[0] = INT64(0x6a09e667f3bcc908);
context->state[1] = INT64(0xbb67ae8584caa73b);
context->state[2] = INT64(0x3c6ef372fe94f82b);
context->state[3] = INT64(0xa54ff53a5f1d36f1);
context->state[4] = INT64(0x510e527fade682d1);
context->state[5] = INT64(0x9b05688c2b3e6c1f);
context->state[6] = INT64(0x1f83d9abfb41bd6b);
context->state[7] = INT64(0x5be0cd19137e2179);
context->bits[0] = 0;
context->bits[1] = 0;
context->curlen = 0;
context->length = 0;
}
void SHA512Update(struct SHA512Context *context, const unsigned char *buf, uint64_t len) {
uint64_t t;
t = context->bits[0];
if ((context->bits[0] = (t + ((uint64_t)len << 3))) < t)
context->bits[1]++;
context->bits[1] += len >> 61;
t = (t >> 3) & 0x7f;
if (t!=0) {
unsigned char *p = context->in + t;
t = 128-t;
if (len < t) {
memcpy(p, buf, len);
if (buf==NULL)
return;
unsigned long n;
while (len>0) {
if (context->curlen == 0 && len>=SHA512BufferSize) {
SHA512Transform(context, (unsigned char *)buf);
context->length += SHA512BufferSize * 8;
buf += SHA512BufferSize;
len -= SHA512BufferSize;
} else {
n = MIN(len, (SHA512BufferSize-context->curlen));
memcpy(context->buf+context->curlen, buf, (size_t)n);
context->curlen += n;
buf += n;
len -= n;
if (context->curlen == SHA512BufferSize) {
SHA512Transform(context, context->buf);
context->length += 8*SHA512BufferSize;
context->curlen = 0;
}
memcpy(p, buf, t);
SHA512Transform(context->buf, context->in);
buf += t;
len -= t;
}
while (len >= 128) {
memcpy(context->in, buf, 128);
SHA512Transform(context->buf, context->in);
buf += 128;
len -= 128;
}
memcpy(context->in, buf, len);
}
void SHA512Final(unsigned char digest[SHA512Length], struct SHA512Context *context) {
unsigned char bits[16];
unsigned int count;
context->length += context->curlen * INT64(8);
context->buf[context->curlen++] = (unsigned char)0x80;
putu64(context->bits[1], bits);
putu64(context->bits[0], bits + 8);
if (context->curlen > 112) {
while (context->curlen < 128) {
context->buf[context->curlen++] = (unsigned char)0;
}
SHA512Transform(context, context->buf);
context->curlen = 0;
}
count = (context->bits[0] >> 3) & 0x7f;
count = (count < 112) ? (112 - count) : (240 - count);
SHA512Update(context, MDPadding, count);
while (context->curlen < 120) {
context->buf[context->curlen++] = (unsigned char)0;
}
SHA512Update(context, bits, 16);
putu64(context->length, context->buf+120);
SHA512Transform(context, context->buf);
for (int i=0; i<8; i++)
putu64(context->buf[i], digest + (8 * i));
for (int i=0; i<8; i++) {
putu64(context->state[i], digest+(8*i));
}
memset(context, 0, sizeof(context));
memset(context, 0, sizeof(struct SHA512Context));
}
/* #define SHA512_F1(x, y, z) (x & y | ~x & z) */
@ -224,29 +231,29 @@ static const uint64_t SHA512_Key[128] = {
};
#define SHA512STEP(a, b, c, d, e, f, g, h, s) \
t1 = h + SHA512_F4(e) + SHA512_F1(e, f, g) + SHA512_Key[s] + in[s]; \
t1 = h + SHA512_F4(e) + SHA512_F1(e, f, g) + SHA512_Key[s] + x[s]; \
t2 = SHA512_F3(a) + SHA512_F2(a, b, c); \
d += t1; \
h = t1 + t2;
void SHA512Transform(uint64_t buf[SHA512BufferSize], const unsigned char inraw[80]) {
uint64_t in[80], t1, t2;
void SHA512Transform(struct SHA512Context *context, unsigned char *buf) {
uint64_t x[80], t1, t2;
int i;
uint64_t a = buf[0];
uint64_t b = buf[1];
uint64_t c = buf[2];
uint64_t d = buf[3];
uint64_t e = buf[4];
uint64_t f = buf[5];
uint64_t g = buf[6];
uint64_t h = buf[7];
uint64_t a = context->state[0];
uint64_t b = context->state[1];
uint64_t c = context->state[2];
uint64_t d = context->state[3];
uint64_t e = context->state[4];
uint64_t f = context->state[5];
uint64_t g = context->state[6];
uint64_t h = context->state[7];
for (i = 0; i < 16; i++)
in[i] = getu64(inraw+8*i);
x[i] = getu64(buf+(8*i));
for (i = 16; i < 80; i++)
in[i] = SHA512_F6(in[i - 2]) + in[i - 7] + SHA512_F5(in[i - 15]) + in[i - 16];
x[i] = SHA512_F6(x[i - 2]) + x[i - 7] + SHA512_F5(x[i - 15]) + x[i - 16];
for (int i=0; i<80; i = i + 8) {
SHA512STEP(a, b, c, d, e, f, g, h, i);
@ -259,12 +266,43 @@ void SHA512Transform(uint64_t buf[SHA512BufferSize], const unsigned char inraw[8
SHA512STEP(b, c, d, e, f, g, h, a, i + 7);
}
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
buf[4] += e;
buf[5] += f;
buf[6] += g;
buf[7] += h;
context->state[0] += a;
context->state[1] += b;
context->state[2] += c;
context->state[3] += d;
context->state[4] += e;
context->state[5] += f;
context->state[6] += g;
context->state[7] += h;
}
int SHA512Test() {
static const struct {
char *msg;
unsigned char hash[SHA512Length];
} tests[] = {
{
"abc",
{0xdd,0xaf,0x35,0xa1,0x93,0x61,0x7a,0xba,0xcc,0x41,0x73,0x49,0xae,0x20,0x41,0x31,0x12,0xe6,0xfa,0x4e,0x89,0xa9,0x7e,0xa2,0x0a,0x9e,0xee,0xe6,0x4b,0x55,0xd3,0x9a,0x21,0x92,0x99,0x2a,0x27,0x4f,0xc1,0xa8,0x36,0xba,0x3c,0x23,0xa3,0xfe,0xeb,0xbd,0x45,0x4d,0x44,0x23,0x64,0x3c,0xe8,0x0e,0x2a,0x9a,0xc9,0x4f,0xa5,0x4c,0xa4,0x9f}
},
{
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
{0x8e,0x95,0x9b,0x75,0xda,0xe3,0x13,0xda,0x8c,0xf4,0xf7,0x28,0x14,0xfc,0x14,0x3f,0x8f,0x77,0x79,0xc6,0xeb,0x9f,0x7f,0xa1,0x72,0x99,0xae,0xad,0xb6,0x88,0x90,0x18,0x50,0x1d,0x28,0x9e,0x49,0x00,0xf7,0xe4,0x33,0x1b,0x99,0xde,0xc4,0xb5,0x43,0x3a,0xc7,0xd3,0x29,0xee,0xb6,0xdd,0x26,0x54,0x5e,0x96,0xe5,0x5b,0x87,0x4b,0xe9,0x09}
},
{NULL, {0}}
};
struct SHA512Context MDContext;
unsigned char MDDigest[SHA512Length];
for (int i=0; tests[i].msg!=NULL; i++) {
SHA512Init(&MDContext);
SHA512Update(&MDContext, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
SHA512Final(MDDigest, &MDContext);
if (memcmp(MDDigest, tests[i].hash, SHA512Length))
return 0;
}
return 1;
}

51
Classes/MD/MGMTiger.h Normal file
View File

@ -0,0 +1,51 @@
//
// MGMTiger.h
//
// Created by Mr. Gecko <GRMrGecko@gmail.com> on 5/31/11.
// No Copyright Claimed. Public Domain.
//
#ifndef _MD_Tiger
#define _MD_Tiger
#ifdef __NEXT_RUNTIME__
#import <Foundation/Foundation.h>
extern NSString * const MDNTiger;
@interface NSString (MGMTiger)
- (NSString *)tiger;
- (NSString *)pathTiger;
@end
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern const struct MGMHashDescription tigerDesc;
char *tigerString(const char *string, int length);
char *tigerFile(const char *path);
#define tigerLength 24
#define tigerBufferSize 64
struct tigerContext {
uint64_t state[3], length;
unsigned long curlen;
unsigned char buf[tigerBufferSize];
};
void tigerInit(struct tigerContext *context);
void tigerUpdate(struct tigerContext *context, const unsigned char *buf, unsigned len);
void tigerFinal(unsigned char digest[tigerLength], struct tigerContext *context);
void tigerTransform(struct tigerContext *context, unsigned char *buf);
int tigerTest();
#ifdef __cplusplus
}
#endif
#endif

822
Classes/MD/MGMTiger.m Normal file
View File

@ -0,0 +1,822 @@
//
// MGMTiger.m
//
// Created by Mr. Gecko <GRMrGecko@gmail.com> on 5/31/11.
// No Copyright Claimed. Public Domain.
// C Algorithm created by Tom St Denis <tomstdenis@gmail.com> <http://libtom.org>
//
#ifdef __NEXT_RUNTIME__
#import "MGMTiger.h"
#import "MGMTypes.h"
NSString * const MDNTiger = @"tiger";
@implementation NSString (MGMTiger)
- (NSString *)tiger {
NSData *MDData = [self dataUsingEncoding:NSUTF8StringEncoding];
struct tigerContext MDContext;
unsigned char MDDigest[tigerLength];
tigerInit(&MDContext);
tigerUpdate(&MDContext, [MDData bytes], [MDData length]);
tigerFinal(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(tigerLength * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<tigerLength; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
NSString *hash = [NSString stringWithUTF8String:stringBuffer];
free(stringBuffer);
return hash;
}
- (NSString *)pathTiger {
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:self];
if (file==nil)
return nil;
struct tigerContext MDContext;
unsigned char MDDigest[tigerLength];
tigerInit(&MDContext);
int length;
do {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSData *MDData = [file readDataOfLength:MDFileReadLength];
length = [MDData length];
tigerUpdate(&MDContext, [MDData bytes], length);
[pool release];
} while (length>0);
tigerFinal(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(tigerLength * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<tigerLength; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
NSString *hash = [NSString stringWithUTF8String:stringBuffer];
free(stringBuffer);
return hash;
}
@end
#else
#include <stdio.h>
#include <string.h>
#include "MGMTiger.h"
#include "MGMTypes.h"
#endif
const struct MGMHashDescription tigerDesc = {
"tiger",
sizeof(struct tigerContext),
(void(*)(void *))&tigerInit,
(void(*)(void *, const unsigned char *, unsigned))&tigerUpdate,
(void(*)(unsigned char *, void *))&tigerFinal,
tigerLength
};
char *tigerString(const char *string, int length) {
struct tigerContext MDContext;
unsigned char MDDigest[tigerLength];
tigerInit(&MDContext);
tigerUpdate(&MDContext, (const unsigned char *)string, length);
tigerFinal(MDDigest, &MDContext);
char *stringBuffer = (char *)malloc(tigerLength * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<tigerLength; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
return stringBuffer;
}
char *tigerFile(const char *path) {
FILE *file = fopen(path, "r");
if (file==NULL)
return NULL;
struct tigerContext MDContext;
unsigned char MDDigest[tigerLength];
tigerInit(&MDContext);
int length;
do {
unsigned char MDData[MDFileReadLength];
length = fread(&MDData, 1, MDFileReadLength, file);
tigerUpdate(&MDContext, MDData, length);
} while (length>0);
tigerFinal(MDDigest, &MDContext);
fclose(file);
char *stringBuffer = (char *)malloc(tigerLength * 2 + 1);
char *hexBuffer = stringBuffer;
for (int i=0; i<tigerLength; i++) {
*hexBuffer++ = hexdigits[(MDDigest[i] >> 4) & 0xF];
*hexBuffer++ = hexdigits[MDDigest[i] & 0xF];
}
*hexBuffer = '\0';
return stringBuffer;
}
void tigerInit(struct tigerContext *context) {
context->state[0] = INT64(0x0123456789ABCDEF);
context->state[1] = INT64(0xFEDCBA9876543210);
context->state[2] = INT64(0xF096A5B4C3B2E187);
context->curlen = 0;
context->length = 0;
}
void tigerUpdate(struct tigerContext *context, const unsigned char *buf, unsigned len) {
if (buf==NULL)
return;
unsigned long n;
while (len>0) {
if (context->curlen == 0 && len>=tigerBufferSize) {
tigerTransform(context, (unsigned char *)buf);
context->length += tigerBufferSize * 8;
buf += tigerBufferSize;
len -= tigerBufferSize;
} else {
n = MIN(len, (tigerBufferSize-context->curlen));
memcpy(context->buf+context->curlen, buf, (size_t)n);
context->curlen += n;
buf += n;
len -= n;
if (context->curlen == tigerBufferSize) {
tigerTransform(context, context->buf);
context->length += 8*tigerBufferSize;
context->curlen = 0;
}
}
}
}
void tigerFinal(unsigned char digest[tigerLength], struct tigerContext *context) {
context->length += context->curlen * 8;
context->buf[context->curlen++] = (unsigned char)0x01;
if (context->curlen > 56) {
while (context->curlen < 64) {
context->buf[context->curlen++] = (unsigned char)0;
}
tigerTransform(context, context->buf);
context->curlen = 0;
}
while (context->curlen < 56) {
context->buf[context->curlen++] = (unsigned char)0;
}
putu64l(context->length, context->buf+56);
tigerTransform(context, context->buf);
putu64l(context->state[0], &digest[0]);
putu64l(context->state[1], &digest[8]);
putu64l(context->state[2], &digest[16]);
memset(context, 0, sizeof(struct tigerContext));
}
#define tiger_t1 (table)
#define tiger_t2 (table+256)
#define tiger_t3 (table+256*2)
#define tiger_t4 (table+256*3)
static const uint64_t table[4*256] = {
INT64(0x02AAB17CF7E90C5E) /* 0 */, INT64(0xAC424B03E243A8EC) /* 1 */,
INT64(0x72CD5BE30DD5FCD3) /* 2 */, INT64(0x6D019B93F6F97F3A) /* 3 */,
INT64(0xCD9978FFD21F9193) /* 4 */, INT64(0x7573A1C9708029E2) /* 5 */,
INT64(0xB164326B922A83C3) /* 6 */, INT64(0x46883EEE04915870) /* 7 */,
INT64(0xEAACE3057103ECE6) /* 8 */, INT64(0xC54169B808A3535C) /* 9 */,
INT64(0x4CE754918DDEC47C) /* 10 */, INT64(0x0AA2F4DFDC0DF40C) /* 11 */,
INT64(0x10B76F18A74DBEFA) /* 12 */, INT64(0xC6CCB6235AD1AB6A) /* 13 */,
INT64(0x13726121572FE2FF) /* 14 */, INT64(0x1A488C6F199D921E) /* 15 */,
INT64(0x4BC9F9F4DA0007CA) /* 16 */, INT64(0x26F5E6F6E85241C7) /* 17 */,
INT64(0x859079DBEA5947B6) /* 18 */, INT64(0x4F1885C5C99E8C92) /* 19 */,
INT64(0xD78E761EA96F864B) /* 20 */, INT64(0x8E36428C52B5C17D) /* 21 */,
INT64(0x69CF6827373063C1) /* 22 */, INT64(0xB607C93D9BB4C56E) /* 23 */,
INT64(0x7D820E760E76B5EA) /* 24 */, INT64(0x645C9CC6F07FDC42) /* 25 */,
INT64(0xBF38A078243342E0) /* 26 */, INT64(0x5F6B343C9D2E7D04) /* 27 */,
INT64(0xF2C28AEB600B0EC6) /* 28 */, INT64(0x6C0ED85F7254BCAC) /* 29 */,
INT64(0x71592281A4DB4FE5) /* 30 */, INT64(0x1967FA69CE0FED9F) /* 31 */,
INT64(0xFD5293F8B96545DB) /* 32 */, INT64(0xC879E9D7F2A7600B) /* 33 */,
INT64(0x860248920193194E) /* 34 */, INT64(0xA4F9533B2D9CC0B3) /* 35 */,
INT64(0x9053836C15957613) /* 36 */, INT64(0xDB6DCF8AFC357BF1) /* 37 */,
INT64(0x18BEEA7A7A370F57) /* 38 */, INT64(0x037117CA50B99066) /* 39 */,
INT64(0x6AB30A9774424A35) /* 40 */, INT64(0xF4E92F02E325249B) /* 41 */,
INT64(0x7739DB07061CCAE1) /* 42 */, INT64(0xD8F3B49CECA42A05) /* 43 */,
INT64(0xBD56BE3F51382F73) /* 44 */, INT64(0x45FAED5843B0BB28) /* 45 */,
INT64(0x1C813D5C11BF1F83) /* 46 */, INT64(0x8AF0E4B6D75FA169) /* 47 */,
INT64(0x33EE18A487AD9999) /* 48 */, INT64(0x3C26E8EAB1C94410) /* 49 */,
INT64(0xB510102BC0A822F9) /* 50 */, INT64(0x141EEF310CE6123B) /* 51 */,
INT64(0xFC65B90059DDB154) /* 52 */, INT64(0xE0158640C5E0E607) /* 53 */,
INT64(0x884E079826C3A3CF) /* 54 */, INT64(0x930D0D9523C535FD) /* 55 */,
INT64(0x35638D754E9A2B00) /* 56 */, INT64(0x4085FCCF40469DD5) /* 57 */,
INT64(0xC4B17AD28BE23A4C) /* 58 */, INT64(0xCAB2F0FC6A3E6A2E) /* 59 */,
INT64(0x2860971A6B943FCD) /* 60 */, INT64(0x3DDE6EE212E30446) /* 61 */,
INT64(0x6222F32AE01765AE) /* 62 */, INT64(0x5D550BB5478308FE) /* 63 */,
INT64(0xA9EFA98DA0EDA22A) /* 64 */, INT64(0xC351A71686C40DA7) /* 65 */,
INT64(0x1105586D9C867C84) /* 66 */, INT64(0xDCFFEE85FDA22853) /* 67 */,
INT64(0xCCFBD0262C5EEF76) /* 68 */, INT64(0xBAF294CB8990D201) /* 69 */,
INT64(0xE69464F52AFAD975) /* 70 */, INT64(0x94B013AFDF133E14) /* 71 */,
INT64(0x06A7D1A32823C958) /* 72 */, INT64(0x6F95FE5130F61119) /* 73 */,
INT64(0xD92AB34E462C06C0) /* 74 */, INT64(0xED7BDE33887C71D2) /* 75 */,
INT64(0x79746D6E6518393E) /* 76 */, INT64(0x5BA419385D713329) /* 77 */,
INT64(0x7C1BA6B948A97564) /* 78 */, INT64(0x31987C197BFDAC67) /* 79 */,
INT64(0xDE6C23C44B053D02) /* 80 */, INT64(0x581C49FED002D64D) /* 81 */,
INT64(0xDD474D6338261571) /* 82 */, INT64(0xAA4546C3E473D062) /* 83 */,
INT64(0x928FCE349455F860) /* 84 */, INT64(0x48161BBACAAB94D9) /* 85 */,
INT64(0x63912430770E6F68) /* 86 */, INT64(0x6EC8A5E602C6641C) /* 87 */,
INT64(0x87282515337DDD2B) /* 88 */, INT64(0x2CDA6B42034B701B) /* 89 */,
INT64(0xB03D37C181CB096D) /* 90 */, INT64(0xE108438266C71C6F) /* 91 */,
INT64(0x2B3180C7EB51B255) /* 92 */, INT64(0xDF92B82F96C08BBC) /* 93 */,
INT64(0x5C68C8C0A632F3BA) /* 94 */, INT64(0x5504CC861C3D0556) /* 95 */,
INT64(0xABBFA4E55FB26B8F) /* 96 */, INT64(0x41848B0AB3BACEB4) /* 97 */,
INT64(0xB334A273AA445D32) /* 98 */, INT64(0xBCA696F0A85AD881) /* 99 */,
INT64(0x24F6EC65B528D56C) /* 100 */, INT64(0x0CE1512E90F4524A) /* 101 */,
INT64(0x4E9DD79D5506D35A) /* 102 */, INT64(0x258905FAC6CE9779) /* 103 */,
INT64(0x2019295B3E109B33) /* 104 */, INT64(0xF8A9478B73A054CC) /* 105 */,
INT64(0x2924F2F934417EB0) /* 106 */, INT64(0x3993357D536D1BC4) /* 107 */,
INT64(0x38A81AC21DB6FF8B) /* 108 */, INT64(0x47C4FBF17D6016BF) /* 109 */,
INT64(0x1E0FAADD7667E3F5) /* 110 */, INT64(0x7ABCFF62938BEB96) /* 111 */,
INT64(0xA78DAD948FC179C9) /* 112 */, INT64(0x8F1F98B72911E50D) /* 113 */,
INT64(0x61E48EAE27121A91) /* 114 */, INT64(0x4D62F7AD31859808) /* 115 */,
INT64(0xECEBA345EF5CEAEB) /* 116 */, INT64(0xF5CEB25EBC9684CE) /* 117 */,
INT64(0xF633E20CB7F76221) /* 118 */, INT64(0xA32CDF06AB8293E4) /* 119 */,
INT64(0x985A202CA5EE2CA4) /* 120 */, INT64(0xCF0B8447CC8A8FB1) /* 121 */,
INT64(0x9F765244979859A3) /* 122 */, INT64(0xA8D516B1A1240017) /* 123 */,
INT64(0x0BD7BA3EBB5DC726) /* 124 */, INT64(0xE54BCA55B86ADB39) /* 125 */,
INT64(0x1D7A3AFD6C478063) /* 126 */, INT64(0x519EC608E7669EDD) /* 127 */,
INT64(0x0E5715A2D149AA23) /* 128 */, INT64(0x177D4571848FF194) /* 129 */,
INT64(0xEEB55F3241014C22) /* 130 */, INT64(0x0F5E5CA13A6E2EC2) /* 131 */,
INT64(0x8029927B75F5C361) /* 132 */, INT64(0xAD139FABC3D6E436) /* 133 */,
INT64(0x0D5DF1A94CCF402F) /* 134 */, INT64(0x3E8BD948BEA5DFC8) /* 135 */,
INT64(0xA5A0D357BD3FF77E) /* 136 */, INT64(0xA2D12E251F74F645) /* 137 */,
INT64(0x66FD9E525E81A082) /* 138 */, INT64(0x2E0C90CE7F687A49) /* 139 */,
INT64(0xC2E8BCBEBA973BC5) /* 140 */, INT64(0x000001BCE509745F) /* 141 */,
INT64(0x423777BBE6DAB3D6) /* 142 */, INT64(0xD1661C7EAEF06EB5) /* 143 */,
INT64(0xA1781F354DAACFD8) /* 144 */, INT64(0x2D11284A2B16AFFC) /* 145 */,
INT64(0xF1FC4F67FA891D1F) /* 146 */, INT64(0x73ECC25DCB920ADA) /* 147 */,
INT64(0xAE610C22C2A12651) /* 148 */, INT64(0x96E0A810D356B78A) /* 149 */,
INT64(0x5A9A381F2FE7870F) /* 150 */, INT64(0xD5AD62EDE94E5530) /* 151 */,
INT64(0xD225E5E8368D1427) /* 152 */, INT64(0x65977B70C7AF4631) /* 153 */,
INT64(0x99F889B2DE39D74F) /* 154 */, INT64(0x233F30BF54E1D143) /* 155 */,
INT64(0x9A9675D3D9A63C97) /* 156 */, INT64(0x5470554FF334F9A8) /* 157 */,
INT64(0x166ACB744A4F5688) /* 158 */, INT64(0x70C74CAAB2E4AEAD) /* 159 */,
INT64(0xF0D091646F294D12) /* 160 */, INT64(0x57B82A89684031D1) /* 161 */,
INT64(0xEFD95A5A61BE0B6B) /* 162 */, INT64(0x2FBD12E969F2F29A) /* 163 */,
INT64(0x9BD37013FEFF9FE8) /* 164 */, INT64(0x3F9B0404D6085A06) /* 165 */,
INT64(0x4940C1F3166CFE15) /* 166 */, INT64(0x09542C4DCDF3DEFB) /* 167 */,
INT64(0xB4C5218385CD5CE3) /* 168 */, INT64(0xC935B7DC4462A641) /* 169 */,
INT64(0x3417F8A68ED3B63F) /* 170 */, INT64(0xB80959295B215B40) /* 171 */,
INT64(0xF99CDAEF3B8C8572) /* 172 */, INT64(0x018C0614F8FCB95D) /* 173 */,
INT64(0x1B14ACCD1A3ACDF3) /* 174 */, INT64(0x84D471F200BB732D) /* 175 */,
INT64(0xC1A3110E95E8DA16) /* 176 */, INT64(0x430A7220BF1A82B8) /* 177 */,
INT64(0xB77E090D39DF210E) /* 178 */, INT64(0x5EF4BD9F3CD05E9D) /* 179 */,
INT64(0x9D4FF6DA7E57A444) /* 180 */, INT64(0xDA1D60E183D4A5F8) /* 181 */,
INT64(0xB287C38417998E47) /* 182 */, INT64(0xFE3EDC121BB31886) /* 183 */,
INT64(0xC7FE3CCC980CCBEF) /* 184 */, INT64(0xE46FB590189BFD03) /* 185 */,
INT64(0x3732FD469A4C57DC) /* 186 */, INT64(0x7EF700A07CF1AD65) /* 187 */,
INT64(0x59C64468A31D8859) /* 188 */, INT64(0x762FB0B4D45B61F6) /* 189 */,
INT64(0x155BAED099047718) /* 190 */, INT64(0x68755E4C3D50BAA6) /* 191 */,
INT64(0xE9214E7F22D8B4DF) /* 192 */, INT64(0x2ADDBF532EAC95F4) /* 193 */,
INT64(0x32AE3909B4BD0109) /* 194 */, INT64(0x834DF537B08E3450) /* 195 */,
INT64(0xFA209DA84220728D) /* 196 */, INT64(0x9E691D9B9EFE23F7) /* 197 */,
INT64(0x0446D288C4AE8D7F) /* 198 */, INT64(0x7B4CC524E169785B) /* 199 */,
INT64(0x21D87F0135CA1385) /* 200 */, INT64(0xCEBB400F137B8AA5) /* 201 */,
INT64(0x272E2B66580796BE) /* 202 */, INT64(0x3612264125C2B0DE) /* 203 */,
INT64(0x057702BDAD1EFBB2) /* 204 */, INT64(0xD4BABB8EACF84BE9) /* 205 */,
INT64(0x91583139641BC67B) /* 206 */, INT64(0x8BDC2DE08036E024) /* 207 */,
INT64(0x603C8156F49F68ED) /* 208 */, INT64(0xF7D236F7DBEF5111) /* 209 */,
INT64(0x9727C4598AD21E80) /* 210 */, INT64(0xA08A0896670A5FD7) /* 211 */,
INT64(0xCB4A8F4309EBA9CB) /* 212 */, INT64(0x81AF564B0F7036A1) /* 213 */,
INT64(0xC0B99AA778199ABD) /* 214 */, INT64(0x959F1EC83FC8E952) /* 215 */,
INT64(0x8C505077794A81B9) /* 216 */, INT64(0x3ACAAF8F056338F0) /* 217 */,
INT64(0x07B43F50627A6778) /* 218 */, INT64(0x4A44AB49F5ECCC77) /* 219 */,
INT64(0x3BC3D6E4B679EE98) /* 220 */, INT64(0x9CC0D4D1CF14108C) /* 221 */,
INT64(0x4406C00B206BC8A0) /* 222 */, INT64(0x82A18854C8D72D89) /* 223 */,
INT64(0x67E366B35C3C432C) /* 224 */, INT64(0xB923DD61102B37F2) /* 225 */,
INT64(0x56AB2779D884271D) /* 226 */, INT64(0xBE83E1B0FF1525AF) /* 227 */,
INT64(0xFB7C65D4217E49A9) /* 228 */, INT64(0x6BDBE0E76D48E7D4) /* 229 */,
INT64(0x08DF828745D9179E) /* 230 */, INT64(0x22EA6A9ADD53BD34) /* 231 */,
INT64(0xE36E141C5622200A) /* 232 */, INT64(0x7F805D1B8CB750EE) /* 233 */,
INT64(0xAFE5C7A59F58E837) /* 234 */, INT64(0xE27F996A4FB1C23C) /* 235 */,
INT64(0xD3867DFB0775F0D0) /* 236 */, INT64(0xD0E673DE6E88891A) /* 237 */,
INT64(0x123AEB9EAFB86C25) /* 238 */, INT64(0x30F1D5D5C145B895) /* 239 */,
INT64(0xBB434A2DEE7269E7) /* 240 */, INT64(0x78CB67ECF931FA38) /* 241 */,
INT64(0xF33B0372323BBF9C) /* 242 */, INT64(0x52D66336FB279C74) /* 243 */,
INT64(0x505F33AC0AFB4EAA) /* 244 */, INT64(0xE8A5CD99A2CCE187) /* 245 */,
INT64(0x534974801E2D30BB) /* 246 */, INT64(0x8D2D5711D5876D90) /* 247 */,
INT64(0x1F1A412891BC038E) /* 248 */, INT64(0xD6E2E71D82E56648) /* 249 */,
INT64(0x74036C3A497732B7) /* 250 */, INT64(0x89B67ED96361F5AB) /* 251 */,
INT64(0xFFED95D8F1EA02A2) /* 252 */, INT64(0xE72B3BD61464D43D) /* 253 */,
INT64(0xA6300F170BDC4820) /* 254 */, INT64(0xEBC18760ED78A77A) /* 255 */,
INT64(0xE6A6BE5A05A12138) /* 256 */, INT64(0xB5A122A5B4F87C98) /* 257 */,
INT64(0x563C6089140B6990) /* 258 */, INT64(0x4C46CB2E391F5DD5) /* 259 */,
INT64(0xD932ADDBC9B79434) /* 260 */, INT64(0x08EA70E42015AFF5) /* 261 */,
INT64(0xD765A6673E478CF1) /* 262 */, INT64(0xC4FB757EAB278D99) /* 263 */,
INT64(0xDF11C6862D6E0692) /* 264 */, INT64(0xDDEB84F10D7F3B16) /* 265 */,
INT64(0x6F2EF604A665EA04) /* 266 */, INT64(0x4A8E0F0FF0E0DFB3) /* 267 */,
INT64(0xA5EDEEF83DBCBA51) /* 268 */, INT64(0xFC4F0A2A0EA4371E) /* 269 */,
INT64(0xE83E1DA85CB38429) /* 270 */, INT64(0xDC8FF882BA1B1CE2) /* 271 */,
INT64(0xCD45505E8353E80D) /* 272 */, INT64(0x18D19A00D4DB0717) /* 273 */,
INT64(0x34A0CFEDA5F38101) /* 274 */, INT64(0x0BE77E518887CAF2) /* 275 */,
INT64(0x1E341438B3C45136) /* 276 */, INT64(0xE05797F49089CCF9) /* 277 */,
INT64(0xFFD23F9DF2591D14) /* 278 */, INT64(0x543DDA228595C5CD) /* 279 */,
INT64(0x661F81FD99052A33) /* 280 */, INT64(0x8736E641DB0F7B76) /* 281 */,
INT64(0x15227725418E5307) /* 282 */, INT64(0xE25F7F46162EB2FA) /* 283 */,
INT64(0x48A8B2126C13D9FE) /* 284 */, INT64(0xAFDC541792E76EEA) /* 285 */,
INT64(0x03D912BFC6D1898F) /* 286 */, INT64(0x31B1AAFA1B83F51B) /* 287 */,
INT64(0xF1AC2796E42AB7D9) /* 288 */, INT64(0x40A3A7D7FCD2EBAC) /* 289 */,
INT64(0x1056136D0AFBBCC5) /* 290 */, INT64(0x7889E1DD9A6D0C85) /* 291 */,
INT64(0xD33525782A7974AA) /* 292 */, INT64(0xA7E25D09078AC09B) /* 293 */,
INT64(0xBD4138B3EAC6EDD0) /* 294 */, INT64(0x920ABFBE71EB9E70) /* 295 */,
INT64(0xA2A5D0F54FC2625C) /* 296 */, INT64(0xC054E36B0B1290A3) /* 297 */,
INT64(0xF6DD59FF62FE932B) /* 298 */, INT64(0x3537354511A8AC7D) /* 299 */,
INT64(0xCA845E9172FADCD4) /* 300 */, INT64(0x84F82B60329D20DC) /* 301 */,
INT64(0x79C62CE1CD672F18) /* 302 */, INT64(0x8B09A2ADD124642C) /* 303 */,
INT64(0xD0C1E96A19D9E726) /* 304 */, INT64(0x5A786A9B4BA9500C) /* 305 */,
INT64(0x0E020336634C43F3) /* 306 */, INT64(0xC17B474AEB66D822) /* 307 */,
INT64(0x6A731AE3EC9BAAC2) /* 308 */, INT64(0x8226667AE0840258) /* 309 */,
INT64(0x67D4567691CAECA5) /* 310 */, INT64(0x1D94155C4875ADB5) /* 311 */,
INT64(0x6D00FD985B813FDF) /* 312 */, INT64(0x51286EFCB774CD06) /* 313 */,
INT64(0x5E8834471FA744AF) /* 314 */, INT64(0xF72CA0AEE761AE2E) /* 315 */,
INT64(0xBE40E4CDAEE8E09A) /* 316 */, INT64(0xE9970BBB5118F665) /* 317 */,
INT64(0x726E4BEB33DF1964) /* 318 */, INT64(0x703B000729199762) /* 319 */,
INT64(0x4631D816F5EF30A7) /* 320 */, INT64(0xB880B5B51504A6BE) /* 321 */,
INT64(0x641793C37ED84B6C) /* 322 */, INT64(0x7B21ED77F6E97D96) /* 323 */,
INT64(0x776306312EF96B73) /* 324 */, INT64(0xAE528948E86FF3F4) /* 325 */,
INT64(0x53DBD7F286A3F8F8) /* 326 */, INT64(0x16CADCE74CFC1063) /* 327 */,
INT64(0x005C19BDFA52C6DD) /* 328 */, INT64(0x68868F5D64D46AD3) /* 329 */,
INT64(0x3A9D512CCF1E186A) /* 330 */, INT64(0x367E62C2385660AE) /* 331 */,
INT64(0xE359E7EA77DCB1D7) /* 332 */, INT64(0x526C0773749ABE6E) /* 333 */,
INT64(0x735AE5F9D09F734B) /* 334 */, INT64(0x493FC7CC8A558BA8) /* 335 */,
INT64(0xB0B9C1533041AB45) /* 336 */, INT64(0x321958BA470A59BD) /* 337 */,
INT64(0x852DB00B5F46C393) /* 338 */, INT64(0x91209B2BD336B0E5) /* 339 */,
INT64(0x6E604F7D659EF19F) /* 340 */, INT64(0xB99A8AE2782CCB24) /* 341 */,
INT64(0xCCF52AB6C814C4C7) /* 342 */, INT64(0x4727D9AFBE11727B) /* 343 */,
INT64(0x7E950D0C0121B34D) /* 344 */, INT64(0x756F435670AD471F) /* 345 */,
INT64(0xF5ADD442615A6849) /* 346 */, INT64(0x4E87E09980B9957A) /* 347 */,
INT64(0x2ACFA1DF50AEE355) /* 348 */, INT64(0xD898263AFD2FD556) /* 349 */,
INT64(0xC8F4924DD80C8FD6) /* 350 */, INT64(0xCF99CA3D754A173A) /* 351 */,
INT64(0xFE477BACAF91BF3C) /* 352 */, INT64(0xED5371F6D690C12D) /* 353 */,
INT64(0x831A5C285E687094) /* 354 */, INT64(0xC5D3C90A3708A0A4) /* 355 */,
INT64(0x0F7F903717D06580) /* 356 */, INT64(0x19F9BB13B8FDF27F) /* 357 */,
INT64(0xB1BD6F1B4D502843) /* 358 */, INT64(0x1C761BA38FFF4012) /* 359 */,
INT64(0x0D1530C4E2E21F3B) /* 360 */, INT64(0x8943CE69A7372C8A) /* 361 */,
INT64(0xE5184E11FEB5CE66) /* 362 */, INT64(0x618BDB80BD736621) /* 363 */,
INT64(0x7D29BAD68B574D0B) /* 364 */, INT64(0x81BB613E25E6FE5B) /* 365 */,
INT64(0x071C9C10BC07913F) /* 366 */, INT64(0xC7BEEB7909AC2D97) /* 367 */,
INT64(0xC3E58D353BC5D757) /* 368 */, INT64(0xEB017892F38F61E8) /* 369 */,
INT64(0xD4EFFB9C9B1CC21A) /* 370 */, INT64(0x99727D26F494F7AB) /* 371 */,
INT64(0xA3E063A2956B3E03) /* 372 */, INT64(0x9D4A8B9A4AA09C30) /* 373 */,
INT64(0x3F6AB7D500090FB4) /* 374 */, INT64(0x9CC0F2A057268AC0) /* 375 */,
INT64(0x3DEE9D2DEDBF42D1) /* 376 */, INT64(0x330F49C87960A972) /* 377 */,
INT64(0xC6B2720287421B41) /* 378 */, INT64(0x0AC59EC07C00369C) /* 379 */,
INT64(0xEF4EAC49CB353425) /* 380 */, INT64(0xF450244EEF0129D8) /* 381 */,
INT64(0x8ACC46E5CAF4DEB6) /* 382 */, INT64(0x2FFEAB63989263F7) /* 383 */,
INT64(0x8F7CB9FE5D7A4578) /* 384 */, INT64(0x5BD8F7644E634635) /* 385 */,
INT64(0x427A7315BF2DC900) /* 386 */, INT64(0x17D0C4AA2125261C) /* 387 */,
INT64(0x3992486C93518E50) /* 388 */, INT64(0xB4CBFEE0A2D7D4C3) /* 389 */,
INT64(0x7C75D6202C5DDD8D) /* 390 */, INT64(0xDBC295D8E35B6C61) /* 391 */,
INT64(0x60B369D302032B19) /* 392 */, INT64(0xCE42685FDCE44132) /* 393 */,
INT64(0x06F3DDB9DDF65610) /* 394 */, INT64(0x8EA4D21DB5E148F0) /* 395 */,
INT64(0x20B0FCE62FCD496F) /* 396 */, INT64(0x2C1B912358B0EE31) /* 397 */,
INT64(0xB28317B818F5A308) /* 398 */, INT64(0xA89C1E189CA6D2CF) /* 399 */,
INT64(0x0C6B18576AAADBC8) /* 400 */, INT64(0xB65DEAA91299FAE3) /* 401 */,
INT64(0xFB2B794B7F1027E7) /* 402 */, INT64(0x04E4317F443B5BEB) /* 403 */,
INT64(0x4B852D325939D0A6) /* 404 */, INT64(0xD5AE6BEEFB207FFC) /* 405 */,
INT64(0x309682B281C7D374) /* 406 */, INT64(0xBAE309A194C3B475) /* 407 */,
INT64(0x8CC3F97B13B49F05) /* 408 */, INT64(0x98A9422FF8293967) /* 409 */,
INT64(0x244B16B01076FF7C) /* 410 */, INT64(0xF8BF571C663D67EE) /* 411 */,
INT64(0x1F0D6758EEE30DA1) /* 412 */, INT64(0xC9B611D97ADEB9B7) /* 413 */,
INT64(0xB7AFD5887B6C57A2) /* 414 */, INT64(0x6290AE846B984FE1) /* 415 */,
INT64(0x94DF4CDEACC1A5FD) /* 416 */, INT64(0x058A5BD1C5483AFF) /* 417 */,
INT64(0x63166CC142BA3C37) /* 418 */, INT64(0x8DB8526EB2F76F40) /* 419 */,
INT64(0xE10880036F0D6D4E) /* 420 */, INT64(0x9E0523C9971D311D) /* 421 */,
INT64(0x45EC2824CC7CD691) /* 422 */, INT64(0x575B8359E62382C9) /* 423 */,
INT64(0xFA9E400DC4889995) /* 424 */, INT64(0xD1823ECB45721568) /* 425 */,
INT64(0xDAFD983B8206082F) /* 426 */, INT64(0xAA7D29082386A8CB) /* 427 */,
INT64(0x269FCD4403B87588) /* 428 */, INT64(0x1B91F5F728BDD1E0) /* 429 */,
INT64(0xE4669F39040201F6) /* 430 */, INT64(0x7A1D7C218CF04ADE) /* 431 */,
INT64(0x65623C29D79CE5CE) /* 432 */, INT64(0x2368449096C00BB1) /* 433 */,
INT64(0xAB9BF1879DA503BA) /* 434 */, INT64(0xBC23ECB1A458058E) /* 435 */,
INT64(0x9A58DF01BB401ECC) /* 436 */, INT64(0xA070E868A85F143D) /* 437 */,
INT64(0x4FF188307DF2239E) /* 438 */, INT64(0x14D565B41A641183) /* 439 */,
INT64(0xEE13337452701602) /* 440 */, INT64(0x950E3DCF3F285E09) /* 441 */,
INT64(0x59930254B9C80953) /* 442 */, INT64(0x3BF299408930DA6D) /* 443 */,
INT64(0xA955943F53691387) /* 444 */, INT64(0xA15EDECAA9CB8784) /* 445 */,
INT64(0x29142127352BE9A0) /* 446 */, INT64(0x76F0371FFF4E7AFB) /* 447 */,
INT64(0x0239F450274F2228) /* 448 */, INT64(0xBB073AF01D5E868B) /* 449 */,
INT64(0xBFC80571C10E96C1) /* 450 */, INT64(0xD267088568222E23) /* 451 */,
INT64(0x9671A3D48E80B5B0) /* 452 */, INT64(0x55B5D38AE193BB81) /* 453 */,
INT64(0x693AE2D0A18B04B8) /* 454 */, INT64(0x5C48B4ECADD5335F) /* 455 */,
INT64(0xFD743B194916A1CA) /* 456 */, INT64(0x2577018134BE98C4) /* 457 */,
INT64(0xE77987E83C54A4AD) /* 458 */, INT64(0x28E11014DA33E1B9) /* 459 */,
INT64(0x270CC59E226AA213) /* 460 */, INT64(0x71495F756D1A5F60) /* 461 */,
INT64(0x9BE853FB60AFEF77) /* 462 */, INT64(0xADC786A7F7443DBF) /* 463 */,
INT64(0x0904456173B29A82) /* 464 */, INT64(0x58BC7A66C232BD5E) /* 465 */,
INT64(0xF306558C673AC8B2) /* 466 */, INT64(0x41F639C6B6C9772A) /* 467 */,
INT64(0x216DEFE99FDA35DA) /* 468 */, INT64(0x11640CC71C7BE615) /* 469 */,
INT64(0x93C43694565C5527) /* 470 */, INT64(0xEA038E6246777839) /* 471 */,
INT64(0xF9ABF3CE5A3E2469) /* 472 */, INT64(0x741E768D0FD312D2) /* 473 */,
INT64(0x0144B883CED652C6) /* 474 */, INT64(0xC20B5A5BA33F8552) /* 475 */,
INT64(0x1AE69633C3435A9D) /* 476 */, INT64(0x97A28CA4088CFDEC) /* 477 */,
INT64(0x8824A43C1E96F420) /* 478 */, INT64(0x37612FA66EEEA746) /* 479 */,
INT64(0x6B4CB165F9CF0E5A) /* 480 */, INT64(0x43AA1C06A0ABFB4A) /* 481 */,
INT64(0x7F4DC26FF162796B) /* 482 */, INT64(0x6CBACC8E54ED9B0F) /* 483 */,
INT64(0xA6B7FFEFD2BB253E) /* 484 */, INT64(0x2E25BC95B0A29D4F) /* 485 */,
INT64(0x86D6A58BDEF1388C) /* 486 */, INT64(0xDED74AC576B6F054) /* 487 */,
INT64(0x8030BDBC2B45805D) /* 488 */, INT64(0x3C81AF70E94D9289) /* 489 */,
INT64(0x3EFF6DDA9E3100DB) /* 490 */, INT64(0xB38DC39FDFCC8847) /* 491 */,
INT64(0x123885528D17B87E) /* 492 */, INT64(0xF2DA0ED240B1B642) /* 493 */,
INT64(0x44CEFADCD54BF9A9) /* 494 */, INT64(0x1312200E433C7EE6) /* 495 */,
INT64(0x9FFCC84F3A78C748) /* 496 */, INT64(0xF0CD1F72248576BB) /* 497 */,
INT64(0xEC6974053638CFE4) /* 498 */, INT64(0x2BA7B67C0CEC4E4C) /* 499 */,
INT64(0xAC2F4DF3E5CE32ED) /* 500 */, INT64(0xCB33D14326EA4C11) /* 501 */,
INT64(0xA4E9044CC77E58BC) /* 502 */, INT64(0x5F513293D934FCEF) /* 503 */,
INT64(0x5DC9645506E55444) /* 504 */, INT64(0x50DE418F317DE40A) /* 505 */,
INT64(0x388CB31A69DDE259) /* 506 */, INT64(0x2DB4A83455820A86) /* 507 */,
INT64(0x9010A91E84711AE9) /* 508 */, INT64(0x4DF7F0B7B1498371) /* 509 */,
INT64(0xD62A2EABC0977179) /* 510 */, INT64(0x22FAC097AA8D5C0E) /* 511 */,
INT64(0xF49FCC2FF1DAF39B) /* 512 */, INT64(0x487FD5C66FF29281) /* 513 */,
INT64(0xE8A30667FCDCA83F) /* 514 */, INT64(0x2C9B4BE3D2FCCE63) /* 515 */,
INT64(0xDA3FF74B93FBBBC2) /* 516 */, INT64(0x2FA165D2FE70BA66) /* 517 */,
INT64(0xA103E279970E93D4) /* 518 */, INT64(0xBECDEC77B0E45E71) /* 519 */,
INT64(0xCFB41E723985E497) /* 520 */, INT64(0xB70AAA025EF75017) /* 521 */,
INT64(0xD42309F03840B8E0) /* 522 */, INT64(0x8EFC1AD035898579) /* 523 */,
INT64(0x96C6920BE2B2ABC5) /* 524 */, INT64(0x66AF4163375A9172) /* 525 */,
INT64(0x2174ABDCCA7127FB) /* 526 */, INT64(0xB33CCEA64A72FF41) /* 527 */,
INT64(0xF04A4933083066A5) /* 528 */, INT64(0x8D970ACDD7289AF5) /* 529 */,
INT64(0x8F96E8E031C8C25E) /* 530 */, INT64(0xF3FEC02276875D47) /* 531 */,
INT64(0xEC7BF310056190DD) /* 532 */, INT64(0xF5ADB0AEBB0F1491) /* 533 */,
INT64(0x9B50F8850FD58892) /* 534 */, INT64(0x4975488358B74DE8) /* 535 */,
INT64(0xA3354FF691531C61) /* 536 */, INT64(0x0702BBE481D2C6EE) /* 537 */,
INT64(0x89FB24057DEDED98) /* 538 */, INT64(0xAC3075138596E902) /* 539 */,
INT64(0x1D2D3580172772ED) /* 540 */, INT64(0xEB738FC28E6BC30D) /* 541 */,
INT64(0x5854EF8F63044326) /* 542 */, INT64(0x9E5C52325ADD3BBE) /* 543 */,
INT64(0x90AA53CF325C4623) /* 544 */, INT64(0xC1D24D51349DD067) /* 545 */,
INT64(0x2051CFEEA69EA624) /* 546 */, INT64(0x13220F0A862E7E4F) /* 547 */,
INT64(0xCE39399404E04864) /* 548 */, INT64(0xD9C42CA47086FCB7) /* 549 */,
INT64(0x685AD2238A03E7CC) /* 550 */, INT64(0x066484B2AB2FF1DB) /* 551 */,
INT64(0xFE9D5D70EFBF79EC) /* 552 */, INT64(0x5B13B9DD9C481854) /* 553 */,
INT64(0x15F0D475ED1509AD) /* 554 */, INT64(0x0BEBCD060EC79851) /* 555 */,
INT64(0xD58C6791183AB7F8) /* 556 */, INT64(0xD1187C5052F3EEE4) /* 557 */,
INT64(0xC95D1192E54E82FF) /* 558 */, INT64(0x86EEA14CB9AC6CA2) /* 559 */,
INT64(0x3485BEB153677D5D) /* 560 */, INT64(0xDD191D781F8C492A) /* 561 */,
INT64(0xF60866BAA784EBF9) /* 562 */, INT64(0x518F643BA2D08C74) /* 563 */,
INT64(0x8852E956E1087C22) /* 564 */, INT64(0xA768CB8DC410AE8D) /* 565 */,
INT64(0x38047726BFEC8E1A) /* 566 */, INT64(0xA67738B4CD3B45AA) /* 567 */,
INT64(0xAD16691CEC0DDE19) /* 568 */, INT64(0xC6D4319380462E07) /* 569 */,
INT64(0xC5A5876D0BA61938) /* 570 */, INT64(0x16B9FA1FA58FD840) /* 571 */,
INT64(0x188AB1173CA74F18) /* 572 */, INT64(0xABDA2F98C99C021F) /* 573 */,
INT64(0x3E0580AB134AE816) /* 574 */, INT64(0x5F3B05B773645ABB) /* 575 */,
INT64(0x2501A2BE5575F2F6) /* 576 */, INT64(0x1B2F74004E7E8BA9) /* 577 */,
INT64(0x1CD7580371E8D953) /* 578 */, INT64(0x7F6ED89562764E30) /* 579 */,
INT64(0xB15926FF596F003D) /* 580 */, INT64(0x9F65293DA8C5D6B9) /* 581 */,
INT64(0x6ECEF04DD690F84C) /* 582 */, INT64(0x4782275FFF33AF88) /* 583 */,
INT64(0xE41433083F820801) /* 584 */, INT64(0xFD0DFE409A1AF9B5) /* 585 */,
INT64(0x4325A3342CDB396B) /* 586 */, INT64(0x8AE77E62B301B252) /* 587 */,
INT64(0xC36F9E9F6655615A) /* 588 */, INT64(0x85455A2D92D32C09) /* 589 */,
INT64(0xF2C7DEA949477485) /* 590 */, INT64(0x63CFB4C133A39EBA) /* 591 */,
INT64(0x83B040CC6EBC5462) /* 592 */, INT64(0x3B9454C8FDB326B0) /* 593 */,
INT64(0x56F56A9E87FFD78C) /* 594 */, INT64(0x2DC2940D99F42BC6) /* 595 */,
INT64(0x98F7DF096B096E2D) /* 596 */, INT64(0x19A6E01E3AD852BF) /* 597 */,
INT64(0x42A99CCBDBD4B40B) /* 598 */, INT64(0xA59998AF45E9C559) /* 599 */,
INT64(0x366295E807D93186) /* 600 */, INT64(0x6B48181BFAA1F773) /* 601 */,
INT64(0x1FEC57E2157A0A1D) /* 602 */, INT64(0x4667446AF6201AD5) /* 603 */,
INT64(0xE615EBCACFB0F075) /* 604 */, INT64(0xB8F31F4F68290778) /* 605 */,
INT64(0x22713ED6CE22D11E) /* 606 */, INT64(0x3057C1A72EC3C93B) /* 607 */,
INT64(0xCB46ACC37C3F1F2F) /* 608 */, INT64(0xDBB893FD02AAF50E) /* 609 */,
INT64(0x331FD92E600B9FCF) /* 610 */, INT64(0xA498F96148EA3AD6) /* 611 */,
INT64(0xA8D8426E8B6A83EA) /* 612 */, INT64(0xA089B274B7735CDC) /* 613 */,
INT64(0x87F6B3731E524A11) /* 614 */, INT64(0x118808E5CBC96749) /* 615 */,
INT64(0x9906E4C7B19BD394) /* 616 */, INT64(0xAFED7F7E9B24A20C) /* 617 */,
INT64(0x6509EADEEB3644A7) /* 618 */, INT64(0x6C1EF1D3E8EF0EDE) /* 619 */,
INT64(0xB9C97D43E9798FB4) /* 620 */, INT64(0xA2F2D784740C28A3) /* 621 */,
INT64(0x7B8496476197566F) /* 622 */, INT64(0x7A5BE3E6B65F069D) /* 623 */,
INT64(0xF96330ED78BE6F10) /* 624 */, INT64(0xEEE60DE77A076A15) /* 625 */,
INT64(0x2B4BEE4AA08B9BD0) /* 626 */, INT64(0x6A56A63EC7B8894E) /* 627 */,
INT64(0x02121359BA34FEF4) /* 628 */, INT64(0x4CBF99F8283703FC) /* 629 */,
INT64(0x398071350CAF30C8) /* 630 */, INT64(0xD0A77A89F017687A) /* 631 */,
INT64(0xF1C1A9EB9E423569) /* 632 */, INT64(0x8C7976282DEE8199) /* 633 */,
INT64(0x5D1737A5DD1F7ABD) /* 634 */, INT64(0x4F53433C09A9FA80) /* 635 */,
INT64(0xFA8B0C53DF7CA1D9) /* 636 */, INT64(0x3FD9DCBC886CCB77) /* 637 */,
INT64(0xC040917CA91B4720) /* 638 */, INT64(0x7DD00142F9D1DCDF) /* 639 */,
INT64(0x8476FC1D4F387B58) /* 640 */, INT64(0x23F8E7C5F3316503) /* 641 */,
INT64(0x032A2244E7E37339) /* 642 */, INT64(0x5C87A5D750F5A74B) /* 643 */,
INT64(0x082B4CC43698992E) /* 644 */, INT64(0xDF917BECB858F63C) /* 645 */,
INT64(0x3270B8FC5BF86DDA) /* 646 */, INT64(0x10AE72BB29B5DD76) /* 647 */,
INT64(0x576AC94E7700362B) /* 648 */, INT64(0x1AD112DAC61EFB8F) /* 649 */,
INT64(0x691BC30EC5FAA427) /* 650 */, INT64(0xFF246311CC327143) /* 651 */,
INT64(0x3142368E30E53206) /* 652 */, INT64(0x71380E31E02CA396) /* 653 */,
INT64(0x958D5C960AAD76F1) /* 654 */, INT64(0xF8D6F430C16DA536) /* 655 */,
INT64(0xC8FFD13F1BE7E1D2) /* 656 */, INT64(0x7578AE66004DDBE1) /* 657 */,
INT64(0x05833F01067BE646) /* 658 */, INT64(0xBB34B5AD3BFE586D) /* 659 */,
INT64(0x095F34C9A12B97F0) /* 660 */, INT64(0x247AB64525D60CA8) /* 661 */,
INT64(0xDCDBC6F3017477D1) /* 662 */, INT64(0x4A2E14D4DECAD24D) /* 663 */,
INT64(0xBDB5E6D9BE0A1EEB) /* 664 */, INT64(0x2A7E70F7794301AB) /* 665 */,
INT64(0xDEF42D8A270540FD) /* 666 */, INT64(0x01078EC0A34C22C1) /* 667 */,
INT64(0xE5DE511AF4C16387) /* 668 */, INT64(0x7EBB3A52BD9A330A) /* 669 */,
INT64(0x77697857AA7D6435) /* 670 */, INT64(0x004E831603AE4C32) /* 671 */,
INT64(0xE7A21020AD78E312) /* 672 */, INT64(0x9D41A70C6AB420F2) /* 673 */,
INT64(0x28E06C18EA1141E6) /* 674 */, INT64(0xD2B28CBD984F6B28) /* 675 */,
INT64(0x26B75F6C446E9D83) /* 676 */, INT64(0xBA47568C4D418D7F) /* 677 */,
INT64(0xD80BADBFE6183D8E) /* 678 */, INT64(0x0E206D7F5F166044) /* 679 */,
INT64(0xE258A43911CBCA3E) /* 680 */, INT64(0x723A1746B21DC0BC) /* 681 */,
INT64(0xC7CAA854F5D7CDD3) /* 682 */, INT64(0x7CAC32883D261D9C) /* 683 */,
INT64(0x7690C26423BA942C) /* 684 */, INT64(0x17E55524478042B8) /* 685 */,
INT64(0xE0BE477656A2389F) /* 686 */, INT64(0x4D289B5E67AB2DA0) /* 687 */,
INT64(0x44862B9C8FBBFD31) /* 688 */, INT64(0xB47CC8049D141365) /* 689 */,
INT64(0x822C1B362B91C793) /* 690 */, INT64(0x4EB14655FB13DFD8) /* 691 */,
INT64(0x1ECBBA0714E2A97B) /* 692 */, INT64(0x6143459D5CDE5F14) /* 693 */,
INT64(0x53A8FBF1D5F0AC89) /* 694 */, INT64(0x97EA04D81C5E5B00) /* 695 */,
INT64(0x622181A8D4FDB3F3) /* 696 */, INT64(0xE9BCD341572A1208) /* 697 */,
INT64(0x1411258643CCE58A) /* 698 */, INT64(0x9144C5FEA4C6E0A4) /* 699 */,
INT64(0x0D33D06565CF620F) /* 700 */, INT64(0x54A48D489F219CA1) /* 701 */,
INT64(0xC43E5EAC6D63C821) /* 702 */, INT64(0xA9728B3A72770DAF) /* 703 */,
INT64(0xD7934E7B20DF87EF) /* 704 */, INT64(0xE35503B61A3E86E5) /* 705 */,
INT64(0xCAE321FBC819D504) /* 706 */, INT64(0x129A50B3AC60BFA6) /* 707 */,
INT64(0xCD5E68EA7E9FB6C3) /* 708 */, INT64(0xB01C90199483B1C7) /* 709 */,
INT64(0x3DE93CD5C295376C) /* 710 */, INT64(0xAED52EDF2AB9AD13) /* 711 */,
INT64(0x2E60F512C0A07884) /* 712 */, INT64(0xBC3D86A3E36210C9) /* 713 */,
INT64(0x35269D9B163951CE) /* 714 */, INT64(0x0C7D6E2AD0CDB5FA) /* 715 */,
INT64(0x59E86297D87F5733) /* 716 */, INT64(0x298EF221898DB0E7) /* 717 */,
INT64(0x55000029D1A5AA7E) /* 718 */, INT64(0x8BC08AE1B5061B45) /* 719 */,
INT64(0xC2C31C2B6C92703A) /* 720 */, INT64(0x94CC596BAF25EF42) /* 721 */,
INT64(0x0A1D73DB22540456) /* 722 */, INT64(0x04B6A0F9D9C4179A) /* 723 */,
INT64(0xEFFDAFA2AE3D3C60) /* 724 */, INT64(0xF7C8075BB49496C4) /* 725 */,
INT64(0x9CC5C7141D1CD4E3) /* 726 */, INT64(0x78BD1638218E5534) /* 727 */,
INT64(0xB2F11568F850246A) /* 728 */, INT64(0xEDFABCFA9502BC29) /* 729 */,
INT64(0x796CE5F2DA23051B) /* 730 */, INT64(0xAAE128B0DC93537C) /* 731 */,
INT64(0x3A493DA0EE4B29AE) /* 732 */, INT64(0xB5DF6B2C416895D7) /* 733 */,
INT64(0xFCABBD25122D7F37) /* 734 */, INT64(0x70810B58105DC4B1) /* 735 */,
INT64(0xE10FDD37F7882A90) /* 736 */, INT64(0x524DCAB5518A3F5C) /* 737 */,
INT64(0x3C9E85878451255B) /* 738 */, INT64(0x4029828119BD34E2) /* 739 */,
INT64(0x74A05B6F5D3CECCB) /* 740 */, INT64(0xB610021542E13ECA) /* 741 */,
INT64(0x0FF979D12F59E2AC) /* 742 */, INT64(0x6037DA27E4F9CC50) /* 743 */,
INT64(0x5E92975A0DF1847D) /* 744 */, INT64(0xD66DE190D3E623FE) /* 745 */,
INT64(0x5032D6B87B568048) /* 746 */, INT64(0x9A36B7CE8235216E) /* 747 */,
INT64(0x80272A7A24F64B4A) /* 748 */, INT64(0x93EFED8B8C6916F7) /* 749 */,
INT64(0x37DDBFF44CCE1555) /* 750 */, INT64(0x4B95DB5D4B99BD25) /* 751 */,
INT64(0x92D3FDA169812FC0) /* 752 */, INT64(0xFB1A4A9A90660BB6) /* 753 */,
INT64(0x730C196946A4B9B2) /* 754 */, INT64(0x81E289AA7F49DA68) /* 755 */,
INT64(0x64669A0F83B1A05F) /* 756 */, INT64(0x27B3FF7D9644F48B) /* 757 */,
INT64(0xCC6B615C8DB675B3) /* 758 */, INT64(0x674F20B9BCEBBE95) /* 759 */,
INT64(0x6F31238275655982) /* 760 */, INT64(0x5AE488713E45CF05) /* 761 */,
INT64(0xBF619F9954C21157) /* 762 */, INT64(0xEABAC46040A8EAE9) /* 763 */,
INT64(0x454C6FE9F2C0C1CD) /* 764 */, INT64(0x419CF6496412691C) /* 765 */,
INT64(0xD3DC3BEF265B0F70) /* 766 */, INT64(0x6D0E60F5C3578A9E) /* 767 */,
INT64(0x5B0E608526323C55) /* 768 */, INT64(0x1A46C1A9FA1B59F5) /* 769 */,
INT64(0xA9E245A17C4C8FFA) /* 770 */, INT64(0x65CA5159DB2955D7) /* 771 */,
INT64(0x05DB0A76CE35AFC2) /* 772 */, INT64(0x81EAC77EA9113D45) /* 773 */,
INT64(0x528EF88AB6AC0A0D) /* 774 */, INT64(0xA09EA253597BE3FF) /* 775 */,
INT64(0x430DDFB3AC48CD56) /* 776 */, INT64(0xC4B3A67AF45CE46F) /* 777 */,
INT64(0x4ECECFD8FBE2D05E) /* 778 */, INT64(0x3EF56F10B39935F0) /* 779 */,
INT64(0x0B22D6829CD619C6) /* 780 */, INT64(0x17FD460A74DF2069) /* 781 */,
INT64(0x6CF8CC8E8510ED40) /* 782 */, INT64(0xD6C824BF3A6ECAA7) /* 783 */,
INT64(0x61243D581A817049) /* 784 */, INT64(0x048BACB6BBC163A2) /* 785 */,
INT64(0xD9A38AC27D44CC32) /* 786 */, INT64(0x7FDDFF5BAAF410AB) /* 787 */,
INT64(0xAD6D495AA804824B) /* 788 */, INT64(0xE1A6A74F2D8C9F94) /* 789 */,
INT64(0xD4F7851235DEE8E3) /* 790 */, INT64(0xFD4B7F886540D893) /* 791 */,
INT64(0x247C20042AA4BFDA) /* 792 */, INT64(0x096EA1C517D1327C) /* 793 */,
INT64(0xD56966B4361A6685) /* 794 */, INT64(0x277DA5C31221057D) /* 795 */,
INT64(0x94D59893A43ACFF7) /* 796 */, INT64(0x64F0C51CCDC02281) /* 797 */,
INT64(0x3D33BCC4FF6189DB) /* 798 */, INT64(0xE005CB184CE66AF1) /* 799 */,
INT64(0xFF5CCD1D1DB99BEA) /* 800 */, INT64(0xB0B854A7FE42980F) /* 801 */,
INT64(0x7BD46A6A718D4B9F) /* 802 */, INT64(0xD10FA8CC22A5FD8C) /* 803 */,
INT64(0xD31484952BE4BD31) /* 804 */, INT64(0xC7FA975FCB243847) /* 805 */,
INT64(0x4886ED1E5846C407) /* 806 */, INT64(0x28CDDB791EB70B04) /* 807 */,
INT64(0xC2B00BE2F573417F) /* 808 */, INT64(0x5C9590452180F877) /* 809 */,
INT64(0x7A6BDDFFF370EB00) /* 810 */, INT64(0xCE509E38D6D9D6A4) /* 811 */,
INT64(0xEBEB0F00647FA702) /* 812 */, INT64(0x1DCC06CF76606F06) /* 813 */,
INT64(0xE4D9F28BA286FF0A) /* 814 */, INT64(0xD85A305DC918C262) /* 815 */,
INT64(0x475B1D8732225F54) /* 816 */, INT64(0x2D4FB51668CCB5FE) /* 817 */,
INT64(0xA679B9D9D72BBA20) /* 818 */, INT64(0x53841C0D912D43A5) /* 819 */,
INT64(0x3B7EAA48BF12A4E8) /* 820 */, INT64(0x781E0E47F22F1DDF) /* 821 */,
INT64(0xEFF20CE60AB50973) /* 822 */, INT64(0x20D261D19DFFB742) /* 823 */,
INT64(0x16A12B03062A2E39) /* 824 */, INT64(0x1960EB2239650495) /* 825 */,
INT64(0x251C16FED50EB8B8) /* 826 */, INT64(0x9AC0C330F826016E) /* 827 */,
INT64(0xED152665953E7671) /* 828 */, INT64(0x02D63194A6369570) /* 829 */,
INT64(0x5074F08394B1C987) /* 830 */, INT64(0x70BA598C90B25CE1) /* 831 */,
INT64(0x794A15810B9742F6) /* 832 */, INT64(0x0D5925E9FCAF8C6C) /* 833 */,
INT64(0x3067716CD868744E) /* 834 */, INT64(0x910AB077E8D7731B) /* 835 */,
INT64(0x6A61BBDB5AC42F61) /* 836 */, INT64(0x93513EFBF0851567) /* 837 */,
INT64(0xF494724B9E83E9D5) /* 838 */, INT64(0xE887E1985C09648D) /* 839 */,
INT64(0x34B1D3C675370CFD) /* 840 */, INT64(0xDC35E433BC0D255D) /* 841 */,
INT64(0xD0AAB84234131BE0) /* 842 */, INT64(0x08042A50B48B7EAF) /* 843 */,
INT64(0x9997C4EE44A3AB35) /* 844 */, INT64(0x829A7B49201799D0) /* 845 */,
INT64(0x263B8307B7C54441) /* 846 */, INT64(0x752F95F4FD6A6CA6) /* 847 */,
INT64(0x927217402C08C6E5) /* 848 */, INT64(0x2A8AB754A795D9EE) /* 849 */,
INT64(0xA442F7552F72943D) /* 850 */, INT64(0x2C31334E19781208) /* 851 */,
INT64(0x4FA98D7CEAEE6291) /* 852 */, INT64(0x55C3862F665DB309) /* 853 */,
INT64(0xBD0610175D53B1F3) /* 854 */, INT64(0x46FE6CB840413F27) /* 855 */,
INT64(0x3FE03792DF0CFA59) /* 856 */, INT64(0xCFE700372EB85E8F) /* 857 */,
INT64(0xA7BE29E7ADBCE118) /* 858 */, INT64(0xE544EE5CDE8431DD) /* 859 */,
INT64(0x8A781B1B41F1873E) /* 860 */, INT64(0xA5C94C78A0D2F0E7) /* 861 */,
INT64(0x39412E2877B60728) /* 862 */, INT64(0xA1265EF3AFC9A62C) /* 863 */,
INT64(0xBCC2770C6A2506C5) /* 864 */, INT64(0x3AB66DD5DCE1CE12) /* 865 */,
INT64(0xE65499D04A675B37) /* 866 */, INT64(0x7D8F523481BFD216) /* 867 */,
INT64(0x0F6F64FCEC15F389) /* 868 */, INT64(0x74EFBE618B5B13C8) /* 869 */,
INT64(0xACDC82B714273E1D) /* 870 */, INT64(0xDD40BFE003199D17) /* 871 */,
INT64(0x37E99257E7E061F8) /* 872 */, INT64(0xFA52626904775AAA) /* 873 */,
INT64(0x8BBBF63A463D56F9) /* 874 */, INT64(0xF0013F1543A26E64) /* 875 */,
INT64(0xA8307E9F879EC898) /* 876 */, INT64(0xCC4C27A4150177CC) /* 877 */,
INT64(0x1B432F2CCA1D3348) /* 878 */, INT64(0xDE1D1F8F9F6FA013) /* 879 */,
INT64(0x606602A047A7DDD6) /* 880 */, INT64(0xD237AB64CC1CB2C7) /* 881 */,
INT64(0x9B938E7225FCD1D3) /* 882 */, INT64(0xEC4E03708E0FF476) /* 883 */,
INT64(0xFEB2FBDA3D03C12D) /* 884 */, INT64(0xAE0BCED2EE43889A) /* 885 */,
INT64(0x22CB8923EBFB4F43) /* 886 */, INT64(0x69360D013CF7396D) /* 887 */,
INT64(0x855E3602D2D4E022) /* 888 */, INT64(0x073805BAD01F784C) /* 889 */,
INT64(0x33E17A133852F546) /* 890 */, INT64(0xDF4874058AC7B638) /* 891 */,
INT64(0xBA92B29C678AA14A) /* 892 */, INT64(0x0CE89FC76CFAADCD) /* 893 */,
INT64(0x5F9D4E0908339E34) /* 894 */, INT64(0xF1AFE9291F5923B9) /* 895 */,
INT64(0x6E3480F60F4A265F) /* 896 */, INT64(0xEEBF3A2AB29B841C) /* 897 */,
INT64(0xE21938A88F91B4AD) /* 898 */, INT64(0x57DFEFF845C6D3C3) /* 899 */,
INT64(0x2F006B0BF62CAAF2) /* 900 */, INT64(0x62F479EF6F75EE78) /* 901 */,
INT64(0x11A55AD41C8916A9) /* 902 */, INT64(0xF229D29084FED453) /* 903 */,
INT64(0x42F1C27B16B000E6) /* 904 */, INT64(0x2B1F76749823C074) /* 905 */,
INT64(0x4B76ECA3C2745360) /* 906 */, INT64(0x8C98F463B91691BD) /* 907 */,
INT64(0x14BCC93CF1ADE66A) /* 908 */, INT64(0x8885213E6D458397) /* 909 */,
INT64(0x8E177DF0274D4711) /* 910 */, INT64(0xB49B73B5503F2951) /* 911 */,
INT64(0x10168168C3F96B6B) /* 912 */, INT64(0x0E3D963B63CAB0AE) /* 913 */,
INT64(0x8DFC4B5655A1DB14) /* 914 */, INT64(0xF789F1356E14DE5C) /* 915 */,
INT64(0x683E68AF4E51DAC1) /* 916 */, INT64(0xC9A84F9D8D4B0FD9) /* 917 */,
INT64(0x3691E03F52A0F9D1) /* 918 */, INT64(0x5ED86E46E1878E80) /* 919 */,
INT64(0x3C711A0E99D07150) /* 920 */, INT64(0x5A0865B20C4E9310) /* 921 */,
INT64(0x56FBFC1FE4F0682E) /* 922 */, INT64(0xEA8D5DE3105EDF9B) /* 923 */,
INT64(0x71ABFDB12379187A) /* 924 */, INT64(0x2EB99DE1BEE77B9C) /* 925 */,
INT64(0x21ECC0EA33CF4523) /* 926 */, INT64(0x59A4D7521805C7A1) /* 927 */,
INT64(0x3896F5EB56AE7C72) /* 928 */, INT64(0xAA638F3DB18F75DC) /* 929 */,
INT64(0x9F39358DABE9808E) /* 930 */, INT64(0xB7DEFA91C00B72AC) /* 931 */,
INT64(0x6B5541FD62492D92) /* 932 */, INT64(0x6DC6DEE8F92E4D5B) /* 933 */,
INT64(0x353F57ABC4BEEA7E) /* 934 */, INT64(0x735769D6DA5690CE) /* 935 */,
INT64(0x0A234AA642391484) /* 936 */, INT64(0xF6F9508028F80D9D) /* 937 */,
INT64(0xB8E319A27AB3F215) /* 938 */, INT64(0x31AD9C1151341A4D) /* 939 */,
INT64(0x773C22A57BEF5805) /* 940 */, INT64(0x45C7561A07968633) /* 941 */,
INT64(0xF913DA9E249DBE36) /* 942 */, INT64(0xDA652D9B78A64C68) /* 943 */,
INT64(0x4C27A97F3BC334EF) /* 944 */, INT64(0x76621220E66B17F4) /* 945 */,
INT64(0x967743899ACD7D0B) /* 946 */, INT64(0xF3EE5BCAE0ED6782) /* 947 */,
INT64(0x409F753600C879FC) /* 948 */, INT64(0x06D09A39B5926DB6) /* 949 */,
INT64(0x6F83AEB0317AC588) /* 950 */, INT64(0x01E6CA4A86381F21) /* 951 */,
INT64(0x66FF3462D19F3025) /* 952 */, INT64(0x72207C24DDFD3BFB) /* 953 */,
INT64(0x4AF6B6D3E2ECE2EB) /* 954 */, INT64(0x9C994DBEC7EA08DE) /* 955 */,
INT64(0x49ACE597B09A8BC4) /* 956 */, INT64(0xB38C4766CF0797BA) /* 957 */,
INT64(0x131B9373C57C2A75) /* 958 */, INT64(0xB1822CCE61931E58) /* 959 */,
INT64(0x9D7555B909BA1C0C) /* 960 */, INT64(0x127FAFDD937D11D2) /* 961 */,
INT64(0x29DA3BADC66D92E4) /* 962 */, INT64(0xA2C1D57154C2ECBC) /* 963 */,
INT64(0x58C5134D82F6FE24) /* 964 */, INT64(0x1C3AE3515B62274F) /* 965 */,
INT64(0xE907C82E01CB8126) /* 966 */, INT64(0xF8ED091913E37FCB) /* 967 */,
INT64(0x3249D8F9C80046C9) /* 968 */, INT64(0x80CF9BEDE388FB63) /* 969 */,
INT64(0x1881539A116CF19E) /* 970 */, INT64(0x5103F3F76BD52457) /* 971 */,
INT64(0x15B7E6F5AE47F7A8) /* 972 */, INT64(0xDBD7C6DED47E9CCF) /* 973 */,
INT64(0x44E55C410228BB1A) /* 974 */, INT64(0xB647D4255EDB4E99) /* 975 */,
INT64(0x5D11882BB8AAFC30) /* 976 */, INT64(0xF5098BBB29D3212A) /* 977 */,
INT64(0x8FB5EA14E90296B3) /* 978 */, INT64(0x677B942157DD025A) /* 979 */,
INT64(0xFB58E7C0A390ACB5) /* 980 */, INT64(0x89D3674C83BD4A01) /* 981 */,
INT64(0x9E2DA4DF4BF3B93B) /* 982 */, INT64(0xFCC41E328CAB4829) /* 983 */,
INT64(0x03F38C96BA582C52) /* 984 */, INT64(0xCAD1BDBD7FD85DB2) /* 985 */,
INT64(0xBBB442C16082AE83) /* 986 */, INT64(0xB95FE86BA5DA9AB0) /* 987 */,
INT64(0xB22E04673771A93F) /* 988 */, INT64(0x845358C9493152D8) /* 989 */,
INT64(0xBE2A488697B4541E) /* 990 */, INT64(0x95A2DC2DD38E6966) /* 991 */,
INT64(0xC02C11AC923C852B) /* 992 */, INT64(0x2388B1990DF2A87B) /* 993 */,
INT64(0x7C8008FA1B4F37BE) /* 994 */, INT64(0x1F70D0C84D54E503) /* 995 */,
INT64(0x5490ADEC7ECE57D4) /* 996 */, INT64(0x002B3C27D9063A3A) /* 997 */,
INT64(0x7EAEA3848030A2BF) /* 998 */, INT64(0xC602326DED2003C0) /* 999 */,
INT64(0x83A7287D69A94086) /* 1000 */, INT64(0xC57A5FCB30F57A8A) /* 1001 */,
INT64(0xB56844E479EBE779) /* 1002 */, INT64(0xA373B40F05DCBCE9) /* 1003 */,
INT64(0xD71A786E88570EE2) /* 1004 */, INT64(0x879CBACDBDE8F6A0) /* 1005 */,
INT64(0x976AD1BCC164A32F) /* 1006 */, INT64(0xAB21E25E9666D78B) /* 1007 */,
INT64(0x901063AAE5E5C33C) /* 1008 */, INT64(0x9818B34448698D90) /* 1009 */,
INT64(0xE36487AE3E1E8ABB) /* 1010 */, INT64(0xAFBDF931893BDCB4) /* 1011 */,
INT64(0x6345A0DC5FBBD519) /* 1012 */, INT64(0x8628FE269B9465CA) /* 1013 */,
INT64(0x1E5D01603F9C51EC) /* 1014 */, INT64(0x4DE44006A15049B7) /* 1015 */,
INT64(0xBF6C70E5F776CBB1) /* 1016 */, INT64(0x411218F2EF552BED) /* 1017 */,
INT64(0xCB0C0708705A36A3) /* 1018 */, INT64(0xE74D14754F986044) /* 1019 */,
INT64(0xCD56D9430EA8280E) /* 1020 */, INT64(0xC12591D7535F5065) /* 1021 */,
INT64(0xC83223F1720AEF96) /* 1022 */, INT64(0xC3A0396F7363A51F) /* 1023 */
};
#ifdef _MSC_VER
#define INLINE __inline
#else
#define INLINE
#endif
void tigerRound(uint64_t *a, uint64_t *b, uint64_t *c, uint64_t x, int mul) {
uint64_t tmp;
tmp = (*c ^= x);
*a -= tiger_t1[byte(tmp, 0)] ^ tiger_t2[byte(tmp, 2)] ^ tiger_t3[byte(tmp, 4)] ^ tiger_t4[byte(tmp, 6)];
tmp = (*b += tiger_t4[byte(tmp, 1)] ^ tiger_t3[byte(tmp, 3)] ^ tiger_t2[byte(tmp,5)] ^ tiger_t1[byte(tmp,7)]);
switch (mul) {
case 5: *b = (tmp << 2) + tmp; break;
case 7: *b = (tmp << 3) - tmp; break;
case 9: *b = (tmp << 3) + tmp; break;
}
}
void tigerPass(uint64_t *a, uint64_t *b, uint64_t *c, uint64_t *x, int mul) {
tigerRound(a,b,c,x[0],mul);
tigerRound(b,c,a,x[1],mul);
tigerRound(c,a,b,x[2],mul);
tigerRound(a,b,c,x[3],mul);
tigerRound(b,c,a,x[4],mul);
tigerRound(c,a,b,x[5],mul);
tigerRound(a,b,c,x[6],mul);
tigerRound(b,c,a,x[7],mul);
}
void tigerSchedule(uint64_t *x) {
x[0] -= x[7] ^ INT64(0xA5A5A5A5A5A5A5A5);
x[1] ^= x[0];
x[2] += x[1];
x[3] -= x[2] ^ ((~x[1])<<19);
x[4] ^= x[3];
x[5] += x[4];
x[6] -= x[5] ^ ((~x[4])>>23);
x[7] ^= x[6];
x[0] += x[7];
x[1] -= x[0] ^ ((~x[7])<<19);
x[2] ^= x[1];
x[3] += x[2];
x[4] -= x[3] ^ ((~x[2])>>23);
x[5] ^= x[4];
x[6] += x[5];
x[7] -= x[6] ^ INT64(0x0123456789ABCDEF);
}
void tigerTransform(struct tigerContext *context, unsigned char *buf) {
uint64_t x[8];
for (unsigned long i=0; i<8; i++) {
x[i] = getu64l(&buf[8*i]);
}
uint64_t a = context->state[0];
uint64_t b = context->state[1];
uint64_t c = context->state[2];
tigerPass(&a,&b,&c,x,5);
tigerSchedule(x);
tigerPass(&c,&a,&b,x,7);
tigerSchedule(x);
tigerPass(&b,&c,&a,x,9);
context->state[0] = a ^ context->state[0];
context->state[1] = b - context->state[1];
context->state[2] = c + context->state[2];
}
int tigerTest() {
static const struct {
char *msg;
unsigned char hash[tigerLength];
} tests[] = {
{
"",
{0x32,0x93,0xac,0x63,0x0c,0x13,0xf0,0x24,0x5f,0x92,0xbb,0xb1,0x76,0x6e,0x16,0x16,0x7a,0x4e,0x58,0x49,0x2d,0xde,0x73,0xf3}
},
{
"abc",
{0x2a,0xab,0x14,0x84,0xe8,0xc1,0x58,0xf2,0xbf,0xb8,0xc5,0xff,0x41,0xb5,0x7a,0x52,0x51,0x29,0x13,0x1c,0x95,0x7b,0x5f,0x93}
},
{
"Tiger",
{0xdd,0x00,0x23,0x07,0x99,0xf5,0x00,0x9f,0xec,0x6d,0xeb,0xc8,0x38,0xbb,0x6a,0x27,0xdf,0x2b,0x9d,0x6f,0x11,0x0c,0x79,0x37}
},
{
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
{0xf7,0x1c,0x85,0x83,0x90,0x2a,0xfb,0x87,0x9e,0xdf,0xe6,0x10,0xf8,0x2c,0x0d,0x47,0x86,0xa3,0xa5,0x34,0x50,0x44,0x86,0xb5}
},
{
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
{0xc5,0x40,0x34,0xe5,0xb4,0x3e,0xb8,0x00,0x58,0x48,0xa7,0xe0,0xae,0x6a,0xac,0x76,0xe4,0xff,0x59,0x0a,0xe7,0x15,0xfd,0x25}
},
{NULL, {0}}
};
struct tigerContext MDContext;
unsigned char MDDigest[tigerLength];
for (int i=0; tests[i].msg!=NULL; i++) {
tigerInit(&MDContext);
tigerUpdate(&MDContext, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
tigerFinal(MDDigest, &MDContext);
if (memcmp(MDDigest, tests[i].hash, tigerLength))
return 0;
}
return 1;
}

View File

@ -9,12 +9,30 @@
#import <Foundation/Foundation.h>
#endif
struct MGMHashDescription {
char *name;
int contextSize;
void (*init)(void *);
void (*update)(void *, const unsigned char *, unsigned);
void (*final)(unsigned char *, void *);
int length;
};
#if !defined(MIN)
#define MIN(A,B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __a : __b; })
#endif
#define INT32(n) n ## UL
#define INT64(n) n ## ULL
#define ROR32(x, b) ((x >> b) | (x << (32 - b)))
#define ROR64(x, b) ((x >> b) | (x << (64 - b)))
#define ROL32(x, b) ((x << b) | (x >> (32 - b)))
#define ROL64(x, b) ((x << b) | (x >> (64 - b)))
#define SHR(x, b) (x >> b)
#define byte(x, n) (((x) >> (8 * (n))) & 255)
#define MDFileReadLength 1048576
static const char hexdigits[] = "0123456789abcdef";

View File

@ -117,7 +117,7 @@ NSString * const cryptBase64 = @"base64";
#else
#include <stdio.h>
#include <string.h>
#include "MGMMD5.h"
#include "MGMBase64.h"
#include "MGMTypes.h"
#endif

View File

@ -7,6 +7,33 @@
objects = {
/* Begin PBXBuildFile section */
2A1022FA13952C7B00325DC6 /* MGMRMD128.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A1022F813952C7B00325DC6 /* MGMRMD128.h */; };
2A1022FB13952C7B00325DC6 /* MGMRMD128.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A1022F913952C7B00325DC6 /* MGMRMD128.m */; };
2A1022FC13952C7B00325DC6 /* MGMRMD128.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A1022F813952C7B00325DC6 /* MGMRMD128.h */; };
2A1022FD13952C7B00325DC6 /* MGMRMD128.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A1022F913952C7B00325DC6 /* MGMRMD128.m */; };
2A1022FE13952C7B00325DC6 /* MGMRMD128.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A1022F813952C7B00325DC6 /* MGMRMD128.h */; };
2A1022FF13952C7B00325DC6 /* MGMRMD128.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A1022F913952C7B00325DC6 /* MGMRMD128.m */; };
2A10230013952C7B00325DC6 /* MGMRMD128.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A1022F813952C7B00325DC6 /* MGMRMD128.h */; };
2A10230113952C7B00325DC6 /* MGMRMD128.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A1022F913952C7B00325DC6 /* MGMRMD128.m */; };
2A10230213952C7B00325DC6 /* MGMRMD128.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A1022F913952C7B00325DC6 /* MGMRMD128.m */; };
2A1023C613955A8500325DC6 /* MGMRMD160.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A1023C413955A8500325DC6 /* MGMRMD160.h */; };
2A1023C713955A8500325DC6 /* MGMRMD160.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A1023C513955A8500325DC6 /* MGMRMD160.m */; };
2A1023C813955A8500325DC6 /* MGMRMD160.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A1023C413955A8500325DC6 /* MGMRMD160.h */; };
2A1023C913955A8500325DC6 /* MGMRMD160.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A1023C513955A8500325DC6 /* MGMRMD160.m */; };
2A1023CA13955A8500325DC6 /* MGMRMD160.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A1023C413955A8500325DC6 /* MGMRMD160.h */; };
2A1023CB13955A8500325DC6 /* MGMRMD160.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A1023C513955A8500325DC6 /* MGMRMD160.m */; };
2A1023CC13955A8500325DC6 /* MGMRMD160.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A1023C413955A8500325DC6 /* MGMRMD160.h */; };
2A1023CD13955A8500325DC6 /* MGMRMD160.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A1023C513955A8500325DC6 /* MGMRMD160.m */; };
2A1023CE13955A8500325DC6 /* MGMRMD160.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A1023C513955A8500325DC6 /* MGMRMD160.m */; };
2A1024381395A9C100325DC6 /* MGMRMD256.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A1024361395A9C100325DC6 /* MGMRMD256.h */; };
2A1024391395A9C100325DC6 /* MGMRMD256.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A1024371395A9C100325DC6 /* MGMRMD256.m */; };
2A10243A1395A9C100325DC6 /* MGMRMD256.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A1024361395A9C100325DC6 /* MGMRMD256.h */; };
2A10243B1395A9C100325DC6 /* MGMRMD256.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A1024371395A9C100325DC6 /* MGMRMD256.m */; };
2A10243C1395A9C100325DC6 /* MGMRMD256.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A1024361395A9C100325DC6 /* MGMRMD256.h */; };
2A10243D1395A9C100325DC6 /* MGMRMD256.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A1024371395A9C100325DC6 /* MGMRMD256.m */; };
2A10243E1395A9C100325DC6 /* MGMRMD256.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A1024361395A9C100325DC6 /* MGMRMD256.h */; };
2A10243F1395A9C100325DC6 /* MGMRMD256.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A1024371395A9C100325DC6 /* MGMRMD256.m */; };
2A1024401395A9C100325DC6 /* MGMRMD256.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A1024371395A9C100325DC6 /* MGMRMD256.m */; };
2A752B6D12C6C31500082F40 /* MGMMD.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A752B6012C6C31500082F40 /* MGMMD.m */; };
2A752B6E12C6C31500082F40 /* MGMMD5.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A752B6212C6C31500082F40 /* MGMMD5.m */; };
2A752B6F12C6C31500082F40 /* MGMSHA1.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A752B6412C6C31500082F40 /* MGMSHA1.m */; };
@ -70,19 +97,55 @@
2A752BA912C6C31500082F40 /* MGMSHA384.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A752B6A12C6C31500082F40 /* MGMSHA384.m */; };
2A752BAA12C6C31500082F40 /* MGMSHA512.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A752B6B12C6C31500082F40 /* MGMSHA512.h */; };
2A752BAB12C6C31500082F40 /* MGMSHA512.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A752B6C12C6C31500082F40 /* MGMSHA512.m */; };
2A752BBE12C6C5FC00082F40 /* MGMBase64.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A752BBC12C6C5FC00082F40 /* MGMBase64.h */; };
2A752BBF12C6C5FC00082F40 /* MGMBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A752BBD12C6C5FC00082F40 /* MGMBase64.m */; };
2A752BC012C6C5FC00082F40 /* MGMBase64.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A752BBC12C6C5FC00082F40 /* MGMBase64.h */; };
2A752BC112C6C5FC00082F40 /* MGMBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A752BBD12C6C5FC00082F40 /* MGMBase64.m */; };
2A752BC212C6C5FC00082F40 /* MGMBase64.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A752BBC12C6C5FC00082F40 /* MGMBase64.h */; };
2A752BC312C6C5FC00082F40 /* MGMBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A752BBD12C6C5FC00082F40 /* MGMBase64.m */; };
2A752BC412C6C5FC00082F40 /* MGMBase64.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A752BBC12C6C5FC00082F40 /* MGMBase64.h */; };
2A752BC512C6C5FC00082F40 /* MGMBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A752BBD12C6C5FC00082F40 /* MGMBase64.m */; };
2A81C83913902B0700723BB3 /* MGMMD2.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A81C83713902B0700723BB3 /* MGMMD2.h */; };
2A81C83A13902B0700723BB3 /* MGMMD2.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A81C83813902B0700723BB3 /* MGMMD2.m */; };
2A81C83B13902B0700723BB3 /* MGMMD2.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A81C83713902B0700723BB3 /* MGMMD2.h */; };
2A81C83C13902B0700723BB3 /* MGMMD2.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A81C83813902B0700723BB3 /* MGMMD2.m */; };
2A81C83D13902B0700723BB3 /* MGMMD2.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A81C83713902B0700723BB3 /* MGMMD2.h */; };
2A81C83E13902B0700723BB3 /* MGMMD2.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A81C83813902B0700723BB3 /* MGMMD2.m */; };
2A81C83F13902B0700723BB3 /* MGMMD2.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A81C83713902B0700723BB3 /* MGMMD2.h */; };
2A81C84013902B0700723BB3 /* MGMMD2.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A81C83813902B0700723BB3 /* MGMMD2.m */; };
2A81C84113902B0700723BB3 /* MGMMD2.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A81C83813902B0700723BB3 /* MGMMD2.m */; };
2A81C873139038A500723BB3 /* MGMMD4.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A81C871139038A500723BB3 /* MGMMD4.h */; };
2A81C874139038A500723BB3 /* MGMMD4.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A81C872139038A500723BB3 /* MGMMD4.m */; };
2A81C875139038A500723BB3 /* MGMMD4.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A81C871139038A500723BB3 /* MGMMD4.h */; };
2A81C876139038A500723BB3 /* MGMMD4.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A81C872139038A500723BB3 /* MGMMD4.m */; };
2A81C877139038A500723BB3 /* MGMMD4.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A81C871139038A500723BB3 /* MGMMD4.h */; };
2A81C878139038A500723BB3 /* MGMMD4.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A81C872139038A500723BB3 /* MGMMD4.m */; };
2A81C879139038A500723BB3 /* MGMMD4.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A81C871139038A500723BB3 /* MGMMD4.h */; };
2A81C87A139038A500723BB3 /* MGMMD4.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A81C872139038A500723BB3 /* MGMMD4.m */; };
2A81C87B139038A500723BB3 /* MGMMD4.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A81C872139038A500723BB3 /* MGMMD4.m */; };
2A8CEBCB13967385007A7909 /* MGMRMD320.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A8CEBC913967385007A7909 /* MGMRMD320.h */; };
2A8CEBCC13967385007A7909 /* MGMRMD320.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A8CEBCA13967385007A7909 /* MGMRMD320.m */; };
2A8CEBCD13967385007A7909 /* MGMRMD320.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A8CEBC913967385007A7909 /* MGMRMD320.h */; };
2A8CEBCE13967385007A7909 /* MGMRMD320.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A8CEBCA13967385007A7909 /* MGMRMD320.m */; };
2A8CEBCF13967385007A7909 /* MGMRMD320.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A8CEBC913967385007A7909 /* MGMRMD320.h */; };
2A8CEBD013967385007A7909 /* MGMRMD320.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A8CEBCA13967385007A7909 /* MGMRMD320.m */; };
2A8CEBD113967385007A7909 /* MGMRMD320.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A8CEBC913967385007A7909 /* MGMRMD320.h */; };
2A8CEBD213967385007A7909 /* MGMRMD320.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A8CEBCA13967385007A7909 /* MGMRMD320.m */; };
2A8CEBD313967385007A7909 /* MGMRMD320.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A8CEBCA13967385007A7909 /* MGMRMD320.m */; };
2A8CEBFC139684FF007A7909 /* MGMTiger.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A8CEBFA139684FF007A7909 /* MGMTiger.h */; };
2A8CEBFD139684FF007A7909 /* MGMTiger.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A8CEBFB139684FF007A7909 /* MGMTiger.m */; };
2A8CEBFE139684FF007A7909 /* MGMTiger.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A8CEBFA139684FF007A7909 /* MGMTiger.h */; };
2A8CEBFF139684FF007A7909 /* MGMTiger.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A8CEBFB139684FF007A7909 /* MGMTiger.m */; };
2A8CEC00139684FF007A7909 /* MGMTiger.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A8CEBFA139684FF007A7909 /* MGMTiger.h */; };
2A8CEC01139684FF007A7909 /* MGMTiger.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A8CEBFB139684FF007A7909 /* MGMTiger.m */; };
2A8CEC02139684FF007A7909 /* MGMTiger.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A8CEBFA139684FF007A7909 /* MGMTiger.h */; };
2A8CEC03139684FF007A7909 /* MGMTiger.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A8CEBFB139684FF007A7909 /* MGMTiger.m */; };
2A8CEC04139684FF007A7909 /* MGMTiger.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A8CEBFB139684FF007A7909 /* MGMTiger.m */; };
2A8CECAB1396BE0B007A7909 /* MGMBase64.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A8CECA91396BE0B007A7909 /* MGMBase64.h */; };
2A8CECAC1396BE0B007A7909 /* MGMBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A8CECAA1396BE0B007A7909 /* MGMBase64.m */; };
2A8CECAD1396BE0B007A7909 /* MGMBase64.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A8CECA91396BE0B007A7909 /* MGMBase64.h */; };
2A8CECAE1396BE0B007A7909 /* MGMBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A8CECAA1396BE0B007A7909 /* MGMBase64.m */; };
2A8CECAF1396BE0B007A7909 /* MGMBase64.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A8CECA91396BE0B007A7909 /* MGMBase64.h */; };
2A8CECB01396BE0B007A7909 /* MGMBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A8CECAA1396BE0B007A7909 /* MGMBase64.m */; };
2A8CECB11396BE0B007A7909 /* MGMBase64.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A8CECA91396BE0B007A7909 /* MGMBase64.h */; };
2A8CECB21396BE0B007A7909 /* MGMBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A8CECAA1396BE0B007A7909 /* MGMBase64.m */; };
2A8CECB31396BE0B007A7909 /* MGMBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A8CECAA1396BE0B007A7909 /* MGMBase64.m */; };
2A91460012233E450075E219 /* MGMTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A2CBB151222A4F200C864D8 /* MGMTypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
2A91461412233F800075E219 /* MGMTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A2CBB151222A4F200C864D8 /* MGMTypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
2A91463B122340780075E219 /* MGMTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A2CBB151222A4F200C864D8 /* MGMTypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
2A914658122341260075E219 /* MGMTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A2CBB151222A4F200C864D8 /* MGMTypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
2A96144D12C6F3E5006CBDB0 /* MGMBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A752BBD12C6C5FC00082F40 /* MGMBase64.m */; };
8DD76F9A0486AA7600D96B5E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* main.m */; settings = {ATTRIBUTES = (); }; };
8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; };
8DD76F9F0486AA7600D96B5E /* MGMMD.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6859EA3029092ED04C91782 /* MGMMD.1 */; };
@ -104,6 +167,12 @@
/* Begin PBXFileReference section */
08FB7796FE84155DC02AAC07 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; wrapsLines = 1; };
08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
2A1022F813952C7B00325DC6 /* MGMRMD128.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMRMD128.h; sourceTree = "<group>"; };
2A1022F913952C7B00325DC6 /* MGMRMD128.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGMRMD128.m; sourceTree = "<group>"; };
2A1023C413955A8500325DC6 /* MGMRMD160.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMRMD160.h; sourceTree = "<group>"; };
2A1023C513955A8500325DC6 /* MGMRMD160.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGMRMD160.m; sourceTree = "<group>"; };
2A1024361395A9C100325DC6 /* MGMRMD256.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMRMD256.h; sourceTree = "<group>"; };
2A1024371395A9C100325DC6 /* MGMRMD256.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGMRMD256.m; sourceTree = "<group>"; };
2A2CBB151222A4F200C864D8 /* MGMTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMTypes.h; sourceTree = "<group>"; };
2A752B5F12C6C31500082F40 /* MGMMD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMMD.h; sourceTree = "<group>"; };
2A752B6012C6C31500082F40 /* MGMMD.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGMMD.m; sourceTree = "<group>"; };
@ -119,8 +188,16 @@
2A752B6A12C6C31500082F40 /* MGMSHA384.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGMSHA384.m; sourceTree = "<group>"; };
2A752B6B12C6C31500082F40 /* MGMSHA512.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMSHA512.h; sourceTree = "<group>"; };
2A752B6C12C6C31500082F40 /* MGMSHA512.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGMSHA512.m; sourceTree = "<group>"; };
2A752BBC12C6C5FC00082F40 /* MGMBase64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMBase64.h; sourceTree = "<group>"; };
2A752BBD12C6C5FC00082F40 /* MGMBase64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGMBase64.m; sourceTree = "<group>"; wrapsLines = 1; };
2A81C83713902B0700723BB3 /* MGMMD2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMMD2.h; sourceTree = "<group>"; };
2A81C83813902B0700723BB3 /* MGMMD2.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGMMD2.m; sourceTree = "<group>"; };
2A81C871139038A500723BB3 /* MGMMD4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMMD4.h; sourceTree = "<group>"; };
2A81C872139038A500723BB3 /* MGMMD4.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGMMD4.m; sourceTree = "<group>"; };
2A8CEBC913967385007A7909 /* MGMRMD320.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMRMD320.h; sourceTree = "<group>"; };
2A8CEBCA13967385007A7909 /* MGMRMD320.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGMRMD320.m; sourceTree = "<group>"; };
2A8CEBFA139684FF007A7909 /* MGMTiger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMTiger.h; sourceTree = "<group>"; };
2A8CEBFB139684FF007A7909 /* MGMTiger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGMTiger.m; sourceTree = "<group>"; };
2A8CECA91396BE0B007A7909 /* MGMBase64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMBase64.h; sourceTree = "<group>"; };
2A8CECAA1396BE0B007A7909 /* MGMBase64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGMBase64.m; sourceTree = "<group>"; };
2A9145F012233D690075E219 /* MGMMD.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MGMMD.framework; sourceTree = BUILT_PRODUCTS_DIR; };
2A9145F712233DB60075E219 /* Framework-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Framework-Info.plist"; sourceTree = "<group>"; };
2A91460C12233E6A0075E219 /* libMGMMD.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMGMMD.a; sourceTree = BUILT_PRODUCTS_DIR; };
@ -219,6 +296,7 @@
2A2CBB151222A4F200C864D8 /* MGMTypes.h */,
2A752B4412C6C2BA00082F40 /* MD */,
2A752BB012C6C32C00082F40 /* Crypt */,
2A8CECA81396BE0B007A7909 /* Other */,
);
path = Classes;
sourceTree = "<group>";
@ -228,8 +306,20 @@
children = (
2A752B5F12C6C31500082F40 /* MGMMD.h */,
2A752B6012C6C31500082F40 /* MGMMD.m */,
2A81C83713902B0700723BB3 /* MGMMD2.h */,
2A81C83813902B0700723BB3 /* MGMMD2.m */,
2A81C871139038A500723BB3 /* MGMMD4.h */,
2A81C872139038A500723BB3 /* MGMMD4.m */,
2A752B6112C6C31500082F40 /* MGMMD5.h */,
2A752B6212C6C31500082F40 /* MGMMD5.m */,
2A1022F813952C7B00325DC6 /* MGMRMD128.h */,
2A1022F913952C7B00325DC6 /* MGMRMD128.m */,
2A1023C413955A8500325DC6 /* MGMRMD160.h */,
2A1023C513955A8500325DC6 /* MGMRMD160.m */,
2A1024361395A9C100325DC6 /* MGMRMD256.h */,
2A1024371395A9C100325DC6 /* MGMRMD256.m */,
2A8CEBC913967385007A7909 /* MGMRMD320.h */,
2A8CEBCA13967385007A7909 /* MGMRMD320.m */,
2A752B6312C6C31500082F40 /* MGMSHA1.h */,
2A752B6412C6C31500082F40 /* MGMSHA1.m */,
2A752B6512C6C31500082F40 /* MGMSHA224.h */,
@ -240,6 +330,8 @@
2A752B6A12C6C31500082F40 /* MGMSHA384.m */,
2A752B6B12C6C31500082F40 /* MGMSHA512.h */,
2A752B6C12C6C31500082F40 /* MGMSHA512.m */,
2A8CEBFA139684FF007A7909 /* MGMTiger.h */,
2A8CEBFB139684FF007A7909 /* MGMTiger.m */,
);
path = MD;
sourceTree = "<group>";
@ -247,12 +339,19 @@
2A752BB012C6C32C00082F40 /* Crypt */ = {
isa = PBXGroup;
children = (
2A752BBC12C6C5FC00082F40 /* MGMBase64.h */,
2A752BBD12C6C5FC00082F40 /* MGMBase64.m */,
);
path = Crypt;
sourceTree = "<group>";
};
2A8CECA81396BE0B007A7909 /* Other */ = {
isa = PBXGroup;
children = (
2A8CECA91396BE0B007A7909 /* MGMBase64.h */,
2A8CECAA1396BE0B007A7909 /* MGMBase64.m */,
);
path = Other;
sourceTree = "<group>";
};
2A9145F612233DB60075E219 /* Resources */ = {
isa = PBXGroup;
children = (
@ -284,7 +383,14 @@
2A752B8A12C6C31500082F40 /* MGMSHA256.h in Headers */,
2A752B8C12C6C31500082F40 /* MGMSHA384.h in Headers */,
2A752B8E12C6C31500082F40 /* MGMSHA512.h in Headers */,
2A752BC212C6C5FC00082F40 /* MGMBase64.h in Headers */,
2A81C83D13902B0700723BB3 /* MGMMD2.h in Headers */,
2A81C877139038A500723BB3 /* MGMMD4.h in Headers */,
2A1022FE13952C7B00325DC6 /* MGMRMD128.h in Headers */,
2A1023CA13955A8500325DC6 /* MGMRMD160.h in Headers */,
2A10243C1395A9C100325DC6 /* MGMRMD256.h in Headers */,
2A8CEBCF13967385007A7909 /* MGMRMD320.h in Headers */,
2A8CEC00139684FF007A7909 /* MGMTiger.h in Headers */,
2A8CECAF1396BE0B007A7909 /* MGMBase64.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -300,7 +406,14 @@
2A752B7C12C6C31500082F40 /* MGMSHA256.h in Headers */,
2A752B7E12C6C31500082F40 /* MGMSHA384.h in Headers */,
2A752B8012C6C31500082F40 /* MGMSHA512.h in Headers */,
2A752BC012C6C5FC00082F40 /* MGMBase64.h in Headers */,
2A81C83B13902B0700723BB3 /* MGMMD2.h in Headers */,
2A81C875139038A500723BB3 /* MGMMD4.h in Headers */,
2A1022FC13952C7B00325DC6 /* MGMRMD128.h in Headers */,
2A1023C813955A8500325DC6 /* MGMRMD160.h in Headers */,
2A10243A1395A9C100325DC6 /* MGMRMD256.h in Headers */,
2A8CEBCD13967385007A7909 /* MGMRMD320.h in Headers */,
2A8CEBFE139684FF007A7909 /* MGMTiger.h in Headers */,
2A8CECAD1396BE0B007A7909 /* MGMBase64.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -316,7 +429,14 @@
2A752B9812C6C31500082F40 /* MGMSHA256.h in Headers */,
2A752B9A12C6C31500082F40 /* MGMSHA384.h in Headers */,
2A752B9C12C6C31500082F40 /* MGMSHA512.h in Headers */,
2A752BBE12C6C5FC00082F40 /* MGMBase64.h in Headers */,
2A81C83913902B0700723BB3 /* MGMMD2.h in Headers */,
2A81C873139038A500723BB3 /* MGMMD4.h in Headers */,
2A1022FA13952C7B00325DC6 /* MGMRMD128.h in Headers */,
2A1023C613955A8500325DC6 /* MGMRMD160.h in Headers */,
2A1024381395A9C100325DC6 /* MGMRMD256.h in Headers */,
2A8CEBCB13967385007A7909 /* MGMRMD320.h in Headers */,
2A8CEBFC139684FF007A7909 /* MGMTiger.h in Headers */,
2A8CECAB1396BE0B007A7909 /* MGMBase64.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -332,7 +452,14 @@
2A752BA612C6C31500082F40 /* MGMSHA256.h in Headers */,
2A752BA812C6C31500082F40 /* MGMSHA384.h in Headers */,
2A752BAA12C6C31500082F40 /* MGMSHA512.h in Headers */,
2A752BC412C6C5FC00082F40 /* MGMBase64.h in Headers */,
2A81C83F13902B0700723BB3 /* MGMMD2.h in Headers */,
2A81C879139038A500723BB3 /* MGMMD4.h in Headers */,
2A10230013952C7B00325DC6 /* MGMRMD128.h in Headers */,
2A1023CC13955A8500325DC6 /* MGMRMD160.h in Headers */,
2A10243E1395A9C100325DC6 /* MGMRMD256.h in Headers */,
2A8CEBD113967385007A7909 /* MGMRMD320.h in Headers */,
2A8CEC02139684FF007A7909 /* MGMTiger.h in Headers */,
2A8CECB11396BE0B007A7909 /* MGMBase64.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -476,7 +603,14 @@
2A752B8B12C6C31500082F40 /* MGMSHA256.m in Sources */,
2A752B8D12C6C31500082F40 /* MGMSHA384.m in Sources */,
2A752B8F12C6C31500082F40 /* MGMSHA512.m in Sources */,
2A752BC312C6C5FC00082F40 /* MGMBase64.m in Sources */,
2A81C83E13902B0700723BB3 /* MGMMD2.m in Sources */,
2A81C878139038A500723BB3 /* MGMMD4.m in Sources */,
2A1022FF13952C7B00325DC6 /* MGMRMD128.m in Sources */,
2A1023CB13955A8500325DC6 /* MGMRMD160.m in Sources */,
2A10243D1395A9C100325DC6 /* MGMRMD256.m in Sources */,
2A8CEBD013967385007A7909 /* MGMRMD320.m in Sources */,
2A8CEC01139684FF007A7909 /* MGMTiger.m in Sources */,
2A8CECB01396BE0B007A7909 /* MGMBase64.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -491,7 +625,14 @@
2A752B7D12C6C31500082F40 /* MGMSHA256.m in Sources */,
2A752B7F12C6C31500082F40 /* MGMSHA384.m in Sources */,
2A752B8112C6C31500082F40 /* MGMSHA512.m in Sources */,
2A752BC112C6C5FC00082F40 /* MGMBase64.m in Sources */,
2A81C83C13902B0700723BB3 /* MGMMD2.m in Sources */,
2A81C876139038A500723BB3 /* MGMMD4.m in Sources */,
2A1022FD13952C7B00325DC6 /* MGMRMD128.m in Sources */,
2A1023C913955A8500325DC6 /* MGMRMD160.m in Sources */,
2A10243B1395A9C100325DC6 /* MGMRMD256.m in Sources */,
2A8CEBCE13967385007A7909 /* MGMRMD320.m in Sources */,
2A8CEBFF139684FF007A7909 /* MGMTiger.m in Sources */,
2A8CECAE1396BE0B007A7909 /* MGMBase64.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -506,7 +647,14 @@
2A752B9912C6C31500082F40 /* MGMSHA256.m in Sources */,
2A752B9B12C6C31500082F40 /* MGMSHA384.m in Sources */,
2A752B9D12C6C31500082F40 /* MGMSHA512.m in Sources */,
2A752BBF12C6C5FC00082F40 /* MGMBase64.m in Sources */,
2A81C83A13902B0700723BB3 /* MGMMD2.m in Sources */,
2A81C874139038A500723BB3 /* MGMMD4.m in Sources */,
2A1022FB13952C7B00325DC6 /* MGMRMD128.m in Sources */,
2A1023C713955A8500325DC6 /* MGMRMD160.m in Sources */,
2A1024391395A9C100325DC6 /* MGMRMD256.m in Sources */,
2A8CEBCC13967385007A7909 /* MGMRMD320.m in Sources */,
2A8CEBFD139684FF007A7909 /* MGMTiger.m in Sources */,
2A8CECAC1396BE0B007A7909 /* MGMBase64.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -521,7 +669,14 @@
2A752BA712C6C31500082F40 /* MGMSHA256.m in Sources */,
2A752BA912C6C31500082F40 /* MGMSHA384.m in Sources */,
2A752BAB12C6C31500082F40 /* MGMSHA512.m in Sources */,
2A752BC512C6C5FC00082F40 /* MGMBase64.m in Sources */,
2A81C84013902B0700723BB3 /* MGMMD2.m in Sources */,
2A81C87A139038A500723BB3 /* MGMMD4.m in Sources */,
2A10230113952C7B00325DC6 /* MGMRMD128.m in Sources */,
2A1023CD13955A8500325DC6 /* MGMRMD160.m in Sources */,
2A10243F1395A9C100325DC6 /* MGMRMD256.m in Sources */,
2A8CEBD213967385007A7909 /* MGMRMD320.m in Sources */,
2A8CEC03139684FF007A7909 /* MGMTiger.m in Sources */,
2A8CECB21396BE0B007A7909 /* MGMBase64.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -537,7 +692,14 @@
2A752B7112C6C31500082F40 /* MGMSHA256.m in Sources */,
2A752B7212C6C31500082F40 /* MGMSHA384.m in Sources */,
2A752B7312C6C31500082F40 /* MGMSHA512.m in Sources */,
2A96144D12C6F3E5006CBDB0 /* MGMBase64.m in Sources */,
2A81C84113902B0700723BB3 /* MGMMD2.m in Sources */,
2A81C87B139038A500723BB3 /* MGMMD4.m in Sources */,
2A10230213952C7B00325DC6 /* MGMRMD128.m in Sources */,
2A1023CE13955A8500325DC6 /* MGMRMD160.m in Sources */,
2A1024401395A9C100325DC6 /* MGMRMD256.m in Sources */,
2A8CEBD313967385007A7909 /* MGMRMD320.m in Sources */,
2A8CEC04139684FF007A7909 /* MGMTiger.m in Sources */,
2A8CECB31396BE0B007A7909 /* MGMBase64.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -548,6 +710,11 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = (
i386,
x86_64,
ppc,
);
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
@ -557,6 +724,8 @@
GCC_PREFIX_HEADER = Prefix.pch;
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = MGMMD;
SDKROOT = macosx10.5;
VALID_ARCHS = "i386 x86_64 ppc";
};
name = Debug;
};
@ -564,23 +733,26 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = (
i386,
x86_64,
ppc,
);
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_MODEL_TUNING = G5;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = Prefix.pch;
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = MGMMD;
SDKROOT = macosx10.5;
VALID_ARCHS = "i386 x86_64 ppc";
};
name = Release;
};
1DEB927908733DD40010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
ppc,
i386,
x86_64,
);
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
@ -590,18 +762,14 @@
"MACOSX_DEPLOYMENT_TARGET[arch=x86_64]" = 10.5;
ONLY_ACTIVE_ARCH = YES;
PREBINDING = NO;
SDKROOT = macosx10.5;
SDKROOT = "";
};
name = Debug;
};
1DEB927A08733DD40010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
ppc,
i386,
x86_64,
);
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
@ -609,7 +777,7 @@
MACOSX_DEPLOYMENT_TARGET = 10.4;
"MACOSX_DEPLOYMENT_TARGET[arch=x86_64]" = 10.5;
PREBINDING = NO;
SDKROOT = macosx10.5;
SDKROOT = "";
};
name = Release;
};

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:MGMMD.xcodeproj">
</FileRef>
</Workspace>

63
main.m
View File

@ -6,20 +6,53 @@
//
#import <Foundation/Foundation.h>
#import "MGMMD2.h"
#import "MGMMD4.h"
#import "MGMMD5.h"
#import "MGMRMD128.h"
#import "MGMRMD160.h"
#import "MGMRMD256.h"
#import "MGMRMD320.h"
#import "MGMSHA1.h"
#import "MGMSHA224.h"
#import "MGMSHA256.h"
#import "MGMSHA384.h"
#import "MGMSHA512.h"
#import "MGMTiger.h"
#import "MGMMD.h"
#import "MGMBase64.h"
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString *correct = @"It is correct.";
NSString *incorrect = @"Something is wrong, it is incorrect.";
/*while (1) {
char *string = (char *)malloc(512);
scanf("%s", string);
if (!strcmp(string, "quit"))
break;
printf("%s\n", SHA512String(string, strlen(string)));
free(string);
}
exit(0);*/
NSString *correct = [@"It is correct." retain];
NSString *incorrect = [@"Something is wrong, it is incorrect." retain];
NSLog(@"Running standared tests");
NSLog(@"MD2: %@", (MD2Test() ? correct : incorrect));
NSLog(@"MD4: %@", (MD4Test() ? correct : incorrect));
NSLog(@"MD5: %@", (MD5Test() ? correct : incorrect));
NSLog(@"RIPEMD128: %@", (RMD128Test() ? correct : incorrect));
NSLog(@"RIPEMD160: %@", (RMD160Test() ? correct : incorrect));
NSLog(@"RIPEMD256: %@", (RMD256Test() ? correct : incorrect));
NSLog(@"RIPEMD320: %@", (RMD320Test() ? correct : incorrect));
NSLog(@"SHA1: %@", (SHA1Test() ? correct : incorrect));
NSLog(@"SHA224: %@", (SHA224Test() ? correct : incorrect));
NSLog(@"SHA256: %@", (SHA256Test() ? correct : incorrect));
NSLog(@"SHA384: %@", (SHA384Test() ? correct : incorrect));
NSLog(@"SHA512: %@", (SHA512Test() ? correct : incorrect));
NSLog(@"Tiger: %@", (tigerTest() ? correct : incorrect));
NSString *MDString = @"Test String";
NSString *hash;
@ -37,9 +70,12 @@ int main (int argc, const char * argv[]) {
hash = [MDString SHA512];
NSLog(@"SHA512: %@ %@", hash, ([hash isEqual:@"924bae629fbad5096a0a68929d5314d5b10b00108c5f9387c98d4c6cfe527a3cb6bba4303ed769c1feb38699800012b50c41e638bf0b47854f78344a3ac442a8"] ? correct : incorrect));
[pool drain];
pool = [NSAutoreleasePool new];
NSString *MDFile = [[NSBundle mainBundle] executablePath];
//Change this to the path of the test file.
MDFile = [[[[MDFile stringByDeletingLastPathComponent] stringByDeletingLastPathComponent] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"MDTest.bin"];
MDFile = [[[[[MDFile stringByDeletingLastPathComponent] stringByDeletingLastPathComponent] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"MDTest.bin"] retain];
NSLog(@"Obj-C File MD of %@", MDFile);
hash = [MDFile pathMD5];
NSLog(@"MD5: %@ %@", hash, ([hash isEqual:@"db393181e59d5b50c72bc582c505ab6f"] ? correct : incorrect));
@ -54,6 +90,9 @@ int main (int argc, const char * argv[]) {
hash = [MDFile pathSHA512];
NSLog(@"SHA512: %@ %@", hash, ([hash isEqual:@"6801c0d3e7fdf43218e5f0986ee3e8dc33928a57470cffbde7ebdc23b454fb06024d5b0cba2646eaf58d8f53bb32eaff0d6a0ad7d97e8b4f607a181bd1bf7936"] ? correct : incorrect));
[pool drain];
pool = [NSAutoreleasePool new];
const char *MDChar = "0123456789abcdefghijklmnopqrstuvwxyz";
char *hashChar;
NSLog(@"C MD of %s", MDChar);
@ -76,6 +115,9 @@ int main (int argc, const char * argv[]) {
NSLog(@"SHA512: %s %@", hashChar, (strcmp(hashChar, "95cadc34aa46b9fdef432f62fe5bad8d9f475bfbecf797d5802bb5f2937a85d93ce4857a6262b03834c01c610d74cd1215f9a466dc6ad3dd15078e3309a03a6d") ? incorrect : correct));
free(hashChar);
[pool drain];
pool = [NSAutoreleasePool new];
const char *MDCharFile = [MDFile UTF8String];
NSLog(@"C File MD of %s", MDCharFile);
hashChar = MD5File(MDCharFile);
@ -109,6 +151,9 @@ int main (int argc, const char * argv[]) {
free(hashChar);
}
[pool drain];
pool = [NSAutoreleasePool new];
MGMMD *md;
NSLog(@"File MGMMD of %@", MDFile);
md = [MGMMD mdWithAlgorithm:@"MD5"];
@ -130,6 +175,11 @@ int main (int argc, const char * argv[]) {
[md updateWithFile:MDFile];
NSLog(@"SHA512: %@ %@", [md finalHash], ([[md finalHash] isEqual:@"6801c0d3e7fdf43218e5f0986ee3e8dc33928a57470cffbde7ebdc23b454fb06024d5b0cba2646eaf58d8f53bb32eaff0d6a0ad7d97e8b4f607a181bd1bf7936"] ? correct : incorrect));
[MDFile release];
[pool drain];
pool = [NSAutoreleasePool new];
MDString = @"asdjl32j4lkjDS;:J;iaslkhjouh3hjsad89y45ioausf89sahuxzyLHuiyf8yHuyhiuash";
NSLog(@"MGMMD of %@", MDString);
md = [MGMMD mdWithAlgorithm:@"MD5"];
@ -144,6 +194,7 @@ int main (int argc, const char * argv[]) {
md = [MGMMD mdWithAlgorithm:@"SHA256"];
[md updateWithString:MDString];
NSLog(@"SHA256: %@ %@", [md finalHash], ([[md finalHash] isEqual:@"4b25724a05afaab26147179fdcfa7f7a81db0464d78072614a57e738b5bf1b0f"] ? correct : incorrect));
hash = [MDString SHA384];
md = [MGMMD mdWithAlgorithm:@"SHA384"];
[md updateWithString:MDString];
NSLog(@"SHA384: %@ %@", [md finalHash], ([[md finalHash] isEqual:@"665fc58df2e22ceafc373b0b951bd100a9e1f60fb68b4758ad88e32e5e5cbc02771c1a7cde672e7c5c6756860ce88a50"] ? correct : incorrect));
@ -151,12 +202,18 @@ int main (int argc, const char * argv[]) {
[md updateWithString:MDString];
NSLog(@"SHA512: %@ %@", [md finalHash], ([[md finalHash] isEqual:@"1c58a65cf90dbeb31f8e4f196ce278936d70507cffea9682a9cbf79da9b046aebca9ed08c6f94d8e9f80cc4df0d5ddc65072cdb8a9b65d9e89b0fbf9bb0700ef"] ? correct : incorrect));
[pool drain];
pool = [NSAutoreleasePool new];
NSString *cryptString = @"Test String";
NSString *crypt = [cryptString encodeBase64];
NSLog(@"Base64 Encrypt: %@ %@", crypt, ([crypt isEqual:@"VGVzdCBTdHJpbmc="] ? correct : incorrect));
crypt = [crypt decodeBase64];
NSLog(@"Base64 Decrypt: %@ %@", crypt, ([crypt isEqual:cryptString] ? correct : incorrect));
[correct release];
[incorrect release];
[pool drain];
return 0;
}