initial checkin
authorClaus Gittinger <cg@exept.de>
Thu, 02 Oct 2014 17:17:58 +0200
changeset 3405 84393adea27c
parent 3404 fc09f433085c
child 3406 d58490ddc83e
initial checkin
RandomRDRand.st
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RandomRDRand.st	Thu Oct 02 17:17:58 2014 +0200
@@ -0,0 +1,133 @@
+"{ Package: 'stx:libbasic2' }"
+
+Object subclass:#RandomRDRand
+	instanceVariableNames:'x y z c'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Magnitude-Numbers'
+!
+
+!RandomRDRand class methodsFor:'documentation'!
+
+documentation
+"
+    Warning: there have been discussions about the security of the intel rdgen instruction
+    and whether there are NSA backdoors built into it.
+    Linus Torwalds refuses to use it for /dev/urandom in the linux kernel, for that very reason.
+    Be sure you know what you are doing, if you use this generator for sensitive cryptographic stuff.
+    We recommend using one of the libcrypt-based generators and use this only to get additional
+    entropy for the seed.
+
+    NO WARRANTY
+
+    This generator uses the rdgen random generator which is built into modern intel chips.
+    Before using, you should check via the isSupported query.
+
+    RandomRDGen new nextInteger
+
+    [see also:]
+        RandomGenerator - the default; uses the machine's /dev/random if available
+        Random  - fast, but generates less quality random numbers
+        RandomTT800 - another random generator
+        RandomParkMiller - another random generator
+        RandomMT19937 - another random generator
+        RandomKISS - another random generator
+        exept:libcrypt - a library containing more stuff based on hashes and cyphers
+
+    [author:]
+        Claus Gittinger.
+"
+! !
+
+!RandomRDRand class methodsFor:'instance creation'!
+
+new
+    self isSupported ifFalse:[ self error:'this generator needs a cpu with rdgen instruction' ].
+    ^ self basicNew 
+        initialize
+!
+
+new:seed
+    "seed is actualy ignored"
+
+    self isSupported ifFalse:[ self error:'this generator needs a cpu with rdgen instruction' ].
+    ^ self basicNew 
+        initialize;
+        seed:seed
+! !
+
+!RandomRDRand class methodsFor:'queries'!
+
+isSupported
+    "true if this architecture supports hardware random numbers"
+
+    ^ OperatingSystem getCPUType = 'x86_64'
+        and:[ (OperatingSystem getSystemInfo at:#extendedInstructions ifAbsent:#())
+              includes:#aes ]
+
+    "
+     self isSupported
+    "
+! !
+
+!RandomRDRand methodsFor:'initialization'!
+
+initialize
+!
+
+seed:seed
+    "/ ignored
+! !
+
+!RandomRDRand methodsFor:'random numbers'!
+
+nextBoolean
+    "generates the next integer in 0..FFFFFFFF"
+
+    ^ self nextInteger > 16r7FFFFFFF
+!
+
+nextInteger
+    "generates the next integer in 0..FFFFFFFF.
+     Notice, it may raise an illegal instruction exception on some cpu chips,
+     even though the cpuid instruction says that it is available"
+
+%{
+    unsigned int r = 0;
+    int cf;
+
+    do {
+#if defined(__i386__) && defined(__GNUC__) && (__GNUC__ >= 2)
+        // Encoding of rdrand %eax
+        asm(".byte 0x0F, 0xC7, 0xF0; adcl $0,%1" :
+            "=a" (r), "=r" (cf) : "0" (r), "1" (cf) : "cc");
+
+#else
+# ifdef USE_DRAND32
+        cf = _rdrand32_step(&r);
+# else
+        goto unsupported;
+# endif
+#endif
+    } while (cf != 0);
+    RETURN (__MKUINT(r));
+
+unsupported: ;
+%}.
+    self primitiveFailed:'unsupported on this architecture'
+
+    "
+     self new nextInteger
+    "
+! !
+
+!RandomRDRand class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/libbasic2/RandomRDRand.st,v 1.1 2014-10-02 15:17:58 cg Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/libbasic2/RandomRDRand.st,v 1.1 2014-10-02 15:17:58 cg Exp $'
+! !
+