1

I need to modify hash code,so that instead of 256 hash value,I get 64 bit hash value following the rule that instead of 256 bit fromula.

h=A||B||C||D||E||F||G||H

where A, B, D, E, F, G, H is 32 bit words, || concat operation. I must receive 64 bit hash with formula

 h=B xor D xor F xor H || A xor C xor E xor G.

I am using following Sha256 implementation but I am unable to find part where this has to be done- http://www.zedwood.com/article/cpp-sha256-function

Where sha should be something like

SHA-256("10301231030456") = 0xe4a6aade78b1c5ad21a76adca6beb75634c1ff45e7aba9d18f861211d43d69e1

the goal is to receive:

SHA-256-mod("10301231030456") = 0xed99b2cb7e462d56

Thank you

Mykola
  • 3,343
  • 6
  • 23
  • 39
njok
  • 53
  • 3

1 Answers1

2

Try to cast your 256 bit array to unsigned long mod_args[8];

std::string sha = sha256("10301231030456");

char hash[32];

for (int i = 0, j = 0; i < sha.length(); i += 2, j++)
{
    std::string sub = sha.substr(i, 2);
    hash[j] = strtoul(sub.c_str(), NULL, 16);
}

unsigned long mod_args[8];
memcpy(mod_args, hash, 32);

than getting 2 pieces of 64 bit:

unsigned long a = mod_args[1] ^ mod_args[3] ^ mod_args[5] ^ mod_args[7];
unsigned long b = mod_args[0] ^ mod_args[2] ^ mod_args[4] ^ mod_args[6]; 

than getting result by concat that two pieces

unsigned long long result = (((unsigned long long)a) << 32) | b;

or

unsigned long long result = (((unsigned long long)b) << 32) | a;

considering what piece of hash must be older a or b

the complete solution is:

#define B_OLDER_THAN_A

int main()
{
    std::string sha = sha256("10301231030456");

    char hash[32];

    for (int i = 0, j = 0; i < sha.length(); i += 2, j++)
    {
        std::string sub = sha.substr(i, 2);
        hash[j] = strtoul(sub.c_str(), NULL, 16);
    }

    unsigned long mod_args[8];
    memcpy(mod_args, hash, 32);

    unsigned long a = mod_args[1] ^ mod_args[3] ^ mod_args[5] ^ mod_args[7];
    unsigned long b = mod_args[0] ^ mod_args[2] ^ mod_args[4] ^ mod_args[6];

#ifdef B_OLDER_THAN_A
    unsigned long long result = (((unsigned long long)b) << 32) | ((unsigned long long)a);
#else
    unsigned long long result = (((unsigned long long)a) << 32) | ((unsigned long long)b);
#endif

    unsigned char output[8] = { 0 };

    memcpy(output, (char*)(&result), 8);

    for (int i = 0; i < 8; i++)
        std::cout << setfill('0') << setw(2) << hex << (unsigned int)(output[i]);

    std::cout << endl;


    return 0;
}
Mykola
  • 3,343
  • 6
  • 23
  • 39