md4 구현이 제대로 작동하지 않는 것 같습니다. 무엇이 잘못 되었습니까? 또한, 나는이 프로젝트가 할당 된 클래스에 있지 않다. 나는 단지 킥을 위해 그것을하고있다. 나는 또한 오히려 당신이 명백한 대답보다 나에게 힌트를 주려고합니다. 감사!C에서의 MD4 구현 - 일관되지만 오류가있는 출력
편집 : 내 결과가 RFC1320에서 제공하는 테스트 벡터와 일치하지 않습니다. 예를 들어 :
From RFC -- MD4 ("abc") = a448017aaf21d8525fc10ae87aa6729d
Mine -- DIGEST: ed763b1deb753a9d8fc7e3f1a653a954 -- 32 BYTES
나는 생각하지만, 내 출력 해시 (32 바이트)
에서 올바른 크기를 점점 내가 명확히 할 필요가 다른 것이 있다면, 의견을주세요!
/**
hThreat @ http://auburn.edu/~dac0007/blog/
"MD4 hashing algorithm -- beginning project 1"
**/
// References
//http://tools.ietf.org/html/rfc1320
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// define 3 auxiliary functions (Copied from RFC1320)
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
#define H(x, y, z) ((x)^(y)^(z))
#define ROTL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
BYTE* stepOne(int bitLen, int byteLen, BYTE* pMsg)
{
/* STEP ONE
*
**/
printf("\n\n\n STEP 1\n--------\n");
// find amount to pad message (assuming it's not already 448 bits)
for(int i=0; i<512 && bitLen%512!=448; i++)
bitLen++;
// amount of data that will be appended
int tPad = (bitLen/8)-byteLen;
// create a memory block of appropriate size
BYTE* bloc = (BYTE*)malloc(tPad+byteLen); // ie 56 bytes
memset(bloc,0,tPad+byteLen); // zero everything out, 0x80, 0x00,...,0x00
printf("Created %d BYTE block\n",tPad+byteLen);
// Set elements of bloc = to elements of pMsg
for(int i=0; i<byteLen; i++)
bloc[i] = pMsg[i];
printf("Set bloc <=> pMsg; bloc = \"%s\"\n",(char*)bloc);
// Pad bloc to spec,
bloc[byteLen] = 0x80; // first byte should be: 1000 0000b
// memset took care of the rest..
printf("-> %s PADDED TO %d BYTES\n","bloc", byteLen+tPad);
printf("-> bloc = \"%s\"\n",(char*)bloc);
// Set pMsg = bloc
pMsg = bloc;
printf("Set pMsg = bloc; pMsg = \"%s\"\n",(char*)pMsg);
return pMsg;
// end step 1
}
BYTE* stepTwo(int bitLen, int byteLen, BYTE* pMsg)
{
printf("\n\n\n STEP 2\n--------\n");
printf("Set pMsg = bloc; pMsg = \"%s\"\n",(char*)pMsg);
// Assuming that the original byteLen of message < 2^64
int originalLen = byteLen;
int tByteLen = (bitLen/8);
// create 64 bit representation of byteLen (b bits)
unsigned long long int uint64 = (unsigned long long int)originalLen*8;
int pdSz = sizeof(uint64);
// create a memory block of appropriate size (Multiple of 512/8)
BYTE* bloc = (BYTE*)malloc(tByteLen + pdSz);// ie 56 + 8 = 64 bytes
memset(bloc,0,tByteLen + pdSz); // zero everything out
printf("Created %d BYTE block\n",tByteLen+pdSz);
// Set elements of bloc = to elements of pMsg
for(int i=0; i<tByteLen; i++)
bloc[i] = pMsg[i];
printf("Set bloc <=> pMsg; bloc = \"%s\"\n",(char*)bloc);
// Append low order DWORD first, as specified
for(int i=0; i<pdSz; i++)
bloc[i+tByteLen] = (BYTE)(uint64 >> i*pdSz);
printf("-> %s PADDED TO %d BYTES\n","bloc", tByteLen+pdSz);
printf("-> bloc = \"%s\"\n",(char*)bloc);
// Set pMsg = bloc
pMsg = bloc;
printf("Set pMsg = bloc; pMsg = \"%s\"\n",(char*)pMsg);
return pMsg;
// step 2 complete
}
void stepThreeFourFive(int bitLen, BYTE* pMsg)
{
/* STEP THREE
*
**/
printf("\n\n\n STEP 3\n--------\n");
// Initialize 4 DWORD buffer
DWORD A = 0x67452301;
DWORD B = 0xefcdab89;
DWORD C = 0x98badcfe;
DWORD D = 0x10325476;
DWORD AA;
DWORD BB;
DWORD CC;
DWORD DD;
printf("(Defined 4 DWORD buffer)");
// end step 3
/* STEP FOUR
*
**/
printf("\n\n\n STEP 4\n--------\n");
// process each 16-word block
BYTE* X = (BYTE*)malloc(4*sizeof(DWORD));
for(int i=0; i<((bitLen/8)/32)-1; i++)
{
// Copy block i into X
for(int j=0; j<16; j++)
X[j] = pMsg[i*16+j];
// save to spec
AA = A;
BB = B;
CC = C;
DD = D;
/* Round 1 */
printf("ROUND 1 ");
A = ROTL((A + F(B,C,D) + X[0]),3);
D = ROTL((D + F(A,B,C) + X[1]),7);
C = ROTL((C + F(D,A,B) + X[2]),11);
B = ROTL((B + F(C,D,A) + X[3]),19);
//
A = ROTL((A + F(B,C,D) + X[4]),3);
D = ROTL((D + F(A,B,C) + X[5]),7);
C = ROTL((C + F(D,A,B) + X[6]),11);
B = ROTL((B + F(C,D,A) + X[7]),19);
//
A = ROTL((A + F(B,C,D) + X[8]),3);
D = ROTL((D + F(A,B,C) + X[9]),7);
C = ROTL((C + F(D,A,B) + X[10]),11);
B = ROTL((B + F(C,D,A) + X[11]),19);
//
A = ROTL((A + F(B,C,D) + X[12]),3);
D = ROTL((D + F(A,B,C) + X[13]),7);
C = ROTL((C + F(D,A,B) + X[14]),11);
B = ROTL((B + F(C,D,A) + X[15]),19);
printf("COMPLETE\n");
/* Round 2 */
printf("ROUND 2 ");
A = ROTL((A + G(B,C,D) + X[0] + 0x5A827999),3);
D = ROTL((D + G(A,B,C) + X[4] + 0x5A827999),5);
C = ROTL((C + G(D,A,B) + X[8] + 0x5A827999),9);
B = ROTL((B + G(C,D,A) + X[12] + 0x5A827999),13);
//
A = ROTL((A + G(B,C,D) + X[1] + 0x5A827999),3);
D = ROTL((D + G(A,B,C) + X[5] + 0x5A827999),5);
C = ROTL((C + G(D,A,B) + X[9] + 0x5A827999),9);
B = ROTL((B + G(C,D,A) + X[13] + 0x5A827999),13);
//
A = ROTL((A + G(B,C,D) + X[2] + 0x5A827999),3);
D = ROTL((D + G(A,B,C) + X[6] + 0x5A827999),5);
C = ROTL((C + G(D,A,B) + X[10] + 0x5A827999),9);
B = ROTL((B + G(C,D,A) + X[14] + 0x5A827999),13);
//
A = ROTL((A + G(B,C,D) + X[3] + 0x5A827999),3);
D = ROTL((D + G(A,B,C) + X[7] + 0x5A827999),5);
C = ROTL((C + G(D,A,B) + X[11] + 0x5A827999),9);
B = ROTL((B + G(C,D,A) + X[15] + 0x5A827999),13);
printf("COMPLETE\n");
/* Round 3 */
printf("ROUND 3 ");
A = ROTL((A + H(B,C,D) + X[0] + 0x6ED9EBA1),3);
D = ROTL((D + H(A,B,C) + X[8] + 0x6ED9EBA1),9);
C = ROTL((C + H(D,A,B) + X[4] + 0x6ED9EBA1),11);
B = ROTL((B + H(C,D,A) + X[12] + 0x6ED9EBA1),15);
//
A = ROTL((A + H(B,C,D) + X[2] + 0x6ED9EBA1),3);
D = ROTL((D + H(A,B,C) + X[10] + 0x6ED9EBA1),9);
C = ROTL((C + H(D,A,B) + X[6] + 0x6ED9EBA1),11);
B = ROTL((B + H(C,D,A) + X[14] + 0x6ED9EBA1),15);
//
A = ROTL((A + H(B,C,D) + X[1] + 0x6ED9EBA1),3);
D = ROTL((D + H(A,B,C) + X[9] + 0x6ED9EBA1),9);
C = ROTL((C + H(D,A,B) + X[5] + 0x6ED9EBA1),11);
B = ROTL((B + H(C,D,A) + X[13] + 0x6ED9EBA1),15);
//
A = ROTL((A + H(B,C,D) + X[3] + 0x6ED9EBA1),3);
D = ROTL((D + H(A,B,C) + X[11] + 0x6ED9EBA1),9);
C = ROTL((C + H(D,A,B) + X[7] + 0x6ED9EBA1),11);
B = ROTL((B + H(C,D,A) + X[15] + 0x6ED9EBA1),15);
printf("COMPLETE\n\n");
// increment registers
A = A + AA;
B = B + BB;
C = C + CC;
D = D + DD;
}
// end step 4
/* STEP FIVE
*
**/
printf("\n\n STEP 5\n--------\n");
// Create a 16 byte buffer for the digest
BYTE* digest = (BYTE*)malloc(4*sizeof(DWORD));
memset(digest,0,4*sizeof(DWORD));
/* output beginning with low order byte of A and ending with high order byte of D */
// fill the buffer
for(int i=0; i<sizeof(DWORD); i++)
{
digest[i] = (BYTE)(A >> i);
digest[i+4] = (BYTE)(B >> i);
digest[i+8] = (BYTE)(C >> i);
digest[i+12] = (BYTE)(D >> i);
}
// print the digest
printf("DIGEST: ");
for(int i=0; i<(4*sizeof(DWORD)); i++)
printf("%x", digest[i]);
printf(" -- %d BYTES", strlen((char*)digest));
free(digest);
free(X);
// end step 5
}
int main()
{
printf("\n STEP 0\n--------\n");
BYTE msg[] = "abc";
int byteLen = strlen((char*)msg);
int bitLen = byteLen*8;
// get a pointer to the byte containing message
BYTE* pMsg = &msg[0];
printf("Message to Digest: \"%s\"\n", pMsg);
printf("Size of Message: %d", byteLen);
pMsg = stepOne(bitLen, byteLen, pMsg);
pMsg = stepTwo(448, byteLen, pMsg);
stepThreeFourFive(512, pMsg);
while(true)
Sleep(1000);
return 0;
}
더 구체적일 수 있습니다. 정확히 작동하지 않는 것은 무엇입니까? "작동하지 않는"것이 어떻게 나타 납니까? –
좋은 지적. "작동하지 않음"이란 내 프로그램에서 생성 된 테스트 벡터가 RFC1320의 테스트 벡터와 일치하지 않는다는 것을 의미합니다. 저는 집에있는 컴퓨터가 아니기 때문에 지금 당장 특정 출력을 제공 할 수는 없습니다 .. 그러나 명확한 설명을 위해 : RFC - MD4 ("abc") = a448017aaf21d8525fc10ae87aa6729d 광산 - "abc"= e76 ..... (나중에 구체적인 예를 게시 할 예정 임). 정확한 크기 (32 바이트)를 얻음에 유의하십시오. – dacman
32 비트 int 또는 64 비트 int로 컴파일 하시겠습니까? 그리고 당신은 어느 것을 가정 했습니까? int 또는 long을 가정 한 다른 암호 알고리즘 구현은 32 비트 뿐이므로 64 비트 환경 용으로 컴파일 될 때 파손 된 암시 적 모듈러스를가집니다. – RBerteig