Guest User

pfifo

a guest
May 21st, 2011
4,331
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #ifdef fail
  2.     #!/bin/bash
  3.     # NOTE you can chmod 0755 this file and then execute it to compile (or just copy and paste)
  4.     gcc -o hashblock hashblock.c -lssl
  5.     exit 0
  6. #endif
  7.  
  8. #include <openssl/sha.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12.  
  13. // this is the block header, it is 80 bytes long (steal this code)
  14. typedef struct block_header {
  15.     unsigned int    version;
  16.     // dont let the "char" fool you, this is binary data not the human readable version
  17.     unsigned char   prev_block[32];
  18.     unsigned char   merkle_root[32];
  19.     unsigned int    timestamp;
  20.     unsigned int    bits;
  21.     unsigned int    nonce;
  22. } block_header;
  23.  
  24.  
  25. // we need a helper function to convert hex to binary, this function is unsafe and slow, but very readable (write something better)
  26. void hex2bin(unsigned char* dest, unsigned char* src)
  27. {
  28.     unsigned char bin;
  29.     int c, pos;
  30.     char buf[3];
  31.  
  32.     pos=0;
  33.     c=0;
  34.     buf[2] = 0;
  35.     while(c < strlen(src))
  36.     {
  37.         // read in 2 characaters at a time
  38.         buf[0] = src[c++];
  39.         buf[1] = src[c++];
  40.         // convert them to a interger and recast to a char (uint8)
  41.         dest[pos++] = (unsigned char)strtol(buf, NULL, 16);
  42.     }
  43.    
  44. }
  45.  
  46. // this function is mostly useless in a real implementation, were only using it for demonstration purposes
  47. void hexdump(unsigned char* data, int len)
  48. {
  49.     int c;
  50.    
  51.     c=0;
  52.     while(c < len)
  53.     {
  54.         printf("%.2x", data[c++]);
  55.     }
  56.     printf("\n");
  57. }
  58.  
  59. // this function swaps the byte ordering of binary data, this code is slow and bloated (write your own)
  60. void byte_swap(unsigned char* data, int len) {
  61.     int c;
  62.     unsigned char tmp[len];
  63.    
  64.     c=0;
  65.     while(c<len)
  66.     {
  67.         tmp[c] = data[len-(c+1)];
  68.         c++;
  69.     }
  70.    
  71.     c=0;
  72.     while(c<len)
  73.     {
  74.         data[c] = tmp[c];
  75.         c++;
  76.     }
  77. }
  78.  
  79. int main() {
  80.     // start with a block header struct
  81.     block_header header;
  82.    
  83.     // we need a place to store the checksums
  84.     unsigned char hash1[SHA256_DIGEST_LENGTH];
  85.     unsigned char hash2[SHA256_DIGEST_LENGTH];
  86.    
  87.     // you should be able to reuse these, but openssl sha256 is slow, so your probbally not going to implement this anyway
  88.     SHA256_CTX sha256_pass1, sha256_pass2;
  89.  
  90.  
  91.     // we are going to supply the block header with the values from the generation block 0
  92.     header.version =    1;
  93.     hex2bin(header.prev_block,      "0000000000000000000000000000000000000000000000000000000000000000");
  94.     hex2bin(header.merkle_root,     "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b");
  95.     header.timestamp =  1231006505;
  96.     header.bits =       486604799;
  97.     header.nonce =      2083236893;
  98.    
  99.     // the endianess of the checksums needs to be little, this swaps them form the big endian format you normally see in block explorer
  100.     byte_swap(header.prev_block, 32);
  101.     byte_swap(header.merkle_root, 32);
  102.    
  103.     // dump out some debug data to the terminal
  104.     printf("sizeof(block_header) = %d\n", sizeof(block_header));
  105.     printf("Block header (in human readable hexadecimal representation): ");
  106.     hexdump((unsigned char*)&header, sizeof(block_header));
  107.  
  108.     // Use SSL's sha256 functions, it needs to be initialized
  109.     SHA256_Init(&sha256_pass1);
  110.     // then you 'can' feed data to it in chuncks, but here were just making one pass cause the data is so small
  111.     SHA256_Update(&sha256_pass1, (unsigned char*)&header, sizeof(block_header));
  112.     // this ends the sha256 session and writes the checksum to hash1
  113.     SHA256_Final(hash1, &sha256_pass1);
  114.    
  115.     // to display this, we want to swap the byte order to big endian
  116.     byte_swap(hash1, SHA256_DIGEST_LENGTH);
  117.     printf("Useless First Pass Checksum: ");
  118.     hexdump(hash1, SHA256_DIGEST_LENGTH);
  119.  
  120.     // but to calculate the checksum again, we need it in little endian, so swap it back
  121.     byte_swap(hash1, SHA256_DIGEST_LENGTH);
  122.    
  123.     //same as above
  124.     SHA256_Init(&sha256_pass2);
  125.     SHA256_Update(&sha256_pass2, hash1, SHA256_DIGEST_LENGTH);
  126.     SHA256_Final(hash2, &sha256_pass2);
  127.    
  128.     byte_swap(hash2, SHA256_DIGEST_LENGTH);
  129.     printf("Target Second Pass Checksum: ");
  130.     hexdump(hash2, SHA256_DIGEST_LENGTH);
  131.  
  132.     return 0;
  133. }
RAW Paste Data