mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
core/crypto: Expose the block sizes for every hash algorithm
While I just went and made this private, this information is required for keying HMAC.
This commit is contained in:
@@ -16,6 +16,11 @@ import "core:mem"
|
|||||||
|
|
||||||
ROUNDS :: 24
|
ROUNDS :: 24
|
||||||
|
|
||||||
|
RATE_224 :: 1152 / 8
|
||||||
|
RATE_256 :: 1088 / 8
|
||||||
|
RATE_384 :: 832 / 8
|
||||||
|
RATE_512 :: 576 / 8
|
||||||
|
|
||||||
Context :: struct {
|
Context :: struct {
|
||||||
st: struct #raw_union {
|
st: struct #raw_union {
|
||||||
b: [200]u8,
|
b: [200]u8,
|
||||||
@@ -174,7 +179,6 @@ reset :: proc(ctx: ^Context) {
|
|||||||
mem.zero_explicit(ctx, size_of(ctx^))
|
mem.zero_explicit(ctx, size_of(ctx^))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shake_xof :: proc(ctx: ^Context) {
|
shake_xof :: proc(ctx: ^Context) {
|
||||||
assert(ctx.is_initialized)
|
assert(ctx.is_initialized)
|
||||||
assert(!ctx.is_finalized)
|
assert(!ctx.is_finalized)
|
||||||
|
|||||||
@@ -17,9 +17,12 @@ package blake2b
|
|||||||
|
|
||||||
import "../_blake2"
|
import "../_blake2"
|
||||||
|
|
||||||
// DIGEST_SIZE is the BLAKE2b digest size.
|
// DIGEST_SIZE is the BLAKE2b digest size in bytes.
|
||||||
DIGEST_SIZE :: 64
|
DIGEST_SIZE :: 64
|
||||||
|
|
||||||
|
// BLOCK_SIZE is the BLAKE2b block size in bytes.
|
||||||
|
BLOCK_SIZE :: _blake2.BLAKE2B_BLOCK_SIZE
|
||||||
|
|
||||||
// Context is a BLAKE2b instance.
|
// Context is a BLAKE2b instance.
|
||||||
Context :: _blake2.Blake2b_Context
|
Context :: _blake2.Blake2b_Context
|
||||||
|
|
||||||
|
|||||||
@@ -17,9 +17,12 @@ package blake2s
|
|||||||
|
|
||||||
import "../_blake2"
|
import "../_blake2"
|
||||||
|
|
||||||
// DIGEST_SIZE is the BLAKE2s digest size.
|
// DIGEST_SIZE is the BLAKE2s digest size in bytes.
|
||||||
DIGEST_SIZE :: 32
|
DIGEST_SIZE :: 32
|
||||||
|
|
||||||
|
// BLOCK_SIZE is the BLAKE2s block size in bytes.
|
||||||
|
BLOCK_SIZE :: _blake2.BLAKE2S_BLOCK_SIZE
|
||||||
|
|
||||||
// Context is a BLAKE2s instance.
|
// Context is a BLAKE2s instance.
|
||||||
Context :: _blake2.Blake2s_Context
|
Context :: _blake2.Blake2s_Context
|
||||||
|
|
||||||
|
|||||||
@@ -58,10 +58,12 @@ hash_stream :: proc(
|
|||||||
|
|
||||||
init(&ctx, algorithm, context.temp_allocator)
|
init(&ctx, algorithm, context.temp_allocator)
|
||||||
|
|
||||||
_BUFFER_SIZE :: 512
|
buffer_size := block_size(&ctx) * 4
|
||||||
buf := make([]byte, _BUFFER_SIZE, context.temp_allocator)
|
buf := make([]byte, buffer_size, context.temp_allocator)
|
||||||
defer mem.zero_explicit(raw_data(buf), _BUFFER_SIZE)
|
defer {
|
||||||
defer delete(buf)
|
mem.zero_explicit(raw_data(buf), buffer_size)
|
||||||
|
delete(buf, context.temp_allocator)
|
||||||
|
}
|
||||||
|
|
||||||
loop: for {
|
loop: for {
|
||||||
n, err := io.read(s, buf)
|
n, err := io.read(s, buf)
|
||||||
@@ -103,7 +105,7 @@ hash_file :: proc(
|
|||||||
if !ok {
|
if !ok {
|
||||||
return nil, io.Error.Unknown
|
return nil, io.Error.Unknown
|
||||||
}
|
}
|
||||||
defer delete(buf)
|
defer delete(buf, allocator)
|
||||||
|
|
||||||
return hash_bytes(algorithm, buf, allocator), io.Error.None
|
return hash_bytes(algorithm, buf, allocator), io.Error.None
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ ALGORITHM_NAMES := [Algorithm]string {
|
|||||||
.Insecure_SHA1 = "SHA-1",
|
.Insecure_SHA1 = "SHA-1",
|
||||||
}
|
}
|
||||||
|
|
||||||
// DIGEST_SIZES is the Algorithm to digest size.
|
// DIGEST_SIZES is the Algorithm to digest size in bytes.
|
||||||
DIGEST_SIZES := [Algorithm]int {
|
DIGEST_SIZES := [Algorithm]int {
|
||||||
.Invalid = 0,
|
.Invalid = 0,
|
||||||
.BLAKE2B = blake2b.DIGEST_SIZE,
|
.BLAKE2B = blake2b.DIGEST_SIZE,
|
||||||
@@ -80,6 +80,29 @@ DIGEST_SIZES := [Algorithm]int {
|
|||||||
.Insecure_SHA1 = sha1.DIGEST_SIZE,
|
.Insecure_SHA1 = sha1.DIGEST_SIZE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BLOCK_SIZES is the Algoritm to block size in bytes.
|
||||||
|
BLOCK_SIZES := [Algorithm]int {
|
||||||
|
.Invalid = 0,
|
||||||
|
.BLAKE2B = blake2b.BLOCK_SIZE,
|
||||||
|
.BLAKE2S = blake2s.BLOCK_SIZE,
|
||||||
|
.SHA224 = sha2.BLOCK_SIZE_256,
|
||||||
|
.SHA256 = sha2.BLOCK_SIZE_256,
|
||||||
|
.SHA384 = sha2.BLOCK_SIZE_512,
|
||||||
|
.SHA512 = sha2.BLOCK_SIZE_512,
|
||||||
|
.SHA512_256 = sha2.BLOCK_SIZE_512,
|
||||||
|
.SHA3_224 = sha3.BLOCK_SIZE_224,
|
||||||
|
.SHA3_256 = sha3.BLOCK_SIZE_256,
|
||||||
|
.SHA3_384 = sha3.BLOCK_SIZE_384,
|
||||||
|
.SHA3_512 = sha3.BLOCK_SIZE_512,
|
||||||
|
.SM3 = sm3.BLOCK_SIZE,
|
||||||
|
.Legacy_KECCAK_224 = keccak.BLOCK_SIZE_224,
|
||||||
|
.Legacy_KECCAK_256 = keccak.BLOCK_SIZE_256,
|
||||||
|
.Legacy_KECCAK_384 = keccak.BLOCK_SIZE_384,
|
||||||
|
.Legacy_KECCAK_512 = keccak.BLOCK_SIZE_512,
|
||||||
|
.Insecure_MD5 = md5.BLOCK_SIZE,
|
||||||
|
.Insecure_SHA1 = sha1.BLOCK_SIZE,
|
||||||
|
}
|
||||||
|
|
||||||
// Context is a concrete instantiation of a specific hash algorithm.
|
// Context is a concrete instantiation of a specific hash algorithm.
|
||||||
Context :: struct {
|
Context :: struct {
|
||||||
_algo: Algorithm,
|
_algo: Algorithm,
|
||||||
@@ -349,7 +372,12 @@ algorithm :: proc(ctx: ^Context) -> Algorithm {
|
|||||||
return ctx._algo
|
return ctx._algo
|
||||||
}
|
}
|
||||||
|
|
||||||
// digest_size returns the digest size of a Context instance.
|
// digest_size returns the digest size of a Context instance in bytes.
|
||||||
digest_size :: proc(ctx: ^Context) -> int {
|
digest_size :: proc(ctx: ^Context) -> int {
|
||||||
return DIGEST_SIZES[ctx._algo]
|
return DIGEST_SIZES[ctx._algo]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// block_size returns the block size of a Context instance in bytes.
|
||||||
|
block_size :: proc(ctx: ^Context) -> int {
|
||||||
|
return BLOCK_SIZES[ctx._algo]
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,6 +27,15 @@ DIGEST_SIZE_384 :: 48
|
|||||||
// DIGEST_SIZE_512 is the Keccak-512 digest size.
|
// DIGEST_SIZE_512 is the Keccak-512 digest size.
|
||||||
DIGEST_SIZE_512 :: 64
|
DIGEST_SIZE_512 :: 64
|
||||||
|
|
||||||
|
// BLOCK_SIZE_224 is the Keccak-224 block size in bytes.
|
||||||
|
BLOCK_SIZE_224 :: _sha3.RATE_224
|
||||||
|
// BLOCK_SIZE_256 is the Keccak-256 block size in bytes.
|
||||||
|
BLOCK_SIZE_256 :: _sha3.RATE_256
|
||||||
|
// BLOCK_SIZE_384 is the Keccak-384 block size in bytes.
|
||||||
|
BLOCK_SIZE_384 :: _sha3.RATE_384
|
||||||
|
// BLOCK_SIZE_512 is the Keccak-512 block size in bytes.
|
||||||
|
BLOCK_SIZE_512 :: _sha3.RATE_512
|
||||||
|
|
||||||
// Context is a Keccak instance.
|
// Context is a Keccak instance.
|
||||||
Context :: distinct _sha3.Context
|
Context :: distinct _sha3.Context
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,12 @@ import "core:encoding/endian"
|
|||||||
import "core:math/bits"
|
import "core:math/bits"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
|
|
||||||
// DIGEST_SIZE is the MD5 digest size.
|
// DIGEST_SIZE is the MD5 digest size in bytes.
|
||||||
DIGEST_SIZE :: 16
|
DIGEST_SIZE :: 16
|
||||||
|
|
||||||
|
// BLOCK_SIZE is the MD5 block size in bytes.
|
||||||
|
BLOCK_SIZE :: 64
|
||||||
|
|
||||||
// Context is a MD5 instance.
|
// Context is a MD5 instance.
|
||||||
Context :: struct {
|
Context :: struct {
|
||||||
data: [BLOCK_SIZE]byte,
|
data: [BLOCK_SIZE]byte,
|
||||||
@@ -131,9 +134,6 @@ reset :: proc(ctx: ^$T) {
|
|||||||
MD5 implementation
|
MD5 implementation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@(private)
|
|
||||||
BLOCK_SIZE :: 64
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@note(zh): F, G, H and I, as mentioned in the RFC, have been inlined into FF, GG, HH
|
@note(zh): F, G, H and I, as mentioned in the RFC, have been inlined into FF, GG, HH
|
||||||
and II respectively, instead of declaring them separately.
|
and II respectively, instead of declaring them separately.
|
||||||
|
|||||||
@@ -23,9 +23,12 @@ import "core:encoding/endian"
|
|||||||
import "core:math/bits"
|
import "core:math/bits"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
|
|
||||||
// DIGEST_SIZE is the SHA1 digest size.
|
// DIGEST_SIZE is the SHA1 digest size in bytes.
|
||||||
DIGEST_SIZE :: 20
|
DIGEST_SIZE :: 20
|
||||||
|
|
||||||
|
// BLOCK_SIZE is the SHA1 block size in bytes.
|
||||||
|
BLOCK_SIZE :: 64
|
||||||
|
|
||||||
// Context is a SHA1 instance.
|
// Context is a SHA1 instance.
|
||||||
Context :: struct {
|
Context :: struct {
|
||||||
data: [BLOCK_SIZE]byte,
|
data: [BLOCK_SIZE]byte,
|
||||||
@@ -138,9 +141,6 @@ reset :: proc(ctx: ^$T) {
|
|||||||
SHA1 implementation
|
SHA1 implementation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@(private)
|
|
||||||
BLOCK_SIZE :: 64
|
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
transform :: proc "contextless" (ctx: ^Context, data: []byte) {
|
transform :: proc "contextless" (ctx: ^Context, data: []byte) {
|
||||||
a, b, c, d, e, i, t: u32
|
a, b, c, d, e, i, t: u32
|
||||||
|
|||||||
+20
-20
@@ -19,20 +19,26 @@ import "core:encoding/endian"
|
|||||||
import "core:math/bits"
|
import "core:math/bits"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
|
|
||||||
// DIGEST_SIZE_224 is the SHA-224 digest size.
|
// DIGEST_SIZE_224 is the SHA-224 digest size in bytes.
|
||||||
DIGEST_SIZE_224 :: 28
|
DIGEST_SIZE_224 :: 28
|
||||||
// DIGEST_SIZE_256 is the SHA-256 digest size.
|
// DIGEST_SIZE_256 is the SHA-256 digest size in bytes.
|
||||||
DIGEST_SIZE_256 :: 32
|
DIGEST_SIZE_256 :: 32
|
||||||
// DIGEST_SIZE_384 is the SHA-384 digest size.
|
// DIGEST_SIZE_384 is the SHA-384 digest size in bytes.
|
||||||
DIGEST_SIZE_384 :: 48
|
DIGEST_SIZE_384 :: 48
|
||||||
// DIGEST_SIZE_512 is the SHA-512 digest size.
|
// DIGEST_SIZE_512 is the SHA-512 digest size in bytes.
|
||||||
DIGEST_SIZE_512 :: 64
|
DIGEST_SIZE_512 :: 64
|
||||||
// DIGEST_SIZE_512_256 is the SHA-512/256 digest size.
|
// DIGEST_SIZE_512_256 is the SHA-512/256 digest size in bytes.
|
||||||
DIGEST_SIZE_512_256 :: 32
|
DIGEST_SIZE_512_256 :: 32
|
||||||
|
|
||||||
|
// BLOCK_SIZE_256 is the SHA-224 and SHA-256 block size in bytes.
|
||||||
|
BLOCK_SIZE_256 :: 64
|
||||||
|
// BLOCK_SIZE_512 is the SHA-384, SHA-512, and SHA-512/256 block size
|
||||||
|
// in bytes.
|
||||||
|
BLOCK_SIZE_512 :: 128
|
||||||
|
|
||||||
// Context_256 is a SHA-224 or SHA-256 instance.
|
// Context_256 is a SHA-224 or SHA-256 instance.
|
||||||
Context_256 :: struct {
|
Context_256 :: struct {
|
||||||
block: [SHA256_BLOCK_SIZE]byte,
|
block: [BLOCK_SIZE_256]byte,
|
||||||
h: [8]u32,
|
h: [8]u32,
|
||||||
bitlength: u64,
|
bitlength: u64,
|
||||||
length: u64,
|
length: u64,
|
||||||
@@ -43,7 +49,7 @@ Context_256 :: struct {
|
|||||||
|
|
||||||
// Context_512 is a SHA-384, SHA-512 or SHA-512/256 instance.
|
// Context_512 is a SHA-384, SHA-512 or SHA-512/256 instance.
|
||||||
Context_512 :: struct {
|
Context_512 :: struct {
|
||||||
block: [SHA512_BLOCK_SIZE]byte,
|
block: [BLOCK_SIZE_512]byte,
|
||||||
h: [8]u64,
|
h: [8]u64,
|
||||||
bitlength: u64,
|
bitlength: u64,
|
||||||
length: u64,
|
length: u64,
|
||||||
@@ -52,7 +58,6 @@ Context_512 :: struct {
|
|||||||
is_initialized: bool,
|
is_initialized: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// init_224 initializes a Context_256 for SHA-224.
|
// init_224 initializes a Context_256 for SHA-224.
|
||||||
init_224 :: proc(ctx: ^Context_256) {
|
init_224 :: proc(ctx: ^Context_256) {
|
||||||
ctx.md_bits = 224
|
ctx.md_bits = 224
|
||||||
@@ -156,9 +161,9 @@ update :: proc(ctx: ^$T, data: []byte) {
|
|||||||
assert(ctx.is_initialized)
|
assert(ctx.is_initialized)
|
||||||
|
|
||||||
when T == Context_256 {
|
when T == Context_256 {
|
||||||
CURR_BLOCK_SIZE :: SHA256_BLOCK_SIZE
|
CURR_BLOCK_SIZE :: BLOCK_SIZE_256
|
||||||
} else when T == Context_512 {
|
} else when T == Context_512 {
|
||||||
CURR_BLOCK_SIZE :: SHA512_BLOCK_SIZE
|
CURR_BLOCK_SIZE :: BLOCK_SIZE_512
|
||||||
}
|
}
|
||||||
|
|
||||||
data := data
|
data := data
|
||||||
@@ -205,12 +210,12 @@ final :: proc(ctx: ^$T, hash: []byte, finalize_clone: bool = false) {
|
|||||||
|
|
||||||
length := ctx.length
|
length := ctx.length
|
||||||
|
|
||||||
raw_pad: [SHA512_BLOCK_SIZE]byte
|
raw_pad: [BLOCK_SIZE_512]byte
|
||||||
when T == Context_256 {
|
when T == Context_256 {
|
||||||
CURR_BLOCK_SIZE :: SHA256_BLOCK_SIZE
|
CURR_BLOCK_SIZE :: BLOCK_SIZE_256
|
||||||
pm_len := 8 // 64-bits for length
|
pm_len := 8 // 64-bits for length
|
||||||
} else when T == Context_512 {
|
} else when T == Context_512 {
|
||||||
CURR_BLOCK_SIZE :: SHA512_BLOCK_SIZE
|
CURR_BLOCK_SIZE :: BLOCK_SIZE_512
|
||||||
pm_len := 16 // 128-bits for length
|
pm_len := 16 // 128-bits for length
|
||||||
}
|
}
|
||||||
pad := raw_pad[:CURR_BLOCK_SIZE]
|
pad := raw_pad[:CURR_BLOCK_SIZE]
|
||||||
@@ -265,11 +270,6 @@ reset :: proc(ctx: ^$T) {
|
|||||||
SHA2 implementation
|
SHA2 implementation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@(private)
|
|
||||||
SHA256_BLOCK_SIZE :: 64
|
|
||||||
@(private)
|
|
||||||
SHA512_BLOCK_SIZE :: 128
|
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
sha256_k := [64]u32 {
|
sha256_k := [64]u32 {
|
||||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||||
@@ -400,12 +400,12 @@ sha2_transf :: proc "contextless" (ctx: ^$T, data: []byte) {
|
|||||||
w: [64]u32
|
w: [64]u32
|
||||||
wv: [8]u32
|
wv: [8]u32
|
||||||
t1, t2: u32
|
t1, t2: u32
|
||||||
CURR_BLOCK_SIZE :: SHA256_BLOCK_SIZE
|
CURR_BLOCK_SIZE :: BLOCK_SIZE_256
|
||||||
} else when T == Context_512 {
|
} else when T == Context_512 {
|
||||||
w: [80]u64
|
w: [80]u64
|
||||||
wv: [8]u64
|
wv: [8]u64
|
||||||
t1, t2: u64
|
t1, t2: u64
|
||||||
CURR_BLOCK_SIZE :: SHA512_BLOCK_SIZE
|
CURR_BLOCK_SIZE :: BLOCK_SIZE_512
|
||||||
}
|
}
|
||||||
|
|
||||||
data := data
|
data := data
|
||||||
|
|||||||
@@ -29,6 +29,15 @@ DIGEST_SIZE_384 :: 48
|
|||||||
// DIGEST_SIZE_512 is the SHA3-512 digest size.
|
// DIGEST_SIZE_512 is the SHA3-512 digest size.
|
||||||
DIGEST_SIZE_512 :: 64
|
DIGEST_SIZE_512 :: 64
|
||||||
|
|
||||||
|
// BLOCK_SIZE_224 is the SHA3-224 block size in bytes.
|
||||||
|
BLOCK_SIZE_224 :: _sha3.RATE_224
|
||||||
|
// BLOCK_SIZE_256 is the SHA3-256 block size in bytes.
|
||||||
|
BLOCK_SIZE_256 :: _sha3.RATE_256
|
||||||
|
// BLOCK_SIZE_384 is the SHA3-384 block size in bytes.
|
||||||
|
BLOCK_SIZE_384 :: _sha3.RATE_384
|
||||||
|
// BLOCK_SIZE_512 is the SHA3-512 block size in bytes.
|
||||||
|
BLOCK_SIZE_512 :: _sha3.RATE_512
|
||||||
|
|
||||||
// Context is a SHA3 instance.
|
// Context is a SHA3 instance.
|
||||||
Context :: distinct _sha3.Context
|
Context :: distinct _sha3.Context
|
||||||
|
|
||||||
|
|||||||
@@ -18,9 +18,12 @@ import "core:encoding/endian"
|
|||||||
import "core:math/bits"
|
import "core:math/bits"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
|
|
||||||
// DIGEST_SIZE is the SM3 digest size.
|
// DIGEST_SIZE is the SM3 digest size in bytes.
|
||||||
DIGEST_SIZE :: 32
|
DIGEST_SIZE :: 32
|
||||||
|
|
||||||
|
// BLOCK_SIZE is the SM3 block size in bytes.
|
||||||
|
BLOCK_SIZE :: 64
|
||||||
|
|
||||||
// Context is a SM3 instance.
|
// Context is a SM3 instance.
|
||||||
Context :: struct {
|
Context :: struct {
|
||||||
state: [8]u32,
|
state: [8]u32,
|
||||||
@@ -133,9 +136,6 @@ reset :: proc(ctx: ^Context) {
|
|||||||
SM3 implementation
|
SM3 implementation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@(private)
|
|
||||||
BLOCK_SIZE :: 64
|
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
IV := [8]u32 {
|
IV := [8]u32 {
|
||||||
0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600,
|
0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600,
|
||||||
|
|||||||
Reference in New Issue
Block a user