diff --git a/code/PRNG2_m32_l8.c b/code/PRNG2_m32_l8.c new file mode 100644 index 0000000..9c51326 --- /dev/null +++ b/code/PRNG2_m32_l8.c @@ -0,0 +1,115 @@ +#include +#include +#include + +#define poly8l 0xB8 +// Exemplo PRNG: PRNG 2 com m=32 e l=8 + +// semente aleatória +static unsigned int x = 0x877;//0x1A3FB; --Best +static unsigned int y = 0xd52585;//0xB7C1E2 +static double nb = pow(2, 24); +static uint8_t seed2= 0xFF; //seed LFSR 8 bits +unsigned int x_aux; +typedef struct{ + uint32_t x; + uint32_t y; +}coord_arnold;//assinatura para estrutura +//Função do mapa de Arnold discreto +coord_arnold arnold(uint32_t x,uint32_t y){ +coord_arnold coord; //assinatura para estrutura + x_aux = x; + coord.x = (2 * x + y); //% MOD; //coord.x e coord.y armazenam o valor na estrutura via passagem por referência + coord.y = (x_aux + y); // % MOD; + return coord; //retorna os valores com assinados +} +// Estrutura do LFSR +struct LFSR { + uint8_t state; // Estado atual do LFSR +}; + + +// Função para iniciar o LFSR a partir da semente dada +void lfsr_init(struct LFSR* lfsr, uint8_t seed) { + lfsr->state = seed; +} + +// Función para generar el siguiente valor del segundo LFSR y actualizar el estado +uint8_t lfsr_next2(struct LFSR* lfsr) { + uint8_t bit = lfsr->state & 1; // Extrae el bit menos significativo + lfsr->state >>= 1; // Desplaza un bit a la derecha + + if (bit) // Si el bit extraído es 1, aplica retroalimentación + lfsr->state ^= poly8l; + + return bit; // Devuelve el bit generado +} +uint64_t prng_m32_l8(void) { + uint8_t Bx[8], By[8]; + uint16_t w[8], z[8]; + uint64_t beta[4], lambda0; +struct LFSR lfsr2; + + // printf("Valores iniciais: x = %08X, y = %08X\n", x, y); + // printf("\n"); + +coord_arnold coord; +coord=arnold((uint32_t)x,(uint32_t)y); + +x=coord.x; +y=coord.y; + + // printf("Valores finais: x = %08X, y = %08X\n", x, y); + // printf("\n"); + uint32_t x1 = 0; + uint32_t y1 = 0; + + lfsr_init(&lfsr2, seed2); + + uint8_t sequence2 = 0; // Inicializar la secuencia como 0 antes de generar la nueva secuencia + + sequence2 <<= 1; + sequence2 |= lfsr_next2(&lfsr2); + + + //Actualizo sus estados + seed2 = lfsr2.state; + + // printf("\n"); + // printf("Depois: S1 = %X, S2 = %X\n", sequence1, sequence2); + + x1 = x; + y1 = y ^ (sequence2); + // Processa os bits em grupos de 4 + for (int i = 0; i < 4; ++i) { + Bx[i] = (x1 >> (8 * i)) & 0xff; + By[i] = (y1 >> (8 * i)) & 0xff; + + w[i] = By[i] | (Bx[i] << 8); + z[i] = Bx[i] * By[i]; + } + + beta[3] = (z[0] ^ w[3] ^ w[2]); + beta[2] = (z[1] ^ w[2] ^ w[1]); + beta[1] = (z[2] ^ w[1] ^ w[0]); + beta[0] = (z[3] ^ w[0] ^ w[3]); + + // Construa a palavra lambda0 + lambda0 = ((beta[3] << 48) | (beta[2] << 32) | (beta[1] << 16) |(beta[0])); + // printf("%ld bits\n",sizeof((w[3] ^ z[0]) ^ (w[1] ^ z[2]))*8); + return lambda0; +} + +int main() +{ + uint64_t sample; + + for (int i = 0; i < 100; i++) + { + sample = prng_m32_l8(); + printf("i: %d, z: %lu\n", i, sample); + } + + return 0; +} + diff --git a/code/PRNG2_m64_l16.c b/code/PRNG2_m64_l16.c new file mode 100644 index 0000000..d2526ab --- /dev/null +++ b/code/PRNG2_m64_l16.c @@ -0,0 +1,125 @@ +#include +#include +#include + +#define poly16l 0xD008 +// Example PRNG: PRNG 2 with m=64 and l=16 + +// random seed +static uint64_t x = 0x7F3B5E9D2A4C7FE; +static uint64_t y = 0x1C6D9A4F8B7E2D3A; +static uint16_t seed2 = 0x3F4E;//0x4D5E6F;// Semente inicial +unsigned int x_aux; +typedef struct{ +uint64_t lambda0; +uint64_t lambda1; +}lambda; +typedef struct{ + uint64_t x; + uint64_t y; +}coord_arnold;//assinatura para estrutura +//Função do mapa de Arnold discreto +coord_arnold arnold(uint64_t x,uint64_t y){ +coord_arnold coord; //assinatura para estrutura + x_aux = x; + coord.x = (2 * x + y); //% MOD; //coord.x e coord.y armazenam o valor na estrutura via passagem por referência + coord.y = (x_aux + y); // % MOD; + return coord; + //retorna os valores com assinados +} +// Estrutura do LFSR +struct LFSR { + uint16_t state; // Estado atual do LFSR +}; + + +// Função para iniciar o LFSR a partir da semente dada +void lfsr_init(struct LFSR* lfsr, uint16_t seed) { + lfsr->state = seed; +} + +// Función para generar el siguiente valor del segundo LFSR y actualizar el estado +uint16_t lfsr_next2(struct LFSR* lfsr) { + uint16_t bit = lfsr->state & 1; // Extrae el bit menos significativo + lfsr->state >>= 1; // Desplaza un bit a la derecha + + if (bit) // Si el bit extraído es 1, aplica retroalimentación + lfsr->state ^= poly16l; + + return bit; // Devuelve el bit generado +} +lambda prng_m64_l16(void) { + uint64_t Bx[4], By[4],lambda0; + uint32_t w[4], z[4]; + uint64_t beta[4]; + +struct LFSR lfsr2; + + + // printf("Valores iniciais: x = %08X, y = %08X\n", x, y); + // printf("\n"); + +coord_arnold coord; +coord=arnold((uint64_t)x,(uint64_t)y); + +x=coord.x; +y=coord.y; + + // printf("Valores finais: x = %08lX, y = %08lX\n", x, y); + // printf("\n"); + uint64_t x1 = 0; + uint64_t y1 = 0; + + + uint64_t sequence2 = 0; // Inicializar la secuencia como 0 antes de generar la nueva secuencia + + + lfsr_init(&lfsr2, seed2); + + sequence2 <<= 1; + sequence2 |= lfsr_next2(&lfsr2); + + + //Actualizo sus estados + seed2 = lfsr2.state; + + // printf("\n"); + // printf("Valores atuais: x = %08lX, y = %08lX\n", x, y); + + x1 = x; + y1 = y ^ (sequence2); + // Processa os bits em grupos de 4 + for (int i = 0; i < 4; ++i) { + Bx[i] = (x1 >> (16 * i)) & 0xffff; + By[i] = (y1 >> (16 * i)) & 0xffff; + + w[i] = By[i] | (Bx[i] << 16); + z[i] = Bx[i] * By[i]; + + } + beta[3] = (z[0] ^ w[3] ^ w[2]); + beta[2] = (z[1] ^ w[2] ^ w[1]); + beta[1] = (z[2] ^ w[1] ^ w[0]); + beta[0] = (z[3] ^ w[0] ^ w[3]); + + lambda l; + l.lambda0 = ((beta[1] << 32) |(beta[0])); + l.lambda1 = ((beta[3] << 32) |(beta[2])); + return l; + + +} + +int main() +{ + lambda sample; + + for (int i = 0; i < 100; i++) + { + sample = prng_m64_l16(); + printf("i: %d, z0: %lu, z1: %lu\n", i, sample.lambda0, sample.lambda1); + } + + return 0; +} + diff --git a/code/PRNG2_m64_l8.c b/code/PRNG2_m64_l8.c new file mode 100644 index 0000000..b8e68d1 --- /dev/null +++ b/code/PRNG2_m64_l8.c @@ -0,0 +1,178 @@ +// Adapted from TestU01 manual +/* +Semente 1: 0x4F6A1C9B +Semente 2: 0x7E3D5F2A +*/ + +#include +#include +#include + +#define poly16l 0xD008 +// Example PRNG: PRNG 2 with m=64 and l=8 + +// random seed +static uint64_t x = 0x7F3B5EA4C7FE; +static uint64_t y = 0x1C6D9A4F8B7E2D3A; +static double nb = pow(2, 24); +static uint16_t seed2 = 0x3F4E;//0x4D5E6F;// Semente inicial +uint64_t x_aux; +//Estrutura para 128bits +typedef struct{ +uint64_t lambda0; +uint64_t lambda1; +}lambda; +//Estrutura para atualizar os valores das coordenadas +typedef struct{ + uint64_t x; + uint64_t y; +}coord_arnold;//assinatura para estrutura +//Função do mapa de Arnold discreto +coord_arnold arnold(uint64_t x, uint64_t y){ +coord_arnold coord; //assinatura para estrutura + x_aux = x; + coord.x = (2 * x + y); //% MOD; //coord.x e coord.y armazenam o valor na estrutura via passagem por referência + coord.y = (x_aux + y); // % MOD; + return coord; //retorna os valores com assinados +} +// Estrutura do LFSR +struct LFSR { + uint16_t state; // Estado atual do LFSR +}; + +// Função para iniciar o LFSR a partir da semente dada +void lfsr_init(struct LFSR* lfsr, uint16_t seed) { + lfsr->state = seed; +} + +// Función para generar el siguiente valor del segundo LFSR y actualizar el estado +uint16_t lfsr_next2(struct LFSR* lfsr) { + uint16_t bit = lfsr->state & 1; // Extrae el bit menos significativo + lfsr->state >>= 1; // Desplaza un bit a la derecha + + if (bit) // Si el bit extraído es 1, aplica retroalimentación + lfsr->state ^= poly16l;//POLYNOMIAL2_HIGH << 48 | POLYNOMIAL2_LOW; + + return bit; // Devuelve el bit generado +} + + +lambda prng_m64_l8 (void) +{ + uint8_t Bx0, Bx1, Bx2, Bx3,Bx4,Bx5,Bx6,Bx7; + uint8_t By0, By1, By2, By3,By4,By5,By6,By7; + uint16_t w0, w1, w2, w3,w4,w5,w6,w7; + uint16_t z0, z1, z2, z3,z4,z5,z6,z7; + uint64_t beta0, beta1, beta2, beta3,beta4,beta5,beta6,beta7; + uint64_t lambda0,lambda1; + struct LFSR lfsr2; + lambda l; +coord_arnold coord; +coord=arnold((uint64_t)x,(uint64_t)y); +x=coord.x; +y=coord.y; + + uint64_t x1 = 0; + uint64_t y1 = 0; + + + lfsr_init(&lfsr2, seed2); + + + uint32_t sequence2 = 0; // Inicializar la secuencia como 0 antes de generar la nueva secuencia + + + + sequence2 <<= 1; + sequence2 |= lfsr_next2(&lfsr2); + + //Actualizo sus estados + seed2 = lfsr2.state; + + x1 =x;//^sequence1; + y1 =y^sequence2; + // Get x[7:0} , y[7:0] + Bx0 = x1 & 0xff; + By0 = y1 & 0xff; + + w0 = By0 | (Bx0 << 8); + z0 = Bx0 * By0; + // Get x[15:7], y[15:7] + Bx1 = (x1 & 0xff00) >> 8; + By1 = (y1 & 0xff00) >> 8; + + w1 = By1 | (Bx1 << 8); + z1 = Bx1 * By1; + + // Get x[23:15], y[23:15] + Bx2 = (x1 & 0xff0000) >> 16; + By2 = (y1 & 0xff0000) >> 16; + + w2 = By2 | (Bx2 << 8); + z2 = Bx2 * By2; + + // Get x[31:23], y[31:23] + Bx3 = (x1 & 0xff000000) >> 24; + By3 = (y1 & 0xff000000) >> 24; + + w3 = By3 | (Bx3 << 8); + z3 = Bx3 * By3; + + // Get x[39:31], y[39:31] + Bx4 = (x1 & 0xff00000000) >> 32; + By4 = (y1 & 0xff00000000) >> 32; + + w4 = By4 | (Bx4 << 8); + z4 = Bx4 * By4; + + // Get x[47:39], y[47:39] + Bx5 = (x1 & 0xff0000000000) >> 40; + By5 = (y1 & 0xff0000000000) >> 40; + + w5 = By5 | (Bx5 << 8); + z5 = Bx5 * By5; + + // Get x[54:47], y[55:47] + Bx6 = (x1 & 0xff000000000000) >> 48; + By6 = (y1 & 0xff000000000000) >> 48; + + w6 = By6 | (Bx6 << 8); + z6 = Bx6 * By6; + + // Get x[63:55], y[63:55] + Bx7 = (x1 & 0xff00000000000000) >> 56; + By7 = (y1 & 0xff00000000000000) >> 56; + + w7 = By7 | (Bx7 << 8); + z7 = Bx7 * By7; + + // Get beta values +beta7 = (z0 ^ w7 ^ w4); +beta6 = (z1 ^ w6 ^ w3); +beta5 = (z2 ^ w5 ^ w2); +beta4 = (z3 ^ w4 ^ w1); +beta3 = (z4 ^ w3 ^ w0); +beta2 = (z5 ^ w2 ^ w7); +beta1 = (z6 ^ w1 ^ w6); +beta0 = (z7 ^ w0 ^ w5); + + + l.lambda0=(beta7<<48|beta6<<32|beta5<<16|beta4); + l.lambda1=(beta3<<48|beta2<<32|beta1<<16|beta0); + return l; + +} + +int main() +{ + lambda sample; + + for (int i = 0; i < 100; i++) + { + sample = prng_m64_l8(); + printf("i: %d, z0: %lu, z1: %lu\n", i, sample.lambda0, sample.lambda1); + } + + return 0; +} +