
ã¯ããã«
ä¹±æ°ãžã§ãã¬ãŒã¿ãŒã¯ãWebã»ãã¥ãªãã£ã®éèŠãªéšåã§ãã çšéã®å°ããªãªã¹ãïŒ
- ã»ãã·ã§ã³ãžã§ãã¬ãŒã¿ãŒïŒPHPSESSIDïŒ
- ãã£ããã£ããã¹ãã®çæ
- æå·å
- ãã¹ã¯ãŒããä¿åããããã®äžå¯éçãªãœã«ãçæ
- ãã¹ã¯ãŒããžã§ãã¬ãŒã¿ãŒ
- ãªã³ã©ã€ã³ã«ãžãã§ã«ãŒããé åžããæé
æ°åã®ã©ã³ãã ãªã·ãŒã±ã³ã¹ãéã©ã³ãã ãªãã®ãšåºå¥ããæ¹æ³ã¯ïŒ
1ã2ã3ã4ã5ã6ã7ã8ã9ã®æ°åã®ã·ãŒã±ã³ã¹ããããšããŸãã 圌女ã¯ã©ã³ãã ã§ããïŒ ã©ã³ãã å€æ°ã«ã¯å³å¯ãªå®çŸ©ããããŸãã ã©ã³ãã å€æ°ã¯ãå®éšã®çµæãšããŠå€ãã®å€ã®1ã€ãåãéã§ããã枬å®åã®ãã®éã®1ã€ãŸãã¯å¥ã®å€ã®åºçŸã¯æ£ç¢ºã«äºæž¬ã§ããŸããã ããããçããã®ã«ååãªæ å ±ããªãããã質åã«çããããšã¯åœ¹ã«ç«ã¡ãŸããã ããã§ããããã®æ°åãããŒããŒãã®äžçªäžã®è¡ã®1ã€ã®ã»ããã§ããããšãå€æãããšããŸãããã ãééããªãå¶ç¶ã§ã¯ãªãã-次ã®çªå·ãå«ã³ãããã«ååãä»ãããšãããªãã¯çµ¶å¯Ÿã«æ£ããã§ãããã ã·ãŒã±ã³ã¹ã¯ããã£ã©ã¯ã¿ãŒéã«äŸåé¢ä¿ããªãå Žåã«ã®ã¿ã©ã³ãã ã«ãªããŸãã ããšãã°ããããã®ã·ã³ãã«ãæšœãå®ããã«åŒã蟌ãã çµæãšããŠçŸããå Žåãã·ãŒã±ã³ã¹ã¯ã©ã³ãã ã«ãªããŸãã
ããå°ãè€éãªäŸãŸãã¯Pi

