{"id":752,"date":"2020-06-12T19:26:17","date_gmt":"2020-06-12T17:26:17","guid":{"rendered":"https:\/\/moijari.com\/?p=752"},"modified":"2020-07-08T23:05:45","modified_gmt":"2020-07-08T21:05:45","slug":"sha256-tiivisteen-laskentaohjelma","status":"publish","type":"post","link":"https:\/\/moijari.com\/?p=752","title":{"rendered":"SHA256 tiivisteen laskentaohjelma"},"content":{"rendered":"\n<p>T\u00e4ss\u00e4 tiivisteohjelma edellista Fort satunnaisbittigeneraattoria varten.<\/p>\n\n\n\n<p>Alun definet m\u00e4\u00e4rittelev\u00e4t Fort-ohjelman k\u00e4ytt\u00e4mille HashInit, HashUpdate ja HashFinal funktioille todelliset nimet. Lis\u00e4ksi m\u00e4\u00e4ritell\u00e4\u00e4n HashName, joka tulostetaan fort_init:in alussa ja HashLen joka sis\u00e4lt\u00e4\u00e4 tiivisteen pituuden.<\/p>\n\n\n\n<p>Sitten typedef:it m\u00e4\u00e4rittelev\u00e4t uudet tyypit IUBYTE, joka on 8 bitti\u00e4 (1 merkki\u00e4) pitk\u00e4., IUWORD, joka on 32 bitti\u00e4 (4 merkki\u00e4) pitk\u00e4 ja IULONG, joka on 64 bitti\u00e4 (8 merkki\u00e4) pitk\u00e4.<\/p>\n\n\n\n<p>Seuraava kappale kuvaa SHA256 yhteysalueen. Yhteysalueen j\u00e4lkeen on ensimm\u00e4inen koodi init, joka alustaa SHA yhteysalueen. Count kent\u00e4ss\u00e4 on t\u00e4h\u00e4nastisten merkkien m\u00e4\u00e4r\u00e4 yhteysalueessa eli ohjelman suorituksen alussa nolla. State[] kenttien arvot ovat 8 ensimm\u00e4isen alkuluvun (2-19) neli\u00f6juuren desimaaliosa 32 bittisen\u00e4 lukuna.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define HashName   \"SHA256\"\n#define HashInit   SHA256Init\n#define HashUpdate SHA256Update\n#define HashFinal  SHA256Final\n#define HashLen    32\n#define HashCtx    SHA256_CONTEXT\n\ntypedef unsigned char IUBYTE;\ntypedef unsigned int IUWORD;\ntypedef unsigned long long IULONG;\n\ntypedef struct {\n    IUWORD state&#91;8];\n    IULONG count;\n    IUBYTE buffer&#91;64];\n} SHA256_CONTEXT;\n\nvoid SHA256Init(SHA256_CONTEXT *sha256)\n{\n  sha256->state&#91;0] = 0x6a09e667;\n  sha256->state&#91;1] = 0xbb67ae85;\n  sha256->state&#91;2] = 0x3c6ef372;\n  sha256->state&#91;3] = 0xa54ff53a;\n  sha256->state&#91;4] = 0x510e527f;\n  sha256->state&#91;5] = 0x9b05688c;\n  sha256->state&#91;6] = 0x1f83d9ab;\n  sha256->state&#91;7] = 0x5be0cd19;\n\n  sha256->count = 0;\n}\n<\/code><\/pre>\n\n\n\n<p>Seuraavana update funktio: Aliohjelma jakaa asiakkaan toimittaman datan 64 merkin pituisiin lohkoihin ja kutsuu transform rutiinia jokaisella lohkolla. Lohkossa voi olla ylij\u00e4\u00e4m\u00e4merkkej\u00e4 edellisest\u00e4 update kutsusta. Samoin t\u00e4m\u00e4n kutsun j\u00e4lkeen voi j\u00e4\u00e4d\u00e4 ylim\u00e4\u00e4r\u00e4isi\u00e4 merkkej\u00e4. Ylim\u00e4\u00e4r\u00e4iset merkit talletetaan yhteysalueen buffer taulukkoon.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void SHA256Update(SHA256_CONTEXT *sha256,\n    unsigned char *data, int len)\n{\n  int i,j;\n\n  \/\/ overflow from previous update\n  j = (int)sha256->count &amp; 63;\n\n  sha256->count+=len;\n\n  \/\/ if full blocks available\n  if((j+len)>63) {\n\n    \/\/ last bytes of next block to buffer\n    memcpy(&amp;sha256->buffer&#91;j],data,64-j); \n\n    \/\/ first full block from buffer\n    SHA256Transform(sha256->state,\n        sha256->buffer);\n\n    \/\/ rest of the full blocks from data\n    for (i = 64 - j ; i + 63 &lt; len; i += 64) {\n      SHA256Transform(sha256->state, &amp;data&#91;i]);\n    }\n\n    \/\/ rest of the bytes to beginning of buffer\n    j = 0;\n  } else\n    \/\/ copy all data from beginning of data\n    i = 0;\n\n  \/\/ overflow from this update to buffer\n  memcpy(&amp;sha256->buffer&#91;j],&amp;data&#91;i],len-i);\n}\n<\/code><\/pre>\n\n\n\n<p>Transform funktion k\u00e4ytt\u00e4m\u00e4 taulukko: taulun arvot ovat 64 ensimm\u00e4isen alkuluvun (2-311) kuutiojuuren desimaaliosa 32 bittisen\u00e4 lukuna.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>IUWORD k256&#91;64] = {\n  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,\n  0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\n  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,\n  0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,\n  0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,\n  0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,\n  0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n};<\/code><\/pre>\n\n\n\n<p>Transform:in k\u00e4ytt\u00e4m\u00e4t makrot<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define RR32(word,bits) ( ((word) >> (bits)) | \\\n        ((word) &lt;&lt; (32 - (bits))) )\n#define RS32(word,bits) ( ((word) >> (bits)) )<\/code><\/pre>\n\n\n\n<p>Transform funktio k\u00e4sittelee yhden lohkon kutsujan toimittamaa tietoa ja p\u00e4ivitt\u00e4\u00e4 tila kentti\u00e4 lohkon sis\u00e4lt\u00e4m\u00e4n tiedon perusteella.<\/p>\n\n\n\n<p>Ensimm\u00e4inen &#8220;for(i=0&#8221; luuppi siirt\u00e4\u00e4 datalohkon (buffer) w taulukon 16 ensimm\u00e4iseen IUWORD:iin. Seuraava &#8220;for(i=16&#8221; luuppi muodostaa loput 64 IUWORD:st\u00e4 yhdistelem\u00e4ll\u00e4 aiempia rivej\u00e4.<\/p>\n\n\n\n<p>Seuraavan kappale siirt\u00e4\u00e4 tiivistetoiminnon (hash) tilan a, b,c &#8230; h muuttujiin. Seuraava &#8220;for(i=64&#8221; luuppi tekee a-h, w[] ja k256 kentille laskentaa ja siirtely\u00e4 muodostaen uudet a-h kent\u00e4t. Kun kaikki 64 kierrosta on tehty yhdistet\u00e4\u00e4n a-h kent\u00e4t taas state[] kenttiin.<\/p>\n\n\n\n<p>Sitten palataan laskemaan seuraavaa lohkoa.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void SHA256Transform(IUWORD state&#91;8], IUBYTE buffer&#91;64])\n{\n  int i;\n\n  IUWORD w&#91;64], s0;\n  IUWORD a, b, c, d, e, f, g, h;\n  IUWORD maj, t2, s1;\n  IUWORD ch, t1;\n\n  \/\/ fill first 16 w&#91;] entries\n  for(i=0;i&lt;16;i++) {\n    w&#91;i] =\n      (IUWORD)buffer&#91;i*4+0] &lt;&lt; 24 |\n      (IUWORD)buffer&#91;i*4+1] &lt;&lt; 16 |\n      (IUWORD)buffer&#91;i*4+2] &lt;&lt; 8  |\n      (IUWORD)buffer&#91;i*4+3];\n  }\n\n  \/\/ fill entries 16-63 of w&#91;]\n  for(i=16;i&lt;64;i++) {\n    s0 = (RR32(w&#91;i-15],7)) ^ \n         (RR32(w&#91;i-15],18)) ^\n         (RS32(w&#91;i-15],3));\n    s1 = (RR32(w&#91;i-2],17)) ^\n         (RR32(w&#91;i-2],19)) ^\n         (RS32(w&#91;i-2],10));\n    w&#91;i] = w&#91;i-16] + s0 + w&#91;i-7] + s1;\n  }\n\n  \/\/ copy state\n  a = state&#91;0];\n  b = state&#91;1];\n  c = state&#91;2];\n  d = state&#91;3];\n  e = state&#91;4];\n  f = state&#91;5];\n  g = state&#91;6];\n  h = state&#91;7];\n\n  for(i=0;i&lt;64;i++) {\n    s0 = (RR32(a,2)) ^ (RR32(a,13)) ^\n           (RR32(a,22));\n    maj = (a &amp; b) ^ (a &amp; c) ^ (b &amp; c);\n    t2 = s0 + maj;\n    s1 = (RR32(e,6)) ^ (RR32(e,11)) ^\n           (RR32(e,25));\n    ch = (e &amp; f) ^ ((~ e) &amp; g);\n    t1 = h + s1 + ch + k256&#91;i] + w&#91;i];\n\n    h = g;\n    g = f;\n    f = e;\n    e = d + t1;\n    d = c;\n    c = b;\n    b = a;\n    a = t1 + t2;\n  }\n\n  \/\/ add compression result to state\n  state&#91;0] += a;\n  state&#91;1] += b;\n  state&#91;2] += c;\n  state&#91;3] += d;\n  state&#91;4] += e;\n  state&#91;5] += f;\n  state&#91;6] += g;\n  state&#91;7] += h;\n}\n<\/code><\/pre>\n\n\n\n<p>Maj funktion testitaulu on seuraavankaltainen: a b ja c ovat parametrit ja m rivill\u00e4 on maj:n arvo. Maj:ssa on bittiarvo, jota on eniten. Jos nollia on kolme tai kaksi, maj:n arvo on 0. Jos taas ykk\u00f6si\u00e4 on kolme tai kaksi maj:n arvo on 1.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>a01000011110001000011101001001111\nb00000101110001110000111001100001\nc11101111011010100011111101010111\nM01000111110001100011111001000111<\/code><\/pre>\n\n\n\n<p>Ch funktio taas taas poimii bitin kent\u00e4n e mukaan f:st\u00e4 tai g:st\u00e4. Jos bitti on 0 poimitaan g:n bitti, jos taas 1 poimitaan f:n bitti.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>e00001000111000011100101011111001\nf00011000010001101000101000101000\ng11011110100111111100110001011110\nC11011110010111101000111000101110<\/code><\/pre>\n\n\n\n<p>Final funktio k\u00e4sittelee viimeisen update kutsun ylij\u00e4\u00e4neen osalohkon lis\u00e4ten materiaalin kokonaismerkkien lukum\u00e4\u00e4r\u00e4n yhteysalueen count kent\u00e4st\u00e4 tiedon loppuun. LIs\u00e4ksi funktio palauttaa SHA256 tiivisteen digest parametrissa.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void SHA256Final(unsigned char digest&#91;32], SHA256_CONTEXT *sha256)\n{\n  int i,j;\n  unsigned char filelenght&#91;8];\n  IULONG count;\n\n  count=sha256->count &lt;&lt; 3;\n  SHA256Update(sha256,\"\\200\",1);\n\n  while((sha256->count &amp; 63) != 56)\n    SHA256Update(sha256,\"\\0\",1);\n\n  filelenght&#91;0]=(unsigned char)\n      (count >> 56)&amp;0xff;\n  filelenght&#91;1]=(unsigned char)\n      (count >> 48)&amp;0xff;\n  filelenght&#91;2]=(unsigned char)\n      (count >> 40)&amp;0xff;\n  filelenght&#91;3]=(unsigned char)\n      (count >> 32)&amp;0xff;\n  filelenght&#91;4]=(unsigned char)\n      (count >> 24)&amp;0xff;\n  filelenght&#91;5]=(unsigned char)\n      (count >> 16)&amp;0xff;\n  filelenght&#91;6]=(unsigned char)\n      (count >> 8 )&amp;0xff;\n  filelenght&#91;7]=(unsigned char)\n      (count&amp;0xff);\n\n  SHA256Update(sha256,filelenght,\n      sizeof(filelenght));\n\n  for(i=0,j=0;i&lt;8;i++) {\n    digest&#91;j++]=(unsigned char)\n        (sha256->state&#91;i] >> 24)&amp;0xff;\n    digest&#91;j++]=(unsigned char)\n        (sha256->state&#91;i] >> 16)&amp;0xff;\n    digest&#91;j++]=(unsigned char)\n        (sha256->state&#91;i] >> 8)&amp;0xff;\n    digest&#91;j++]=(unsigned char)\n        (sha256->state&#91;i] )&amp;0xff;\n  }\n}<\/code><\/pre>\n\n\n\n<p>Pieni testip\u00e4\u00e4ohjelma:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int SHA256Test(char *string,int rounds,\n      char *hashs) {\n  int ok;\n  char temp&#91;3];\n  unsigned char result&#91;32];\n  HashCtx hash;\n\n  fprintf(stdout,\"s=%s\\n\",string);\n  fprintf(stdout,\"h=%s\\n\",hashs);\n  HashInit(&amp;hash);\n  for(int c=0;c&lt;rounds;c++)\n    HashUpdate(&amp;hash,string,strlen(string));\n  HashFinal(result,&amp;hash);\n  fprintf(stdout,\"r=\");\n  ok=1;\n  for(int c=0;c&lt;sizeof(result);c++) {\n    sprintf(temp,\"%02x\",result&#91;c]);\n    fprintf(stdout,\"%s\",temp);\n    if(strncmp(temp,hashs+c*2,2))\n      ok=0;\n  }\n  if(ok)\n    fprintf(stdout,\", ok\");\n  else\n    fprintf(stdout,\", error\");\n  fprintf(stdout,\"\\n\");\n\n  return(ok);\n}\n\nvoid main(int argc,char *argv&#91;])\n{\n  int ok;\n\n  fprintf(stdout,\"sizeof(IUBYTE):%lu\",\n      sizeof(IUBYTE));\n  fprintf(stdout,\", sizeof(IUWORD):%lu\",\n      sizeof(IUWORD));\n  fprintf(stdout,\", sizeof(IULONG):%lu\",\n      sizeof(IULONG));\n  fprintf(stdout,\"\\n\");\n\nSHA256Test(\"abc\",1,\"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad\");\nSHA256Test(\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\",1,\"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1\");\nSHA256Test(\"a\",1000000,\"cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0\");\nSHA256Test(\"The quick brown fox jumps over the lazy dog\",1,\"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592\");\n}<\/code><\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>T\u00e4ss\u00e4 tiivisteohjelma edellista Fort satunnaisbittigeneraattoria varten. Alun definet m\u00e4\u00e4rittelev\u00e4t Fort-ohjelman k\u00e4ytt\u00e4mille HashInit, HashUpdate ja HashFinal funktioille todelliset nimet. Lis\u00e4ksi m\u00e4\u00e4ritell\u00e4\u00e4n HashName, joka tulostetaan fort_init:in alussa ja HashLen joka sis\u00e4lt\u00e4\u00e4 tiivisteen pituuden. Sitten typedef:it m\u00e4\u00e4rittelev\u00e4t uudet tyypit IUBYTE, joka on 8 bitti\u00e4 (1 merkki\u00e4) pitk\u00e4., IUWORD, joka on 32 bitti\u00e4 (4 merkki\u00e4) pitk\u00e4 ja IULONG, joka&hellip; <a class=\"more-link\" href=\"https:\/\/moijari.com\/?p=752\">Continue reading <span class=\"screen-reader-text\">SHA256 tiivisteen laskentaohjelma<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[11],"tags":[],"_links":{"self":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/752"}],"collection":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=752"}],"version-history":[{"count":40,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/752\/revisions"}],"predecessor-version":[{"id":833,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/752\/revisions\/833"}],"wp:attachment":[{"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=752"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=752"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=752"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}