diff options
| author | Indrajith K L | 2022-12-03 17:00:20 +0530 | 
|---|---|---|
| committer | Indrajith K L | 2022-12-03 17:00:20 +0530 | 
| commit | f5c4671bfbad96bf346bd7e9a21fc4317b4959df (patch) | |
| tree | 2764fc62da58f2ba8da7ed341643fc359873142f /v_windows/v/old/vlib/crypto/rand | |
| download | cli-tools-windows-f5c4671bfbad96bf346bd7e9a21fc4317b4959df.tar.gz cli-tools-windows-f5c4671bfbad96bf346bd7e9a21fc4317b4959df.tar.bz2 cli-tools-windows-f5c4671bfbad96bf346bd7e9a21fc4317b4959df.zip  | |
Diffstat (limited to 'v_windows/v/old/vlib/crypto/rand')
| -rw-r--r-- | v_windows/v/old/vlib/crypto/rand/crypto_rand_read_test.v | 15 | ||||
| -rw-r--r-- | v_windows/v/old/vlib/crypto/rand/rand.v | 10 | ||||
| -rw-r--r-- | v_windows/v/old/vlib/crypto/rand/rand_darwin.c.v | 21 | ||||
| -rw-r--r-- | v_windows/v/old/vlib/crypto/rand/rand_default.c.v | 9 | ||||
| -rw-r--r-- | v_windows/v/old/vlib/crypto/rand/rand_linux.c.v | 39 | ||||
| -rw-r--r-- | v_windows/v/old/vlib/crypto/rand/rand_solaris.c.v | 42 | ||||
| -rw-r--r-- | v_windows/v/old/vlib/crypto/rand/rand_windows.c.v | 25 | ||||
| -rw-r--r-- | v_windows/v/old/vlib/crypto/rand/utils.v | 55 | 
8 files changed, 216 insertions, 0 deletions
diff --git a/v_windows/v/old/vlib/crypto/rand/crypto_rand_read_test.v b/v_windows/v/old/vlib/crypto/rand/crypto_rand_read_test.v new file mode 100644 index 0000000..824923d --- /dev/null +++ b/v_windows/v/old/vlib/crypto/rand/crypto_rand_read_test.v @@ -0,0 +1,15 @@ +import crypto.rand + +fn test_reading() ? { +	a := rand.read(32) ? +	// dump(a.hex()) +	assert a.len == 32 +	mut histogram := [256]int{} +	for b in a { +		histogram[b]++ +	} +	// dump(histogram) +	for h in histogram { +		assert h < 10 +	} +} diff --git a/v_windows/v/old/vlib/crypto/rand/rand.v b/v_windows/v/old/vlib/crypto/rand/rand.v new file mode 100644 index 0000000..0703558 --- /dev/null +++ b/v_windows/v/old/vlib/crypto/rand/rand.v @@ -0,0 +1,10 @@ +// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. + +module rand + +struct ReadError { +	msg  string = 'crypto.rand.read() error reading random bytes' +	code int +} diff --git a/v_windows/v/old/vlib/crypto/rand/rand_darwin.c.v b/v_windows/v/old/vlib/crypto/rand/rand_darwin.c.v new file mode 100644 index 0000000..a53198b --- /dev/null +++ b/v_windows/v/old/vlib/crypto/rand/rand_darwin.c.v @@ -0,0 +1,21 @@ +// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. + +module rand + +#include <Security/SecRandom.h> + +#flag darwin -framework Security + +fn C.SecRandomCopyBytes(rnd C.SecRandomRef, count size_t, bytes voidptr) int + +// read returns an array of `bytes_needed` random bytes read from the OS. +pub fn read(bytes_needed int) ?[]byte { +	mut buffer := []byte{len: bytes_needed} +	status := C.SecRandomCopyBytes(C.SecRandomRef(0), bytes_needed, buffer.data) +	if status != 0 { +		return IError(&ReadError{}) +	} +	return buffer +} diff --git a/v_windows/v/old/vlib/crypto/rand/rand_default.c.v b/v_windows/v/old/vlib/crypto/rand/rand_default.c.v new file mode 100644 index 0000000..2e1e823 --- /dev/null +++ b/v_windows/v/old/vlib/crypto/rand/rand_default.c.v @@ -0,0 +1,9 @@ +// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. +module rand + +// read returns an array of `bytes_needed` random bytes read from the OS. +pub fn read(bytes_needed int) ?[]byte { +	return error('rand.read is not implemented on this platform') +} diff --git a/v_windows/v/old/vlib/crypto/rand/rand_linux.c.v b/v_windows/v/old/vlib/crypto/rand/rand_linux.c.v new file mode 100644 index 0000000..52ff3da --- /dev/null +++ b/v_windows/v/old/vlib/crypto/rand/rand_linux.c.v @@ -0,0 +1,39 @@ +// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. +module rand + +#include <sys/syscall.h> + +const ( +	read_batch_size = 256 +) + +// read returns an array of `bytes_needed` random bytes read from the OS. +pub fn read(bytes_needed int) ?[]byte { +	mut buffer := unsafe { malloc_noscan(bytes_needed) } +	mut bytes_read := 0 +	mut remaining_bytes := bytes_needed +	// getrandom syscall wont block if requesting <= 256 bytes +	for bytes_read < bytes_needed { +		batch_size := if remaining_bytes > rand.read_batch_size { +			rand.read_batch_size +		} else { +			remaining_bytes +		} +		rbytes := unsafe { getrandom(batch_size, buffer + bytes_read) } +		if rbytes == -1 { +			unsafe { free(buffer) } +			return IError(&ReadError{}) +		} +		bytes_read += rbytes +	} +	return unsafe { buffer.vbytes(bytes_needed) } +} + +fn getrandom(bytes_needed int, buffer voidptr) int { +	if bytes_needed > rand.read_batch_size { +		panic('getrandom() dont request more than $rand.read_batch_size bytes at once.') +	} +	return unsafe { C.syscall(C.SYS_getrandom, buffer, bytes_needed, 0) } +} diff --git a/v_windows/v/old/vlib/crypto/rand/rand_solaris.c.v b/v_windows/v/old/vlib/crypto/rand/rand_solaris.c.v new file mode 100644 index 0000000..8d0ba0c --- /dev/null +++ b/v_windows/v/old/vlib/crypto/rand/rand_solaris.c.v @@ -0,0 +1,42 @@ +// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. + +module rand + +#include <sys/random.h> + +fn C.getrandom(p &byte, n size_t, flags u32) int + +const ( +	read_batch_size = 256 +) + +// read returns an array of `bytes_needed` random bytes read from the OS. +pub fn read(bytes_needed int) ?[]byte { +	mut buffer := unsafe { malloc_noscan(bytes_needed) } +	mut bytes_read := 0 +	mut remaining_bytes := bytes_needed +	// getrandom syscall wont block if requesting <= 256 bytes +	for bytes_read < bytes_needed { +		batch_size := if remaining_bytes > rand.read_batch_size { +			rand.read_batch_size +		} else { +			remaining_bytes +		} +		rbytes := unsafe { getrandom(batch_size, buffer + bytes_read) } +		if rbytes == -1 { +			unsafe { free(buffer) } +			return IError(&ReadError{}) +		} +		bytes_read += rbytes +	} +	return unsafe { buffer.vbytes(bytes_needed) } +} + +fn v_getrandom(bytes_needed int, buffer voidptr) int { +	if bytes_needed > rand.read_batch_size { +		panic('getrandom() dont request more than $rand.read_batch_size bytes at once.') +	} +	return C.getrandom(buffer, bytes_needed, 0) +} diff --git a/v_windows/v/old/vlib/crypto/rand/rand_windows.c.v b/v_windows/v/old/vlib/crypto/rand/rand_windows.c.v new file mode 100644 index 0000000..075a3ed --- /dev/null +++ b/v_windows/v/old/vlib/crypto/rand/rand_windows.c.v @@ -0,0 +1,25 @@ +// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. + +module rand + +#flag windows -Llibraries/bcrypt +#flag windows -lbcrypt +#include <bcrypt.h> + +const ( +	status_success                  = 0x00000000 +	bcrypt_use_system_preferred_rng = 0x00000002 +) + +// read returns an array of `bytes_needed` random bytes read from the OS. +pub fn read(bytes_needed int) ?[]byte { +	mut buffer := []byte{len: bytes_needed} +	// use bcrypt_use_system_preferred_rng because we passed null as algo +	status := C.BCryptGenRandom(0, buffer.data, bytes_needed, rand.bcrypt_use_system_preferred_rng) +	if status != rand.status_success { +		return IError(&ReadError{}) +	} +	return buffer +} diff --git a/v_windows/v/old/vlib/crypto/rand/utils.v b/v_windows/v/old/vlib/crypto/rand/utils.v new file mode 100644 index 0000000..31eaf2d --- /dev/null +++ b/v_windows/v/old/vlib/crypto/rand/utils.v @@ -0,0 +1,55 @@ +// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. + +module rand + +import math.bits +import encoding.binary + +// int_u64 returns a random unsigned 64-bit integer `u64` read from a real OS source of entropy. +pub fn int_u64(max u64) ?u64 { +	bitlen := bits.len_64(max) +	if bitlen == 0 { +		return u64(0) +	} +	k := (bitlen + 7) / 8 +	mut b := u64(bitlen % 8) +	if b == u64(0) { +		b = u64(8) +	} +	mut n := u64(0) +	for { +		mut bytes := read(k) ? +		bytes[0] &= byte(int(u64(1) << b) - 1) +		x := bytes_to_u64(bytes) +		n = x[0] +		// NOTE: maybe until we have bigint could do it another way? +		// if x.len > 1 { +		// 	n = u64(u32(x[1])<<u32(32)) | n +		// } +		if n < max { +			return n +		} +	} +	return n +} + +fn bytes_to_u64(b []byte) []u64 { +	ws := 64 / 8 +	mut z := []u64{len: ((b.len + ws - 1) / ws)} +	mut i := b.len +	for k := 0; i >= ws; k++ { +		z[k] = binary.big_endian_u64(b[i - ws..i]) +		i -= ws +	} +	if i > 0 { +		mut d := u64(0) +		for s := u64(0); i > 0; s += u64(8) { +			d |= u64(b[i - 1]) << s +			i-- +		} +		z[z.len - 1] = d +	} +	return z +}  | 
