core/crypto/blake2: odinfmt (NFC)

This commit is contained in:
Yawning Angel
2023-11-17 16:53:29 +09:00
parent 12b370ddc1
commit d6e0e5d3f6
3 changed files with 152 additions and 139 deletions
+40 -27
View File
@@ -12,10 +12,10 @@ package _blake2
import "../util" import "../util"
BLAKE2S_BLOCK_SIZE :: 64 BLAKE2S_BLOCK_SIZE :: 64
BLAKE2S_SIZE :: 32 BLAKE2S_SIZE :: 32
BLAKE2B_BLOCK_SIZE :: 128 BLAKE2B_BLOCK_SIZE :: 128
BLAKE2B_SIZE :: 64 BLAKE2B_SIZE :: 64
Blake2s_Context :: struct { Blake2s_Context :: struct {
h: [8]u32, h: [8]u32,
@@ -28,7 +28,7 @@ Blake2s_Context :: struct {
is_keyed: bool, is_keyed: bool,
size: byte, size: byte,
is_last_node: bool, is_last_node: bool,
cfg: Blake2_Config, cfg: Blake2_Config,
} }
Blake2b_Context :: struct { Blake2b_Context :: struct {
@@ -42,15 +42,17 @@ Blake2b_Context :: struct {
is_keyed: bool, is_keyed: bool,
size: byte, size: byte,
is_last_node: bool, is_last_node: bool,
cfg: Blake2_Config, cfg: Blake2_Config,
} }
Blake2_Config :: struct { Blake2_Config :: struct {
size: byte, size: byte,
key: []byte, key: []byte,
salt: []byte, salt: []byte,
person: []byte, person: []byte,
tree: union{Blake2_Tree}, tree: union {
Blake2_Tree,
},
} }
Blake2_Tree :: struct { Blake2_Tree :: struct {
@@ -108,8 +110,8 @@ init :: proc(ctx: ^$T) {
p[3] = ctx.cfg.tree.(Blake2_Tree).max_depth p[3] = ctx.cfg.tree.(Blake2_Tree).max_depth
util.PUT_U32_LE(p[4:], ctx.cfg.tree.(Blake2_Tree).leaf_size) util.PUT_U32_LE(p[4:], ctx.cfg.tree.(Blake2_Tree).leaf_size)
when T == Blake2s_Context { when T == Blake2s_Context {
p[8] = byte(ctx.cfg.tree.(Blake2_Tree).node_offset) p[8] = byte(ctx.cfg.tree.(Blake2_Tree).node_offset)
p[9] = byte(ctx.cfg.tree.(Blake2_Tree).node_offset >> 8) p[9] = byte(ctx.cfg.tree.(Blake2_Tree).node_offset >> 8)
p[10] = byte(ctx.cfg.tree.(Blake2_Tree).node_offset >> 16) p[10] = byte(ctx.cfg.tree.(Blake2_Tree).node_offset >> 16)
p[11] = byte(ctx.cfg.tree.(Blake2_Tree).node_offset >> 24) p[11] = byte(ctx.cfg.tree.(Blake2_Tree).node_offset >> 24)
p[12] = byte(ctx.cfg.tree.(Blake2_Tree).node_offset >> 32) p[12] = byte(ctx.cfg.tree.(Blake2_Tree).node_offset >> 32)
@@ -142,7 +144,7 @@ init :: proc(ctx: ^$T) {
ctx.is_keyed = true ctx.is_keyed = true
} }
copy(ctx.ih[:], ctx.h[:]) copy(ctx.ih[:], ctx.h[:])
copy(ctx.h[:], ctx.ih[:]) copy(ctx.h[:], ctx.ih[:])
if ctx.is_keyed { if ctx.is_keyed {
update(ctx, ctx.padded_key[:]) update(ctx, ctx.padded_key[:])
} }
@@ -229,7 +231,7 @@ blake2b_final :: proc "contextless" (ctx: ^Blake2b_Context, hash: []byte) {
ctx.f[0] = 0xffffffffffffffff ctx.f[0] = 0xffffffffffffffff
if ctx.is_last_node { if ctx.is_last_node {
ctx.f[1] = 0xffffffffffffffff ctx.f[1] = 0xffffffffffffffff
} }
blocks(ctx, ctx.x[:]) blocks(ctx, ctx.x[:])
@@ -257,16 +259,17 @@ blocks :: proc "contextless" (ctx: ^$T, p: []byte) {
} }
blake2s_blocks :: #force_inline proc "contextless" (ctx: ^Blake2s_Context, p: []byte) { blake2s_blocks :: #force_inline proc "contextless" (ctx: ^Blake2s_Context, p: []byte) {
h0, h1, h2, h3, h4, h5, h6, h7 := ctx.h[0], ctx.h[1], ctx.h[2], ctx.h[3], ctx.h[4], ctx.h[5], ctx.h[6], ctx.h[7] h0, h1, h2, h3, h4, h5, h6, h7 :=
ctx.h[0], ctx.h[1], ctx.h[2], ctx.h[3], ctx.h[4], ctx.h[5], ctx.h[6], ctx.h[7]
p := p p := p
for len(p) >= BLAKE2S_BLOCK_SIZE { for len(p) >= BLAKE2S_BLOCK_SIZE {
ctx.t[0] += BLAKE2S_BLOCK_SIZE ctx.t[0] += BLAKE2S_BLOCK_SIZE
if ctx.t[0] < BLAKE2S_BLOCK_SIZE { if ctx.t[0] < BLAKE2S_BLOCK_SIZE {
ctx.t[1] += 1 ctx.t[1] += 1
} }
v0, v1, v2, v3, v4, v5, v6, v7 := h0, h1, h2, h3, h4, h5, h6, h7 v0, v1, v2, v3, v4, v5, v6, v7 := h0, h1, h2, h3, h4, h5, h6, h7
v8 := BLAKE2S_IV[0] v8 := BLAKE2S_IV[0]
v9 := BLAKE2S_IV[1] v9 := BLAKE2S_IV[1]
v10 := BLAKE2S_IV[2] v10 := BLAKE2S_IV[2]
v11 := BLAKE2S_IV[3] v11 := BLAKE2S_IV[3]
v12 := BLAKE2S_IV[4] ~ ctx.t[0] v12 := BLAKE2S_IV[4] ~ ctx.t[0]
@@ -1409,17 +1412,19 @@ blake2s_blocks :: #force_inline proc "contextless" (ctx: ^Blake2s_Context, p: []
h7 ~= v7 ~ v15 h7 ~= v7 ~ v15
p = p[BLAKE2S_BLOCK_SIZE:] p = p[BLAKE2S_BLOCK_SIZE:]
} }
ctx.h[0], ctx.h[1], ctx.h[2], ctx.h[3], ctx.h[4], ctx.h[5], ctx.h[6], ctx.h[7] = h0, h1, h2, h3, h4, h5, h6, h7 ctx.h[0], ctx.h[1], ctx.h[2], ctx.h[3], ctx.h[4], ctx.h[5], ctx.h[6], ctx.h[7] =
h0, h1, h2, h3, h4, h5, h6, h7
} }
blake2b_blocks :: #force_inline proc "contextless" (ctx: ^Blake2b_Context, p: []byte) { blake2b_blocks :: #force_inline proc "contextless" (ctx: ^Blake2b_Context, p: []byte) {
h0, h1, h2, h3, h4, h5, h6, h7 := ctx.h[0], ctx.h[1], ctx.h[2], ctx.h[3], ctx.h[4], ctx.h[5], ctx.h[6], ctx.h[7] h0, h1, h2, h3, h4, h5, h6, h7 :=
ctx.h[0], ctx.h[1], ctx.h[2], ctx.h[3], ctx.h[4], ctx.h[5], ctx.h[6], ctx.h[7]
p := p p := p
for len(p) >= BLAKE2B_BLOCK_SIZE { for len(p) >= BLAKE2B_BLOCK_SIZE {
ctx.t[0] += BLAKE2B_BLOCK_SIZE ctx.t[0] += BLAKE2B_BLOCK_SIZE
if ctx.t[0] < BLAKE2B_BLOCK_SIZE { if ctx.t[0] < BLAKE2B_BLOCK_SIZE {
ctx.t[1]+=1 ctx.t[1] += 1
} }
v0, v1, v2, v3, v4, v5, v6, v7 := h0, h1, h2, h3, h4, h5, h6, h7 v0, v1, v2, v3, v4, v5, v6, v7 := h0, h1, h2, h3, h4, h5, h6, h7
v8 := BLAKE2B_IV[0] v8 := BLAKE2B_IV[0]
v9 := BLAKE2B_IV[1] v9 := BLAKE2B_IV[1]
@@ -1431,9 +1436,16 @@ blake2b_blocks :: #force_inline proc "contextless" (ctx: ^Blake2b_Context, p: []
v15 := BLAKE2B_IV[7] ~ ctx.f[1] v15 := BLAKE2B_IV[7] ~ ctx.f[1]
m: [16]u64 = --- m: [16]u64 = ---
j := 0 j := 0
for i := 0; i < 16; i+=1 { for i := 0; i < 16; i += 1 {
m[i] = u64(p[j]) | u64(p[j + 1]) << 8 | u64(p[j + 2]) << 16 | u64(p[j + 3]) << 24 | m[i] =
u64(p[j + 4]) << 32 | u64(p[j + 5]) << 40 | u64(p[j + 6]) << 48 | u64(p[j + 7]) << 56 u64(p[j]) |
u64(p[j + 1]) << 8 |
u64(p[j + 2]) << 16 |
u64(p[j + 3]) << 24 |
u64(p[j + 4]) << 32 |
u64(p[j + 5]) << 40 |
u64(p[j + 6]) << 48 |
u64(p[j + 7]) << 56
j += 8 j += 8
} }
v0 += m[0] v0 += m[0]
@@ -2790,5 +2802,6 @@ blake2b_blocks :: #force_inline proc "contextless" (ctx: ^Blake2b_Context, p: []
h7 ~= v7 ~ v15 h7 ~= v7 ~ v15
p = p[BLAKE2B_BLOCK_SIZE:] p = p[BLAKE2B_BLOCK_SIZE:]
} }
ctx.h[0], ctx.h[1], ctx.h[2], ctx.h[3], ctx.h[4], ctx.h[5], ctx.h[6], ctx.h[7] = h0, h1, h2, h3, h4, h5, h6, h7 ctx.h[0], ctx.h[1], ctx.h[2], ctx.h[3], ctx.h[4], ctx.h[5], ctx.h[6], ctx.h[7] =
} h0, h1, h2, h3, h4, h5, h6, h7
}
+56 -56
View File
@@ -7,12 +7,12 @@ package blake2b
List of contributors: List of contributors:
zhibog, dotbmp: Initial implementation. zhibog, dotbmp: Initial implementation.
Interface for the BLAKE2B hashing algorithm. Interface for the BLAKE2b hashing algorithm.
BLAKE2B and BLAKE2B share the implementation in the _blake2 package. BLAKE2b and BLAKE2s share the implementation in the _blake2 package.
*/ */
import "core:os"
import "core:io" import "core:io"
import "core:os"
import "../_blake2" import "../_blake2"
@@ -25,87 +25,87 @@ DIGEST_SIZE :: 64
// hash_string will hash the given input and return the // hash_string will hash the given input and return the
// computed hash // computed hash
hash_string :: proc(data: string) -> [DIGEST_SIZE]byte { hash_string :: proc(data: string) -> [DIGEST_SIZE]byte {
return hash_bytes(transmute([]byte)(data)) return hash_bytes(transmute([]byte)(data))
} }
// hash_bytes will hash the given input and return the // hash_bytes will hash the given input and return the
// computed hash // computed hash
hash_bytes :: proc(data: []byte) -> [DIGEST_SIZE]byte { hash_bytes :: proc(data: []byte) -> [DIGEST_SIZE]byte {
hash: [DIGEST_SIZE]byte hash: [DIGEST_SIZE]byte
ctx: _blake2.Blake2b_Context ctx: _blake2.Blake2b_Context
cfg: _blake2.Blake2_Config cfg: _blake2.Blake2_Config
cfg.size = _blake2.BLAKE2B_SIZE cfg.size = _blake2.BLAKE2B_SIZE
ctx.cfg = cfg ctx.cfg = cfg
_blake2.init(&ctx) _blake2.init(&ctx)
_blake2.update(&ctx, data) _blake2.update(&ctx, data)
_blake2.final(&ctx, hash[:]) _blake2.final(&ctx, hash[:])
return hash return hash
} }
// hash_string_to_buffer will hash the given input and assign the // hash_string_to_buffer will hash the given input and assign the
// computed hash to the second parameter. // computed hash to the second parameter.
// It requires that the destination buffer is at least as big as the digest size // It requires that the destination buffer is at least as big as the digest size
hash_string_to_buffer :: proc(data: string, hash: []byte) { hash_string_to_buffer :: proc(data: string, hash: []byte) {
hash_bytes_to_buffer(transmute([]byte)(data), hash) hash_bytes_to_buffer(transmute([]byte)(data), hash)
} }
// hash_bytes_to_buffer will hash the given input and write the // hash_bytes_to_buffer will hash the given input and write the
// computed hash into the second parameter. // computed hash into the second parameter.
// It requires that the destination buffer is at least as big as the digest size // It requires that the destination buffer is at least as big as the digest size
hash_bytes_to_buffer :: proc(data, hash: []byte) { hash_bytes_to_buffer :: proc(data, hash: []byte) {
assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size")
ctx: _blake2.Blake2b_Context ctx: _blake2.Blake2b_Context
cfg: _blake2.Blake2_Config cfg: _blake2.Blake2_Config
cfg.size = _blake2.BLAKE2B_SIZE cfg.size = _blake2.BLAKE2B_SIZE
ctx.cfg = cfg ctx.cfg = cfg
_blake2.init(&ctx) _blake2.init(&ctx)
_blake2.update(&ctx, data) _blake2.update(&ctx, data)
_blake2.final(&ctx, hash) _blake2.final(&ctx, hash)
} }
// hash_stream will read the stream in chunks and compute a // hash_stream will read the stream in chunks and compute a
// hash from its contents // hash from its contents
hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
hash: [DIGEST_SIZE]byte hash: [DIGEST_SIZE]byte
ctx: _blake2.Blake2b_Context ctx: _blake2.Blake2b_Context
cfg: _blake2.Blake2_Config cfg: _blake2.Blake2_Config
cfg.size = _blake2.BLAKE2B_SIZE cfg.size = _blake2.BLAKE2B_SIZE
ctx.cfg = cfg ctx.cfg = cfg
_blake2.init(&ctx) _blake2.init(&ctx)
buf := make([]byte, 512) buf := make([]byte, 512)
defer delete(buf) defer delete(buf)
read := 1 read := 1
for read > 0 { for read > 0 {
read, _ = io.read(s, buf) read, _ = io.read(s, buf)
if read > 0 { if read > 0 {
_blake2.update(&ctx, buf[:read]) _blake2.update(&ctx, buf[:read])
} }
} }
_blake2.final(&ctx, hash[:]) _blake2.final(&ctx, hash[:])
return hash, true return hash, true
} }
// hash_file will read the file provided by the given handle // hash_file will read the file provided by the given handle
// and compute a hash // and compute a hash
hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) { hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) {
if !load_at_once { if !load_at_once {
return hash_stream(os.stream_from_handle(hd)) return hash_stream(os.stream_from_handle(hd))
} else { } else {
if buf, ok := os.read_entire_file(hd); ok { if buf, ok := os.read_entire_file(hd); ok {
return hash_bytes(buf[:]), ok return hash_bytes(buf[:]), ok
} }
} }
return [DIGEST_SIZE]byte{}, false return [DIGEST_SIZE]byte{}, false
} }
hash :: proc { hash :: proc {
hash_stream, hash_stream,
hash_file, hash_file,
hash_bytes, hash_bytes,
hash_string, hash_string,
hash_bytes_to_buffer, hash_bytes_to_buffer,
hash_string_to_buffer, hash_string_to_buffer,
} }
/* /*
@@ -115,13 +115,13 @@ hash :: proc {
Blake2b_Context :: _blake2.Blake2b_Context Blake2b_Context :: _blake2.Blake2b_Context
init :: proc(ctx: ^_blake2.Blake2b_Context) { init :: proc(ctx: ^_blake2.Blake2b_Context) {
_blake2.init(ctx) _blake2.init(ctx)
} }
update :: proc "contextless" (ctx: ^_blake2.Blake2b_Context, data: []byte) { update :: proc "contextless" (ctx: ^_blake2.Blake2b_Context, data: []byte) {
_blake2.update(ctx, data) _blake2.update(ctx, data)
} }
final :: proc "contextless" (ctx: ^_blake2.Blake2b_Context, hash: []byte) { final :: proc "contextless" (ctx: ^_blake2.Blake2b_Context, hash: []byte) {
_blake2.final(ctx, hash) _blake2.final(ctx, hash)
} }
+56 -56
View File
@@ -7,12 +7,12 @@ package blake2s
List of contributors: List of contributors:
zhibog, dotbmp: Initial implementation. zhibog, dotbmp: Initial implementation.
Interface for the BLAKE2S hashing algorithm. Interface for the BLAKE2s hashing algorithm.
BLAKE2B and BLAKE2B share the implementation in the _blake2 package. BLAKE2s and BLAKE2b share the implementation in the _blake2 package.
*/ */
import "core:os"
import "core:io" import "core:io"
import "core:os"
import "../_blake2" import "../_blake2"
@@ -25,21 +25,21 @@ DIGEST_SIZE :: 32
// hash_string will hash the given input and return the // hash_string will hash the given input and return the
// computed hash // computed hash
hash_string :: proc(data: string) -> [DIGEST_SIZE]byte { hash_string :: proc(data: string) -> [DIGEST_SIZE]byte {
return hash_bytes(transmute([]byte)(data)) return hash_bytes(transmute([]byte)(data))
} }
// hash_bytes will hash the given input and return the // hash_bytes will hash the given input and return the
// computed hash // computed hash
hash_bytes :: proc(data: []byte) -> [DIGEST_SIZE]byte { hash_bytes :: proc(data: []byte) -> [DIGEST_SIZE]byte {
hash: [DIGEST_SIZE]byte hash: [DIGEST_SIZE]byte
ctx: _blake2.Blake2s_Context ctx: _blake2.Blake2s_Context
cfg: _blake2.Blake2_Config cfg: _blake2.Blake2_Config
cfg.size = _blake2.BLAKE2S_SIZE cfg.size = _blake2.BLAKE2S_SIZE
ctx.cfg = cfg ctx.cfg = cfg
_blake2.init(&ctx) _blake2.init(&ctx)
_blake2.update(&ctx, data) _blake2.update(&ctx, data)
_blake2.final(&ctx, hash[:]) _blake2.final(&ctx, hash[:])
return hash return hash
} }
@@ -47,65 +47,65 @@ hash_bytes :: proc(data: []byte) -> [DIGEST_SIZE]byte {
// computed hash to the second parameter. // computed hash to the second parameter.
// It requires that the destination buffer is at least as big as the digest size // It requires that the destination buffer is at least as big as the digest size
hash_string_to_buffer :: proc(data: string, hash: []byte) { hash_string_to_buffer :: proc(data: string, hash: []byte) {
hash_bytes_to_buffer(transmute([]byte)(data), hash) hash_bytes_to_buffer(transmute([]byte)(data), hash)
} }
// hash_bytes_to_buffer will hash the given input and write the // hash_bytes_to_buffer will hash the given input and write the
// computed hash into the second parameter. // computed hash into the second parameter.
// It requires that the destination buffer is at least as big as the digest size // It requires that the destination buffer is at least as big as the digest size
hash_bytes_to_buffer :: proc(data, hash: []byte) { hash_bytes_to_buffer :: proc(data, hash: []byte) {
assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size")
ctx: _blake2.Blake2s_Context ctx: _blake2.Blake2s_Context
cfg: _blake2.Blake2_Config cfg: _blake2.Blake2_Config
cfg.size = _blake2.BLAKE2S_SIZE cfg.size = _blake2.BLAKE2S_SIZE
ctx.cfg = cfg ctx.cfg = cfg
_blake2.init(&ctx) _blake2.init(&ctx)
_blake2.update(&ctx, data) _blake2.update(&ctx, data)
_blake2.final(&ctx, hash) _blake2.final(&ctx, hash)
} }
// hash_stream will read the stream in chunks and compute a // hash_stream will read the stream in chunks and compute a
// hash from its contents // hash from its contents
hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
hash: [DIGEST_SIZE]byte hash: [DIGEST_SIZE]byte
ctx: _blake2.Blake2s_Context ctx: _blake2.Blake2s_Context
cfg: _blake2.Blake2_Config cfg: _blake2.Blake2_Config
cfg.size = _blake2.BLAKE2S_SIZE cfg.size = _blake2.BLAKE2S_SIZE
ctx.cfg = cfg ctx.cfg = cfg
_blake2.init(&ctx) _blake2.init(&ctx)
buf := make([]byte, 512) buf := make([]byte, 512)
defer delete(buf) defer delete(buf)
read := 1 read := 1
for read > 0 { for read > 0 {
read, _ = io.read(s, buf) read, _ = io.read(s, buf)
if read > 0 { if read > 0 {
_blake2.update(&ctx, buf[:read]) _blake2.update(&ctx, buf[:read])
} }
} }
_blake2.final(&ctx, hash[:]) _blake2.final(&ctx, hash[:])
return hash, true return hash, true
} }
// hash_file will read the file provided by the given handle // hash_file will read the file provided by the given handle
// and compute a hash // and compute a hash
hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) { hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) {
if !load_at_once { if !load_at_once {
return hash_stream(os.stream_from_handle(hd)) return hash_stream(os.stream_from_handle(hd))
} else { } else {
if buf, ok := os.read_entire_file(hd); ok { if buf, ok := os.read_entire_file(hd); ok {
return hash_bytes(buf[:]), ok return hash_bytes(buf[:]), ok
} }
} }
return [DIGEST_SIZE]byte{}, false return [DIGEST_SIZE]byte{}, false
} }
hash :: proc { hash :: proc {
hash_stream, hash_stream,
hash_file, hash_file,
hash_bytes, hash_bytes,
hash_string, hash_string,
hash_bytes_to_buffer, hash_bytes_to_buffer,
hash_string_to_buffer, hash_string_to_buffer,
} }
/* /*
@@ -115,13 +115,13 @@ hash :: proc {
Blake2s_Context :: _blake2.Blake2b_Context Blake2s_Context :: _blake2.Blake2b_Context
init :: proc(ctx: ^_blake2.Blake2s_Context) { init :: proc(ctx: ^_blake2.Blake2s_Context) {
_blake2.init(ctx) _blake2.init(ctx)
} }
update :: proc "contextless" (ctx: ^_blake2.Blake2s_Context, data: []byte) { update :: proc "contextless" (ctx: ^_blake2.Blake2s_Context, data: []byte) {
_blake2.update(ctx, data) _blake2.update(ctx, data)
} }
final :: proc "contextless" (ctx: ^_blake2.Blake2s_Context, hash: []byte) { final :: proc "contextless" (ctx: ^_blake2.Blake2s_Context, hash: []byte) {
_blake2.final(ctx, hash) _blake2.final(ctx, hash)
} }