plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

genrandom.c (1171B)


      1 #include "os.h"
      2 #include <mp.h>
      3 #include <libsec.h>
      4 
      5 typedef struct State{
      6 	QLock		lock;
      7 	int		seeded;
      8 	uvlong		seed;
      9 	DES3state	des3;
     10 } State;
     11 static State x917state;
     12 
     13 static void
     14 X917(uchar *rand, int nrand)
     15 {
     16 	int i, m, n8;
     17 	uvlong I, x;
     18 
     19 	/* 1. Compute intermediate value I = Ek(time). */
     20 	I = nsec();
     21 	triple_block_cipher(x917state.des3.expanded, (uchar*)&I, 0); /* two-key EDE */
     22 
     23 	/* 2. x[i] = Ek(I^seed);  seed = Ek(x[i]^I); */
     24 	m = (nrand+7)/8;
     25 	for(i=0; i<m; i++){
     26 		x = I ^ x917state.seed;
     27 		triple_block_cipher(x917state.des3.expanded, (uchar*)&x, 0);
     28 		n8 = (nrand>8) ? 8 : nrand;
     29 		memcpy(rand, (uchar*)&x, n8);
     30 		rand += 8;
     31 		nrand -= 8;
     32 		x ^= I;
     33 		triple_block_cipher(x917state.des3.expanded, (uchar*)&x, 0);
     34 		x917state.seed = x;
     35 	}
     36 }
     37 
     38 static void
     39 X917init(void)
     40 {
     41 	int n;
     42 	uchar mix[128];
     43 	uchar key3[3][8];
     44 	ulong *ulp;
     45 
     46 	ulp = (ulong*)key3;
     47 	for(n = 0; n < sizeof(key3)/sizeof(ulong); n++)
     48 		ulp[n] = truerand();
     49 	setupDES3state(&x917state.des3, key3, nil);
     50 	X917(mix, sizeof mix);
     51 	x917state.seeded = 1;
     52 }
     53 
     54 void
     55 genrandom(uchar *p, int n)
     56 {
     57 	qlock(&x917state.lock);
     58 	if(x917state.seeded == 0)
     59 		X917init();
     60 	X917(p, n);
     61 	qunlock(&x917state.lock);
     62 }