randomread(void *p, ulong n)
{
Chachastate c;
- ulong b;
if(n == 0)
return 0;
if(hwrandbuf != nil)
(*hwrandbuf)(p, n);
- /* copy chacha state and advance block counter */
+ /* copy chacha state, rekey and increment iv */
qlock(rs);
c = *rs;
- b = rs->input[12];
- rs->input[12] += (n + ChachaBsize-1)/ChachaBsize;
- if(rs->input[12] < b) rs->input[13]++;
+ chacha_encrypt((uchar*)&rs->input[4], 32, &c);
+ if(++rs->input[13] == 0)
+ if(++rs->input[14] == 0)
+ ++rs->input[15];
qunlock(rs);
/* encrypt the buffer, can fault */
{
randomread(p, n);
}
+
+/* used by rand(),nrand() */
+long
+lrand(void)
+{
+ /* xoroshiro128+ algorithm */
+ static int seeded = 0;
+ static uvlong s[2];
+ static Lock lk;
+ ulong r;
+
+ if(seeded == 0){
+ randomread(s, sizeof(s));
+ seeded = (s[0] | s[1]) != 0;
+ }
+
+ lock(&lk);
+ r = (s[0] + s[1]) >> 33;
+ s[1] ^= s[0];
+ s[0] = (s[0] << 55 | s[0] >> 9) ^ s[1] ^ (s[1] << 14);
+ s[1] = (s[1] << 36 | s[1] >> 28);
+ unlock(&lk);
+
+ return r;
+}