mirror of
https://strlcat.eu/rys/tfnoisegen.git
synced 2025-06-16 01:34:27 +02:00
Threefish cipher based raw PRN/noise generator.
This commit is contained in:
commit
76b80ded3a
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
_*
|
||||||
|
*.swp
|
||||||
|
*.o
|
||||||
|
*.out
|
||||||
|
*.key
|
||||||
|
*.diff
|
||||||
|
*.patch
|
||||||
|
tags
|
||||||
|
libtf.a
|
||||||
|
tfrand
|
27
Makefile
Normal file
27
Makefile
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
PROGS = tfrand
|
||||||
|
PROGSRCS = $(PROGS:=.c)
|
||||||
|
PROGOBJS = $(PROGSRCS:.c=.o)
|
||||||
|
SRCS = $(filter-out $(PROGSRCS), $(wildcard *.c))
|
||||||
|
HDRS = $(wildcard *.h)
|
||||||
|
OBJS = $(SRCS:.c=.o)
|
||||||
|
|
||||||
|
ifneq (,$(DEBUG))
|
||||||
|
override CFLAGS+=-Wall -O0 -g
|
||||||
|
else
|
||||||
|
override CFLAGS+=-O3
|
||||||
|
endif
|
||||||
|
|
||||||
|
default: $(OBJS) libtf.a tfrand
|
||||||
|
all: $(OBJS) libtf.a $(PROGS)
|
||||||
|
|
||||||
|
%.o: %.c $(HDRS)
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
libtf.a: $(OBJS)
|
||||||
|
$(AR) cru $@ $^
|
||||||
|
|
||||||
|
$(PROGS): %: %.o libtf.a
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f libtf.a $(OBJS) $(PROGOBJS) $(SUPPOBJS) $(PROGS)
|
43
README
Normal file
43
README
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
Threefish cipher based raw PRN/noise generator.
|
||||||
|
|
||||||
|
PURPOSE
|
||||||
|
This PRNG is shortened, 32 bit integer version of Threefish-256 block cipher.
|
||||||
|
It is technically a 128 bit block cipher with 256 bit key.
|
||||||
|
|
||||||
|
It's purpose is to generate fillers fast, for use in file or disk shredders.
|
||||||
|
It is not meant to be secure, i.e. collision/bias free, but it is good at
|
||||||
|
generating random noise equal to average output of /dev/urandom, yet much faster.
|
||||||
|
|
||||||
|
Typical performance on Athlon 5000+, x86-32 is about 170M/sec.
|
||||||
|
|
||||||
|
Included tfrand program generates random noise to stdout.
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Build example:
|
||||||
|
|
||||||
|
make tfrand
|
||||||
|
|
||||||
|
Test it:
|
||||||
|
|
||||||
|
./tfrand >rng.out
|
||||||
|
|
||||||
|
Measure performance (install tfcrypt first):
|
||||||
|
|
||||||
|
./tfrand | tfcrypt -V.5 -P - /dev/null
|
||||||
|
|
||||||
|
Use libtf.a library in your code, see headers for function references:
|
||||||
|
tfe.h: STREAM reference.
|
||||||
|
tfprng.h: PRNG reference.
|
||||||
|
|
||||||
|
WARNING
|
||||||
|
Do NOT use it as cipher! It's just a random block generator.
|
||||||
|
You have been warned.
|
||||||
|
|
||||||
|
ORIGIN
|
||||||
|
This code is derived from tfcipher library.
|
||||||
|
|
||||||
|
LICENSE
|
||||||
|
Public domain -- free to reuse and adapt.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Andrey Rys <rys@lynxlynx.ru>, 17Mar2019.
|
50
tfcore.h
Normal file
50
tfcore.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#ifndef _THREEFISH_CIPHER_CORE_HEADER
|
||||||
|
#define _THREEFISH_CIPHER_CORE_HEADER
|
||||||
|
|
||||||
|
#ifndef _THREEFISH_CIPHER_DEFINITIONS_HEADER
|
||||||
|
#error Threefish definitions header is required! Include tfdef.h first.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ROL(x, s, max) ((x << s) | (x >> (-s & (max-1))))
|
||||||
|
#define ROR(x, s, max) ((x >> s) | (x << (-s & (max-1))))
|
||||||
|
|
||||||
|
#define KE_MIX(x, y, k1, k2, sl) \
|
||||||
|
do { \
|
||||||
|
x += k1; \
|
||||||
|
y += x; \
|
||||||
|
y += k2; \
|
||||||
|
x = ROL(x, sl, TF_UNIT_BITS); \
|
||||||
|
x ^= y; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define BE_MIX(x, y, sl) \
|
||||||
|
do { \
|
||||||
|
x += y; \
|
||||||
|
y = ROL(y, sl, TF_UNIT_BITS); \
|
||||||
|
y ^= x; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define KD_MIX(x, y, k1, k2, sr) \
|
||||||
|
do { \
|
||||||
|
x ^= y; \
|
||||||
|
x = ROR(x, sr, TF_UNIT_BITS); \
|
||||||
|
y -= x; \
|
||||||
|
y -= k2; \
|
||||||
|
x -= k1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define BD_MIX(x, y, sr) \
|
||||||
|
do { \
|
||||||
|
y ^= x; \
|
||||||
|
y = ROR(y, sr, TF_UNIT_BITS); \
|
||||||
|
x -= y; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
enum tf_rotations {
|
||||||
|
TFS_KS01 = 7, TFS_KS02 = 25, TFS_KS03 = 19, TFS_KS04 = 7,
|
||||||
|
TFS_BS01 = 5, TFS_BS02 = 27, TFS_BS03 = 26, TFS_BS04 = 6,
|
||||||
|
TFS_BS05 = 14, TFS_BS06 = 11, TFS_BS07 = 24, TFS_BS08 = 18,
|
||||||
|
TFS_BS09 = 9, TFS_BS10 = 24, TFS_BS11 = 6, TFS_BS12 = 7,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
34
tfdef.h
Normal file
34
tfdef.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef _THREEFISH_CIPHER_DEFINITIONS_HEADER
|
||||||
|
#define _THREEFISH_CIPHER_DEFINITIONS_HEADER
|
||||||
|
|
||||||
|
#ifndef _DEFAULT_SOURCE
|
||||||
|
#define _DEFAULT_SOURCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _BSD_SOURCE
|
||||||
|
#define _BSD_SOURCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define TF_UNIT_TYPE uint32_t
|
||||||
|
|
||||||
|
#define TF_NR_BLOCK_BITS 128
|
||||||
|
#define TF_NR_KEY_BITS 256
|
||||||
|
#define TF_NR_BLOCK_UNITS 4
|
||||||
|
#define TF_NR_KEY_UNITS 8
|
||||||
|
|
||||||
|
#define TF_BYTE_TYPE uint8_t
|
||||||
|
#define TF_SIZE_UNIT (sizeof(TF_UNIT_TYPE))
|
||||||
|
#define TF_BLOCK_SIZE (TF_SIZE_UNIT * TF_NR_BLOCK_UNITS)
|
||||||
|
#define TF_KEY_SIZE (TF_SIZE_UNIT * TF_NR_KEY_UNITS)
|
||||||
|
|
||||||
|
#define TF_TO_BITS(x) ((x) * 8)
|
||||||
|
#define TF_FROM_BITS(x) ((x) / 8)
|
||||||
|
#define TF_MAX_BITS TF_NR_BLOCK_BITS
|
||||||
|
#define TF_UNIT_BITS (TF_SIZE_UNIT * 8)
|
||||||
|
|
||||||
|
void tf_encrypt_rawblk(TF_UNIT_TYPE *O, const TF_UNIT_TYPE *I, const TF_UNIT_TYPE *K);
|
||||||
|
|
||||||
|
#endif
|
57
tfe.c
Normal file
57
tfe.c
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include "tfdef.h"
|
||||||
|
#include "tfe.h"
|
||||||
|
|
||||||
|
void tfe_init_iv(struct tfe_stream *tfe, const void *key, const void *iv)
|
||||||
|
{
|
||||||
|
memset(tfe, 0, sizeof(struct tfe_stream));
|
||||||
|
memcpy(tfe->key, key, TF_KEY_SIZE);
|
||||||
|
if (iv) memcpy(tfe->iv, iv, TF_BLOCK_SIZE);
|
||||||
|
tfe->carry_bytes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tfe_init(struct tfe_stream *tfe, const void *key)
|
||||||
|
{
|
||||||
|
tfe_init_iv(tfe, key, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tfe_emit(void *dst, size_t szdst, struct tfe_stream *tfe)
|
||||||
|
{
|
||||||
|
TF_BYTE_TYPE *udst = dst;
|
||||||
|
size_t sz = szdst;
|
||||||
|
|
||||||
|
if (!dst && szdst == 0) {
|
||||||
|
memset(tfe, 0, sizeof(struct tfe_stream));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tfe->carry_bytes > 0) {
|
||||||
|
if (tfe->carry_bytes > szdst) {
|
||||||
|
memcpy(udst, tfe->carry_block, szdst);
|
||||||
|
memmove(tfe->carry_block, tfe->carry_block+szdst, tfe->carry_bytes-szdst);
|
||||||
|
tfe->carry_bytes -= szdst;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(udst, tfe->carry_block, tfe->carry_bytes);
|
||||||
|
udst += tfe->carry_bytes;
|
||||||
|
sz -= tfe->carry_bytes;
|
||||||
|
tfe->carry_bytes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sz >= TF_BLOCK_SIZE) {
|
||||||
|
do {
|
||||||
|
tf_encrypt_rawblk(tfe->iv, tfe->iv, tfe->key);
|
||||||
|
memcpy(udst, tfe->iv, TF_BLOCK_SIZE);
|
||||||
|
udst += TF_BLOCK_SIZE;
|
||||||
|
} while ((sz -= TF_BLOCK_SIZE) >= TF_BLOCK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sz) {
|
||||||
|
tf_encrypt_rawblk(tfe->iv, tfe->iv, tfe->key);
|
||||||
|
memcpy(udst, tfe->iv, sz);
|
||||||
|
udst = (TF_BYTE_TYPE *)tfe->iv;
|
||||||
|
tfe->carry_bytes = TF_BLOCK_SIZE-sz;
|
||||||
|
memcpy(tfe->carry_block, udst+sz, tfe->carry_bytes);
|
||||||
|
}
|
||||||
|
}
|
17
tfe.h
Normal file
17
tfe.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef _TF_STREAM_CIPHER_DEFS
|
||||||
|
#define _TF_STREAM_CIPHER_DEFS
|
||||||
|
|
||||||
|
#include "tfdef.h"
|
||||||
|
|
||||||
|
struct tfe_stream {
|
||||||
|
TF_UNIT_TYPE key[TF_NR_KEY_UNITS];
|
||||||
|
TF_UNIT_TYPE iv[TF_NR_BLOCK_UNITS];
|
||||||
|
TF_BYTE_TYPE carry_block[TF_BLOCK_SIZE];
|
||||||
|
size_t carry_bytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
void tfe_init(struct tfe_stream *tfe, const void *key);
|
||||||
|
void tfe_init_iv(struct tfe_stream *tfe, const void *key, const void *iv);
|
||||||
|
void tfe_emit(void *dst, size_t szdst, struct tfe_stream *tfe);
|
||||||
|
|
||||||
|
#endif
|
51
tfenc.c
Normal file
51
tfenc.c
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#include "tfdef.h"
|
||||||
|
#include "tfcore.h"
|
||||||
|
|
||||||
|
#define PROCESS_BLOCKP(x,k1,k2,k3,k4,k5,k6) \
|
||||||
|
do { \
|
||||||
|
KE_MIX(Y, X, k1 + k2, k3, TFS_KS01); \
|
||||||
|
KE_MIX(T, Z, k4 + x, k5 + k6, TFS_KS02); \
|
||||||
|
\
|
||||||
|
BE_MIX(X, T, TFS_BS01); BE_MIX(Z, Y, TFS_BS02); \
|
||||||
|
BE_MIX(X, Y, TFS_BS03); BE_MIX(Z, T, TFS_BS04); \
|
||||||
|
BE_MIX(X, T, TFS_BS05); BE_MIX(Z, Y, TFS_BS06); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define PROCESS_BLOCKN(x,k1,k2,k3,k4,k5,k6) \
|
||||||
|
do { \
|
||||||
|
KE_MIX(Y, X, k1 + k2, k3, TFS_KS03); \
|
||||||
|
KE_MIX(T, Z, k4 + x, k5 + k6, TFS_KS04); \
|
||||||
|
\
|
||||||
|
BE_MIX(X, T, TFS_BS07); BE_MIX(Z, Y, TFS_BS08); \
|
||||||
|
BE_MIX(X, Y, TFS_BS09); BE_MIX(Z, T, TFS_BS10); \
|
||||||
|
BE_MIX(X, T, TFS_BS11); BE_MIX(Z, Y, TFS_BS12); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
void tf_encrypt_rawblk(TF_UNIT_TYPE *O, const TF_UNIT_TYPE *I, const TF_UNIT_TYPE *K)
|
||||||
|
{
|
||||||
|
TF_UNIT_TYPE X, Y, Z, T;
|
||||||
|
TF_UNIT_TYPE K0, K1, K2, K3;
|
||||||
|
TF_UNIT_TYPE K4, T0, T1, T2;
|
||||||
|
|
||||||
|
X = I[0]; Y = I[1]; Z = I[2]; T = I[3];
|
||||||
|
|
||||||
|
K0 = K[0]; K1 = K[1]; K2 = K[2]; K3 = K[3];
|
||||||
|
K4 = K[4]; T0 = K[5]; T1 = K[6]; T2 = K[7];
|
||||||
|
|
||||||
|
PROCESS_BLOCKP( 1,K1,T0,K0,K3,K2,T1);
|
||||||
|
PROCESS_BLOCKN( 2,K2,T1,K1,K4,K3,T2);
|
||||||
|
PROCESS_BLOCKP( 3,K3,T2,K2,K0,K4,T0);
|
||||||
|
PROCESS_BLOCKN( 4,K4,T0,K3,K1,K0,T1);
|
||||||
|
|
||||||
|
PROCESS_BLOCKP( 5,K0,T1,K4,K2,K1,T2);
|
||||||
|
PROCESS_BLOCKN( 6,K1,T2,K0,K3,K2,T0);
|
||||||
|
PROCESS_BLOCKP( 7,K2,T0,K1,K4,K3,T1);
|
||||||
|
PROCESS_BLOCKN( 8,K3,T1,K2,K0,K4,T2);
|
||||||
|
|
||||||
|
PROCESS_BLOCKP( 9,K4,T2,K3,K1,K0,T0);
|
||||||
|
PROCESS_BLOCKN(10,K0,T0,K4,K2,K1,T1);
|
||||||
|
PROCESS_BLOCKP(11,K1,T1,K0,K3,K2,T2);
|
||||||
|
PROCESS_BLOCKN(12,K2,T2,K1,K4,K3,T0);
|
||||||
|
|
||||||
|
O[0] = X + K3; O[1] = Y + K4 + T0; O[2] = Z + K0 + T1; O[3] = T + K1 + 18;
|
||||||
|
}
|
94
tfprng.c
Normal file
94
tfprng.c
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include "tfe.h"
|
||||||
|
#include "tfprng.h"
|
||||||
|
|
||||||
|
struct tf_prng_data {
|
||||||
|
struct tfe_stream tfe;
|
||||||
|
short init;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tf_prng_data tf_prng_sdata;
|
||||||
|
|
||||||
|
size_t tf_prng_datasize(void)
|
||||||
|
{
|
||||||
|
return sizeof(struct tf_prng_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tf_prng_seedkey_r(void *sdata, const void *skey)
|
||||||
|
{
|
||||||
|
TF_UNIT_TYPE k[TF_NR_KEY_UNITS];
|
||||||
|
struct tf_prng_data *rprng = sdata;
|
||||||
|
|
||||||
|
memset(rprng, 0, tf_prng_datasize());
|
||||||
|
if (!skey) return;
|
||||||
|
|
||||||
|
memcpy(k, skey, TF_KEY_SIZE);
|
||||||
|
tfe_init(&rprng->tfe, k);
|
||||||
|
rprng->init = 1;
|
||||||
|
|
||||||
|
memset(k, 0, TF_KEY_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tf_prng_seedkey(const void *skey)
|
||||||
|
{
|
||||||
|
tf_prng_seedkey_r(&tf_prng_sdata, skey);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tf_prng_genrandom_r(void *sdata, void *result, size_t need)
|
||||||
|
{
|
||||||
|
struct tf_prng_data *rprng = sdata;
|
||||||
|
memset(result, 0, need);
|
||||||
|
tfe_emit(result, need, &rprng->tfe);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tf_prng_genrandom(void *result, size_t need)
|
||||||
|
{
|
||||||
|
tf_prng_genrandom_r(&tf_prng_sdata, result, need);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tf_prng_seed_r(void *sdata, TF_UNIT_TYPE seed)
|
||||||
|
{
|
||||||
|
TF_UNIT_TYPE k[TF_NR_KEY_UNITS];
|
||||||
|
struct tf_prng_data *rprng = sdata;
|
||||||
|
size_t x;
|
||||||
|
|
||||||
|
memset(rprng, 0, tf_prng_datasize());
|
||||||
|
for (x = 0; x < TF_NR_KEY_UNITS; x++) k[x] = seed;
|
||||||
|
tfe_init(&rprng->tfe, k);
|
||||||
|
rprng->init = 1;
|
||||||
|
|
||||||
|
memset(k, 0, TF_KEY_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tf_prng_seed(TF_UNIT_TYPE seed)
|
||||||
|
{
|
||||||
|
tf_prng_seed_r(&tf_prng_sdata, seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
TF_UNIT_TYPE tf_prng_random_r(void *sdata)
|
||||||
|
{
|
||||||
|
struct tf_prng_data *rprng = sdata;
|
||||||
|
TF_UNIT_TYPE r;
|
||||||
|
|
||||||
|
if (!rprng->init) return 0;
|
||||||
|
|
||||||
|
tfe_emit(&r, sizeof(r), &rprng->tfe);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
TF_UNIT_TYPE tf_prng_random(void)
|
||||||
|
{
|
||||||
|
return tf_prng_random_r(&tf_prng_sdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
TF_UNIT_TYPE tf_prng_range_r(void *sdata, TF_UNIT_TYPE s, TF_UNIT_TYPE d)
|
||||||
|
{
|
||||||
|
TF_UNIT_TYPE c = tf_prng_random_r(sdata);
|
||||||
|
if (d <= s) return s;
|
||||||
|
return s + c / ((TF_UNIT_TYPE)~0 / (d - s + 1) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TF_UNIT_TYPE tf_prng_range(TF_UNIT_TYPE s, TF_UNIT_TYPE d)
|
||||||
|
{
|
||||||
|
return tf_prng_range_r(&tf_prng_sdata, s, d);
|
||||||
|
}
|
22
tfprng.h
Normal file
22
tfprng.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef _TF_PRNG_DEFINITIONS_HEADER
|
||||||
|
#define _TF_PRNG_DEFINITIONS_HEADER
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "tfdef.h"
|
||||||
|
|
||||||
|
#define TF_PRNG_KEY_SIZE TF_KEY_SIZE
|
||||||
|
#define TF_PRNG_SIZE_UNIT TF_SIZE_UNIT
|
||||||
|
|
||||||
|
size_t tf_prng_datasize(void);
|
||||||
|
void tf_prng_seedkey_r(void *sdata, const void *skey);
|
||||||
|
void tf_prng_seedkey(const void *skey);
|
||||||
|
void tf_prng_genrandom_r(void *sdata, void *result, size_t need);
|
||||||
|
void tf_prng_genrandom(void *result, size_t need);
|
||||||
|
void tf_prng_seed_r(void *sdata, TF_UNIT_TYPE seed);
|
||||||
|
void tf_prng_seed(TF_UNIT_TYPE seed);
|
||||||
|
TF_UNIT_TYPE tf_prng_random_r(void *sdata);
|
||||||
|
TF_UNIT_TYPE tf_prng_random(void);
|
||||||
|
TF_UNIT_TYPE tf_prng_range_r(void *sdata, TF_UNIT_TYPE s, TF_UNIT_TYPE d);
|
||||||
|
TF_UNIT_TYPE tf_prng_range(TF_UNIT_TYPE s, TF_UNIT_TYPE d);
|
||||||
|
|
||||||
|
#endif
|
31
tfrand.c
Normal file
31
tfrand.c
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "tfdef.h"
|
||||||
|
#include "tfprng.h"
|
||||||
|
|
||||||
|
#define DATASIZE 65536
|
||||||
|
|
||||||
|
static char data[DATASIZE];
|
||||||
|
static char key[TF_KEY_SIZE];
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = open("/dev/urandom", O_RDONLY);
|
||||||
|
if (fd != -1) {
|
||||||
|
read(fd, key, sizeof(key));
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
tf_prng_seedkey(key);
|
||||||
|
while (1) {
|
||||||
|
tf_prng_genrandom(data, DATASIZE);
|
||||||
|
if (write(1, data, DATASIZE) == -1) return 1;
|
||||||
|
}
|
||||||
|
tf_prng_seedkey(NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user