æ°åPiã®æ°ååã¯ã©ã³ãã ãšèŠãªãããŸãã ãžã§ãã¬ãŒã¿ãŒã¯ãPiãè¡šããããã®æŽŸçã«åºã¥ããŠãæªç¥ã®ãã€ã³ãããéå§ããŸãã PIã¯æããã«ã©ã³ãã ãªã·ãŒã±ã³ã¹ã§ããããããã®ãããªãžã§ãã¬ãŒã¿ãŒã¯ããããã次ã®ãããã®ãã¹ããã«åæ ŒããŸãã ãã ãããã®ã¢ãããŒãã¯ãæ¹è©çã«ä¿¡é Œã§ãããã®ã§ã¯ãããŸãã-æå·è§£èªè ãPiçªå·ã®ã©ã®ããããçŸåšäœ¿çšãããŠããããå€æããå Žåã圌ã¯ãã¹ãŠã®ååŸã®ããããèšç®ã§ããŸãã
ãã®äŸã§ã¯ãä¹±æ°ãžã§ãã¬ãŒã¿ãŒã«ãã1ã€ã®å¶éã課ããŠããŸãã æå·è§£èªè ã¯ãä¹±æ°ãžã§ãã¬ãŒã¿ãŒã®åäœãäºæž¬ã§ããªãã¯ãã§ãã
æ¬äŒŒä¹±æ°ãžã§ãã¬ãŒã¿ãŒïŒPRNGïŒãšä¹±æ°ãžã§ãã¬ãŒã¿ãŒïŒRNGïŒã®éã
ãšã³ããããŒã®ãœãŒã¹ã¯ããšã³ããããŒãèç©ããããããä¹±æ°ãçæããããã«ä¹±æ°ãžã§ãã¬ãŒã¿ãŒïŒRNGïŒãå¿ èŠãšããåæå€ïŒåæå€ãã·ãŒãïŒãååŸããããã«äœ¿çšãããŸãã PRNGã¯åäžã®åæå€ã䜿çšãããã®åæå€ããæ¬äŒŒä¹±æ°ãçæãããŸããRNGã¯åžžã«ä¹±æ°ãçæããæåã¯ããŸããŸãªãšã³ããããŒã®ãœãŒã¹ã«ãã£ãŠæäŸãããé«å質ã®ä¹±æ°å€ãæã¡ãŸãã
ãšã³ããããŒã¯ç¡ç§©åºã®å°ºåºŠã§ãã æ å ±ãšã³ããããŒã¯ãæ å ±ã®äžç¢ºå®æ§ãŸãã¯äºæž¬äžèœæ§ã®å°ºåºŠã§ãã
RNG = PRNG +ãšã³ããããŒã®ãœãŒã¹ãšèšããŸãã
PRSPã®è匱æ§
- æ°åéã®äºæž¬å¯èœãªé¢ä¿ã
- ãžã§ãã¬ãŒã¿ãŒã®äºæž¬å¯èœãªåæå€ã
- ä¹±æ°ã®çæãããã·ãŒã±ã³ã¹ã®çãæéã®é·ãããã®åŸããžã§ãã¬ãŒã¿ãŒã¯ãµã€ã¯ã«ã«ãªããŸãã
ç·åœ¢ååPRNGïŒLCPRNGïŒ
æå·åŒ·åºŠãæããªãæ¬äŒŒä¹±æ°ãçæããäžè¬çãªæ¹æ³ã ç·åœ¢ååæ³ã¯ã次ã®åŒã§äžãããããèªç¶æ°mãæ³ãšããç·åœ¢å埩ã·ãŒã±ã³ã¹ã®ã¡ã³ããŒãèšç®ããããšã§æ§æãããŸãã

ããã§ãaïŒä¹æ°ïŒãcïŒå æ°ïŒãmïŒãã¹ã¯ïŒã¯ããã€ãã®æŽæ°ä¿æ°ã§ãã çµæã®ã·ãŒã±ã³ã¹ã¯ã·ãŒãX0ã®éžæã«äŸåãããã®ç°ãªãå€ã«å¯ŸããŠãä¹±æ°ã®ç°ãªãã·ãŒã±ã³ã¹ãååŸãããŸãã
ä¿æ°ãéžæããããã«ãåšæã®é·ããæ倧åããããããã£ããããŸãïŒæ倧é·ã¯mã§ãïŒãã€ãŸããçºé»æ©ããµã€ã¯ã«ãéå§ããç¬éã§ã[1]ã
ãžã§ãã¬ãŒã¿ãŒã«ããã€ãã®ä¹±æ°X0ãX1ãX2ãX3ãäžããŸãã æ¹çšåŒç³»ãå€æ

