DBS4: new blend

Kaikki oikeudet pidätetään ©. 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ään nimesi ja asuinpaikkakuntasi. Kiitokset lahjoituksestasi.

Edellisen artikkellin paras osa oli ressu2:



#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <ctype.h>

#include <sys/time.h>
#include <time.h>

#define MAIN 2

unsigned char *procname;
static unsigned char *programname = "Ressu2 version 1.00 ©";
static unsigned char *copyright = "Copyright (c) 2013-2026 Jari Kuivaniemi (moijari.com), Helsinki, Finland. Kaikki oikeudet pidätetään!";
int my_output = 0;

void my_dump(unsigned char *header, int len, unsigned char *buf, int linelen)
{
  int c;

  if(my_output) {
    fprintf(stdout,"\n");
    my_output = 0;
  }
  for(c = 0; c < len; c++) {
    if(c % linelen == 0) {
      if(c > 0)
	fprintf(stdout,"\n");
      fprintf(stdout,"%-10s", header);
    }
    fprintf(stdout," %02x", buf[c]);
  }
  fprintf(stdout,"\n");
  fflush(stdout);
}

#define aDEBUG8 2

#define aUSE_URANDOM 2
#define USE_RESSU2 2
#define USE_PSEUDORESSU2 2
#define USE_RESSU2TWIST 2

#if defined USE_RESSU2 || defined USE_PSEUDORESSU2 || defined USE_RESSU2TWIST

static unsigned long long my_ressu_useconds()
{
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return((unsigned long long) tv.tv_usec + 1000000ULL * (unsigned long long) tv.tv_sec);
}

static unsigned char my_ressu_lowusec() /* JariK 2013 */
{
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return(tv.tv_usec & 0xff);
}

static int randomness = 0;

#define RESSU_ROTATELEFT8(byte, bits) ( ((byte) >> (8 - (bits))) | ((byte) << (bits)) )

static void my_ressu2_round(int size, unsigned char *buffer) // ressu JariK 2013, 2025
{
  int c, d, byte;
  unsigned char e;
  static int f = 0, prevbyte = -1;
  unsigned long long usec;
  
  for(c = 0; c < 8; c++) { // eight bits per byte
    for(d = 0; d < size; d++) { // rotate + xor
      e = buffer[d];
      e = RESSU_ROTATELEFT8(e, 1);  // rotate byte left 1 bits
      byte = my_ressu_lowusec();
      buffer[d] = e ^ byte;
      if(prevbyte != byte) {
	prevbyte = byte;
	randomness++;
      }
    }
    for(d = 0; d < size; d++) { // swap
      f = (f + 16 + buffer[d] + 2) % size;
      e = buffer[d];
      buffer[d] = buffer[f];
      buffer[f] = e;
    }
    
    // more randomness from clocks
    usec = clock();
    while(usec > 0) {
      f = (f + usec) % size;
      usec /= size;
    }
    usec = my_ressu_useconds();
    while(usec > 0) {
      f = (f + usec) % size;
      usec /= size;
    }
  } // end of for(c = 0; c < 8; c++
}

#include "newressu.h"

#define RESSU2_BYTES 2048 // now 2048
#define RESSU2_RANDOMNESS_NEEDED 2048 // now 2048 
#define RESSU2_CLOCKS_NEEDED 20480 // now 20480
#define RESSU2_MINIMUM_ROUNDS 5 // now 5

