/*
  file LFSR4.C
  created Sun Oct 23 20:24:34 CEST 2005 by Yann GUIDON (whygee@f-cpu.org)
  version Sun Oct 30 05:41:47 CET 2005 : Alpha port
  version 2007-01-17 : trying on Sparc
  version 2007-01-22 : tested on CRAY YMP-EL :-)

  This file implements a 32-bit LFSR (generates 4 billions bits before wraparound)
  but this adaptation of the Schneier code provides 4 bits each time
 */

#include "def64.h"

#define LFSR_POLY0 0x80000057
#define LFSR_POLY1 (((LFSR_POLY0>>1)|(LFSR_POLY0<<31)) & 0xFFFFFFFF)
#define LFSR_POLY2 (((LFSR_POLY1>>1)|(LFSR_POLY1<<31)) & 0xFFFFFFFF)
#define LFSR_POLY3 (((LFSR_POLY2>>1)|(LFSR_POLY2<<31)) & 0xFFFFFFFF)

U32 LFSR4_TABLE[16]= {
  0,
  LFSR_POLY0,
             LFSR_POLY1,
  LFSR_POLY0^LFSR_POLY1,
                        LFSR_POLY2,
  LFSR_POLY0^           LFSR_POLY2,
             LFSR_POLY1^LFSR_POLY2,
  LFSR_POLY0^LFSR_POLY1^LFSR_POLY2,
                                   LFSR_POLY3,
  LFSR_POLY0^                      LFSR_POLY3,
             LFSR_POLY1^           LFSR_POLY3,
  LFSR_POLY0^LFSR_POLY1^           LFSR_POLY3,
                        LFSR_POLY2^LFSR_POLY3,
  LFSR_POLY0^           LFSR_POLY2^LFSR_POLY3,
             LFSR_POLY1^LFSR_POLY2^LFSR_POLY3,
  LFSR_POLY0^LFSR_POLY1^LFSR_POLY2^LFSR_POLY3
};

U32 LFSR_reg = 0x12345678; /* anything except zero */

static inline U32 lfsr4() {
  U32 t=LFSR_reg & 15;
  U32 u=LFSR_reg ^ LFSR4_TABLE[t];
  LFSR_reg = ( (u >> 4) | (u << 28) ) & 0xFFFFFFFF;
  return t;
}

#ifdef STANDALONE_TEST_LFSR4

#include <stdio.h>

/* The program should display the following numbers :
8705035aac711c5cbe5a513f6f2f97cfb7a9b8646ef9765738b99ba809f5
 */

int main() {
  int i;

  for (i=0; i<60; i++) {
    printf("%01x" ,lfsr4());
  }
  printf("\n");
  return 0;
}
#endif
