Цитата:
	
	
		| 
					Сообщение от Бурундук  Вы не имеете доступа к этим материалам. Необходим красный допуск, которым обладают избранные члены персонала. Ошибка доступа.
 
 | 
	
  
AMPRNG rev1.0 core routines for PARANOID mode of pseudo-random generator
Secure pseudo-random stream generator and stream cipher,
initialized by 80-512 bit key and (optional) 80-128 bit IV
usage:
Create (key, key_length, is_iv_used, drop_length)
if is_iv_used set, then call
SetIV (iv, iv_length)
to get output,
use PRNG() or GenetateRandom()
to crypt,
use Crypt()
2. AMPRNG pseudo-random generator test utility
Generates random file,
such file you can test by ENT or DIEHARD batterry.
usage: amprng <output file>
*/
#include "amprng.h"
#include "sbox.h"
u8 P[256], MG[256], m, z, savedkey[256];
s32 pos, savedkl, droplen;
#define Morph for (i = 0; i != kl; i++) SEED[i] = MKBOX[SEED[i]];
#define Cycle                                                                       \
	for (i = 0; i != 2048; i++)                                                     \
	{                                                                               \
	  idx = i & 255;                                                                \
	  m = P[(P[idx] + NL[(m + TK[(SEED[i & (kl - 1)] + idx) & 255]) & 255]) & 255]; \
	  t = P[idx];                                                                   \
	  P[idx] = P[m];                                                                \
	  P[m] = t;                                                                     \
	 }                                                                              \
 
#define MGCycle                                                                     \
for (i = 0; i != 2048; i++)                                                         \
	{                                                                               \
	  idx = i & 255;                                                                \
	  z = MG[(MG[idx] + NL[(z + TK[(SEED[i & (kl - 1)] + idx) & 255]) &             \
		255]) & 255];                                                               \
	  t = MG[idx];                                                                  \
	  MG[idx] = MG[z];                                                              \
	  MG[z] = t;                                                                    \
  }                                                                                 \
 
#define SWAP1                       \
	for (i = 0; i != 256; i++)      \
 {                                  \
	  T[i]  = P[i];                 \
	  P[i]  = NL[i];                \
	  NL[i] = T[i];                 \
 }                                  \
 
#define SWAP2                       \
	for (i = 0; i != 256; i++)      \
 {                                  \
	  T[i]  = P[i];                 \
	  P[i]  = TK[i];                \
	  TK[i] = T[i];                 \
}                                   \
 
#define SWAP3                       \
	for (i = 0; i != 256; i++)      \
 {                                  \
	  T[i]  = NL[i];                \
	  NL[i] = TK[i];                \
	  TK[i] = T[i];                 \
}                                   \
 
void setup(const u8 *key, s32 kl, s32 iv)
{
  s32  i, idx;
  u8 t, NL[256], TK[256], SEED[256], T[256];
  for (i = 0; i != kl; i++)
    SEED[i] = key[i];
  for (i = 0; i != 256; i++)
    {
      if (iv == 0) P[i] = i;
      NL[i] = NLBOX[i];
      TK[i] = TKBOX[i];
    }
  m = 0;
  Morph;
  Cycle;
  SWAP1;
  Morph;
  Cycle;
  SWAP2;
  Morph;
  Cycle;
  SWAP1;
  Morph;
  Cycle;
  Morph;
  SWAP3;
  Morph;
  if (iv == 0)
    {
      for (i = 0; i != 256; i++)
        MG[i] = MGBOX[i];
    }
  z = 0;
  MGCycle;
  pos = 0;
}
void Create(const u8 *key, s32 kl, s32 useiv, s32 drop)
{
  s32 i;
  setup(key, kl, 0);
  if ((useiv == 1))
    {
      savedkl = kl;
      for (i = 0; i != kl; i++)
        savedkey[i] = key[i];
    }
  droplen = drop;
}
void SetIV(const u8 *iv, s32 ivl)
{
  s32 i;
  setup(iv, ivl, 1);
  setup(savedkey, savedkl, 1);
  for (i = 0; i != 256; i++) savedkey[i] = 0;
  savedkl = 0;
}
u8 PRNG (void)
{
  u8 t, output;
  if (droplen == 0)	droplen = 1;
  do
    {
      m = P[MG[(m + P[pos]) & 255]];
      z = MG[P[(z + MG[pos]) & 255]];
      output = P[P[(P[m] + 1) & 255]];
      t = P[pos];
      P[pos] = P[m];
      P[m] = t;
      t = MG[pos];
      MG[pos] = MG[z];
      MG[z] = t;
      pos = (pos + 1) & 255;
      droplen-- ;
    }
  while (droplen != 0);
  return output;
}
void GenerateRandom(u8 *buffer, s32 len)
{
  s32 i;
  for (i = 0; i != len; i++)
    buffer[i] = PRNG();
}
void Crypt(u8 *buffer, s32 len)
{
  s32 i;
  for (i = 0; i != len; i++)
    buffer[i] = buffer[i] ^  PRNG();
}
#ifdef PRNG_TEST
#include <stdio.h>
int
main (int argc, u8 *argv[])
{
  FILE *f;
  u8 buffer [512], key[64], iv[64];
  s32 i, n;
  if (argc < 2)
    {
      fprintf (stderr, "usage: %s <output filename>\n", argv[0]);
      return (1);
    }
  if ((f = fopen (argv[1], "wb+")) == NULL)
    {
      fprintf (stderr, "failed to open '%s' for writing.\n", argv[1]);
      return (1);
    }
  for (i = 0; i != 64; i++)
    {
      key[i] = i & 5;
      iv[i] = i & 2;
    }
  Create(key, 64, 1, 768);
  SetIV(iv, 64);
  for (i = 0; i != 1024 * 1024; i++)
    {
      GenerateRandom(buffer, 128);
      fwrite (buffer, 128, 1, f);
    }
  fclose (f);
  return (0);
}
#endif
