1 module random;
2 
3 import std.exception;
4 
5 public class ScryptRNGException : Exception
6 {
7     this(string message) {super(message);}
8 }
9 
10 ubyte[] scryptRNG(uint len) {
11 	if (len == 0) {
12 		throw new ScryptRNGException
13             ("RNG requested length must be greater than zero!");
14 	}
15 
16 	ubyte[] ret = new ubyte[len];
17 
18 	version(Posix)
19 	{
20         import std.stdio;
21 		import std.exception;
22 		import std.format;
23 
24 		try {
25 			File dev_random = File("/dev/urandom", "rb");
26 			dev_random.setvbuf(null, _IONBF);
27 
28 			try {
29 				ret = dev_random.rawRead(ret);
30 			} catch(ErrnoException errno) {
31 				throw new ScryptRNGException(
32                     format( "Could not read from /dev/urandom. "~
33                             "ERRNO: %d, Message: %s", errno.errno, errno.msg));
34 			} catch(Exception ex) {
35 				throw new ScryptRNGException(
36                     format( "Could not read from /dev/urandom. "~
37                             "Message: %s",ex.msg));
38 			} finally {
39                 dev_random.close();
40             }
41 		}
42 		catch(ErrnoException errno) {
43 			throw new ScryptRNGException(
44                 format( "Could not open /dev/urandom. "~
45                         "ERRNO: %d, Message: %s", errno.errno, errno.msg));
46 		} catch(Exception ex) {
47 			throw new ScryptRNGException(
48                 format( "Could not open /dev/urandom. "~ 
49                          "Message: %s", ex.msg));
50 		}
51 	} else {
52 		static assert(0, "OS is not supported by scrypt.");
53 	}
54 
55 	return ret;
56 }
57 
58 unittest {
59     import std.stdio;
60     import std.conv;
61 
62     writeln("+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=");
63     writeln("+ Test scryptRNG(32)");
64     writeln("+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=");
65     ubyte[] rn1 = scryptRNG(32);
66     ubyte[] rn2 = scryptRNG(32);
67     writeln("*** > rn1: " ~ to!string(rn1));
68     writeln("*** > rn2: " ~ to!string(rn2));
69 
70 
71     assert((rn1 != rn2) is true);
72     writeln("*** > passed");
73 }