void my_ressu2_bytes(int size, unsigned char *buffer) // Ressu2 v1.1 JariK 2013, 2025, 2026
{
  int c, d, clocksused;
  static int ressu_pos = 0, initneeded = 1;
  static unsigned char ressu[RESSU2_BYTES];
  
  for(c = 0; c < size; c++) {
    if(ressu_pos == 0) {
      if(initneeded) {
	memset(&ressu, 0, sizeof(ressu));
	initneeded = 0;
      }
      randomness = 0;
      clocksused = 0;
      //memset(&ressu, 0, sizeof(ressu));
      
      for(d = 0; d < RESSU2_MINIMUM_ROUNDS ||
	    randomness < RESSU2_RANDOMNESS_NEEDED ||
	    clocksused < RESSU2_CLOCKS_NEEDED
	    ; d++) {
	my_ressu2_round(sizeof(ressu), ressu);
	clocksused += (sizeof(ressu) * 8);
      }
      
#ifdef DEBUG8
      my_dump("myressu2g", sizeof(ressu), ressu, 32);      
#endif
    } // end of if(ressu_pos == 0
    buffer[c] ^= ressu[ressu_pos];
    ressu_pos = (ressu_pos + 1) % sizeof(ressu);
  } // end of for(c = 0; c < size; c++
#ifdef DEBUG8
  my_dump("myressu2", size, buffer, 32);
#endif
}

#endif // end of #if defined USE_RESSU2 || defined USE_PSEUDORESSU2 || defined USE_RESSU2TWIST

#if defined USE_PSEUDORESSU2 || defined USE_RESSU2TWIST

unsigned char cvar[16];
int cvarsize = 0;

void inccvar()
{
  int c;

  /* 16 bytes, LSB first */
  for(c = 0; ++cvar[c] == 0 && c < sizeof(cvar) - 1; c++);

  if(cvarsize < c)
    cvarsize = c;

#ifdef DEBUG20
  ressu_dump("cvar", cvarsize + 1, cvar, 32);
#endif
}

void clearcvar()
{
  int c;

  cvarsize = 0;
  
  for(c = 0; c < sizeof(cvar); c++)
    cvar[c] = 0;

  for(c = 0; c < sizeof(cvar); c++)
    if(cvar[c] != 0)
      cvarsize = c;
}

#include "sha256.h"

#define PSEUDORESSU2_BYTES 32*1024 // bytes between topups
#define PSEUDORESSU2_TOPUP_BYTES 32*1024 // bytes between topups
#define PSEUDORESSU2_TOPUP_SIZE 32 // topup size in bytes (32 bytes, 256 bits)
#define PSEUDORESSU2_TOPUP_TWICE 2 // off by default

static unsigned char pseudoressu2_key[HashLen]; // 32 bytes, 256 bits

static void my_pseudoressu2_internalbytes(unsigned char *digest)
{
  HashCtx hash;

  HashInit(&hash);
  HashUpdate(&hash, pseudoressu2_key, sizeof(pseudoressu2_key)); // add old randomness to hash
  HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
  inccvar();
  HashFinal(digest, &hash);
  memset(&hash, 0, sizeof(hash)); // forget hash
}

static void my_pseudoressu2_addrandomness(int size, unsigned char *buffer)
{
  unsigned long long usec;
  HashCtx hash;

  HashInit(&hash);
  HashUpdate(&hash, pseudoressu2_key, sizeof(pseudoressu2_key)); // add old randomness to hash
  HashUpdate(&hash, (unsigned char *) &cvar, cvarsize + 1);
  inccvar();
  usec = my_ressu_useconds(); // add timestamp to hash
  HashUpdate(&hash, (unsigned char *)&usec, sizeof(usec));
  usec = clock(); // add processor time to hash (for randomness)
  HashUpdate(&hash, (unsigned char *)&usec, sizeof(usec));
  HashUpdate(&hash, buffer, size); // add given randomness to hash
  HashFinal(pseudoressu2_key, &hash); // save as new key
  memset(&hash, 0, sizeof(hash)); // forget hash
}

static void my_pseudoressu2_topup()
{
  unsigned char topup[PSEUDORESSU2_TOPUP_SIZE]; // 32 bytes, 256 bits

  memset(&topup, 0, sizeof(topup)); // forget topup
  my_ressu2_bytes(sizeof(topup), topup);
#ifdef DEBUG8
  my_dump("topup", sizeof(topup), topup, 32);
#endif
  my_pseudoressu2_addrandomness(sizeof(topup), topup);

  memset(&topup, 0, sizeof(topup)); // forget topup
}