ãã®ã·ã¹ãã ã解決ããããä¿æ°aãcãmã決å®ã§ããŸãã ãŠã£ãããã£ã¢[8]ã«ãããšããã®ã·ã¹ãã ã«ã¯è§£æ±ºçããããŸãããåç¬ã§è§£æ±ºããã解決çãèŠã€ããããšã¯ã§ããŸããã§ããã ãã®åéã§å©ããŠããã ããã°å¹žãã§ãã
ç·åœ¢ååæ³ã®çµæã®äºæž¬
ç·åœ¢ååæ³ã®æ°å€ãäºæž¬ããããã®äž»ãªã¢ã«ãŽãªãºã ã¯Plumsteadã®ã¢ã«ãŽãªãºã ã§ãããã®ã¢ã«ãŽãªãºã ã®å®è£ ã¯ããã[4] ïŒãªã³ã©ã€ã³ã§èµ·åããŸãïŒããã³ãã[5]ã§èŠã€ããããšãã§ããŸãã ã¢ã«ãŽãªãºã ã®èª¬æã¯[9]ã«ãããŸãã
Javaã§ã®ååã¡ãœããã®åçŽãªå®è£ ã
public static int a = 45; public static int c = 21; public static int m = 67; public static int seed = 2; public static int getRand() { seed = (a * seed + c) % m; return seed; } public static void main(String[] args) { for(int i=0; i<30; i++) System.out.println(getRand()); }
20ã®çªå·ããµã€ãã«éä¿¡ããããšã§[4] ã次ã®æ å ±ãååŸã§ããŸãã æ°åãå€ãã»ã©ã確çãé«ããªããŸãã
Javaã®çµã¿èŸŒã¿ä¹±æ°ãžã§ãã¬ãŒã¿ãŒã®ãããã³ã°
CïŒrandïŒãC ++ïŒrandïŒãJavaãªã©ã®å€ãã®ããã°ã©ãã³ã°èšèªã¯LCPRNGã䜿çšããŸãã äŸãšããŠjava.utils.Randomã䜿çšããŠãããã³ã°ããæ¹æ³ãèŠãŠã¿ãŸãããã ãã®ã¯ã©ã¹ã®ãœãŒã¹ã³ãŒãïŒjdk1.7ïŒãèŠããšã䜿çšãããŠããå®æ°ã確èªã§ããŸãã
private static final long multiplier = 0x5DEECE66DL; // 25214903917 private static final long addend = 0xBL; // 11 private static final long mask = (1L << 48) - 1; // 281474976710655 = 2^48 â 1
java.utils.Randon.nextIntïŒïŒã¡ãœããã¯æ¬¡ã®ããã«ãªããŸãïŒããã§ã¯ããã== 32ïŒ
protected int next(int bits) { long oldseed, nextseed; AtomicLong seed = this.seed; do { oldseed = seed.get(); nextseed = (oldseed * multiplier + addend) & mask; } while (!seed.compareAndSet(oldseed, nextseed)); return (int)(nextseed >>> (48 - bits)); }
çµæã¯ã48-32 = 16ãããã ãå³ã«ã·ããããã次ã®ã·ãŒãã§ãã ãã®æ¹æ³ã¯ãåãæšãŠãããããããšåŒã°ãããã©ãã¯ããã¯ã¹ã§ã¯ç¹ã«äžå¿«ã§ãããã«ãŒããã©ãŒã¹ã«å¥ã®ã«ãŒããè¿œå ããå¿ èŠããããŸãã ãã«ãŒããã©ãŒã¹ã䜿çšããŠãããã³ã°ãçºçããŸãã
é£ç¶ããŠçæããã2ã€ã®æ°å€x1ããã³x2ãç¥ã£ãŠãããšããŸãã 次ã«ã2 ^ 16 = 65536ã®oldseedãªãã·ã§ã³ãå埩åŠçããŠãåŒãx1ã«é©çšããå¿ èŠããããŸãã
((x1*multiplier + addend) & mask) << 16
x2ã«çãããªããŸã§ã ãã«ãŒããã©ãŒã¹ã®ã³ãŒãã¯æ¬¡ã®ããã«ãªããŸã
import java.lang.reflect.Field; import java.util.Random; import java.util.concurrent.atomic.AtomicLong; public class PasswordCracking { public static final long multiplier = 0x5DEECE66DL; public static final long addend = 0xBL; public static final long mask = (1L << 48) - 1; public static void main(String[] args) { Random random = new Random(); long v1 = random.nextInt(); long v2 = random.nextInt(); long v3 = random.nextInt(); long v4 = random.nextInt(); System.out.println("v1=" + v1 + "\nv2=" + v2 + "\nv3=" + v3 + "\nv4=" + v4); // brute-force seed for (int i = 0; i < 65536; i++) { long seed = (((long) v1) << 16) + i; int nextInt = (int)(((seed * multiplier + addend) & mask) >>> 16); if (nextInt == v2) { System.out.println("Seed found: " + seed); Random crackingRandom = new Random(); try { /* set the seed for Random to be convinced that we have found the right seed because constructor Random (long seed) uses the private static long initialScramble (long seed) { return (seed ^ multiplier) & mask; } for simplicity will use Reflection */ Field privateSeedField = Random.class.getDeclaredField("seed"); privateSeedField.setAccessible(true); AtomicLong crackingSeed = (AtomicLong)privateSeedField.get(crackingRandom); crackingSeed.set(seed); }catch(Exception e) { System.out.println(e.toString()); System.exit(1); } long cv1 = crackingRandom.nextInt(); long cv2 = crackingRandom.nextInt(); long cv3 = crackingRandom.nextInt(); long cv4 = crackingRandom.nextInt(); System.out.println("Set fiend seed and generate random numbers"); System.out.println("cv1=" + cv1 + "\ncv2=" + cv2 + "\ncv3=" + cv3 + "\ncv4=" + cv4); break; } } } }
ãã®ããã°ã©ã ã®åºåã¯æ¬¡ã®ããã«ãªããŸãã
v1 = -1184958941 v2 = 274285127 v3 = -1566774765 v4 = 30466408 Seed found: -77657469128792 Set fiend seed and generate random numbers cv1 = 274285127 cv2 = -1566774765 cv3 = 30466408 cv4 = -803980434
æåã®ã·ãŒãã¯èŠã€ãããŸããã§ããããã·ãŒãã¯2çªç®ã®æ°å€ãçæããããã«äœ¿çšãããããšãç解ããã®ã¯ç°¡åã§ãã å ã®ã·ãŒããèŠã€ããã«ã¯ãJavaãã·ãŒãã®å€æã«äœ¿çšããããã€ãã®æäœãéã®é åºã§å®è¡ããå¿ èŠããããŸãã
public static long getPreviousSeed(long prevSeed) { long seed = prevSeed; // reverse the addend from the seed seed -= addend; // reverse the addend long result = 0; // iterate through the seeds bits for (int i = 0; i < 48; i++) { long mask = 1L << i; // find the next bit long bit = seed & mask; // add it to the result result |= bit; if (bit == mask) { // if the bit was 1, subtract its effects from the seed seed -= multiplier << i; } } System.out.println("Previous seed: " + result); return result; }
ãããŠä»ããœãŒã¹ã³ãŒãã§çœ®ãæããŸã
crackingSeed.setïŒã·ãŒãïŒ;
ã«
crackingSeed.setïŒgetPreviousSeedïŒã·ãŒãïŒïŒ;
ããã§ãJavaã§PRNGãæ£åžžã«è§£èªã§ããŸããã
PHPã§PRNG Mersenneãã€ã¹ã¿ãŒããããã³ã°ãã
Mersenne Twisteræ¬äŒŒä¹±æ°ãçæããããã®å¥ã®éæå·åã¢ã«ãŽãªãºã ãæ€èšããŠãã ããã ã¢ã«ãŽãªãºã ã®äž»ãªå©ç¹ã¯ãçæé床ãš2 ^ 19937-1ã®å·šå€§ãªæéã§ããä»åã¯ãphpãœãŒã¹ã³ãŒãããŒãžã§ã³5.4.6ã®mt_srandïŒïŒããã³mt_randïŒïŒã¢ã«ãŽãªãºã ã®å®è£ ãåæããŸãã
ãã¡ã€ã«ã®å
容/ext/standard/basic_functions.h
#define MT_N (624) /* rand.c */ php_uint32 state[MT_N+1]; /* state vector + 1 extra to not violate ANSI C */ php_uint32 *next; /* next random value is computed from here */ int left; /* can *next++ this many times before reloading */ unsigned int rand_seed; /* Seed for rand(), in ts version */ zend_bool rand_is_seeded; /* Whether rand() has been seeded */ zend_bool mt_rand_is_seeded; /* Whether mt_rand() has been seeded */
ãã¡ã€ã«/ext/standard/rand.cã®å
容ïŒ
#define N MT_N /* length of state vector */ #define M (397) /* a period parameter */ #define hiBit(u) ((u) & 0x80000000U) /* mask all but highest bit of u */ #define loBit(u) ((u) & 0x00000001U) /* mask all but lowest bit of u */ #define loBits(u) ((u) & 0x7FFFFFFFU) /* mask the highest bit of u */ #define mixBits(u, v) (hiBit(u)|loBits(v)) /* move hi bit of u to hi bit of v */ #define twist(m,u,v) (m ^ (mixBits(u,v)>>1) ^ ((php_uint32)(-(php_int32)(loBit(u))) & 0x9908b0dfU)) /* {{{ php_mt_reload */ static inline void php_mt_reload(TSRMLS_D) { /* Generate N new values in state Made clearer and faster by Matthew Bellew (matthew.bellew@home.com) */ register php_uint32 *state = BG(state); register php_uint32 *p = state; register int i; for (i = N - M; i--; ++p) *p = twist(p[M], p[0], p[1]); for (i = M; --i; ++p) *p = twist(p[MN], p[0], p[1]); *p = twist(p[MN], p[0], state[0]); BG(left) = N; BG(next) = state; } /* }}} */ /* {{{ php_mt_initialize */ static inline void php_mt_initialize(php_uint32 seed, php_uint32 *state) { /* Initialize generator state with seed See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier. In previous versions, most significant bits (MSBs) of the seed affect only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto. */ register php_uint32 *s = state; register php_uint32 *r = state; register int i = 1; *s++ = seed & 0xffffffffU; for( ; i < N; ++i ) { *s++ = ( 1812433253U * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffU; r++; } } /* }}} */ /* {{{ php_mt_srand */ PHPAPI void php_mt_srand(php_uint32 seed TSRMLS_DC) { /* Seed the generator with a simple uint32 */ php_mt_initialize(seed, BG(state)); php_mt_reload(TSRMLS_C); /* Seed only once */ BG(mt_rand_is_seeded) = 1; } /* }}} */ /* {{{ php_mt_rand */ PHPAPI php_uint32 php_mt_rand(TSRMLS_D) { /* Pull a 32-bit integer from the generator state Every other access function simply transforms the numbers extracted here */ register php_uint32 s1; if (BG(left) == 0) { php_mt_reload(TSRMLS_C); } --BG(left); s1 = *BG(next)++; s1 ^= (s1 >> 11); s1 ^= (s1 << 7) & 0x9d2c5680U; s1 ^= (s1 << 15) & 0xefc60000U; return ( s1 ^ (s1 >> 18) ); }
php_mt_reloadã¯ãåæåäžããã³php_mt_randã624ååŒã³åºããåŸã«åŒã³åºãããããšã«æ°ä»ããããããŸããã æåŸãããããã³ã°ãå§ããŸããããphp_mt_randïŒïŒé¢æ°ã®æåŸã§å€æãéã«ããŸãã ïŒs1 ^ïŒs1 >> 18ïŒïŒãæ€èšããŠãã ããã ãã€ããªè¡šçŸã§ã¯ãæäœã¯æ¬¡ã®ããã«ãªããŸãã
101101110101111001 11111001110010 s1
00000000000000000010110111010111100111111001110010 s1 >> 18
101101110101111001 01001110100101 s1 ^ïŒs1 >> 18ïŒ
æåã®18ãããïŒå€ªåã§åŒ·èª¿è¡šç€ºïŒã¯å€æŽãããŠããªãããšãããããŸãã
ãããã·ãããšxorãå転ããããã®2ã€ã®é¢æ°ãèšè¿°ããŸã
public static long unBitshiftRightXor(long value, long shift) { // we part of the value we are up to (with a width of shift bits) long i = 0; // we accumulate the result here long result = 0; // iterate until we've done the full 32 bits while (i * shift < 32) { // create a mask for this part long partMask = (-1 << (32 - shift)) >>> (shift * i); // obtain the part long part = value & partMask; // unapply the xor from the next part of the integer value ^= part >>> shift; // add the part to the result result |= part; i++; } return result; } public static long unBitshiftLeftXor(long value, long shift, long mask) { // we part of the value we are up to (with a width of shift bits) long i = 0; // we accumulate the result here long result = 0; // iterate until we've done the full 32 bits while (i * shift < 32) { // create a mask for this part long partMask = (-1 >>> (32 - shift)) << (shift * i); // obtain the part long part = value & partMask; // unapply the xor from the next part of the integer value ^= (part << shift) & mask; // add the part to the result result |= part; i++; } return result; }
php_mt_randïŒïŒé¢æ°ã®æåŸã®è¡ãå転ããã³ãŒãã¯æ¬¡ã®ããã«ãªããŸã
long value = output; value = unBitshiftRightXor(value, 18); value = unBitshiftLeftXor(value, 15, 0xefc60000); value = unBitshiftLeftXor(value, 7, 0x9d2c5680); value = unBitshiftRightXor(value, 11);
Mersenne Twisterã§çæããã624åã®é£ç¶çªå·ãããããããã®é£ç¶çªå·ã«ãã®ã¢ã«ãŽãªãºã ãé©çšãããšãMersenne Twisterã®å®å šãªç¶æ ãåŸãããŸããæ¢ç¥ã®å€ã®ã»ããã«å¯ŸããŠphp_mt_reloadãå®è¡ããããšã§ãåŸç¶ã®åå€ãç°¡åã«æ±ºå®ã§ããŸãã
ãããã³ã°ãšãªã¢
å£ãããã®ã¯ãªããšæããªããããªãã¯æ·±ã誀解ãããŠããŸãã èå³æ·±ãåéã®1ã€ã¯ãAdobe Flashä¹±æ°ãžã§ãã¬ãŒã¿ãŒïŒAction Script 3.0ïŒã§ãã ãã®ç¹åŸŽã¯ãã¯ããŒãºããœãŒã¹ã³ãŒããšã·ãŒãã¿ã¹ã¯ã®æ¬ åŠã§ãã äž»ãªé¢å¿ã¯ãå€ãã®ãªã³ã©ã€ã³ã«ãžããšãªã³ã©ã€ã³ããŒã«ãŒã§ã®äœ¿çšã§ãã
ãã«ã®çºæ¿ã¬ãŒãããæ¯æ¥ã®ãã©ãã£ãã¯ã«è²»ããããæéãŸã§ãæ°åã®ã·ãŒã±ã³ã¹ã¯å€æ°ãããŸãã ãããŠããã®ãããªããŒã¿ã§ãã¿ãŒã³ãèŠã€ããããšã¯ç°¡åãªäœæ¥ã§ã¯ãããŸããã
æ¬äŒŒä¹±æ°ãžã§ãã¬ãŒã¿ãŒã®ååžã®èšå®
ä»»æã®ã©ã³ãã å€æ°ã«å¯ŸããŠãååžãæå®ã§ããŸãã äŸãã°ã«ãŒãã䜿ã£ãŠç§»åãããšããšãŒã¹ã9ãããé »ç¹ã«èœãšãããšãã§ããŸãã 以äžã¯ãäžè§ååžãšææ°ååžã®äŸã§ãã
äžè§ååž
C99ã®èšèªã§äžè§ååžã®ç¢ºçå€æ°ãçæããäŸã瀺ããŸã[7] ã
double triangular(double a, double b, double c) { double U = rand() / (double) RAND_MAX; double F = (c - a) / (b - a); if (U <= F) return a + sqrt(U * (b - a) * (c - a)); else return b - sqrt((1 - U) * (b - a) * (b - c)); }
ãã®å Žåãã©ã³ãã å€æ°randïŒïŒãåããäžè§ååžé¢æ°ã«åºã¥ããŠååžãèšå®ããŸãã ãã©ã¡ãŒã¿ãŒa = -40ãb = 100ãc = 50ã®å Žåã10,000,000枬å®ã®ã°ã©ãã¯æ¬¡ã®ããã«ãªããŸãã

ææ°ååž
ææ°é¢æ°çã«ååžããã©ã³ãã å€æ°ã®ã»ã³ãµãŒãååŸãããšããŸãã ãã®å ŽåãFïŒxïŒ= 1-expïŒ-lambda * xïŒã 次ã«ãæ¹çšåŒy = 1-expïŒ-lambda * xïŒã®è§£ãããx = -logïŒ1-yïŒ/ lambdaãååŸããŸãã
æåŸã®åŒã®å¯Ÿæ°ã®äžã®åŒã¯ãéé[0,1ïŒã§åäžãªååžãæã£ãŠããããšã«æ°ä»ãããšãã§ããŸããããã«ããã次ã®åŒã«åŸã£ãŠå¥ã®åæ£ã·ãŒã±ã³ã¹ãååŸã§ããŸããx = -logïŒyïŒ/ lambda ïŒã©ã³ãïŒïŒïŒã
PRNGãã¹ã
äžéšã®éçºè ã¯ã䜿çšããçææ¹æ³ãé ããããç¬èªã®æ¹æ³ãèãåºããå Žåãããã§ä¿è·ã«ååã§ãããšèããŠããŸãã ããã¯éåžžã«äžè¬çãªèª€è§£ã§ãã æ°åã®ã·ãŒã±ã³ã¹å ã®äŸåé¢ä¿ãèŠã€ããããã®ç¹å¥ãªæ¹æ³ãšææ³ãããããšã«æ³šæããŠãã ããã
ããç¥ãããŠãããã¹ãã®1ã€ã¯ã次ã®ãããã®ãã¹ãã§ããããã¯ãæå·åŒ·åºŠã«ã€ããŠæ¬äŒŒä¹±æ°ãžã§ãã¬ãŒã¿ãŒããã§ãã¯ãããã¹ãã§ãã ãã®ãã¹ãã§ã¯ãã©ã³ãã ã·ãŒã±ã³ã¹ã®æåã®kããããç¥ã£ãŠããã°ã1/2ããã倧ãã確çã§k + 1ããããäºæž¬ã§ããå€é åŒã¢ã«ãŽãªãºã ã䜿çšããªãã§ãã ããã
æå·çè«ã§ã¯ãå¥ã®åé¡ã¯ããžã§ãã¬ãŒã¿ãŒã«ãã£ãŠçæãããæ°åãŸãã¯ãããã®ã·ãŒã±ã³ã¹ãã©ããããã©ã³ãã ã§ãããã決å®ããããšã§ãã éåžžããã®ç®çã®ããã«ãDIEHARDãNISTãªã©ã®ããŸããŸãªçµ±èšãã¹ãã䜿çšãããŸãã 1982幎ã®Andrew Yaoã¯ãã次ã®ããããã¹ããã«åæ Œãããžã§ãã¬ãŒã¿ãŒããå€é åŒæéã§å®äºã§ããä»ã®ã©ã³ãã ã©ã³ãã çµ±èšãã¹ãã«åæ Œããããšã蚌æããŸããã
ã€ã³ã¿ãŒããã[10]㧠ãDIEHARDãã¹ãããã³ä»ã®å€ãã®ãã¹ãã«åæ ŒããŠãã¢ã«ãŽãªãºã ã®é倧ãªèæ§ãå€æã§ããŸãã
æ¢ç¥ã®ä¹±æ°ãžã§ãã¬ãŒã¿ãŒã®ãããã³ã°
- ãšã³ããããŒã®äœãåæã®Netscape SSLæå·åãããã³ã«[11]
- PHP ã»ãã·ã§ã³ã®è匱æ§habrahabr.ru/company/pt/blog/149746
- ãã€ã¯ããœããCryptGenRandom [12]
- å€ãã®ãªã³ã©ã€ã³ã«ãžãã¯ãPRNGã®è匱æ§ãéããŠè€æ°åæšçã«ãããŠããŸãã
åç §è³æ
[1] Donald Knuthãããã°ã©ãã³ã°ã®æè¡ïŒç¬¬2å·»ïŒæŽŸçã¢ã«ãŽãªãºã ïŒ
[2] Bruce SchneierãApplied CryptographyïŒç¬¬16ç« ïŒ
[4] www.staff.uni-mainz.de/pommeren/Kryptologie/Bitstrom/2_Analyse/LCGcrack.html
[5] www.staff.uni-mainz.de/pommeren/Kryptologie99/English.html
[6] en.wikipedia.org/wiki/Mersenne_twister
[7] en.wikipedia.org/wiki/Triangular_distribution
[8] en.wikipedia.org/wiki/Linear_Congruent_Method
[9] zaic101.ru/files/728/using_linear_congruential_generators_for_cryptographic_purposes.pdf
[10] www.cacert.at/random
[11] www.cs.berkeley.edu/~daw/papers/ddj-netscape.html
[12] www.computerworld.com/s/article/9048438/Microsoft_confirms_that_XP_contains_random_number_generator_bug
[13] md5 raz0r.name/articles/magiya-sluchajnyx-chisel-chast-2/comment-page-1ãä»ããçæã®èå³æ·±ãäŸã説æãããŠããŸã
ãªãªãžãã«
jazzy.id.au/default/2010/09/20/cracking_random_number_generators_part_1.html
jazzy.id.au/default/2010/09/21/cracking_random_number_generators_part_2.html
jazzy.id.au/default/2010/09/22/cracking_random_number_generators_part_3.html
jazzy.id.au/default/2010/09/25/cracking_random_number_generators_part_4.html