RESSU2 current source

    A   B   C   D   E   F   G   H   I  
  +-----------+-----------+-----------+
A |           |           | 3       5 |
B |         5 |           |     8     |
C |     7     | 4         |           |
  +-----------+-----------+-----------+
D | 1         |         3 | 6         |
E |           |           | 5         |
F | 2         |     1   8 |           |
  +-----------+-----------+-----------+
G |           |         9 |     1   6 |
H | 4   2     |           |           |
I |           | 6   7     |     4     |
  +-----------+-----------+-----------+
  s:0 gu:0 st:0 ro:6 clues:21

Kaikki oikeudet pidätetään ©.Suomessa voi vastaanottaa lahjoituksia, mutta niitä ei voi pyytää. Jos haluat tukea projektia (osallistua palvelinkustannuksiin, tarjota koodausvissyn, uuden läppärin 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 tai nimimerkkisi ja asuinpaikkakuntasi. Kiitokset lahjoituksestasi. Suuremman kun 100€ lahjoituksen vastalahjaksi saat tulostetun, vesileimatun ja muovitetun sudokun oheisista sudokuista (kirjoita viestin loppuun ‘sudoku2026vol2’). Vaihda kakkonen haluamaasi vol numeroon. Jos haluat sudokun postitse jätä viesti jossa on nimimerkkisi, asuinpaikkakuntasi ja osoitteesi osoitteeseen moijaricom@gmail.com.

Ressu2 current source

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

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

#define MAIN

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 USE_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.0 JariK 2013, 2025
{
  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;
  int space = 1;
  int chars = 0;
  int columns = 0;
  int lines = 0;
  int words = 16;
  int wordlength = 2;
  int screen = 0;
  int lim = 256;
  
  procname = argv[0];

  int clines, ccolumns;

  //print hello world line

#define DEBUG76 2
#ifdef DEBUG76
  fprintf(stdout,"Hello world");
  //  fprintf(stdout,"Hello world\n");
  for(clines = 0; clines < 10; clines++) {
    fprintf(stdout, "%05x", clines);
    my_output = 1;
    for(ccolumns = 0; ccolumns < 32; ccolumns++) {
      fprintf(stdout, " ");
      fprintf(stdout, "%0*llx", (int) 2, (unsigned long long) my_random_genlimit(lim));
    }
    //fprintf(stdout,"\n");
    fprintf(stdout," ");
  }
    
  
#endif // end of #ifdef DEBUG76

  //
  // 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
    } else if(!strcmp("-c*", argv[c])) {
      struct winsize w;
      ioctl(0, TIOCGWINSZ, &w);
      chars = w.ws_col;
      words = 0;
      
    } else if(!strcmp("-l*", argv[c])) {
      struct winsize w;
      ioctl(0, TIOCGWINSZ, &w);
      lines = w.ws_row-1;
      
    } else if(!strncmp("--chars*", argv[c], 8)) {
      struct winsize w;
      ioctl(0, TIOCGWINSZ, &w);
      chars = w.ws_col;
      words = 0;
      
    } else if(!strncmp("--lines*", argv[c], 8)) {
      struct winsize w;
      ioctl(0, TIOCGWINSZ, &w);
      lines = w.ws_row-1;
      
    } else if(!strncmp("--lim", argv[c], 5)) {
      if(isdigit(*(argv[c] + 7))) {
	lim = atoi(argv[c] + 7);
      } else if(c + 1 < argc) {
	lim = atoi(argv[c + 1]);
	c++;
      }
      
    } else if(!strncmp("--screen", argv[c], 8)) { // screenful
      struct winsize w;
      ioctl(0, TIOCGWINSZ, &w);
      chars = w.ws_col;
      lines = w.ws_row-1;
      words = 0;
      screen = 1;
      
    } else if(!strncmp("--chars", argv[c], 7)) {  // characters per line
      if(isdigit(*(argv[c] + 7))) {
	chars = atoi(argv[c] + 7);
      } else if(c + 1 < argc) {
	chars = atoi(argv[c + 1]);
	c++;
      }
      if(chars < 1)
	chars = 72;
      words = 0;
      screen = 0;
      
    } else if(!strncmp("-c", argv[c], 2)) {  // characters per line
      if(isdigit(*(argv[c] + 2))) {
	chars = atoi(argv[c] + 2);
      } else if(c + 1 < argc) {
	chars = atoi(argv[c + 1]);
	c++;
      }
      if(chars < 1)
	chars = 72;
      words = 0;
      screen = 0;
      columns = 0;
    } else if(!strncmp("--lines",argv[c], 7)) { // lines
      if(isdigit(*(argv[c] + 7))) {
	lines = atoll(argv[c] + 7);
      } else if(c + 1 < argc) {
	lines = atoll(argv[c + 1]);
	c++;
      }
      screen = 0;
      
    } else if(!strncmp("--words",argv[c], 7)) { // lines
      if(isdigit(*(argv[c] + 7))) {
	words = atoll(argv[c] + 7);
      } else if(c + 1 < argc) {
	words = atoll(argv[c + 1]);
	c++;
      }
      screen = 0;

    } else if(!strncmp("--space",argv[c], 7)) { // lines
      if(isdigit(*(argv[c] + 7))) {
	space = !space;
      }
      screen = 0;
      
    } else if(!strncmp("-l",argv[c], 2)) { // lines
      if(isdigit(*(argv[c] + 2))) {
	lines = atoll(argv[c] + 2);
      } else if(c + 1 < argc) {
	lines = atoll(argv[c + 1]);
	c++;
      }
      screen = 0;
    }
  } //end of for(c = 1; c < argc; c++)

#define aTESTING 2
  
#ifdef TESTING
  unsigned char columnsstring[32];
  sprintf(columnsstring, "%05d", lines + 1);
  fprintf(stdout,"Hello world!\n");
  if(lim == 0)
    lim = 256;
  if(columns == 0)
    columns = 16;
  if(lines == 0)
    lines = 10;
  if(words == 0) {
    words = 16;
    chars = words * (space + wordlength);
  }
  for(clines = 0; clines < lines; clines++) {
    fprintf(stdout, "%0*lld", 2, (unsigned long long) clines);
    //fprintf(stdout, "%0*llx", (int) 2, (unsigned long long) my_random_genlimit(lim));
    my_output = 1;
    columns = strlen(columnsstring);
    for(ccolumns = 0; ccolumns < columns; ccolumns++) {
      if(space == 1)
	fprintf(stdout, " ");
      wordlength = lim;
      fprintf(stdout, "%0*llx", (int) 2, (unsigned long long) my_random_genlimit(lim));
      fprintf(stdout, "%0*llx", (int) wordlength, (unsigned long long) my_random_genlimit(lim));
    }
    fprintf(stdout, "\n");
  }
#endif // testing()
  return(0);
}

#endif // end of #ifdef MAIN
Published
Categorized as muuta

Leave a comment