void my_pseudoressu2_bytes(int size, unsigned char *buffer) // JariK 2022, 2025
{
  int c;
  static int pseudoressu_pos = 0, topup_counter = 0, initneeded = 1;
  static unsigned char pseudoressu[HashLen]; // 32 bytes, 256 bits

  for(c = 0; c < size; c++) {
    if(pseudoressu_pos == 0) {
      if(topup_counter == 0) {
	if(initneeded) {
	  my_ressu2_bytes(sizeof(pseudoressu2_key), pseudoressu2_key); // get first key
#ifdef DEBUG8
	  my_dump("first key", sizeof(pseudoressu2_key), pseudoressu2_key, 32);
#endif
	  initneeded = 0;
	} // end of if(initneeded
	
	my_pseudoressu2_topup(); // add randomness to key, first block also
#ifdef PSEUDORESSU2_TOPUP_TWICE
	my_pseudoressu2_topup(); // add randomness to key, first block also
#endif
	topup_counter = PSEUDORESSU2_TOPUP_BYTES;
      } // end of if(topup_counter == 0
      
      my_pseudoressu2_internalbytes(pseudoressu); // get random bits using the key
#ifdef DEBUG8
      my_dump("next data", sizeof(pseudoressu), pseudoressu, 32);
#endif
      topup_counter -= sizeof(pseudoressu);
    } // end of if(pseudoressu_pos == 0

    buffer[c] ^= pseudoressu[pseudoressu_pos];
    pseudoressu_pos = (pseudoressu_pos + 1) % sizeof(pseudoressu);
  } // end of for(c = 0; c < size; c++
  
  my_pseudoressu2_internalbytes(pseudoressu2_key); // replace key with new random one
#ifdef DEBUG8
  my_dump("new key", sizeof(pseudoressu2_key), pseudoressu2_key, 32);
#endif
#ifdef DEBUG8
  my_dump("pseudoressu", size, buffer, 32);
#endif
}

#endif // end of #if defined USE_PSEUDORESSU2 || defined USE_RESSU2TWIST

#ifdef USE_RESSU2TWIST

void my_ressu2twist_bytes(int size, unsigned char *buffer) // JariK 2023, 2025
{
  //urandom_bytes(size, buffer);
  my_ressu2_bytes(size, buffer);
  my_pseudoressu2_bytes(size, buffer);
#ifdef DEBUG8
  my_dump("ressu2twist", size, buffer, 32);
#endif
}

#endif // end of #ifdef USE_RESSU2TWIST

#ifdef USE_URANDOM

void my_readfile_xor(int size, unsigned char *buffer, unsigned char *filename)
{
  int c, n, filebuffer_pos = 0;
  unsigned char filebuffer[64];
  FILE *fp1;

  if((fp1 = fopen(filename, "rb")) == NULL) {
    fprintf(stderr,"%s: fopen(): cannot open file %s\n",
	    procname, filename);
    exit(1);
  }

  for(c = 0; c < size; c++) {
    if(filebuffer_pos == 0) {
      n = (size - c < sizeof(filebuffer)) ? size - c : sizeof(filebuffer);
      if(fread(filebuffer, 1, n, fp1) < n) {
	fprintf(stderr,"%s: fread(): cannot read file %s\n",
		procname, filename);
	exit(1);
      }
#ifdef DEBUG8
      my_dump("file", n, filebuffer, 32);
#endif
    } // end of if(file_pos == 0
    buffer[c] ^= filebuffer[filebuffer_pos];
    filebuffer_pos = (filebuffer_pos + 1) % sizeof(filebuffer);
  } // end of for(c = 0; c < size; c++

  fclose(fp1);

  memset(filebuffer, 0, sizeof(filebuffer)); // forget file
}

static unsigned char urandomfilename[128] = "/dev/urandom";

void my_urandom_bytes(int size, unsigned char *buffer)
{
  my_readfile_xor(size, buffer, urandomfilename);
#ifdef DEBUG8
  my_dump("urandom", size, buffer, 32);
#endif
}

#endif // end of #ifdef USE_URANDOM

