aboutsummaryrefslogtreecommitdiff
path: root/core/crypto
diff options
context:
space:
mode:
authorYawning Angel <yawning@schwanenlied.me>2025-01-18 13:51:04 +0900
committerYawning Angel <yawning@schwanenlied.me>2025-03-23 19:14:33 +0900
commit2f301e46dc21e6a4660ac669a5ffb20e2f2297dd (patch)
tree49a763346409bf72515b0e1638f66ba3f2e52ac2 /core/crypto
parentdc94452fb99c889df78e992b59540032a2be6e15 (diff)
core/crypto: Switch to using `ensure`
Diffstat (limited to 'core/crypto')
-rw-r--r--core/crypto/_aes/ct64/ct64_enc.odin4
-rw-r--r--core/crypto/_aes/ct64/ct64_keysched.odin4
-rw-r--r--core/crypto/_aes/ct64/ghash.odin5
-rw-r--r--core/crypto/_aes/ct64/helpers.odin24
-rw-r--r--core/crypto/_blake2/blake2.odin28
-rw-r--r--core/crypto/_chacha20/chacha20.odin25
-rw-r--r--core/crypto/_edwards25519/edwards25519.odin8
-rw-r--r--core/crypto/_edwards25519/edwards25519_scalar.odin8
-rw-r--r--core/crypto/_fiat/field_poly1305/field.odin4
-rw-r--r--core/crypto/_fiat/field_scalar25519/field.odin9
-rw-r--r--core/crypto/_sha3/sha3.odin33
-rw-r--r--core/crypto/_sha3/sp800_185.odin20
-rw-r--r--core/crypto/aead/low_level.odin12
-rw-r--r--core/crypto/aes/aes_ctr.odin12
-rw-r--r--core/crypto/aes/aes_ecb.odin16
-rw-r--r--core/crypto/aes/aes_gcm.odin36
-rw-r--r--core/crypto/aes/aes_gcm_hw_intel.odin2
-rw-r--r--core/crypto/blake2b/blake2b.odin5
-rw-r--r--core/crypto/blake2s/blake2s.odin5
-rw-r--r--core/crypto/chacha20/chacha20.odin16
-rw-r--r--core/crypto/chacha20poly1305/chacha20poly1305.odin28
-rw-r--r--core/crypto/deoxysii/deoxysii.odin33
-rw-r--r--core/crypto/ed25519/ed25519.odin32
-rw-r--r--core/crypto/hmac/hmac.odin13
-rw-r--r--core/crypto/kmac/kmac.odin12
-rw-r--r--core/crypto/legacy/keccak/keccak.odin18
-rw-r--r--core/crypto/legacy/md5/md5.odin9
-rw-r--r--core/crypto/legacy/sha1/sha1.odin9
-rw-r--r--core/crypto/poly1305/poly1305.odin12
-rw-r--r--core/crypto/ristretto255/ristretto255.odin38
-rw-r--r--core/crypto/ristretto255/ristretto255_scalar.odin8
-rw-r--r--core/crypto/sha2/sha2.odin11
-rw-r--r--core/crypto/siphash/siphash.odin17
-rw-r--r--core/crypto/sm3/sm3.odin11
-rw-r--r--core/crypto/x25519/x25519.odin12
-rw-r--r--core/crypto/x448/x448.odin12
36 files changed, 188 insertions, 363 deletions
diff --git a/core/crypto/_aes/ct64/ct64_enc.odin b/core/crypto/_aes/ct64/ct64_enc.odin
index e099b3eaf..bee6de722 100644
--- a/core/crypto/_aes/ct64/ct64_enc.odin
+++ b/core/crypto/_aes/ct64/ct64_enc.odin
@@ -23,9 +23,7 @@
package aes_ct64
add_round_key :: proc "contextless" (q: ^[8]u64, sk: []u64) #no_bounds_check {
- if len(sk) < 8 {
- panic_contextless("aes/ct64: invalid round key size")
- }
+ ensure_contextless(len(sk) >= 8, "aes/ct64: invalid round key size")
q[0] ~= sk[0]
q[1] ~= sk[1]
diff --git a/core/crypto/_aes/ct64/ct64_keysched.odin b/core/crypto/_aes/ct64/ct64_keysched.odin
index 591bf53e6..0f00bba57 100644
--- a/core/crypto/_aes/ct64/ct64_keysched.odin
+++ b/core/crypto/_aes/ct64/ct64_keysched.odin
@@ -41,7 +41,7 @@ sub_word :: proc "contextless" (x: u32) -> u32 {
}
@(private, require_results)
-keysched :: proc(comp_skey: []u64, key: []byte) -> int {
+keysched :: proc "contextless" (comp_skey: []u64, key: []byte) -> int {
num_rounds, key_len := 0, len(key)
switch key_len {
case _aes.KEY_SIZE_128:
@@ -51,7 +51,7 @@ keysched :: proc(comp_skey: []u64, key: []byte) -> int {
case _aes.KEY_SIZE_256:
num_rounds = _aes.ROUNDS_256
case:
- panic("crypto/aes: invalid AES key size")
+ panic_contextless("crypto/aes: invalid AES key size")
}
skey: [60]u32 = ---
diff --git a/core/crypto/_aes/ct64/ghash.odin b/core/crypto/_aes/ct64/ghash.odin
index fe6e364fc..0c885d8ba 100644
--- a/core/crypto/_aes/ct64/ghash.odin
+++ b/core/crypto/_aes/ct64/ghash.odin
@@ -63,9 +63,8 @@ rev64 :: proc "contextless" (x: u64) -> u64 {
// Note: `dst` is both an input and an output, to support easy implementation
// of GCM.
ghash :: proc "contextless" (dst, key, data: []byte) {
- if len(dst) != _aes.GHASH_BLOCK_SIZE || len(key) != _aes.GHASH_BLOCK_SIZE {
- panic_contextless("aes/ghash: invalid dst or key size")
- }
+ ensure_contextless(len(dst) == _aes.GHASH_BLOCK_SIZE)
+ ensure_contextless(len(key) == _aes.GHASH_BLOCK_SIZE)
buf := data
l := len(buf)
diff --git a/core/crypto/_aes/ct64/helpers.odin b/core/crypto/_aes/ct64/helpers.odin
index b26817cb3..4f2d9800c 100644
--- a/core/crypto/_aes/ct64/helpers.odin
+++ b/core/crypto/_aes/ct64/helpers.odin
@@ -31,41 +31,31 @@ and_interleaved :: #force_inline proc "contextless" (a0, a1, b0, b1: u64) -> (u6
}
load_blockx1 :: proc "contextless" (q: ^[8]u64, src: []byte) {
- if len(src) != _aes.BLOCK_SIZE {
- panic_contextless("aes/ct64: invalid block size")
- }
+ ensure_contextless(len(src) == _aes.BLOCK_SIZE, "aes/ct64: invalid block size")
q[0], q[4] = #force_inline load_interleaved(src)
orthogonalize(q)
}
store_blockx1 :: proc "contextless" (dst: []byte, q: ^[8]u64) {
- if len(dst) != _aes.BLOCK_SIZE {
- panic_contextless("aes/ct64: invalid block size")
- }
+ ensure_contextless(len(dst) == _aes.BLOCK_SIZE, "aes/ct64: invalid block size")
orthogonalize(q)
#force_inline store_interleaved(dst, q[0], q[4])
}
load_blocks :: proc "contextless" (q: ^[8]u64, src: [][]byte) {
- if n := len(src); n > STRIDE || n == 0 {
- panic_contextless("aes/ct64: invalid block(s) size")
- }
+ ensure_contextless(len(src) == 0 || len(src) <= STRIDE, "aes/ct64: invalid block(s) size")
for s, i in src {
- if len(s) != _aes.BLOCK_SIZE {
- panic_contextless("aes/ct64: invalid block size")
- }
+ ensure_contextless(len(s) == _aes.BLOCK_SIZE, "aes/ct64: invalid block size")
q[i], q[i + 4] = #force_inline load_interleaved(s)
}
orthogonalize(q)
}
store_blocks :: proc "contextless" (dst: [][]byte, q: ^[8]u64) {
- if n := len(dst); n > STRIDE || n == 0 {
- panic_contextless("aes/ct64: invalid block(s) size")
- }
+ ensure_contextless(len(dst) == 0 || len(dst) <= STRIDE, "aes/ct64: invalid block(s) size")
orthogonalize(q)
for d, i in dst {
@@ -73,9 +63,7 @@ store_blocks :: proc "contextless" (dst: [][]byte, q: ^[8]u64) {
if d == nil {
break
}
- if len(d) != _aes.BLOCK_SIZE {
- panic_contextless("aes/ct64: invalid block size")
- }
+ ensure_contextless(len(d) == _aes.BLOCK_SIZE, "aes/ct64: invalid block size")
#force_inline store_interleaved(d, q[i], q[i + 4])
}
}
diff --git a/core/crypto/_blake2/blake2.odin b/core/crypto/_blake2/blake2.odin
index a012b7e70..89fbe3a7a 100644
--- a/core/crypto/_blake2/blake2.odin
+++ b/core/crypto/_blake2/blake2.odin
@@ -18,6 +18,8 @@ BLAKE2S_SIZE :: 32
BLAKE2B_BLOCK_SIZE :: 128
BLAKE2B_SIZE :: 64
+MAX_SIZE :: 255
+
Blake2s_Context :: struct {
h: [8]u32,
t: [2]u32,
@@ -82,16 +84,13 @@ BLAKE2B_IV := [8]u64 {
0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
}
-init :: proc(ctx: ^$T, cfg: ^Blake2_Config) {
+init :: proc "contextless" (ctx: ^$T, cfg: ^Blake2_Config) {
when T == Blake2s_Context {
max_size :: BLAKE2S_SIZE
} else when T == Blake2b_Context {
max_size :: BLAKE2B_SIZE
}
-
- if cfg.size > max_size {
- panic("blake2: requested output size exceeeds algorithm max")
- }
+ ensure_contextless(cfg.size <= max_size, "blake2: requested output size exceeeds algorithm max")
// To save having to allocate a scratch buffer, use the internal
// data buffer (`ctx.x`), as it is exactly the correct size.
@@ -167,8 +166,8 @@ init :: proc(ctx: ^$T, cfg: ^Blake2_Config) {
ctx.is_initialized = true
}
-update :: proc(ctx: ^$T, p: []byte) {
- assert(ctx.is_initialized)
+update :: proc "contextless" (ctx: ^$T, p: []byte) {
+ ensure_contextless(ctx.is_initialized)
p := p
when T == Blake2s_Context {
@@ -195,8 +194,8 @@ update :: proc(ctx: ^$T, p: []byte) {
ctx.nx += copy(ctx.x[ctx.nx:], p)
}
-final :: proc(ctx: ^$T, hash: []byte, finalize_clone: bool = false) {
- assert(ctx.is_initialized)
+final :: proc "contextless" (ctx: ^$T, hash: []byte, finalize_clone: bool = false) {
+ ensure_contextless(ctx.is_initialized)
ctx := ctx
if finalize_clone {
@@ -206,24 +205,19 @@ final :: proc(ctx: ^$T, hash: []byte, finalize_clone: bool = false) {
}
defer(reset(ctx))
+ ensure_contextless(len(hash) >= int(ctx.size), "crypto/blake2: invalid destination digest size")
when T == Blake2s_Context {
- if len(hash) < int(ctx.size) {
- panic("crypto/blake2s: invalid destination digest size")
- }
blake2s_final(ctx, hash)
} else when T == Blake2b_Context {
- if len(hash) < int(ctx.size) {
- panic("crypto/blake2b: invalid destination digest size")
- }
blake2b_final(ctx, hash)
}
}
-clone :: proc(ctx, other: ^$T) {
+clone :: proc "contextless" (ctx, other: ^$T) {
ctx^ = other^
}
-reset :: proc(ctx: ^$T) {
+reset :: proc "contextless" (ctx: ^$T) {
if !ctx.is_initialized {
return
}
diff --git a/core/crypto/_chacha20/chacha20.odin b/core/crypto/_chacha20/chacha20.odin
index c7812f7ab..1a4b5a507 100644
--- a/core/crypto/_chacha20/chacha20.odin
+++ b/core/crypto/_chacha20/chacha20.odin
@@ -45,9 +45,8 @@ Context :: struct {
// derivation is expected to be handled by the caller, so that the
// HChaCha call can be suitably accelerated.
init :: proc "contextless" (ctx: ^Context, key, iv: []byte, is_xchacha: bool) {
- if len(key) != KEY_SIZE || len(iv) != IV_SIZE {
- panic_contextless("chacha20: invalid key or IV size")
- }
+ ensure_contextless(len(key) == KEY_SIZE, "chacha20: invalid key size")
+ ensure_contextless(len(iv) == IV_SIZE, "chacha20: invalid key size")
k, n := key, iv
@@ -75,12 +74,10 @@ init :: proc "contextless" (ctx: ^Context, key, iv: []byte, is_xchacha: bool) {
// seek seeks the (X)ChaCha20 stream counter to the specified block.
seek :: proc(ctx: ^Context, block_nr: u64) {
- assert(ctx._is_initialized)
+ ensure(ctx._is_initialized)
if ctx._is_ietf_flavor {
- if block_nr > MAX_CTR_IETF {
- panic("crypto/chacha20: attempted to seek past maximum counter")
- }
+ ensure(block_nr <= MAX_CTR_IETF, "crypto/chacha20: attempted to seek past maximum counter")
} else {
ctx._s[13] = u32(block_nr >> 32)
}
@@ -101,7 +98,7 @@ check_counter_limit :: proc(ctx: ^Context, nr_blocks: int) {
// Enforce the maximum consumed keystream per IV.
//
// While all modern "standard" definitions of ChaCha20 use
- // the IETF 32-bit counter, for XChaCha20 most common
+ // the IETF 32-bit counter, for XChaCha20 historical
// implementations allow for a 64-bit counter.
//
// Honestly, the answer here is "use a MRAE primitive", but
@@ -109,14 +106,14 @@ check_counter_limit :: proc(ctx: ^Context, nr_blocks: int) {
ERR_CTR_EXHAUSTED :: "crypto/chacha20: maximum (X)ChaCha20 keystream per IV reached"
+ ctr_ok: bool
if ctx._is_ietf_flavor {
- if u64(ctx._s[12]) + u64(nr_blocks) > MAX_CTR_IETF {
- panic(ERR_CTR_EXHAUSTED)
- }
+ ctr_ok = u64(ctx._s[12]) + u64(nr_blocks) <= MAX_CTR_IETF
} else {
ctr := (u64(ctx._s[13]) << 32) | u64(ctx._s[12])
- if _, carry := bits.add_u64(ctr, u64(nr_blocks), 0); carry != 0 {
- panic(ERR_CTR_EXHAUSTED)
- }
+ _, carry := bits.add_u64(ctr, u64(nr_blocks), 0)
+ ctr_ok = carry == 0
}
+
+ ensure(ctr_ok, "crypto/chacha20: maximum (X)ChaCha20 keystream per IV reached")
}
diff --git a/core/crypto/_edwards25519/edwards25519.odin b/core/crypto/_edwards25519/edwards25519.odin
index 0234ba05a..d6f01d497 100644
--- a/core/crypto/_edwards25519/edwards25519.odin
+++ b/core/crypto/_edwards25519/edwards25519.odin
@@ -108,9 +108,7 @@ ge_set :: proc "contextless" (ge, a: ^Group_Element) {
@(require_results)
ge_set_bytes :: proc "contextless" (ge: ^Group_Element, b: []byte) -> bool {
- if len(b) != 32 {
- panic_contextless("edwards25519: invalid group element size")
- }
+ ensure_contextless(len(b) == 32, "edwards25519: invalid group element size")
b_ := (^[32]byte)(raw_data(b))
// Do the work in a scratch element, so that ge is unchanged on
@@ -167,9 +165,7 @@ ge_set_bytes :: proc "contextless" (ge: ^Group_Element, b: []byte) -> bool {
}
ge_bytes :: proc "contextless" (ge: ^Group_Element, dst: []byte) {
- if len(dst) != 32 {
- panic_contextless("edwards25519: invalid group element size")
- }
+ ensure_contextless(len(dst) == 32, "edwards25519: invalid group element size")
dst_ := (^[32]byte)(raw_data(dst))
// Convert the element to affine (x, y) representation.
diff --git a/core/crypto/_edwards25519/edwards25519_scalar.odin b/core/crypto/_edwards25519/edwards25519_scalar.odin
index f650b27d3..68c79a6e8 100644
--- a/core/crypto/_edwards25519/edwards25519_scalar.odin
+++ b/core/crypto/_edwards25519/edwards25519_scalar.odin
@@ -24,17 +24,13 @@ sc_set_u64 :: proc "contextless" (sc: ^Scalar, i: u64) {
@(require_results)
sc_set_bytes :: proc "contextless" (sc: ^Scalar, b: []byte) -> bool {
- if len(b) != 32 {
- panic_contextless("edwards25519: invalid scalar size")
- }
+ ensure_contextless(len(b) == 32, "edwards25519: invalid scalar size")
b_ := (^[32]byte)(raw_data(b))
return field.fe_from_bytes(sc, b_)
}
sc_set_bytes_rfc8032 :: proc "contextless" (sc: ^Scalar, b: []byte) {
- if len(b) != 32 {
- panic_contextless("edwards25519: invalid scalar size")
- }
+ ensure_contextless(len(b) == 32, "edwards25519: invalid scalar size")
b_ := (^[32]byte)(raw_data(b))
field.fe_from_bytes_rfc8032(sc, b_)
}
diff --git a/core/crypto/_fiat/field_poly1305/field.odin b/core/crypto/_fiat/field_poly1305/field.odin
index c888f1e8b..caaece98e 100644
--- a/core/crypto/_fiat/field_poly1305/field.odin
+++ b/core/crypto/_fiat/field_poly1305/field.odin
@@ -28,9 +28,7 @@ fe_from_bytes :: #force_inline proc "contextless" (
// makes implementing the actual MAC block processing considerably
// neater.
- if len(arg1) != 16 {
- panic_contextless("poly1305: invalid field element size")
- }
+ ensure_contextless(len(arg1) == 16, "poly1305: invalid field element size")
// While it may be unwise to do deserialization here on our
// own when fiat-crypto provides equivalent functionality,
diff --git a/core/crypto/_fiat/field_scalar25519/field.odin b/core/crypto/_fiat/field_scalar25519/field.odin
index 430891641..933637c54 100644
--- a/core/crypto/_fiat/field_scalar25519/field.odin
+++ b/core/crypto/_fiat/field_scalar25519/field.odin
@@ -94,9 +94,8 @@ fe_from_bytes_wide :: proc "contextless" (
@(private)
_fe_from_bytes_short :: proc "contextless" (out1: ^Montgomery_Domain_Field_Element, arg1: []byte) {
// INVARIANT: len(arg1) < 32.
- if len(arg1) >= 32 {
- panic_contextless("edwards25519: oversized short scalar")
- }
+ ensure_contextless(len(arg1) < 32, "edwards25519: oversized short scalar")
+
tmp: [32]byte
copy(tmp[:], arg1)
@@ -105,9 +104,7 @@ _fe_from_bytes_short :: proc "contextless" (out1: ^Montgomery_Domain_Field_Eleme
}
fe_to_bytes :: proc "contextless" (out1: []byte, arg1: ^Montgomery_Domain_Field_Element) {
- if len(out1) != 32 {
- panic_contextless("edwards25519: oversized scalar output buffer")
- }
+ ensure_contextless(len(out1) == 32, "edwards25519: oversized scalar output buffer")
tmp: Non_Montgomery_Domain_Field_Element
fe_from_montgomery(&tmp, arg1)
diff --git a/core/crypto/_sha3/sha3.odin b/core/crypto/_sha3/sha3.odin
index 98e15b29d..52b3fbda9 100644
--- a/core/crypto/_sha3/sha3.odin
+++ b/core/crypto/_sha3/sha3.odin
@@ -122,7 +122,7 @@ keccakf :: proc "contextless" (st: ^[25]u64) {
}
}
-init :: proc(ctx: ^Context) {
+init :: proc "contextless" (ctx: ^Context) {
for i := 0; i < 25; i += 1 {
ctx.st.q[i] = 0
}
@@ -133,9 +133,9 @@ init :: proc(ctx: ^Context) {
ctx.is_finalized = false
}
-update :: proc(ctx: ^Context, data: []byte) {
- assert(ctx.is_initialized)
- assert(!ctx.is_finalized)
+update :: proc "contextless" (ctx: ^Context, data: []byte) {
+ ensure_contextless(ctx.is_initialized)
+ ensure_contextless(!ctx.is_finalized)
j := ctx.pt
for i := 0; i < len(data); i += 1 {
@@ -149,12 +149,9 @@ update :: proc(ctx: ^Context, data: []byte) {
ctx.pt = j
}
-final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
- assert(ctx.is_initialized)
-
- if len(hash) < ctx.mdlen {
- panic("crypto/sha3: invalid destination digest size")
- }
+final :: proc "contextless" (ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
+ ensure_contextless(ctx.is_initialized)
+ ensure_contextless(len(hash) >= ctx.mdlen, "crypto/sha3: invalid destination digest size")
ctx := ctx
if finalize_clone {
@@ -173,11 +170,11 @@ final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
}
}
-clone :: proc(ctx, other: ^Context) {
+clone :: proc "contextless" (ctx, other: ^Context) {
ctx^ = other^
}
-reset :: proc(ctx: ^Context) {
+reset :: proc "contextless" (ctx: ^Context) {
if !ctx.is_initialized {
return
}
@@ -185,9 +182,9 @@ reset :: proc(ctx: ^Context) {
mem.zero_explicit(ctx, size_of(ctx^))
}
-shake_xof :: proc(ctx: ^Context) {
- assert(ctx.is_initialized)
- assert(!ctx.is_finalized)
+shake_xof :: proc "contextless" (ctx: ^Context) {
+ ensure_contextless(ctx.is_initialized)
+ ensure_contextless(!ctx.is_finalized)
ctx.st.b[ctx.pt] ~= ctx.dsbyte
ctx.st.b[ctx.rsiz - 1] ~= 0x80
@@ -197,9 +194,9 @@ shake_xof :: proc(ctx: ^Context) {
ctx.is_finalized = true // No more absorb, unlimited squeeze.
}
-shake_out :: proc(ctx: ^Context, hash: []byte) {
- assert(ctx.is_initialized)
- assert(ctx.is_finalized)
+shake_out :: proc "contextless" (ctx: ^Context, hash: []byte) {
+ ensure_contextless(ctx.is_initialized)
+ ensure_contextless(ctx.is_finalized)
j := ctx.pt
for i := 0; i < len(hash); i += 1 {
diff --git a/core/crypto/_sha3/sp800_185.odin b/core/crypto/_sha3/sp800_185.odin
index a08cb1d11..8390d8490 100644
--- a/core/crypto/_sha3/sp800_185.odin
+++ b/core/crypto/_sha3/sp800_185.odin
@@ -3,7 +3,7 @@ package _sha3
import "core:encoding/endian"
import "core:math/bits"
-init_cshake :: proc(ctx: ^Context, n, s: []byte, sec_strength: int) {
+init_cshake :: proc "contextless" (ctx: ^Context, n, s: []byte, sec_strength: int) {
ctx.mdlen = sec_strength / 8
// No domain separator is equivalent to vanilla SHAKE.
@@ -18,7 +18,7 @@ init_cshake :: proc(ctx: ^Context, n, s: []byte, sec_strength: int) {
bytepad(ctx, [][]byte{n, s}, rate_cshake(sec_strength))
}
-final_cshake :: proc(ctx: ^Context, dst: []byte, finalize_clone: bool = false) {
+final_cshake :: proc "contextless" (ctx: ^Context, dst: []byte, finalize_clone: bool = false) {
ctx := ctx
if finalize_clone {
tmp_ctx: Context
@@ -32,7 +32,7 @@ final_cshake :: proc(ctx: ^Context, dst: []byte, finalize_clone: bool = false) {
shake_out(ctx, dst)
}
-rate_cshake :: #force_inline proc(sec_strength: int) -> int {
+rate_cshake :: #force_inline proc "contextless" (sec_strength: int) -> int {
switch sec_strength {
case 128:
return RATE_128
@@ -40,7 +40,7 @@ rate_cshake :: #force_inline proc(sec_strength: int) -> int {
return RATE_256
}
- panic("crypto/sha3: invalid security strength")
+ panic_contextless("crypto/sha3: invalid security strength")
}
// right_encode and left_encode are defined to support 0 <= x < 2^2040
@@ -55,7 +55,7 @@ rate_cshake :: #force_inline proc(sec_strength: int) -> int {
@(private, rodata)
_PAD: [RATE_128]byte // Biggest possible value of w per spec.
-bytepad :: proc(ctx: ^Context, x_strings: [][]byte, w: int) {
+bytepad :: proc "contextless" (ctx: ^Context, x_strings: [][]byte, w: int) {
// 1. z = left_encode(w) || X.
z_hi: u64
z_lo := left_right_encode(ctx, 0, u64(w), true)
@@ -70,9 +70,7 @@ bytepad :: proc(ctx: ^Context, x_strings: [][]byte, w: int) {
// This isn't actually possible, at least with the currently
// defined SP 800-185 routines.
- if carry != 0 {
- panic("crypto/sha3: bytepad input length overflow")
- }
+ ensure_contextless(carry == 0, "crypto/sha3: bytepad input length overflow")
}
// We skip this step as we are doing a byte-oriented implementation
@@ -95,7 +93,7 @@ bytepad :: proc(ctx: ^Context, x_strings: [][]byte, w: int) {
}
}
-encode_string :: #force_inline proc(ctx: ^Context, s: []byte) -> (u64, u64) {
+encode_string :: #force_inline proc "contextless" (ctx: ^Context, s: []byte) -> (u64, u64) {
l := encode_byte_len(ctx, len(s), true) // left_encode
update(ctx, s)
@@ -104,13 +102,13 @@ encode_string :: #force_inline proc(ctx: ^Context, s: []byte) -> (u64, u64) {
return hi, lo
}
-encode_byte_len :: #force_inline proc(ctx: ^Context, l: int, is_left: bool) -> u64 {
+encode_byte_len :: #force_inline proc "contextless" (ctx: ^Context, l: int, is_left: bool) -> u64 {
hi, lo := bits.mul_u64(u64(l), 8)
return left_right_encode(ctx, hi, lo, is_left)
}
@(private)
-left_right_encode :: proc(ctx: ^Context, hi, lo: u64, is_left: bool) -> u64 {
+left_right_encode :: proc "contextless" (ctx: ^Context, hi, lo: u64, is_left: bool) -> u64 {
HI_OFFSET :: 1
LO_OFFSET :: HI_OFFSET + 8
RIGHT_OFFSET :: LO_OFFSET + 8
diff --git a/core/crypto/aead/low_level.odin b/core/crypto/aead/low_level.odin
index e90d07bc6..c80574a0d 100644
--- a/core/crypto/aead/low_level.odin
+++ b/core/crypto/aead/low_level.odin
@@ -128,9 +128,7 @@ init :: proc(ctx: ^Context, algorithm: Algorithm, key: []byte, impl: Implementat
reset(ctx)
}
- if len(key) != KEY_SIZES[algorithm] {
- panic("crypto/aead: invalid key size")
- }
+ ensure(len(key) == KEY_SIZES[algorithm], "crypto/aead: invalid key size")
// Directly specialize the union by setting the type ID (save a copy).
reflect.set_union_variant_typeid(
@@ -167,9 +165,7 @@ init :: proc(ctx: ^Context, algorithm: Algorithm, key: []byte, impl: Implementat
//
// dst and plaintext MUST alias exactly or not at all.
seal_ctx :: proc(ctx: ^Context, dst, tag, iv, aad, plaintext: []byte) {
- if len(tag) != TAG_SIZES[ctx._algo] {
- panic("crypto/aead: invalid tag size")
- }
+ ensure(len(tag) == TAG_SIZES[ctx._algo], "crypto/aead: invalid tag size")
switch &impl in ctx._impl {
case aes.Context_GCM:
@@ -193,9 +189,7 @@ seal_ctx :: proc(ctx: ^Context, dst, tag, iv, aad, plaintext: []byte) {
// dst and plaintext MUST alias exactly or not at all.
@(require_results)
open_ctx :: proc(ctx: ^Context, dst, iv, aad, ciphertext, tag: []byte) -> bool {
- if len(tag) != TAG_SIZES[ctx._algo] {
- panic("crypto/aead: invalid tag size")
- }
+ ensure(len(tag) == TAG_SIZES[ctx._algo], "crypto/aead: invalid tag size")
switch &impl in ctx._impl {
case aes.Context_GCM:
diff --git a/core/crypto/aes/aes_ctr.odin b/core/crypto/aes/aes_ctr.odin
index 20b75e57f..a74133235 100644
--- a/core/crypto/aes/aes_ctr.odin
+++ b/core/crypto/aes/aes_ctr.odin
@@ -21,9 +21,7 @@ Context_CTR :: struct {
// init_ctr initializes a Context_CTR with the provided key and IV.
init_ctr :: proc(ctx: ^Context_CTR, key, iv: []byte, impl := DEFAULT_IMPLEMENTATION) {
- if len(iv) != CTR_IV_SIZE {
- panic("crypto/aes: invalid CTR IV size")
- }
+ ensure(len(iv) == CTR_IV_SIZE, "crypto/aes: invalid CTR IV size")
init_impl(&ctx._impl, key, impl)
ctx._off = BLOCK_SIZE
@@ -36,16 +34,14 @@ init_ctr :: proc(ctx: ^Context_CTR, key, iv: []byte, impl := DEFAULT_IMPLEMENTAT
// keystream, and writes the resulting output to dst. dst and src MUST
// alias exactly or not at all.
xor_bytes_ctr :: proc(ctx: ^Context_CTR, dst, src: []byte) {
- assert(ctx._is_initialized)
+ ensure(ctx._is_initialized)
src, dst := src, dst
if dst_len := len(dst); dst_len < len(src) {
src = src[:dst_len]
}
- if bytes.alias_inexactly(dst, src) {
- panic("crypto/aes: dst and src alias inexactly")
- }
+ ensure(!bytes.alias_inexactly(dst, src), "crypto/aes: dst and src alias inexactly")
#no_bounds_check for remaining := len(src); remaining > 0; {
// Process multiple blocks at once
@@ -82,7 +78,7 @@ xor_bytes_ctr :: proc(ctx: ^Context_CTR, dst, src: []byte) {
// keystream_bytes_ctr fills dst with the raw AES-CTR keystream output.
keystream_bytes_ctr :: proc(ctx: ^Context_CTR, dst: []byte) {
- assert(ctx._is_initialized)
+ ensure(ctx._is_initialized)
dst := dst
#no_bounds_check for remaining := len(dst); remaining > 0; {
diff --git a/core/crypto/aes/aes_ecb.odin b/core/crypto/aes/aes_ecb.odin
index 32476006c..cac62de5d 100644
--- a/core/crypto/aes/aes_ecb.odin
+++ b/core/crypto/aes/aes_ecb.odin
@@ -19,11 +19,9 @@ init_ecb :: proc(ctx: ^Context_ECB, key: []byte, impl := DEFAULT_IMPLEMENTATION)
// encrypt_ecb encrypts the BLOCK_SIZE buffer src, and writes the result to dst.
encrypt_ecb :: proc(ctx: ^Context_ECB, dst, src: []byte) {
- assert(ctx._is_initialized)
-
- if len(dst) != BLOCK_SIZE || len(src) != BLOCK_SIZE {
- panic("crypto/aes: invalid buffer size(s)")
- }
+ ensure(ctx._is_initialized)
+ ensure(len(dst) == BLOCK_SIZE, "crypto/aes: invalid dst size")
+ ensure(len(dst) == BLOCK_SIZE, "crypto/aes: invalid src size")
switch &impl in ctx._impl {
case ct64.Context:
@@ -35,11 +33,9 @@ encrypt_ecb :: proc(ctx: ^Context_ECB, dst, src: []byte) {
// decrypt_ecb decrypts the BLOCK_SIZE buffer src, and writes the result to dst.
decrypt_ecb :: proc(ctx: ^Context_ECB, dst, src: []byte) {
- assert(ctx._is_initialized)
-
- if len(dst) != BLOCK_SIZE || len(src) != BLOCK_SIZE {
- panic("crypto/aes: invalid buffer size(s)")
- }
+ ensure(ctx._is_initialized)
+ ensure(len(dst) == BLOCK_SIZE, "crypto/aes: invalid dst size")
+ ensure(len(dst) == BLOCK_SIZE, "crypto/aes: invalid src size")
switch &impl in ctx._impl {
case ct64.Context:
diff --git a/core/crypto/aes/aes_gcm.odin b/core/crypto/aes/aes_gcm.odin
index 8616821ce..d349aa353 100644
--- a/core/crypto/aes/aes_gcm.odin
+++ b/core/crypto/aes/aes_gcm.odin
@@ -36,15 +36,11 @@ init_gcm :: proc(ctx: ^Context_GCM, key: []byte, impl := DEFAULT_IMPLEMENTATION)
//
// dst and plaintext MUST alias exactly or not at all.
seal_gcm :: proc(ctx: ^Context_GCM, dst, tag, iv, aad, plaintext: []byte) {
- assert(ctx._is_initialized)
+ ensure(ctx._is_initialized)
gcm_validate_common_slice_sizes(tag, iv, aad, plaintext)
- if len(dst) != len(plaintext) {
- panic("crypto/aes: invalid destination ciphertext size")
- }
- if bytes.alias_inexactly(dst, plaintext) {
- panic("crypto/aes: dst and plaintext alias inexactly")
- }
+ ensure(len(dst) == len(plaintext), "crypto/aes: invalid destination ciphertext size")
+ ensure(!bytes.alias_inexactly(dst, plaintext), "crypto/aes: dst and plaintext alias inexactly")
if impl, is_hw := ctx._impl.(Context_Impl_Hardware); is_hw {
gcm_seal_hw(&impl, dst, tag, iv, aad, plaintext)
@@ -76,15 +72,11 @@ seal_gcm :: proc(ctx: ^Context_GCM, dst, tag, iv, aad, plaintext: []byte) {
// dst and plaintext MUST alias exactly or not at all.
@(require_results)
open_gcm :: proc(ctx: ^Context_GCM, dst, iv, aad, ciphertext, tag: []byte) -> bool {
- assert(ctx._is_initialized)
+ ensure(ctx._is_initialized)
gcm_validate_common_slice_sizes(tag, iv, aad, ciphertext)
- if len(dst) != len(ciphertext) {
- panic("crypto/aes: invalid destination plaintext size")
- }
- if bytes.alias_inexactly(dst, ciphertext) {
- panic("crypto/aes: dst and ciphertext alias inexactly")
- }
+ ensure(len(dst) == len(ciphertext), "crypto/aes: invalid destination plaintext size")
+ ensure(!bytes.alias_inexactly(dst, ciphertext), "crypto/aes: dst and ciphertext alias inexactly")
if impl, is_hw := ctx._impl.(Context_Impl_Hardware); is_hw {
return gcm_open_hw(&impl, dst, iv, aad, ciphertext, tag)
@@ -122,21 +114,13 @@ reset_gcm :: proc "contextless" (ctx: ^Context_GCM) {
@(private = "file")
gcm_validate_common_slice_sizes :: proc(tag, iv, aad, text: []byte) {
- if len(tag) != GCM_TAG_SIZE {
- panic("crypto/aes: invalid GCM tag size")
- }
+ ensure(len(tag) == GCM_TAG_SIZE, "crypto/aes: invalid GCM tag size")
// The specification supports IVs in the range [1, 2^64) bits.
- if l := len(iv); l == 0 || u64(l) >= GCM_IV_SIZE_MAX {
- panic("crypto/aes: invalid GCM IV size")
- }
+ ensure(len(iv) == 0 || u64(len(iv)) <= GCM_IV_SIZE_MAX, "crypto/aes: invalid GCM IV size")
- if aad_len := u64(len(aad)); aad_len > GCM_A_MAX {
- panic("crypto/aes: oversized GCM aad")
- }
- if text_len := u64(len(text)); text_len > GCM_P_MAX {
- panic("crypto/aes: oversized GCM src data")
- }
+ ensure(u64(len(aad)) <= GCM_A_MAX, "crypto/aes: oversized GCM aad")
+ ensure(u64(len(text)) <= GCM_P_MAX, "crypto/aes: oversized GCM data")
}
@(private = "file")
diff --git a/core/crypto/aes/aes_gcm_hw_intel.odin b/core/crypto/aes/aes_gcm_hw_intel.odin
index 4cb5ab3b2..3982d1452 100644
--- a/core/crypto/aes/aes_gcm_hw_intel.odin
+++ b/core/crypto/aes/aes_gcm_hw_intel.odin
@@ -235,7 +235,7 @@ gctr_hw :: proc(
// BUG: Sticking this in gctr_hw (like the other implementations) crashes
// the compiler.
//
-// src/check_expr.cpp(7892): Assertion Failure: `c->curr_proc_decl->entity`
+// src/check_expr.cpp(8104): Assertion Failure: `c->curr_proc_decl->entity`
@(private = "file", enable_target_feature = "sse4.1")
hw_inc_ctr32 :: #force_inline proc "contextless" (src: ^x86.__m128i, ctr: u32) -> (x86.__m128i, u32) {
ret := x86._mm_insert_epi32(src^, i32(intrinsics.byte_swap(ctr)), 3)
diff --git a/core/crypto/blake2b/blake2b.odin b/core/crypto/blake2b/blake2b.odin
index 16b19e349..3b3fc6649 100644
--- a/core/crypto/blake2b/blake2b.odin
+++ b/core/crypto/blake2b/blake2b.odin
@@ -28,9 +28,8 @@ Context :: _blake2.Blake2b_Context
// init initializes a Context with the default BLAKE2b config.
init :: proc(ctx: ^Context, digest_size := DIGEST_SIZE) {
- if digest_size > 255 {
- panic("blake2b: invalid digest size")
- }
+ ensure(digest_size <= _blake2.MAX_SIZE, "crypto/blake2b: invalid digest size")
+
cfg: _blake2.Blake2_Config
cfg.size = u8(digest_size)
_blake2.init(ctx, &cfg)
diff --git a/core/crypto/blake2s/blake2s.odin b/core/crypto/blake2s/blake2s.odin
index f7d3abe03..9bbd44541 100644
--- a/core/crypto/blake2s/blake2s.odin
+++ b/core/crypto/blake2s/blake2s.odin
@@ -28,9 +28,8 @@ Context :: _blake2.Blake2s_Context
// init initializes a Context with the default BLAKE2s config.
init :: proc(ctx: ^Context, digest_size := DIGEST_SIZE) {
- if digest_size > 255 {
- panic("blake2s: invalid digest size")
- }
+ ensure(digest_size <= _blake2.MAX_SIZE, "crypto/blake2s: invalid digest size")
+
cfg: _blake2.Blake2_Config
cfg.size = u8(digest_size)
_blake2.init(ctx, &cfg)
diff --git a/core/crypto/chacha20/chacha20.odin b/core/crypto/chacha20/chacha20.odin
index dfab2bc65..e8d67eb3e 100644
--- a/core/crypto/chacha20/chacha20.odin
+++ b/core/crypto/chacha20/chacha20.odin
@@ -27,12 +27,8 @@ Context :: struct {
// init inititializes a Context for ChaCha20 or XChaCha20 with the provided
// key and iv.
init :: proc(ctx: ^Context, key, iv: []byte, impl := DEFAULT_IMPLEMENTATION) {
- if len(key) != KEY_SIZE {
- panic("crypto/chacha20: invalid (X)ChaCha20 key size")
- }
- if l := len(iv); l != IV_SIZE && l != XIV_SIZE {
- panic("crypto/chacha20: invalid (X)ChaCha20 IV size")
- }
+ ensure(len(key) == KEY_SIZE, "crypto/chacha20: invalid (X)ChaCha20 key size")
+ ensure(len(iv) == IV_SIZE || len(iv) == XIV_SIZE, "crypto/chacha20: invalid (X)ChaCha20 IV size")
k, n := key, iv
@@ -67,16 +63,14 @@ seek :: proc(ctx: ^Context, block_nr: u64) {
// keystream, and writes the resulting output to dst. Dst and src MUST
// alias exactly or not at all.
xor_bytes :: proc(ctx: ^Context, dst, src: []byte) {
- assert(ctx._state._is_initialized)
+ ensure(ctx._state._is_initialized)
src, dst := src, dst
if dst_len := len(dst); dst_len < len(src) {
src = src[:dst_len]
}
- if bytes.alias_inexactly(dst, src) {
- panic("crypto/chacha20: dst and src alias inexactly")
- }
+ ensure(!bytes.alias_inexactly(dst, src), "crypto/chacha20: dst and src alias inexactly")
st := &ctx._state
#no_bounds_check for remaining := len(src); remaining > 0; {
@@ -114,7 +108,7 @@ xor_bytes :: proc(ctx: ^Context, dst, src: []byte) {
// keystream_bytes fills dst with the raw (X)ChaCha20 keystream output.
keystream_bytes :: proc(ctx: ^Context, dst: []byte) {
- assert(ctx._state._is_initialized)
+ ensure(ctx._state._is_initialized)
dst, st := dst, &ctx._state
#no_bounds_check for remaining := len(dst); remaining > 0; {
diff --git a/core/crypto/chacha20poly1305/chacha20poly1305.odin b/core/crypto/chacha20poly1305/chacha20poly1305.odin
index 3ef2a5586..6706b3820 100644
--- a/core/crypto/chacha20poly1305/chacha20poly1305.odin
+++ b/core/crypto/chacha20poly1305/chacha20poly1305.odin
@@ -29,13 +29,9 @@ _P_MAX :: 64 * 0xffffffff // 64 * (2^32-1)
@(private)
_validate_common_slice_sizes :: proc (tag, iv, aad, text: []byte, is_xchacha: bool) {
- if len(tag) != TAG_SIZE {
- panic("crypto/chacha20poly1305: invalid destination tag size")
- }
expected_iv_len := is_xchacha ? XIV_SIZE : IV_SIZE
- if len(iv) != expected_iv_len {
- panic("crypto/chacha20poly1305: invalid IV size")
- }
+ ensure(len(tag) == TAG_SIZE, "crypto/chacha20poly1305: invalid destination tag size")
+ ensure(len(iv) == expected_iv_len, "crypto/chacha20poly1305: invalid IV size")
#assert(size_of(int) == 8 || size_of(int) <= 4)
when size_of(int) == 8 {
@@ -45,9 +41,7 @@ _validate_common_slice_sizes :: proc (tag, iv, aad, text: []byte, is_xchacha: bo
// A_MAX is limited by size_of(int), so there is no need to
// enforce it. P_MAX only needs to be checked on 64-bit targets,
// for reasons that should be obvious.
- if text_len := len(text); text_len > _P_MAX {
- panic("crypto/chacha20poly1305: oversized src data")
- }
+ ensure(len(text) <= _P_MAX, "crypto/chacha20poly1305: oversized src data")
}
}
@@ -71,9 +65,7 @@ Context :: struct {
// init initializes a Context with the provided key, for AEAD_CHACHA20_POLY1305.
init :: proc(ctx: ^Context, key: []byte, impl := chacha20.DEFAULT_IMPLEMENTATION) {
- if len(key) != KEY_SIZE {
- panic("crypto/chacha20poly1305: invalid key size")
- }
+ ensure(len(key) == KEY_SIZE, "crypto/chacha20poly1305: invalid key size")
copy(ctx._key[:], key)
ctx._impl = impl
@@ -96,13 +88,11 @@ init_xchacha :: proc(ctx: ^Context, key: []byte, impl := chacha20.DEFAULT_IMPLEM
//
// dst and plaintext MUST alias exactly or not at all.
seal :: proc(ctx: ^Context, dst, tag, iv, aad, plaintext: []byte) {
- assert(ctx._is_initialized)
+ ensure(ctx._is_initialized)
ciphertext := dst
_validate_common_slice_sizes(tag, iv, aad, plaintext, ctx._is_xchacha)
- if len(ciphertext) != len(plaintext) {
- panic("crypto/chacha20poly1305: invalid destination ciphertext size")
- }
+ ensure(len(ciphertext) == len(plaintext), "crypto/chacha20poly1305: invalid destination ciphertext size")
stream_ctx: chacha20.Context = ---
chacha20.init(&stream_ctx, ctx._key[:],iv, ctx._impl)
@@ -153,13 +143,11 @@ seal :: proc(ctx: ^Context, dst, tag, iv, aad, plaintext: []byte) {
// dst and plaintext MUST alias exactly or not at all.
@(require_results)
open :: proc(ctx: ^Context, dst, iv, aad, ciphertext, tag: []byte) -> bool {
- assert(ctx._is_initialized)
+ ensure(ctx._is_initialized)
plaintext := dst
_validate_common_slice_sizes(tag, iv, aad, ciphertext, ctx._is_xchacha)
- if len(ciphertext) != len(plaintext) {
- panic("crypto/chacha20poly1305: invalid destination plaintext size")
- }
+ ensure(len(ciphertext) == len(plaintext), "crypto/chacha20poly1305: invalid destination plaintext size")
// Note: Unlike encrypt, this can fail early, so use defer for
// sanitization rather than assuming control flow reaches certain
diff --git a/core/crypto/deoxysii/deoxysii.odin b/core/crypto/deoxysii/deoxysii.odin
index 2aff1d8b4..cead770e2 100644
--- a/core/crypto/deoxysii/deoxysii.odin
+++ b/core/crypto/deoxysii/deoxysii.odin
@@ -76,13 +76,8 @@ Context :: struct {
@(private)
_validate_common_slice_sizes :: proc (ctx: ^Context, tag, iv, aad, text: []byte) {
- if len(tag) != TAG_SIZE {
- panic("crypto/deoxysii: invalid tag size")
- }
-
- if len(iv) != IV_SIZE {
- panic("crypto/deoxysii: invalid IV size")
- }
+ ensure(len(tag) == TAG_SIZE, "crypto/deoxysii: invalid tag size")
+ ensure(len(iv) == IV_SIZE, "crypto/deoxysii: invalid IV size")
#assert(size_of(int) == 8 || size_of(int) <= 4)
// For the nonce-misuse resistant mode, the total size of the
@@ -95,9 +90,7 @@ _validate_common_slice_sizes :: proc (ctx: ^Context, tag, iv, aad, text: []byte)
// init initializes a Context with the provided key.
init :: proc(ctx: ^Context, key: []byte, impl := aes.DEFAULT_IMPLEMENTATION) {
- if len(key) != KEY_SIZE {
- panic("crypto/deoxysii: invalid key size")
- }
+ ensure(len(key) == KEY_SIZE, "crypto/deoxysii: invalid key size")
ctx._impl = impl
if ctx._impl == .Hardware && !is_hardware_accelerated() {
@@ -114,15 +107,11 @@ init :: proc(ctx: ^Context, key: []byte, impl := aes.DEFAULT_IMPLEMENTATION) {
//
// dst and plaintext MUST alias exactly or not at all.
seal :: proc(ctx: ^Context, dst, tag, iv, aad, plaintext: []byte) {
- assert(ctx._is_initialized)
+ ensure(ctx._is_initialized)
_validate_common_slice_sizes(ctx, tag, iv, aad, plaintext)
- if len(dst) != len(plaintext) {
- panic("crypto/deoxysii: invalid destination ciphertext size")
- }
- if bytes.alias_inexactly(dst, plaintext) {
- panic("crypto/deoxysii: dst and plaintext alias inexactly")
- }
+ ensure(len(dst) == len(plaintext), "crypto/deoxysii: invalid destination ciphertext size")
+ ensure(!bytes.alias_inexactly(dst, plaintext), "crypto/deoxysii: dst and plaintext alias inexactly")
switch ctx._impl {
case .Hardware:
@@ -140,15 +129,11 @@ seal :: proc(ctx: ^Context, dst, tag, iv, aad, plaintext: []byte) {
// dst and plaintext MUST alias exactly or not at all.
@(require_results)
open :: proc(ctx: ^Context, dst, iv, aad, ciphertext, tag: []byte) -> bool {
- assert(ctx._is_initialized)
+ ensure(ctx._is_initialized)
_validate_common_slice_sizes(ctx, tag, iv, aad, ciphertext)
- if len(dst) != len(ciphertext) {
- panic("crypto/deoxysii: invalid destination plaintext size")
- }
- if bytes.alias_inexactly(dst, ciphertext) {
- panic("crypto/deoxysii: dst and ciphertext alias inexactly")
- }
+ ensure(len(dst) == len(ciphertext), "crypto/deoxysii: invalid destination plaintext size")
+ ensure(!bytes.alias_inexactly(dst, ciphertext), "crypto/deoxysii: dst and ciphertext alias inexactly")
ok: bool
switch ctx._impl {
diff --git a/core/crypto/ed25519/ed25519.odin b/core/crypto/ed25519/ed25519.odin
index 460a19563..deeb80685 100644
--- a/core/crypto/ed25519/ed25519.odin
+++ b/core/crypto/ed25519/ed25519.odin
@@ -81,12 +81,8 @@ private_key_set_bytes :: proc(priv_key: ^Private_Key, b: []byte) -> bool {
// private_key_bytes sets dst to byte-encoding of priv_key.
private_key_bytes :: proc(priv_key: ^Private_Key, dst: []byte) {
- if !priv_key._is_initialized {
- panic("crypto/ed25519: uninitialized private key")
- }
- if len(dst) != PRIVATE_KEY_SIZE {
- panic("crypto/ed25519: invalid destination size")
- }
+ ensure(priv_key._is_initialized, "crypto/ed25519: uninitialized private key")
+ ensure(len(dst) == PRIVATE_KEY_SIZE, "crypto/ed25519: invalid destination size")
copy(dst, priv_key._b[:])
}
@@ -98,12 +94,8 @@ private_key_clear :: proc "contextless" (priv_key: ^Private_Key) {
// sign writes the signature by priv_key over msg to sig.
sign :: proc(priv_key: ^Private_Key, msg, sig: []byte) {
- if !priv_key._is_initialized {
- panic("crypto/ed25519: uninitialized private key")
- }
- if len(sig) != SIGNATURE_SIZE {
- panic("crypto/ed25519: invalid destination size")
- }
+ ensure(priv_key._is_initialized, "crypto/ed25519: uninitialized private key")
+ ensure(len(sig) == SIGNATURE_SIZE, "crypto/ed25519: invalid destination size")
// 1. Compute the hash of the private key d, H(d) = (h_0, h_1, ..., h_2b-1)
// using SHA-512 for Ed25519. H(d) may be precomputed.
@@ -178,9 +170,7 @@ public_key_set_bytes :: proc "contextless" (pub_key: ^Public_Key, b: []byte) ->
// public_key_set_priv sets pub_key to the public component of priv_key.
public_key_set_priv :: proc(pub_key: ^Public_Key, priv_key: ^Private_Key) {
- if !priv_key._is_initialized {
- panic("crypto/ed25519: uninitialized public key")
- }
+ ensure(priv_key._is_initialized, "crypto/ed25519: uninitialized public key")
src := &priv_key._pub_key
copy(pub_key._b[:], src._b[:])
@@ -191,21 +181,15 @@ public_key_set_priv :: proc(pub_key: ^Public_Key, priv_key: ^Private_Key) {
// public_key_bytes sets dst to byte-encoding of pub_key.
public_key_bytes :: proc(pub_key: ^Public_Key, dst: []byte) {
- if !pub_key._is_initialized {
- panic("crypto/ed25519: uninitialized public key")
- }
- if len(dst) != PUBLIC_KEY_SIZE {
- panic("crypto/ed25519: invalid destination size")
- }
+ ensure(pub_key._is_initialized, "crypto/ed25519: uninitialized public key")
+ ensure(len(dst) == PUBLIC_KEY_SIZE, "crypto/ed25519: invalid destination size")
copy(dst, pub_key._b[:])
}
// public_key_equal returns true iff pub_key is equal to other.
public_key_equal :: proc(pub_key, other: ^Public_Key) -> bool {
- if !pub_key._is_initialized || !other._is_initialized {
- panic("crypto/ed25519: uninitialized public key")
- }
+ ensure(pub_key._is_initialized && other._is_initialized, "crypto/ed25519: uninitialized public key")
return crypto.compare_constant_time(pub_key._b[:], other._b[:]) == 1
}
diff --git a/core/crypto/hmac/hmac.odin b/core/crypto/hmac/hmac.odin
index 4813a9938..f74d6492f 100644
--- a/core/crypto/hmac/hmac.odin
+++ b/core/crypto/hmac/hmac.odin
@@ -56,7 +56,7 @@ init :: proc(ctx: ^Context, algorithm: hash.Algorithm, key: []byte) {
// update adds more data to the Context.
update :: proc(ctx: ^Context, data: []byte) {
- assert(ctx._is_initialized)
+ ensure(ctx._is_initialized)
hash.update(&ctx._i_hash, data)
}
@@ -64,13 +64,10 @@ update :: proc(ctx: ^Context, data: []byte) {
// final finalizes the Context, writes the tag to dst, and calls
// reset on the Context.
final :: proc(ctx: ^Context, dst: []byte) {
- assert(ctx._is_initialized)
-
defer (reset(ctx))
- if len(dst) != ctx._tag_sz {
- panic("crypto/hmac: invalid destination tag size")
- }
+ ensure(ctx._is_initialized)
+ ensure(len(dst) == ctx._tag_sz, "crypto/hmac: invalid destination tag size")
hash.final(&ctx._i_hash, dst) // H((k ^ ipad) || text)
@@ -105,14 +102,14 @@ reset :: proc(ctx: ^Context) {
// algorithm returns the Algorithm used by a Context instance.
algorithm :: proc(ctx: ^Context) -> hash.Algorithm {
- assert(ctx._is_initialized)
+ ensure(ctx._is_initialized)
return hash.algorithm(&ctx._i_hash)
}
// tag_size returns the tag size of a Context instance in bytes.
tag_size :: proc(ctx: ^Context) -> int {
- assert(ctx._is_initialized)
+ ensure(ctx._is_initialized)
return ctx._tag_sz
}
diff --git a/core/crypto/kmac/kmac.odin b/core/crypto/kmac/kmac.odin
index 298cbf428..6f58e20a7 100644
--- a/core/crypto/kmac/kmac.odin
+++ b/core/crypto/kmac/kmac.odin
@@ -36,6 +36,7 @@ sum :: proc(sec_strength: int, dst, msg, key, domain_sep: []byte) {
// tag is valid.
verify :: proc(sec_strength: int, tag, msg, key, domain_sep: []byte, allocator := context.temp_allocator) -> bool {
derived_tag := make([]byte, len(tag), allocator)
+ defer(delete(derived_tag))
sum(sec_strength, derived_tag, msg, key, domain_sep)
@@ -59,8 +60,6 @@ init_256 :: proc(ctx: ^Context, key, domain_sep: []byte) {
// update adds more data to the Context.
update :: proc(ctx: ^Context, data: []byte) {
- assert(ctx.is_initialized)
-
shake.write((^shake.Context)(ctx), data)
}
@@ -68,12 +67,9 @@ update :: proc(ctx: ^Context, data: []byte) {
// on the Context. This routine will panic if the dst length is less than
// MIN_TAG_SIZE.
final :: proc(ctx: ^Context, dst: []byte) {
- assert(ctx.is_initialized)
defer reset(ctx)
- if len(dst) < MIN_TAG_SIZE {
- panic("crypto/kmac: invalid KMAC tag_size, too short")
- }
+ ensure(len(dst) >= MIN_TAG_SIZE, "crypto/kmac: invalid KMAC tag_size, too short")
_sha3.final_cshake((^_sha3.Context)(ctx), dst)
}
@@ -103,9 +99,7 @@ _init_kmac :: proc(ctx: ^Context, key, s: []byte, sec_strength: int) {
reset(ctx)
}
- if len(key) < sec_strength / 8 {
- panic("crypto/kmac: invalid KMAC key, too short")
- }
+ ensure(len(key) >= sec_strength / 8, "crypto/kmac: invalid KMAC key, too short")
ctx_ := (^_sha3.Context)(ctx)
_sha3.init_cshake(ctx_, N_KMAC, s, sec_strength)
diff --git a/core/crypto/legacy/keccak/keccak.odin b/core/crypto/legacy/keccak/keccak.odin
index 6ca66b7ca..40fc2729f 100644
--- a/core/crypto/legacy/keccak/keccak.odin
+++ b/core/crypto/legacy/keccak/keccak.odin
@@ -40,37 +40,37 @@ BLOCK_SIZE_512 :: _sha3.RATE_512
Context :: distinct _sha3.Context
// init_224 initializes a Context for Keccak-224.
-init_224 :: proc(ctx: ^Context) {
+init_224 :: proc "contextless" (ctx: ^Context) {
ctx.mdlen = DIGEST_SIZE_224
_init(ctx)
}
// init_256 initializes a Context for Keccak-256.
-init_256 :: proc(ctx: ^Context) {
+init_256 :: proc "contextless" (ctx: ^Context) {
ctx.mdlen = DIGEST_SIZE_256
_init(ctx)
}
// init_384 initializes a Context for Keccak-384.
-init_384 :: proc(ctx: ^Context) {
+init_384 :: proc "contextless" (ctx: ^Context) {
ctx.mdlen = DIGEST_SIZE_384
_init(ctx)
}
// init_512 initializes a Context for Keccak-512.
-init_512 :: proc(ctx: ^Context) {
+init_512 :: proc "contextless" (ctx: ^Context) {
ctx.mdlen = DIGEST_SIZE_512
_init(ctx)
}
@(private)
-_init :: proc(ctx: ^Context) {
+_init :: proc "contextless" (ctx: ^Context) {
ctx.dsbyte = _sha3.DS_KECCAK
_sha3.init((^_sha3.Context)(ctx))
}
// update adds more data to the Context.
-update :: proc(ctx: ^Context, data: []byte) {
+update :: proc "contextless" (ctx: ^Context, data: []byte) {
_sha3.update((^_sha3.Context)(ctx), data)
}
@@ -79,17 +79,17 @@ update :: proc(ctx: ^Context, data: []byte) {
//
// Iff finalize_clone is set, final will work on a copy of the Context,
// which is useful for for calculating rolling digests.
-final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
+final :: proc "contextless" (ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
_sha3.final((^_sha3.Context)(ctx), hash, finalize_clone)
}
// clone clones the Context other into ctx.
-clone :: proc(ctx, other: ^Context) {
+clone :: proc "contextless" (ctx, other: ^Context) {
_sha3.clone((^_sha3.Context)(ctx), (^_sha3.Context)(other))
}
// reset sanitizes the Context. The Context must be re-initialized to
// be used again.
-reset :: proc(ctx: ^Context) {
+reset :: proc "contextless" (ctx: ^Context) {
_sha3.reset((^_sha3.Context)(ctx))
}
diff --git a/core/crypto/legacy/md5/md5.odin b/core/crypto/legacy/md5/md5.odin
index 28b47e0b3..050501d98 100644
--- a/core/crypto/legacy/md5/md5.odin
+++ b/core/crypto/legacy/md5/md5.odin
@@ -53,7 +53,7 @@ init :: proc(ctx: ^Context) {
// update adds more data to the Context.
update :: proc(ctx: ^Context, data: []byte) {
- assert(ctx.is_initialized)
+ ensure(ctx.is_initialized)
for i := 0; i < len(data); i += 1 {
ctx.data[ctx.datalen] = data[i]
@@ -72,11 +72,8 @@ update :: proc(ctx: ^Context, data: []byte) {
// Iff finalize_clone is set, final will work on a copy of the Context,
// which is useful for for calculating rolling digests.
final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
- assert(ctx.is_initialized)
-
- if len(hash) < DIGEST_SIZE {
- panic("crypto/md5: invalid destination digest size")
- }
+ ensure(ctx.is_initialized)
+ ensure(len(hash) >= DIGEST_SIZE, "crypto/md5: invalid destination digest size")
ctx := ctx
if finalize_clone {
diff --git a/core/crypto/legacy/sha1/sha1.odin b/core/crypto/legacy/sha1/sha1.odin
index 1025ecb5b..5a2b57005 100644
--- a/core/crypto/legacy/sha1/sha1.odin
+++ b/core/crypto/legacy/sha1/sha1.odin
@@ -60,7 +60,7 @@ init :: proc(ctx: ^Context) {
// update adds more data to the Context.
update :: proc(ctx: ^Context, data: []byte) {
- assert(ctx.is_initialized)
+ ensure(ctx.is_initialized)
for i := 0; i < len(data); i += 1 {
ctx.data[ctx.datalen] = data[i]
@@ -79,11 +79,8 @@ update :: proc(ctx: ^Context, data: []byte) {
// Iff finalize_clone is set, final will work on a copy of the Context,
// which is useful for for calculating rolling digests.
final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
- assert(ctx.is_initialized)
-
- if len(hash) < DIGEST_SIZE {
- panic("crypto/sha1: invalid destination digest size")
- }
+ ensure(ctx.is_initialized)
+ ensure(len(hash) >= DIGEST_SIZE, "crypto/sha1: invalid destination digest size")
ctx := ctx
if finalize_clone {
diff --git a/core/crypto/poly1305/poly1305.odin b/core/crypto/poly1305/poly1305.odin
index ea0e6c907..3dd915da7 100644
--- a/core/crypto/poly1305/poly1305.odin
+++ b/core/crypto/poly1305/poly1305.odin
@@ -60,9 +60,7 @@ Context :: struct {
// init initializes a Context with the specified key. The key SHOULD be
// unique and MUST be unpredictable for each invocation.
init :: proc(ctx: ^Context, key: []byte) {
- if len(key) != KEY_SIZE {
- panic("crypto/poly1305: invalid key size")
- }
+ ensure(len(key) == KEY_SIZE, "crypto/poly1305: invalid key size")
// r = le_bytes_to_num(key[0..15])
// r = clamp(r) (r &= 0xffffffc0ffffffc0ffffffc0fffffff)
@@ -85,7 +83,7 @@ init :: proc(ctx: ^Context, key: []byte) {
// update adds more data to the Context.
update :: proc(ctx: ^Context, data: []byte) {
- assert(ctx._is_initialized)
+ ensure(ctx._is_initialized)
msg := data
msg_len := len(data)
@@ -124,12 +122,10 @@ update :: proc(ctx: ^Context, data: []byte) {
// final finalizes the Context, writes the tag to dst, and calls
// reset on the Context.
final :: proc(ctx: ^Context, dst: []byte) {
- assert(ctx._is_initialized)
defer reset(ctx)
- if len(dst) != TAG_SIZE {
- panic("poly1305: invalid destination tag size")
- }
+ ensure(ctx._is_initialized)
+ ensure(len(dst) == TAG_SIZE, "poly1305: invalid destination tag size")
// Process remaining block
if ctx._leftover > 0 {
diff --git a/core/crypto/ristretto255/ristretto255.odin b/core/crypto/ristretto255/ristretto255.odin
index c4d3f2615..20a002900 100644
--- a/core/crypto/ristretto255/ristretto255.odin
+++ b/core/crypto/ristretto255/ristretto255.odin
@@ -76,7 +76,7 @@ ge_clear :: proc "contextless" (ge: ^Group_Element) {
// ge_set sets `ge = a`.
ge_set :: proc(ge, a: ^Group_Element) {
- _ge_assert_initialized([]^Group_Element{a})
+ _ge_ensure_initialized([]^Group_Element{a})
grp.ge_set(&ge._p, &a._p)
ge._is_initialized = true
@@ -199,9 +199,7 @@ ge_set_bytes :: proc "contextless" (ge: ^Group_Element, b: []byte) -> bool {
// ge_set_wide_bytes sets ge to the result of deriving a ristretto255
// group element, from a wide (512-bit) byte string.
ge_set_wide_bytes :: proc(ge: ^Group_Element, b: []byte) {
- if len(b) != WIDE_ELEMENT_SIZE {
- panic("crypto/ristretto255: invalid wide input size")
- }
+ ensure(len(b) == WIDE_ELEMENT_SIZE, "crypto/ristretto255: invalid wide input size")
// The element derivation function on an input string b proceeds as
// follows:
@@ -222,10 +220,8 @@ ge_set_wide_bytes :: proc(ge: ^Group_Element, b: []byte) {
// ge_bytes sets dst to the canonical encoding of ge.
ge_bytes :: proc(ge: ^Group_Element, dst: []byte) {
- _ge_assert_initialized([]^Group_Element{ge})
- if len(dst) != ELEMENT_SIZE {
- panic("crypto/ristretto255: invalid destination size")
- }
+ _ge_ensure_initialized([]^Group_Element{ge})
+ ensure(len(dst) == ELEMENT_SIZE, "crypto/ristretto255: invalid destination size")
x0, y0, z0, t0 := &ge._p.x, &ge._p.y, &ge._p.z, &ge._p.t
@@ -306,7 +302,7 @@ ge_bytes :: proc(ge: ^Group_Element, dst: []byte) {
// ge_add sets `ge = a + b`.
ge_add :: proc(ge, a, b: ^Group_Element) {
- _ge_assert_initialized([]^Group_Element{a, b})
+ _ge_ensure_initialized([]^Group_Element{a, b})
grp.ge_add(&ge._p, &a._p, &b._p)
ge._is_initialized = true
@@ -314,7 +310,7 @@ ge_add :: proc(ge, a, b: ^Group_Element) {
// ge_double sets `ge = a + a`.
ge_double :: proc(ge, a: ^Group_Element) {
- _ge_assert_initialized([]^Group_Element{a})
+ _ge_ensure_initialized([]^Group_Element{a})
grp.ge_double(&ge._p, &a._p)
ge._is_initialized = true
@@ -322,7 +318,7 @@ ge_double :: proc(ge, a: ^Group_Element) {
// ge_negate sets `ge = -a`.
ge_negate :: proc(ge, a: ^Group_Element) {
- _ge_assert_initialized([]^Group_Element{a})
+ _ge_ensure_initialized([]^Group_Element{a})
grp.ge_negate(&ge._p, &a._p)
ge._is_initialized = true
@@ -330,7 +326,7 @@ ge_negate :: proc(ge, a: ^Group_Element) {
// ge_scalarmult sets `ge = A * sc`.
ge_scalarmult :: proc(ge, A: ^Group_Element, sc: ^Scalar) {
- _ge_assert_initialized([]^Group_Element{A})
+ _ge_ensure_initialized([]^Group_Element{A})
grp.ge_scalarmult(&ge._p, &A._p, sc)
ge._is_initialized = true
@@ -344,7 +340,7 @@ ge_scalarmult_generator :: proc "contextless" (ge: ^Group_Element, sc: ^Scalar)
// ge_scalarmult_vartime sets `ge = A * sc` in variable time.
ge_scalarmult_vartime :: proc(ge, A: ^Group_Element, sc: ^Scalar) {
- _ge_assert_initialized([]^Group_Element{A})
+ _ge_ensure_initialized([]^Group_Element{A})
grp.ge_scalarmult_vartime(&ge._p, &A._p, sc)
ge._is_initialized = true
@@ -358,7 +354,7 @@ ge_double_scalarmult_generator_vartime :: proc(
A: ^Group_Element,
b: ^Scalar,
) {
- _ge_assert_initialized([]^Group_Element{A})
+ _ge_ensure_initialized([]^Group_Element{A})
grp.ge_double_scalarmult_basepoint_vartime(&ge._p, a, &A._p, b)
ge._is_initialized = true
@@ -367,7 +363,7 @@ ge_double_scalarmult_generator_vartime :: proc(
// ge_cond_negate sets `ge = a` iff `ctrl == 0` and `ge = -a` iff `ctrl == 1`.
// Behavior for all other values of ctrl are undefined,
ge_cond_negate :: proc(ge, a: ^Group_Element, ctrl: int) {
- _ge_assert_initialized([]^Group_Element{a})
+ _ge_ensure_initialized([]^Group_Element{a})
grp.ge_cond_negate(&ge._p, &a._p, ctrl)
ge._is_initialized = true
@@ -376,7 +372,7 @@ ge_cond_negate :: proc(ge, a: ^Group_Element, ctrl: int) {
// ge_cond_assign sets `ge = ge` iff `ctrl == 0` and `ge = a` iff `ctrl == 1`.
// Behavior for all other values of ctrl are undefined,
ge_cond_assign :: proc(ge, a: ^Group_Element, ctrl: int) {
- _ge_assert_initialized([]^Group_Element{ge, a})
+ _ge_ensure_initialized([]^Group_Element{ge, a})
grp.ge_cond_assign(&ge._p, &a._p, ctrl)
}
@@ -384,7 +380,7 @@ ge_cond_assign :: proc(ge, a: ^Group_Element, ctrl: int) {
// ge_cond_select sets `ge = a` iff `ctrl == 0` and `ge = b` iff `ctrl == 1`.
// Behavior for all other values of ctrl are undefined,
ge_cond_select :: proc(ge, a, b: ^Group_Element, ctrl: int) {
- _ge_assert_initialized([]^Group_Element{a, b})
+ _ge_ensure_initialized([]^Group_Element{a, b})
grp.ge_cond_select(&ge._p, &a._p, &b._p, ctrl)
ge._is_initialized = true
@@ -393,7 +389,7 @@ ge_cond_select :: proc(ge, a, b: ^Group_Element, ctrl: int) {
// ge_equal returns 1 iff `a == b`, and 0 otherwise.
@(require_results)
ge_equal :: proc(a, b: ^Group_Element) -> int {
- _ge_assert_initialized([]^Group_Element{a, b})
+ _ge_ensure_initialized([]^Group_Element{a, b})
// CT_EQ(x1 * y2, y1 * x2) | CT_EQ(y1 * y2, x1 * x2)
ax_by, ay_bx, ay_by, ax_bx: field.Tight_Field_Element = ---, ---, ---, ---
@@ -501,10 +497,8 @@ ge_map :: proc "contextless" (ge: ^Group_Element, b: []byte) {
}
@(private)
-_ge_assert_initialized :: proc(ges: []^Group_Element) {
+_ge_ensure_initialized :: proc(ges: []^Group_Element) {
for ge in ges {
- if !ge._is_initialized {
- panic("crypto/ristretto255: uninitialized group element")
- }
+ ensure(ge._is_initialized, "crypto/ristretto255: uninitialized group element")
}
}
diff --git a/core/crypto/ristretto255/ristretto255_scalar.odin b/core/crypto/ristretto255/ristretto255_scalar.odin
index 1ecb490e0..75844b3f4 100644
--- a/core/crypto/ristretto255/ristretto255_scalar.odin
+++ b/core/crypto/ristretto255/ristretto255_scalar.odin
@@ -42,9 +42,7 @@ sc_set_bytes :: proc(sc: ^Scalar, b: []byte) -> bool {
// scalar, from a wide (512-bit) byte string by interpreting b as a
// little-endian value, and reducing it mod the group order.
sc_set_bytes_wide :: proc(sc: ^Scalar, b: []byte) {
- if len(b) != WIDE_SCALAR_SIZE {
- panic("crypto/ristretto255: invalid wide input size")
- }
+ ensure(len(b) == WIDE_SCALAR_SIZE, "crypto/ristretto255: invalid wide input size")
b_ := (^[WIDE_SCALAR_SIZE]byte)(raw_data(b))
grp.sc_set_bytes_wide(sc, b_)
@@ -52,9 +50,7 @@ sc_set_bytes_wide :: proc(sc: ^Scalar, b: []byte) {
// sc_bytes sets dst to the canonical encoding of sc.
sc_bytes :: proc(sc: ^Scalar, dst: []byte) {
- if len(dst) != SCALAR_SIZE {
- panic("crypto/ristretto255: invalid destination size")
- }
+ ensure(len(dst) == SCALAR_SIZE, "crypto/ristretto255: invalid destination size")
grp.sc_bytes(dst, sc)
}
diff --git a/core/crypto/sha2/sha2.odin b/core/crypto/sha2/sha2.odin
index 8ab0ce005..bf9b81601 100644
--- a/core/crypto/sha2/sha2.odin
+++ b/core/crypto/sha2/sha2.odin
@@ -158,7 +158,7 @@ _init :: proc(ctx: ^$T) {
// update adds more data to the Context.
update :: proc(ctx: ^$T, data: []byte) {
- assert(ctx.is_initialized)
+ ensure(ctx.is_initialized)
when T == Context_256 {
CURR_BLOCK_SIZE :: BLOCK_SIZE_256
@@ -194,11 +194,8 @@ update :: proc(ctx: ^$T, data: []byte) {
// Iff finalize_clone is set, final will work on a copy of the Context,
// which is useful for for calculating rolling digests.
final :: proc(ctx: ^$T, hash: []byte, finalize_clone: bool = false) {
- assert(ctx.is_initialized)
-
- if len(hash) * 8 < ctx.md_bits {
- panic("crypto/sha2: invalid destination digest size")
- }
+ ensure(ctx.is_initialized)
+ ensure(len(hash) * 8 >= ctx.md_bits, "crypto/sha2: invalid destination digest size")
ctx := ctx
if finalize_clone {
@@ -238,7 +235,7 @@ final :: proc(ctx: ^$T, hash: []byte, finalize_clone: bool = false) {
endian.unchecked_put_u64be(pad[8:], length_lo)
update(ctx, pad[0:16])
}
- assert(ctx.bitlength == 0)
+ assert(ctx.bitlength == 0) // Check for bugs
when T == Context_256 {
for i := 0; i < ctx.md_bits / 32; i += 1 {
diff --git a/core/crypto/siphash/siphash.odin b/core/crypto/siphash/siphash.odin
index c145ab3f0..f9fe50cb0 100644
--- a/core/crypto/siphash/siphash.odin
+++ b/core/crypto/siphash/siphash.odin
@@ -219,18 +219,14 @@ verify_4_8 :: proc {
*/
init :: proc(ctx: ^Context, key: []byte, c_rounds, d_rounds: int) {
- if len(key) != KEY_SIZE {
- panic("crypto/siphash; invalid key size")
- }
+ ensure(len(key) == KEY_SIZE,"crypto/siphash; invalid key size")
ctx.c_rounds = c_rounds
ctx.d_rounds = d_rounds
is_valid_setting :=
(ctx.c_rounds == 1 && ctx.d_rounds == 3) ||
(ctx.c_rounds == 2 && ctx.d_rounds == 4) ||
(ctx.c_rounds == 4 && ctx.d_rounds == 8)
- if !is_valid_setting {
- panic("crypto/siphash: incorrect rounds set up")
- }
+ ensure(is_valid_setting, "crypto/siphash: incorrect rounds set up")
ctx.k0 = endian.unchecked_get_u64le(key[:8])
ctx.k1 = endian.unchecked_get_u64le(key[8:])
ctx.v0 = 0x736f6d6570736575 ~ ctx.k0
@@ -245,7 +241,7 @@ init :: proc(ctx: ^Context, key: []byte, c_rounds, d_rounds: int) {
}
update :: proc(ctx: ^Context, data: []byte) {
- assert(ctx.is_initialized, "crypto/siphash: context is not initialized")
+ ensure(ctx.is_initialized)
data := data
ctx.total_length += len(data)
@@ -269,7 +265,7 @@ update :: proc(ctx: ^Context, data: []byte) {
}
final :: proc(ctx: ^Context, dst: ^u64) {
- assert(ctx.is_initialized, "crypto/siphash: context is not initialized")
+ ensure(ctx.is_initialized)
tmp: [BLOCK_SIZE]byte
copy(tmp[:], ctx.buf[:ctx.last_block])
@@ -336,9 +332,8 @@ _get_byte :: #force_inline proc "contextless" (byte_num: byte, into: u64) -> byt
@(private)
_collect_output :: #force_inline proc(dst: []byte, hash: u64) {
- if len(dst) < DIGEST_SIZE {
- panic("crypto/siphash: invalid tag size")
- }
+ ensure(len(dst) >= DIGEST_SIZE, "crypto/siphash: invalid tag size")
+
dst[0] = _get_byte(7, hash)
dst[1] = _get_byte(6, hash)
dst[2] = _get_byte(5, hash)
diff --git a/core/crypto/sm3/sm3.odin b/core/crypto/sm3/sm3.odin
index 06a5ef2db..6487c5e8c 100644
--- a/core/crypto/sm3/sm3.odin
+++ b/core/crypto/sm3/sm3.odin
@@ -53,7 +53,7 @@ init :: proc(ctx: ^Context) {
// update adds more data to the Context.
update :: proc(ctx: ^Context, data: []byte) {
- assert(ctx.is_initialized)
+ ensure(ctx.is_initialized)
data := data
ctx.length += u64(len(data))
@@ -83,11 +83,8 @@ update :: proc(ctx: ^Context, data: []byte) {
// Iff finalize_clone is set, final will work on a copy of the Context,
// which is useful for for calculating rolling digests.
final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
- assert(ctx.is_initialized)
-
- if len(hash) < DIGEST_SIZE {
- panic("crypto/sm3: invalid destination digest size")
- }
+ ensure(ctx.is_initialized)
+ ensure(len(hash) >= DIGEST_SIZE, "crypto/sm3: invalid destination digest size")
ctx := ctx
if finalize_clone {
@@ -110,7 +107,7 @@ final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
length <<= 3
endian.unchecked_put_u64be(pad[:], length)
update(ctx, pad[0:8])
- assert(ctx.bitlength == 0)
+ assert(ctx.bitlength == 0) // Check for bugs
for i := 0; i < DIGEST_SIZE / 4; i += 1 {
endian.unchecked_put_u32be(hash[i * 4:], ctx.state[i])
diff --git a/core/crypto/x25519/x25519.odin b/core/crypto/x25519/x25519.odin
index fcb7015f3..6805c3ff8 100644
--- a/core/crypto/x25519/x25519.odin
+++ b/core/crypto/x25519/x25519.odin
@@ -101,15 +101,9 @@ _scalarmult :: proc "contextless" (out, scalar, point: ^[32]byte) {
// scalarmult "multiplies" the provided scalar and point, and writes the
// resulting point to dst.
scalarmult :: proc(dst, scalar, point: []byte) {
- if len(scalar) != SCALAR_SIZE {
- panic("crypto/x25519: invalid scalar size")
- }
- if len(point) != POINT_SIZE {
- panic("crypto/x25519: invalid point size")
- }
- if len(dst) != POINT_SIZE {
- panic("crypto/x25519: invalid destination point size")
- }
+ ensure(len(scalar) == SCALAR_SIZE, "crypto/x25519: invalid scalar size")
+ ensure(len(point) == POINT_SIZE, "crypto/x25519: invalid point size")
+ ensure(len(dst) == POINT_SIZE, "crypto/x25519: invalid destination point size")
// "clamp" the scalar
e: [32]byte = ---
diff --git a/core/crypto/x448/x448.odin b/core/crypto/x448/x448.odin
index d3aad6ac5..43c5d25e0 100644
--- a/core/crypto/x448/x448.odin
+++ b/core/crypto/x448/x448.odin
@@ -127,15 +127,9 @@ _scalarmult :: proc "contextless" (out, scalar, point: ^[56]byte) {
// scalarmult "multiplies" the provided scalar and point, and writes the
// resulting point to dst.
scalarmult :: proc(dst, scalar, point: []byte) {
- if len(scalar) != SCALAR_SIZE {
- panic("crypto/x448: invalid scalar size")
- }
- if len(point) != POINT_SIZE {
- panic("crypto/x448: invalid point size")
- }
- if len(dst) != POINT_SIZE {
- panic("crypto/x448: invalid destination point size")
- }
+ ensure(len(scalar) == SCALAR_SIZE, "crypto/x448: invalid scalar size")
+ ensure(len(point) == POINT_SIZE, "crypto/x448: invalid point size")
+ ensure(len(dst) == POINT_SIZE, "crypto/x448: invalid destination point size")
// "clamp" the scalar
e: [56]byte = ---