{"id":4003,"date":"2026-08-24T22:09:33","date_gmt":"2026-08-24T20:09:33","guid":{"rendered":"https:\/\/moijari.com\/?p=4003"},"modified":"2026-08-24T22:09:34","modified_gmt":"2026-08-24T20:09:34","slug":"dbs4-new-blend","status":"publish","type":"post","link":"https:\/\/moijari.com\/?p=4003","title":{"rendered":"DBS4: new blend"},"content":{"rendered":"\n<p>Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n \u00a9. Jos haluat tukea projektia (osallistua palvelinkustannuksiin, tarjota koodausvissyn tai tulevaisuudessa maksaa palkkaa), laita muutaman euron lahjoituksesi Danske Bank tilille FI15 8312 0710 7275 83 (SWIFT:DABAFIHH), maksun saaja Jari Kuivaniemi. Kirjoita viestikentt\u00e4\u00e4n nimesi ja asuinpaikkakuntasi. Kiitokset lahjoituksestasi.<\/p>\n\n\n\n<p>Edellisen artikkellin paras osa oli ressu2:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\n\n#include &lt;stdio.h>\n#include &lt;stdlib.h>\n#include &lt;memory.h>\n#include &lt;ctype.h>\n\n#include &lt;sys\/time.h>\n#include &lt;time.h>\n\n#define MAIN 2\n\nunsigned char *procname;\nstatic unsigned char *programname = \"Ressu2 version 1.00 \u00a9\";\nstatic unsigned char *copyright = \"Copyright (c) 2013-2026 Jari Kuivaniemi (moijari.com), Helsinki, Finland. Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n!\";\nint my_output = 0;\n\nvoid my_dump(unsigned char *header, int len, unsigned char *buf, int linelen)\n{\n  int c;\n\n  if(my_output) {\n    fprintf(stdout,\"\\n\");\n    my_output = 0;\n  }\n  for(c = 0; c &lt; len; c++) {\n    if(c % linelen == 0) {\n      if(c > 0)\n\tfprintf(stdout,\"\\n\");\n      fprintf(stdout,\"%-10s\", header);\n    }\n    fprintf(stdout,\" %02x\", buf&#91;c]);\n  }\n  fprintf(stdout,\"\\n\");\n  fflush(stdout);\n}\n\n#define aDEBUG8 2\n\n#define aUSE_URANDOM 2\n#define USE_RESSU2 2\n#define USE_PSEUDORESSU2 2\n#define USE_RESSU2TWIST 2\n\n#if defined USE_RESSU2 || defined USE_PSEUDORESSU2 || defined USE_RESSU2TWIST\n\nstatic unsigned long long my_ressu_useconds()\n{\n  struct timeval tv;\n  gettimeofday(&amp;tv, NULL);\n  return((unsigned long long) tv.tv_usec + 1000000ULL * (unsigned long long) tv.tv_sec);\n}\n\nstatic unsigned char my_ressu_lowusec() \/* JariK 2013 *\/\n{\n  struct timeval tv;\n  gettimeofday(&amp;tv, NULL);\n  return(tv.tv_usec &amp; 0xff);\n}\n\nstatic int randomness = 0;\n\n#define RESSU_ROTATELEFT8(byte, bits) ( ((byte) >> (8 - (bits))) | ((byte) &lt;&lt; (bits)) )\n\nstatic void my_ressu2_round(int size, unsigned char *buffer) \/\/ ressu JariK 2013, 2025\n{\n  int c, d, byte;\n  unsigned char e;\n  static int f = 0, prevbyte = -1;\n  unsigned long long usec;\n  \n  for(c = 0; c &lt; 8; c++) { \/\/ eight bits per byte\n    for(d = 0; d &lt; size; d++) { \/\/ rotate + xor\n      e = buffer&#91;d];\n      e = RESSU_ROTATELEFT8(e, 1);  \/\/ rotate byte left 1 bits\n      byte = my_ressu_lowusec();\n      buffer&#91;d] = e ^ byte;\n      if(prevbyte != byte) {\n\tprevbyte = byte;\n\trandomness++;\n      }\n    }\n    for(d = 0; d &lt; size; d++) { \/\/ swap\n      f = (f + 16 + buffer&#91;d] + 2) % size;\n      e = buffer&#91;d];\n      buffer&#91;d] = buffer&#91;f];\n      buffer&#91;f] = e;\n    }\n    \n    \/\/ more randomness from clocks\n    usec = clock();\n    while(usec > 0) {\n      f = (f + usec) % size;\n      usec \/= size;\n    }\n    usec = my_ressu_useconds();\n    while(usec > 0) {\n      f = (f + usec) % size;\n      usec \/= size;\n    }\n  } \/\/ end of for(c = 0; c &lt; 8; c++\n}\n\n#include \"newressu.h\"\n\n#define RESSU2_BYTES 2048 \/\/ now 2048\n#define RESSU2_RANDOMNESS_NEEDED 2048 \/\/ now 2048 \n#define RESSU2_CLOCKS_NEEDED 20480 \/\/ now 20480\n#define RESSU2_MINIMUM_ROUNDS 5 \/\/ now 5\n\nvoid my_ressu2_bytes(int size, unsigned char *buffer) \/\/ Ressu2 v1.1 JariK 2013, 2025, 2026\n{\n  int c, d, clocksused;\n  static int ressu_pos = 0, initneeded = 1;\n  static unsigned char ressu&#91;RESSU2_BYTES];\n  \n  for(c = 0; c &lt; size; c++) {\n    if(ressu_pos == 0) {\n      if(initneeded) {\n\tmemset(&amp;ressu, 0, sizeof(ressu));\n\tinitneeded = 0;\n      }\n      randomness = 0;\n      clocksused = 0;\n      \/\/memset(&amp;ressu, 0, sizeof(ressu));\n      \n      for(d = 0; d &lt; RESSU2_MINIMUM_ROUNDS ||\n\t    randomness &lt; RESSU2_RANDOMNESS_NEEDED ||\n\t    clocksused &lt; RESSU2_CLOCKS_NEEDED\n\t    ; d++) {\n\tmy_ressu2_round(sizeof(ressu), ressu);\n\tclocksused += (sizeof(ressu) * 8);\n      }\n      \n#ifdef DEBUG8\n      my_dump(\"myressu2g\", sizeof(ressu), ressu, 32);      \n#endif\n    } \/\/ end of if(ressu_pos == 0\n    buffer&#91;c] ^= ressu&#91;ressu_pos];\n    ressu_pos = (ressu_pos + 1) % sizeof(ressu);\n  } \/\/ end of for(c = 0; c &lt; size; c++\n#ifdef DEBUG8\n  my_dump(\"myressu2\", size, buffer, 32);\n#endif\n}\n\n#endif \/\/ end of #if defined USE_RESSU2 || defined USE_PSEUDORESSU2 || defined USE_RESSU2TWIST\n\n#if defined USE_PSEUDORESSU2 || defined USE_RESSU2TWIST\n\nunsigned char cvar&#91;16];\nint cvarsize = 0;\n\nvoid inccvar()\n{\n  int c;\n\n  \/* 16 bytes, LSB first *\/\n  for(c = 0; ++cvar&#91;c] == 0 &amp;&amp; c &lt; sizeof(cvar) - 1; c++);\n\n  if(cvarsize &lt; c)\n    cvarsize = c;\n\n#ifdef DEBUG20\n  ressu_dump(\"cvar\", cvarsize + 1, cvar, 32);\n#endif\n}\n\nvoid clearcvar()\n{\n  int c;\n\n  cvarsize = 0;\n  \n  for(c = 0; c &lt; sizeof(cvar); c++)\n    cvar&#91;c] = 0;\n\n  for(c = 0; c &lt; sizeof(cvar); c++)\n    if(cvar&#91;c] != 0)\n      cvarsize = c;\n}\n\n#include \"sha256.h\"\n\n#define PSEUDORESSU2_BYTES 32*1024 \/\/ bytes between topups\n#define PSEUDORESSU2_TOPUP_BYTES 32*1024 \/\/ bytes between topups\n#define PSEUDORESSU2_TOPUP_SIZE 32 \/\/ topup size in bytes (32 bytes, 256 bits)\n#define PSEUDORESSU2_TOPUP_TWICE 2 \/\/ off by default\n\nstatic unsigned char pseudoressu2_key&#91;HashLen]; \/\/ 32 bytes, 256 bits\n\nstatic void my_pseudoressu2_internalbytes(unsigned char *digest)\n{\n  HashCtx hash;\n\n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, pseudoressu2_key, sizeof(pseudoressu2_key)); \/\/ add old randomness to hash\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n  HashFinal(digest, &amp;hash);\n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n}\n\nstatic void my_pseudoressu2_addrandomness(int size, unsigned char *buffer)\n{\n  unsigned long long usec;\n  HashCtx hash;\n\n  HashInit(&amp;hash);\n  HashUpdate(&amp;hash, pseudoressu2_key, sizeof(pseudoressu2_key)); \/\/ add old randomness to hash\n  HashUpdate(&amp;hash, (unsigned char *) &amp;cvar, cvarsize + 1);\n  inccvar();\n  usec = my_ressu_useconds(); \/\/ add timestamp to hash\n  HashUpdate(&amp;hash, (unsigned char *)&amp;usec, sizeof(usec));\n  usec = clock(); \/\/ add processor time to hash (for randomness)\n  HashUpdate(&amp;hash, (unsigned char *)&amp;usec, sizeof(usec));\n  HashUpdate(&amp;hash, buffer, size); \/\/ add given randomness to hash\n  HashFinal(pseudoressu2_key, &amp;hash); \/\/ save as new key\n  memset(&amp;hash, 0, sizeof(hash)); \/\/ forget hash\n}\n\nstatic void my_pseudoressu2_topup()\n{\n  unsigned char topup&#91;PSEUDORESSU2_TOPUP_SIZE]; \/\/ 32 bytes, 256 bits\n\n  memset(&amp;topup, 0, sizeof(topup)); \/\/ forget topup\n  my_ressu2_bytes(sizeof(topup), topup);\n#ifdef DEBUG8\n  my_dump(\"topup\", sizeof(topup), topup, 32);\n#endif\n  my_pseudoressu2_addrandomness(sizeof(topup), topup);\n\n  memset(&amp;topup, 0, sizeof(topup)); \/\/ forget topup\n}\n\nvoid my_pseudoressu2_bytes(int size, unsigned char *buffer) \/\/ JariK 2022, 2025\n{\n  int c;\n  static int pseudoressu_pos = 0, topup_counter = 0, initneeded = 1;\n  static unsigned char pseudoressu&#91;HashLen]; \/\/ 32 bytes, 256 bits\n\n  for(c = 0; c &lt; size; c++) {\n    if(pseudoressu_pos == 0) {\n      if(topup_counter == 0) {\n\tif(initneeded) {\n\t  my_ressu2_bytes(sizeof(pseudoressu2_key), pseudoressu2_key); \/\/ get first key\n#ifdef DEBUG8\n\t  my_dump(\"first key\", sizeof(pseudoressu2_key), pseudoressu2_key, 32);\n#endif\n\t  initneeded = 0;\n\t} \/\/ end of if(initneeded\n\t\n\tmy_pseudoressu2_topup(); \/\/ add randomness to key, first block also\n#ifdef PSEUDORESSU2_TOPUP_TWICE\n\tmy_pseudoressu2_topup(); \/\/ add randomness to key, first block also\n#endif\n\ttopup_counter = PSEUDORESSU2_TOPUP_BYTES;\n      } \/\/ end of if(topup_counter == 0\n      \n      my_pseudoressu2_internalbytes(pseudoressu); \/\/ get random bits using the key\n#ifdef DEBUG8\n      my_dump(\"next data\", sizeof(pseudoressu), pseudoressu, 32);\n#endif\n      topup_counter -= sizeof(pseudoressu);\n    } \/\/ end of if(pseudoressu_pos == 0\n\n    buffer&#91;c] ^= pseudoressu&#91;pseudoressu_pos];\n    pseudoressu_pos = (pseudoressu_pos + 1) % sizeof(pseudoressu);\n  } \/\/ end of for(c = 0; c &lt; size; c++\n  \n  my_pseudoressu2_internalbytes(pseudoressu2_key); \/\/ replace key with new random one\n#ifdef DEBUG8\n  my_dump(\"new key\", sizeof(pseudoressu2_key), pseudoressu2_key, 32);\n#endif\n#ifdef DEBUG8\n  my_dump(\"pseudoressu\", size, buffer, 32);\n#endif\n}\n\n#endif \/\/ end of #if defined USE_PSEUDORESSU2 || defined USE_RESSU2TWIST\n\n#ifdef USE_RESSU2TWIST\n\nvoid my_ressu2twist_bytes(int size, unsigned char *buffer) \/\/ JariK 2023, 2025\n{\n  \/\/urandom_bytes(size, buffer);\n  my_ressu2_bytes(size, buffer);\n  my_pseudoressu2_bytes(size, buffer);\n#ifdef DEBUG8\n  my_dump(\"ressu2twist\", size, buffer, 32);\n#endif\n}\n\n#endif \/\/ end of #ifdef USE_RESSU2TWIST\n\n#ifdef USE_URANDOM\n\nvoid my_readfile_xor(int size, unsigned char *buffer, unsigned char *filename)\n{\n  int c, n, filebuffer_pos = 0;\n  unsigned char filebuffer&#91;64];\n  FILE *fp1;\n\n  if((fp1 = fopen(filename, \"rb\")) == NULL) {\n    fprintf(stderr,\"%s: fopen(): cannot open file %s\\n\",\n\t    procname, filename);\n    exit(1);\n  }\n\n  for(c = 0; c &lt; size; c++) {\n    if(filebuffer_pos == 0) {\n      n = (size - c &lt; sizeof(filebuffer)) ? size - c : sizeof(filebuffer);\n      if(fread(filebuffer, 1, n, fp1) &lt; n) {\n\tfprintf(stderr,\"%s: fread(): cannot read file %s\\n\",\n\t\tprocname, filename);\n\texit(1);\n      }\n#ifdef DEBUG8\n      my_dump(\"file\", n, filebuffer, 32);\n#endif\n    } \/\/ end of if(file_pos == 0\n    buffer&#91;c] ^= filebuffer&#91;filebuffer_pos];\n    filebuffer_pos = (filebuffer_pos + 1) % sizeof(filebuffer);\n  } \/\/ end of for(c = 0; c &lt; size; c++\n\n  fclose(fp1);\n\n  memset(filebuffer, 0, sizeof(filebuffer)); \/\/ forget file\n}\n\nstatic unsigned char urandomfilename&#91;128] = \"\/dev\/urandom\";\n\nvoid my_urandom_bytes(int size, unsigned char *buffer)\n{\n  my_readfile_xor(size, buffer, urandomfilename);\n#ifdef DEBUG8\n  my_dump(\"urandom\", size, buffer, 32);\n#endif\n}\n\n#endif \/\/ end of #ifdef USE_URANDOM\n\nvoid my_random_bytes(int size, unsigned char *buffer)\n{\n#ifdef USE_URANDOM\n  my_urandom_bytes(size, buffer);\n#endif\n  \/\/ressu_round(size, buffer);\n  \/\/ressu_genbytes(size, buffer);\n  \/\/pseudoressu_bytes(size, buffer);\n  \/\/ressutwist_bytes(size, buffer);\n  \/\/my_ressu2_round(size, buffer);\n#ifdef USE_PSEUDORESSU2\n  my_pseudoressu2_bytes(size, buffer);\n#endif\n#ifdef USE_RESSU2TWIST\n  my_ressu2twist_bytes(size, buffer);\n#endif\n#ifdef USE_RESSU2\n  my_ressu2_bytes(size, buffer);\n#endif\n}\n\n#define GENT_SIZE 128\n\nstatic unsigned char gent&#91;GENT_SIZE];\nstatic unsigned int gent_pos = 0;\n\nint my_random_byte()\n{\n  unsigned char ch;\n  static int initneeded = 1;\n\n  if(gent_pos == 0) {\n    if(initneeded) {\n      memset(&amp;gent, 0, sizeof(gent));\n      initneeded = 0;\n    }\n    my_random_bytes(sizeof(gent), gent);\n  }\n  ch = gent&#91;gent_pos];\n  gent_pos = (gent_pos + 1) % sizeof(gent);\n\n  return(ch);\n}\n\nunsigned long my_random_genlimit(unsigned long limit)\n{\n  int c;\n  unsigned long word;\n  static unsigned long lastlimit = 0, highlimit;\n  static int bytes;\n  \n  if(lastlimit != limit) { \/\/ if limit changes, calculate new highlimit and bytes\n    lastlimit = limit;\n    if(limit &lt;= 0x100) {\n      \/\/ highest multiplier of limit that fits to needed bytes\n      highlimit = (0x100 \/ limit) * limit;\n      \/\/ number of bytes needed\n      bytes = 1;\n    } else if(limit &lt;= 0x10000) {\n      highlimit = (0x10000 \/ limit) * limit;\n      bytes = 2;\n    } else if(limit &lt;= 0x1000000) {\n      highlimit = (0x1000000 \/ limit) * limit;\n      bytes = 3;\n    } else if(limit &lt;= 0x100000000) {\n      highlimit = (0x100000000 \/ limit) * limit;\n      bytes = 4;\n    } else if(limit &lt;= 0x10000000000) {\n      highlimit = (0x10000000000 \/ limit) * limit;\n      bytes = 5;\n    } else if(limit &lt;= 0x1000000000000) {\n      highlimit = (0x1000000000000 \/ limit) * limit;\n      bytes = 6;\n    } else if(limit &lt;= 0x100000000000000) {\n      highlimit = (0x100000000000000 \/ limit) * limit;\n      bytes = 7;\n    } else { \/\/ if(limit &lt;= 0xffffffffffffffff) {\n      highlimit = (0xffffffffffffffff \/ limit) * limit;      \n      bytes = 8;\n    }\n  } \/\/ if(lastlimit != limit)\n\n  for(;;) {\n    word = 0;\n    for(c = 0; c &lt; bytes; c++)\n      word = word &lt;&lt; 8 | my_random_byte();\n    if(word &lt; highlimit)\n      break;\n  }\n\n  word %= limit;\n  \n  return(word);\n}\n\nvoid ressu2_version()\n{\n  fprintf(stderr, \"%s\", programname); \/\/ touch these outside #ifdef MAIN\n  fprintf(stderr, \", %s\", copyright);\n}\n\n#include &lt;sys\/ioctl.h> \/\/ for TIOCGWINSZ\n\n#ifdef MAIN\n\nint main(int argc, char *argv&#91;])\n{\n  int c, d;\n\n  procname = argv&#91;0];\n\n  \/\/\n  \/\/ look thru command line parameters\n  \/\/\n\n  for(c = 1; c &lt; argc; c++) {\n    if(!strcmp(\"--copyright\", argv&#91;c]) ||\n       !strcmp(\"--version\", argv&#91;c])) {\n      ressu2_version();\n#ifdef SHA256\n      fprintf(stderr,\"\\nsha256(\");\n      for(int c = 0; c &lt; HashLen; c++) {\n\tfprintf(stderr, \"%02x\", programfiledigest&#91;c]);\n      }\n#endif \/\/ end of #ifdef SHA256\n\n    }\n  }\n\n  for(c = 0; c &lt; 10; c++) {\n    fprintf(stdout, \"%05x\", c);\n    my_output = 1;\n    for(d = 0; d &lt; 32; d++) {\n      fprintf(stdout, \" \");\n      fprintf(stdout, \"%02llx\", (unsigned long long) my_random_genlimit(0x100));\n    }\n    fprintf(stdout,\"\\n\");\n  }\n}\n#endif \/\/ end of #ifdef MAIN<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Kaikki oikeudet pid\u00e4tet\u00e4\u00e4n \u00a9. Jos haluat tukea projektia (osallistua palvelinkustannuksiin, tarjota koodausvissyn tai tulevaisuudessa maksaa palkkaa), laita muutaman euron lahjoituksesi Danske Bank tilille FI15 8312 0710 7275 83 (SWIFT:DABAFIHH), maksun saaja Jari Kuivaniemi. Kirjoita viestikentt\u00e4\u00e4n nimesi ja asuinpaikkakuntasi. Kiitokset lahjoituksestasi. Edellisen artikkellin paras osa oli ressu2:<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/4003"}],"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=4003"}],"version-history":[{"count":1,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/4003\/revisions"}],"predecessor-version":[{"id":4004,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/4003\/revisions\/4004"}],"wp:attachment":[{"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4003"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4003"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4003"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}