void my_random_bytes(int size, unsigned char *buffer)
{
#ifdef USE_URANDOM
  my_urandom_bytes(size, buffer);
#endif
  //ressu_round(size, buffer);
  //ressu_genbytes(size, buffer);
  //pseudoressu_bytes(size, buffer);
  //ressutwist_bytes(size, buffer);
  //my_ressu2_round(size, buffer);
#ifdef USE_PSEUDORESSU2
  my_pseudoressu2_bytes(size, buffer);
#endif
#ifdef USE_RESSU2TWIST
  my_ressu2twist_bytes(size, buffer);
#endif
#ifdef USE_RESSU2
  my_ressu2_bytes(size, buffer);
#endif
}

#define GENT_SIZE 128

static unsigned char gent[GENT_SIZE];
static unsigned int gent_pos = 0;

int my_random_byte()
{
  unsigned char ch;
  static int initneeded = 1;

  if(gent_pos == 0) {
    if(initneeded) {
      memset(&gent, 0, sizeof(gent));
      initneeded = 0;
    }
    my_random_bytes(sizeof(gent), gent);
  }
  ch = gent[gent_pos];
  gent_pos = (gent_pos + 1) % sizeof(gent);

  return(ch);
}

unsigned long my_random_genlimit(unsigned long limit)
{
  int c;
  unsigned long word;
  static unsigned long lastlimit = 0, highlimit;
  static int bytes;
  
  if(lastlimit != limit) { // if limit changes, calculate new highlimit and bytes
    lastlimit = limit;
    if(limit <= 0x100) {
      // highest multiplier of limit that fits to needed bytes
      highlimit = (0x100 / limit) * limit;
      // number of bytes needed
      bytes = 1;
    } else if(limit <= 0x10000) {
      highlimit = (0x10000 / limit) * limit;
      bytes = 2;
    } else if(limit <= 0x1000000) {
      highlimit = (0x1000000 / limit) * limit;
      bytes = 3;
    } else if(limit <= 0x100000000) {
      highlimit = (0x100000000 / limit) * limit;
      bytes = 4;
    } else if(limit <= 0x10000000000) {
      highlimit = (0x10000000000 / limit) * limit;
      bytes = 5;
    } else if(limit <= 0x1000000000000) {
      highlimit = (0x1000000000000 / limit) * limit;
      bytes = 6;
    } else if(limit <= 0x100000000000000) {
      highlimit = (0x100000000000000 / limit) * limit;
      bytes = 7;
    } else { // if(limit <= 0xffffffffffffffff) {
      highlimit = (0xffffffffffffffff / limit) * limit;      
      bytes = 8;
    }
  } // if(lastlimit != limit)

  for(;;) {
    word = 0;
    for(c = 0; c < bytes; c++)
      word = word << 8 | my_random_byte();
    if(word < highlimit)
      break;
  }

  word %= limit;
  
  return(word);
}

void ressu2_version()
{
  fprintf(stderr, "%s", programname); // touch these outside #ifdef MAIN
  fprintf(stderr, ", %s", copyright);
}

#include <sys/ioctl.h> // for TIOCGWINSZ

#ifdef MAIN

int main(int argc, char *argv[])
{
  int c, d;

  procname = argv[0];

  //
  // look thru command line parameters
  //

  for(c = 1; c < argc; c++) {
    if(!strcmp("--copyright", argv[c]) ||
       !strcmp("--version", argv[c])) {
      ressu2_version();
#ifdef SHA256
      fprintf(stderr,"\nsha256(");
      for(int c = 0; c < HashLen; c++) {
	fprintf(stderr, "%02x", programfiledigest[c]);
      }
#endif // end of #ifdef SHA256

    }
  }

  for(c = 0; c < 10; c++) {
    fprintf(stdout, "%05x", c);
    my_output = 1;
    for(d = 0; d < 32; d++) {
      fprintf(stdout, " ");
      fprintf(stdout, "%02llx", (unsigned long long) my_random_genlimit(0x100));
    }
    fprintf(stdout,"\n");
  }
}
#endif // end of #ifdef MAIN
Published
Categorized as muuta

Leave a comment