aboutsummaryrefslogtreecommitdiff
path: root/lib/random
diff options
context:
space:
mode:
Diffstat (limited to 'lib/random')
-rw-r--r--lib/random/random.tm46
1 files changed, 23 insertions, 23 deletions
diff --git a/lib/random/random.tm b/lib/random/random.tm
index 107fad66..6d639c3a 100644
--- a/lib/random/random.tm
+++ b/lib/random/random.tm
@@ -6,7 +6,7 @@ use ./chacha.h
struct chacha_ctx(j0,j1,j2,j3,j4,j5,j6,j7,j8,j9,j10,j11,j12,j13,j14,j15:Int32; extern, secret)
func from_seed(seed:[Byte]=[] -> chacha_ctx)
- return C_code:chacha_ctx(
+ return C_code:chacha_ctx `
chacha_ctx ctx;
uint8_t seed_bytes[KEYSZ + IVSZ] = {};
for (int64_t i = 0; i < (int64_t)sizeof(seed_bytes); i++)
@@ -14,23 +14,24 @@ struct chacha_ctx(j0,j1,j2,j3,j4,j5,j6,j7,j8,j9,j10,j11,j12,j13,j14,j15:Int32; e
chacha_keysetup(&ctx, seed_bytes);
chacha_ivsetup(&ctx, seed_bytes + KEYSZ);
ctx
- )
+ `
random := RandomNumberGenerator.new()
func _os_random_bytes(count:Int64 -> [Byte])
- return C_code:[Byte](
+ return C_code:[Byte] `
uint8_t *random_bytes = GC_MALLOC_ATOMIC(@count);
assert(getrandom(random_bytes, (size_t)@count, 0) == (size_t)@count);
(List_t){.length=@count, .data=random_bytes, .stride=1, .atomic=1}
- )
+ `
+
struct RandomNumberGenerator(_chacha:chacha_ctx, _random_bytes:[Byte]=[]; secret)
func new(seed:[Byte]?=none, -> @RandomNumberGenerator)
ctx := chacha_ctx.from_seed(seed or _os_random_bytes(40))
return @RandomNumberGenerator(ctx, [])
func _rekey(rng:&RandomNumberGenerator)
- rng._random_bytes = C_code:[Byte](
+ rng._random_bytes = C_code:[Byte] `
Byte_t new_keystream[KEYSZ + IVSZ] = {};
// Fill the buffer with the keystream
chacha_encrypt_bytes(&@rng->_chacha, new_keystream, new_keystream, sizeof(new_keystream));
@@ -41,10 +42,10 @@ struct RandomNumberGenerator(_chacha:chacha_ctx, _random_bytes:[Byte]=[]; secret
memset(new_bytes.data, 0, new_bytes.length);
chacha_encrypt_bytes(&@rng->_chacha, new_bytes.data, new_bytes.data, new_bytes.length);
new_bytes
- )
+ `
func _fill_bytes(rng:&RandomNumberGenerator, dest:&Memory, needed:Int64)
- C_code {
+ C_code `
while (@needed > 0) {
if (@rng->_random_bytes.length == 0)
@(rng._rekey());
@@ -60,13 +61,13 @@ struct RandomNumberGenerator(_chacha:chacha_ctx, _random_bytes:[Byte]=[]; secret
@dest += batch_size;
@needed -= batch_size;
}
- }
+ `
func bytes(rng:&RandomNumberGenerator, count:Int -> [Byte])
count64 := Int64(count)
- buf := C_code:@Memory(GC_MALLOC_ATOMIC(@count64))
+ buf := C_code:@Memory `GC_MALLOC_ATOMIC(@count64)`
rng._fill_bytes(buf, count64)
- return C_code:[Byte]((List_t){.data=@buf, .stride=1, .atomic=1, .length=@count64})
+ return C_code:[Byte] `(List_t){.data=@buf, .stride=1, .atomic=1, .length=@count64}`
func byte(rng:&RandomNumberGenerator -> Byte)
byte : &Byte
@@ -87,7 +88,7 @@ struct RandomNumberGenerator(_chacha:chacha_ctx, _random_bytes:[Byte]=[]; secret
if min == Int64.min and max == Int64.max
return random_int64
- return C_code:Int64(
+ return C_code:Int64 `
uint64_t range = (uint64_t)@max - (uint64_t)@min + 1;
uint64_t min_r = -range % range;
uint64_t r;
@@ -97,7 +98,7 @@ struct RandomNumberGenerator(_chacha:chacha_ctx, _random_bytes:[Byte]=[]; secret
if (r >= min_r) break;
}
(int64_t)((uint64_t)@min + (r % range))
- )
+ `
func int32(rng:&RandomNumberGenerator, min=Int32.min, max=Int32.max -> Int32)
fail("Random minimum value $min is larger than the maximum value $max") if min > max
@@ -107,7 +108,7 @@ struct RandomNumberGenerator(_chacha:chacha_ctx, _random_bytes:[Byte]=[]; secret
if min == Int32.min and max == Int32.max
return random_int32
- return C_code:Int32(
+ return C_code:Int32 `
uint32_t range = (uint32_t)@max - (uint32_t)@min + 1;
uint32_t min_r = -range % range;
uint32_t r;
@@ -117,7 +118,7 @@ struct RandomNumberGenerator(_chacha:chacha_ctx, _random_bytes:[Byte]=[]; secret
if (r >= min_r) break;
}
(int32_t)((uint32_t)@min + (r % range))
- )
+ `
func int16(rng:&RandomNumberGenerator, min=Int16.min, max=Int16.max -> Int16)
fail("Random minimum value $min is larger than the maximum value $max") if min > max
@@ -127,7 +128,7 @@ struct RandomNumberGenerator(_chacha:chacha_ctx, _random_bytes:[Byte]=[]; secret
if min == Int16.min and max == Int16.max
return random_int16
- return C_code:Int16(
+ return C_code:Int16 `
uint16_t range = (uint16_t)@max - (uint16_t)@min + 1;
uint16_t min_r = -range % range;
uint16_t r;
@@ -137,7 +138,7 @@ struct RandomNumberGenerator(_chacha:chacha_ctx, _random_bytes:[Byte]=[]; secret
if (r >= min_r) break;
}
(int16_t)((uint16_t)@min + (r % range))
- )
+ `
func int8(rng:&RandomNumberGenerator, min=Int8.min, max=Int8.max -> Int8)
fail("Random minimum value $min is larger than the maximum value $max") if min > max
@@ -147,7 +148,7 @@ struct RandomNumberGenerator(_chacha:chacha_ctx, _random_bytes:[Byte]=[]; secret
if min == Int8.min and max == Int8.max
return random_int8
- return C_code:Int8(
+ return C_code:Int8 `
uint8_t range = (uint8_t)@max - (uint8_t)@min + 1;
uint8_t min_r = -range % range;
uint8_t r;
@@ -157,11 +158,11 @@ struct RandomNumberGenerator(_chacha:chacha_ctx, _random_bytes:[Byte]=[]; secret
if (r >= min_r) break;
}
(int8_t)((uint8_t)@min + (r % range))
- )
+ `
func num(rng:&RandomNumberGenerator, min=0., max=1. -> Num)
num_buf : &Num
- return C_code:Num(
+ return C_code:Num `
if (@min > @max) fail("Random minimum value (", @min, ") is larger than the maximum value (", @max, ")");
if (@min == @max) return @min;
@@ -179,13 +180,13 @@ struct RandomNumberGenerator(_chacha:chacha_ctx, _random_bytes:[Byte]=[]; secret
r.num -= 1.0;
(@min == 0.0 && @max == 1.0) ? r.num : ((1.0-r.num)*@min + r.num*@max)
- )
+ `
func num32(rng:&RandomNumberGenerator, min=Num32(0.), max=Num32(1.) -> Num32)
return Num32(rng.num(Num(min), Num(max)))
func int(rng:&RandomNumberGenerator, min:Int, max:Int -> Int)
- return C_code:Int(
+ return C_code:Int `
if (likely(((@min.small & @max.small) & 1) != 0)) {
int32_t r = @(rng.int32(Int32(min), Int32(max)));
return I_small(r);
@@ -217,8 +218,7 @@ struct RandomNumberGenerator(_chacha:chacha_ctx, _random_bytes:[Byte]=[]; secret
gmp_randclear(gmp_rng);
Int$plus(@min, Int$from_mpz(r))
- )
-
+ `
func main()
>> rng := RandomNumberGenerator.new()