2009-06-22 3 views
1

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; 
} 
+2

더 구체적일 수 있습니다. 정확히 작동하지 않는 것은 무엇입니까? "작동하지 않는"것이 어떻게 나타 납니까? –

+0

좋은 지적. "작동하지 않음"이란 내 프로그램에서 생성 된 테스트 벡터가 RFC1320의 테스트 벡터와 일치하지 않는다는 것을 의미합니다. 저는 집에있는 컴퓨터가 아니기 때문에 지금 당장 특정 출력을 제공 할 수는 없습니다 .. 그러나 명확한 설명을 위해 : RFC - MD4 ("abc") = a448017aaf21d8525fc10ae87aa6729d 광산 - "abc"= e76 ..... (나중에 구체적인 예를 게시 할 예정 임). 정확한 크기 (32 바이트)를 얻음에 유의하십시오. – dacman

+1

32 비트 int 또는 64 비트 int로 컴파일 하시겠습니까? 그리고 당신은 어느 것을 가정 했습니까? int 또는 long을 가정 한 다른 암호 알고리즘 구현은 32 비트 뿐이므로 64 비트 환경 용으로 컴파일 될 때 파손 된 암시 적 모듈러스를가집니다. – RBerteig

답변

2

왜 당신은 각 단계에서 A, B, C, D의 결과를 인쇄하고, 각 라인에 대한 표준 구현 (RFC 1320)의 결과를 비교하지 않습니다.

MD5를 생성하거나 수정하는 방법을 구현할 때 MD5와 함께 해본 적이 있습니다.

+1

비교를 위해 RFC 버전을 설치하고 실행하는 것은 좋은 생각입니다. – dacman