mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-04 14:48:47 +00:00
core/crypto: Documentation cleanups
This commit is contained in:
@@ -1,3 +1,10 @@
|
|||||||
|
/*
|
||||||
|
package blake2b implements the BLAKE2b hash algorithm.
|
||||||
|
|
||||||
|
See:
|
||||||
|
- https://datatracker.ietf.org/doc/html/rfc7693
|
||||||
|
- https://www.blake2.net
|
||||||
|
*/
|
||||||
package blake2b
|
package blake2b
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6,34 +13,44 @@ package blake2b
|
|||||||
|
|
||||||
List of contributors:
|
List of contributors:
|
||||||
zhibog, dotbmp: Initial implementation.
|
zhibog, dotbmp: Initial implementation.
|
||||||
|
|
||||||
Interface for the vanilla BLAKE2b hashing algorithm.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import "../_blake2"
|
import "../_blake2"
|
||||||
|
|
||||||
|
// DIGEST_SIZE is the BLAKE2b digest size.
|
||||||
DIGEST_SIZE :: 64
|
DIGEST_SIZE :: 64
|
||||||
|
|
||||||
|
// Context is a BLAKE2b instance.
|
||||||
Context :: _blake2.Blake2b_Context
|
Context :: _blake2.Blake2b_Context
|
||||||
|
|
||||||
|
// init initializes a Context with the default BLAKE2b config.
|
||||||
init :: proc(ctx: ^Context) {
|
init :: proc(ctx: ^Context) {
|
||||||
cfg: _blake2.Blake2_Config
|
cfg: _blake2.Blake2_Config
|
||||||
cfg.size = _blake2.BLAKE2B_SIZE
|
cfg.size = _blake2.BLAKE2B_SIZE
|
||||||
_blake2.init(ctx, &cfg)
|
_blake2.init(ctx, &cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update adds more data to the Context.
|
||||||
update :: proc(ctx: ^Context, data: []byte) {
|
update :: proc(ctx: ^Context, data: []byte) {
|
||||||
_blake2.update(ctx, data)
|
_blake2.update(ctx, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// final finalizes the Context, writes the digest to hash, and calls
|
||||||
|
// reset on the Context.
|
||||||
|
//
|
||||||
|
// 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(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
|
||||||
_blake2.final(ctx, hash, finalize_clone)
|
_blake2.final(ctx, hash, finalize_clone)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clone clones the Context other into ctx.
|
||||||
clone :: proc(ctx, other: ^Context) {
|
clone :: proc(ctx, other: ^Context) {
|
||||||
_blake2.clone(ctx, other)
|
_blake2.clone(ctx, other)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reset sanitizes the Context. The Context must be re-initialized to
|
||||||
|
// be used again.
|
||||||
reset :: proc(ctx: ^Context) {
|
reset :: proc(ctx: ^Context) {
|
||||||
_blake2.reset(ctx)
|
_blake2.reset(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
/*
|
||||||
|
package blake2s implements the BLAKE2s hash algorithm.
|
||||||
|
|
||||||
|
See:
|
||||||
|
- https://datatracker.ietf.org/doc/html/rfc7693
|
||||||
|
- https://www.blake2.net/
|
||||||
|
*/
|
||||||
package blake2s
|
package blake2s
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6,34 +13,44 @@ package blake2s
|
|||||||
|
|
||||||
List of contributors:
|
List of contributors:
|
||||||
zhibog, dotbmp: Initial implementation.
|
zhibog, dotbmp: Initial implementation.
|
||||||
|
|
||||||
Interface for the vanilla BLAKE2s hashing algorithm.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import "../_blake2"
|
import "../_blake2"
|
||||||
|
|
||||||
|
// DIGEST_SIZE is the BLAKE2s digest size.
|
||||||
DIGEST_SIZE :: 32
|
DIGEST_SIZE :: 32
|
||||||
|
|
||||||
|
// Context is a BLAKE2s instance.
|
||||||
Context :: _blake2.Blake2s_Context
|
Context :: _blake2.Blake2s_Context
|
||||||
|
|
||||||
|
// init initializes a Context with the default BLAKE2s config.
|
||||||
init :: proc(ctx: ^Context) {
|
init :: proc(ctx: ^Context) {
|
||||||
cfg: _blake2.Blake2_Config
|
cfg: _blake2.Blake2_Config
|
||||||
cfg.size = _blake2.BLAKE2S_SIZE
|
cfg.size = _blake2.BLAKE2S_SIZE
|
||||||
_blake2.init(ctx, &cfg)
|
_blake2.init(ctx, &cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update adds more data to the Context.
|
||||||
update :: proc(ctx: ^Context, data: []byte) {
|
update :: proc(ctx: ^Context, data: []byte) {
|
||||||
_blake2.update(ctx, data)
|
_blake2.update(ctx, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// final finalizes the Context, writes the digest to hash, and calls
|
||||||
|
// reset on the Context.
|
||||||
|
//
|
||||||
|
// 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(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
|
||||||
_blake2.final(ctx, hash, finalize_clone)
|
_blake2.final(ctx, hash, finalize_clone)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clone clones the Context other into ctx.
|
||||||
clone :: proc(ctx, other: ^Context) {
|
clone :: proc(ctx, other: ^Context) {
|
||||||
_blake2.clone(ctx, other)
|
_blake2.clone(ctx, other)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reset sanitizes the Context. The Context must be re-initialized to
|
||||||
|
// be used again.
|
||||||
reset :: proc(ctx: ^Context) {
|
reset :: proc(ctx: ^Context) {
|
||||||
_blake2.reset(ctx)
|
_blake2.reset(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -329,8 +329,8 @@ clone :: proc(ctx, other: ^Context, allocator := context.allocator) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset sanitizes the Context and frees resources internal to the
|
// reset sanitizes the Context. The Context must be re-initialized to
|
||||||
// Context. The Context must be re-initialized to be used again.
|
// be used again.
|
||||||
reset :: proc(ctx: ^Context) {
|
reset :: proc(ctx: ^Context) {
|
||||||
switch impl in ctx._impl {
|
switch impl in ctx._impl {
|
||||||
case ^blake2b.Context:
|
case ^blake2b.Context:
|
||||||
|
|||||||
@@ -1,3 +1,11 @@
|
|||||||
|
/*
|
||||||
|
package keccak implements the Keccak hash algorithm family.
|
||||||
|
|
||||||
|
During the SHA-3 standardization process, the padding scheme was changed
|
||||||
|
thus Keccac and SHA-3 produce different outputs. Most users should use
|
||||||
|
SHA-3 and/or SHAKE instead, however the legacy algorithm is provided for
|
||||||
|
backward compatibility purposes.
|
||||||
|
*/
|
||||||
package keccak
|
package keccak
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6,37 +14,41 @@ package keccak
|
|||||||
|
|
||||||
List of contributors:
|
List of contributors:
|
||||||
zhibog, dotbmp: Initial implementation.
|
zhibog, dotbmp: Initial implementation.
|
||||||
|
|
||||||
Interface for the Keccak hashing algorithm. Most users will probably
|
|
||||||
want SHA-3 and/or SHAKE instead, however the padding was changed during
|
|
||||||
the standardization process by NIST, thus the legacy Keccak algorithm
|
|
||||||
is provided.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import "../../_sha3"
|
import "../../_sha3"
|
||||||
|
|
||||||
|
// DIGEST_SIZE_224 is the Keccak-224 digest size.
|
||||||
DIGEST_SIZE_224 :: 28
|
DIGEST_SIZE_224 :: 28
|
||||||
|
// DIGEST_SIZE_256 is the Keccak-256 digest size.
|
||||||
DIGEST_SIZE_256 :: 32
|
DIGEST_SIZE_256 :: 32
|
||||||
|
// DIGEST_SIZE_384 is the Keccak-384 digest size.
|
||||||
DIGEST_SIZE_384 :: 48
|
DIGEST_SIZE_384 :: 48
|
||||||
|
// DIGEST_SIZE_512 is the Keccak-512 digest size.
|
||||||
DIGEST_SIZE_512 :: 64
|
DIGEST_SIZE_512 :: 64
|
||||||
|
|
||||||
|
// Context is a Keccak instance.
|
||||||
Context :: distinct _sha3.Context
|
Context :: distinct _sha3.Context
|
||||||
|
|
||||||
|
// init_224 initializes a Context for Keccak-224.
|
||||||
init_224 :: proc(ctx: ^Context) {
|
init_224 :: proc(ctx: ^Context) {
|
||||||
ctx.mdlen = DIGEST_SIZE_224
|
ctx.mdlen = DIGEST_SIZE_224
|
||||||
_init(ctx)
|
_init(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init_256 initializes a Context for Keccak-256.
|
||||||
init_256 :: proc(ctx: ^Context) {
|
init_256 :: proc(ctx: ^Context) {
|
||||||
ctx.mdlen = DIGEST_SIZE_256
|
ctx.mdlen = DIGEST_SIZE_256
|
||||||
_init(ctx)
|
_init(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init_384 initializes a Context for Keccak-384.
|
||||||
init_384 :: proc(ctx: ^Context) {
|
init_384 :: proc(ctx: ^Context) {
|
||||||
ctx.mdlen = DIGEST_SIZE_384
|
ctx.mdlen = DIGEST_SIZE_384
|
||||||
_init(ctx)
|
_init(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init_512 initializes a Context for Keccak-512.
|
||||||
init_512 :: proc(ctx: ^Context) {
|
init_512 :: proc(ctx: ^Context) {
|
||||||
ctx.mdlen = DIGEST_SIZE_512
|
ctx.mdlen = DIGEST_SIZE_512
|
||||||
_init(ctx)
|
_init(ctx)
|
||||||
@@ -48,18 +60,27 @@ _init :: proc(ctx: ^Context) {
|
|||||||
_sha3.init(transmute(^_sha3.Context)(ctx))
|
_sha3.init(transmute(^_sha3.Context)(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update adds more data to the Context.
|
||||||
update :: proc(ctx: ^Context, data: []byte) {
|
update :: proc(ctx: ^Context, data: []byte) {
|
||||||
_sha3.update(transmute(^_sha3.Context)(ctx), data)
|
_sha3.update(transmute(^_sha3.Context)(ctx), data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// final finalizes the Context, writes the digest to hash, and calls
|
||||||
|
// reset on the Context.
|
||||||
|
//
|
||||||
|
// 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(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
|
||||||
_sha3.final(transmute(^_sha3.Context)(ctx), hash, finalize_clone)
|
_sha3.final(transmute(^_sha3.Context)(ctx), hash, finalize_clone)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clone clones the Context other into ctx.
|
||||||
clone :: proc(ctx, other: ^Context) {
|
clone :: proc(ctx, other: ^Context) {
|
||||||
_sha3.clone(transmute(^_sha3.Context)(ctx), transmute(^_sha3.Context)(other))
|
_sha3.clone(transmute(^_sha3.Context)(ctx), transmute(^_sha3.Context)(other))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reset sanitizes the Context. The Context must be re-initialized to
|
||||||
|
// be used again.
|
||||||
reset :: proc(ctx: ^Context) {
|
reset :: proc(ctx: ^Context) {
|
||||||
_sha3.reset(transmute(^_sha3.Context)(ctx))
|
_sha3.reset(transmute(^_sha3.Context)(ctx))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
/*
|
||||||
|
package md5 implements the MD5 hash algorithm.
|
||||||
|
|
||||||
|
WARNING: The MD5 algorithm is known to be insecure and should only be
|
||||||
|
used for interoperating with legacy applications.
|
||||||
|
|
||||||
|
See:
|
||||||
|
- https://eprint.iacr.org/2005/075
|
||||||
|
- https://datatracker.ietf.org/doc/html/rfc1321
|
||||||
|
*/
|
||||||
package md5
|
package md5
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6,16 +16,26 @@ package md5
|
|||||||
|
|
||||||
List of contributors:
|
List of contributors:
|
||||||
zhibog, dotbmp: Initial implementation.
|
zhibog, dotbmp: Initial implementation.
|
||||||
|
|
||||||
Implementation of the MD5 hashing algorithm, as defined in RFC 1321 <https://datatracker.ietf.org/doc/html/rfc1321>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import "core:encoding/endian"
|
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 :: 16
|
DIGEST_SIZE :: 16
|
||||||
|
|
||||||
|
// Context is a MD5 instance.
|
||||||
|
Context :: struct {
|
||||||
|
data: [BLOCK_SIZE]byte,
|
||||||
|
state: [4]u32,
|
||||||
|
bitlen: u64,
|
||||||
|
datalen: u32,
|
||||||
|
|
||||||
|
is_initialized: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
// init initializes a Context.
|
||||||
init :: proc(ctx: ^Context) {
|
init :: proc(ctx: ^Context) {
|
||||||
ctx.state[0] = 0x67452301
|
ctx.state[0] = 0x67452301
|
||||||
ctx.state[1] = 0xefcdab89
|
ctx.state[1] = 0xefcdab89
|
||||||
@@ -28,6 +48,7 @@ init :: proc(ctx: ^Context) {
|
|||||||
ctx.is_initialized = true
|
ctx.is_initialized = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update adds more data to the Context.
|
||||||
update :: proc(ctx: ^Context, data: []byte) {
|
update :: proc(ctx: ^Context, data: []byte) {
|
||||||
assert(ctx.is_initialized)
|
assert(ctx.is_initialized)
|
||||||
|
|
||||||
@@ -42,6 +63,11 @@ update :: proc(ctx: ^Context, data: []byte) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// final finalizes the Context, writes the digest to hash, and calls
|
||||||
|
// reset on the Context.
|
||||||
|
//
|
||||||
|
// 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(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
|
||||||
assert(ctx.is_initialized)
|
assert(ctx.is_initialized)
|
||||||
|
|
||||||
@@ -86,10 +112,13 @@ final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clone clones the Context other into ctx.
|
||||||
clone :: proc(ctx, other: ^$T) {
|
clone :: proc(ctx, other: ^$T) {
|
||||||
ctx^ = other^
|
ctx^ = other^
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reset sanitizes the Context. The Context must be re-initialized to
|
||||||
|
// be used again.
|
||||||
reset :: proc(ctx: ^$T) {
|
reset :: proc(ctx: ^$T) {
|
||||||
if !ctx.is_initialized {
|
if !ctx.is_initialized {
|
||||||
return
|
return
|
||||||
@@ -102,17 +131,9 @@ reset :: proc(ctx: ^$T) {
|
|||||||
MD5 implementation
|
MD5 implementation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@(private)
|
||||||
BLOCK_SIZE :: 64
|
BLOCK_SIZE :: 64
|
||||||
|
|
||||||
Context :: struct {
|
|
||||||
data: [BLOCK_SIZE]byte,
|
|
||||||
state: [4]u32,
|
|
||||||
bitlen: u64,
|
|
||||||
datalen: u32,
|
|
||||||
|
|
||||||
is_initialized: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@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.
|
||||||
|
|||||||
@@ -1,3 +1,14 @@
|
|||||||
|
/*
|
||||||
|
package sha1 implements the SHA1 hash algorithm.
|
||||||
|
|
||||||
|
WARNING: The SHA1 algorithm is known to be insecure and should only be
|
||||||
|
used for interoperating with legacy applications.
|
||||||
|
|
||||||
|
See:
|
||||||
|
- https://eprint.iacr.org/2017/190
|
||||||
|
- https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
|
||||||
|
- https://datatracker.ietf.org/doc/html/rfc3174
|
||||||
|
*/
|
||||||
package sha1
|
package sha1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6,16 +17,27 @@ package sha1
|
|||||||
|
|
||||||
List of contributors:
|
List of contributors:
|
||||||
zhibog, dotbmp: Initial implementation.
|
zhibog, dotbmp: Initial implementation.
|
||||||
|
|
||||||
Implementation of the SHA1 hashing algorithm, as defined in RFC 3174 <https://datatracker.ietf.org/doc/html/rfc3174>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import "core:encoding/endian"
|
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 :: 20
|
DIGEST_SIZE :: 20
|
||||||
|
|
||||||
|
// Context is a SHA1 instance.
|
||||||
|
Context :: struct {
|
||||||
|
data: [BLOCK_SIZE]byte,
|
||||||
|
state: [5]u32,
|
||||||
|
k: [4]u32,
|
||||||
|
bitlen: u64,
|
||||||
|
datalen: u32,
|
||||||
|
|
||||||
|
is_initialized: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
// init initializes a Context.
|
||||||
init :: proc(ctx: ^Context) {
|
init :: proc(ctx: ^Context) {
|
||||||
ctx.state[0] = 0x67452301
|
ctx.state[0] = 0x67452301
|
||||||
ctx.state[1] = 0xefcdab89
|
ctx.state[1] = 0xefcdab89
|
||||||
@@ -33,6 +55,7 @@ init :: proc(ctx: ^Context) {
|
|||||||
ctx.is_initialized = true
|
ctx.is_initialized = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update adds more data to the Context.
|
||||||
update :: proc(ctx: ^Context, data: []byte) {
|
update :: proc(ctx: ^Context, data: []byte) {
|
||||||
assert(ctx.is_initialized)
|
assert(ctx.is_initialized)
|
||||||
|
|
||||||
@@ -47,6 +70,11 @@ update :: proc(ctx: ^Context, data: []byte) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// final finalizes the Context, writes the digest to hash, and calls
|
||||||
|
// reset on the Context.
|
||||||
|
//
|
||||||
|
// 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(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
|
||||||
assert(ctx.is_initialized)
|
assert(ctx.is_initialized)
|
||||||
|
|
||||||
@@ -91,10 +119,13 @@ final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clone clones the Context other into ctx.
|
||||||
clone :: proc(ctx, other: ^$T) {
|
clone :: proc(ctx, other: ^$T) {
|
||||||
ctx^ = other^
|
ctx^ = other^
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reset sanitizes the Context. The Context must be re-initialized to
|
||||||
|
// be used again.
|
||||||
reset :: proc(ctx: ^$T) {
|
reset :: proc(ctx: ^$T) {
|
||||||
if !ctx.is_initialized {
|
if !ctx.is_initialized {
|
||||||
return
|
return
|
||||||
@@ -107,18 +138,9 @@ reset :: proc(ctx: ^$T) {
|
|||||||
SHA1 implementation
|
SHA1 implementation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@(private)
|
||||||
BLOCK_SIZE :: 64
|
BLOCK_SIZE :: 64
|
||||||
|
|
||||||
Context :: struct {
|
|
||||||
data: [BLOCK_SIZE]byte,
|
|
||||||
state: [5]u32,
|
|
||||||
k: [4]u32,
|
|
||||||
bitlen: u64,
|
|
||||||
datalen: u32,
|
|
||||||
|
|
||||||
is_initialized: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
@(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
|
||||||
|
|||||||
+51
-23
@@ -1,3 +1,10 @@
|
|||||||
|
/*
|
||||||
|
package sha2 implements the SHA2 hash algorithm family.
|
||||||
|
|
||||||
|
See:
|
||||||
|
- https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
|
||||||
|
- https://datatracker.ietf.org/doc/html/rfc3874
|
||||||
|
*/
|
||||||
package sha2
|
package sha2
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6,41 +13,71 @@ package sha2
|
|||||||
|
|
||||||
List of contributors:
|
List of contributors:
|
||||||
zhibog, dotbmp: Initial implementation.
|
zhibog, dotbmp: Initial implementation.
|
||||||
|
|
||||||
Implementation of the SHA2 hashing algorithm, as defined in <https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf>
|
|
||||||
and in RFC 3874 <https://datatracker.ietf.org/doc/html/rfc3874>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import "core:encoding/endian"
|
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 :: 28
|
DIGEST_SIZE_224 :: 28
|
||||||
|
// DIGEST_SIZE_256 is the SHA-256 digest size.
|
||||||
DIGEST_SIZE_256 :: 32
|
DIGEST_SIZE_256 :: 32
|
||||||
|
// DIGEST_SIZE_384 is the SHA-384 digest size.
|
||||||
DIGEST_SIZE_384 :: 48
|
DIGEST_SIZE_384 :: 48
|
||||||
|
// DIGEST_SIZE_512 is the SHA-512 digest size.
|
||||||
DIGEST_SIZE_512 :: 64
|
DIGEST_SIZE_512 :: 64
|
||||||
|
// DIGEST_SIZE_512_256 is the SHA-512/256 digest size.
|
||||||
DIGEST_SIZE_512_256 :: 32
|
DIGEST_SIZE_512_256 :: 32
|
||||||
|
|
||||||
|
// Context_256 is a SHA-224 or SHA-256 instance.
|
||||||
|
Context_256 :: struct {
|
||||||
|
block: [SHA256_BLOCK_SIZE]byte,
|
||||||
|
h: [8]u32,
|
||||||
|
bitlength: u64,
|
||||||
|
length: u64,
|
||||||
|
md_bits: int,
|
||||||
|
|
||||||
|
is_initialized: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Context_512 is a SHA-384, SHA-512 or SHA-512/256 instance.
|
||||||
|
Context_512 :: struct {
|
||||||
|
block: [SHA512_BLOCK_SIZE]byte,
|
||||||
|
h: [8]u64,
|
||||||
|
bitlength: u64,
|
||||||
|
length: u64,
|
||||||
|
md_bits: int,
|
||||||
|
|
||||||
|
is_initialized: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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
|
||||||
_init(ctx)
|
_init(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init_256 initializes a Context_256 for SHA-256.
|
||||||
init_256 :: proc(ctx: ^Context_256) {
|
init_256 :: proc(ctx: ^Context_256) {
|
||||||
ctx.md_bits = 256
|
ctx.md_bits = 256
|
||||||
_init(ctx)
|
_init(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init_384 initializes a Context_512 for SHA-384.
|
||||||
init_384 :: proc(ctx: ^Context_512) {
|
init_384 :: proc(ctx: ^Context_512) {
|
||||||
ctx.md_bits = 384
|
ctx.md_bits = 384
|
||||||
_init(ctx)
|
_init(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init_512 initializes a Context_512 for SHA-512.
|
||||||
init_512 :: proc(ctx: ^Context_512) {
|
init_512 :: proc(ctx: ^Context_512) {
|
||||||
ctx.md_bits = 512
|
ctx.md_bits = 512
|
||||||
_init(ctx)
|
_init(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init_512_256 initializes a Context_512 for SHA-512/256.
|
||||||
init_512_256 :: proc(ctx: ^Context_512) {
|
init_512_256 :: proc(ctx: ^Context_512) {
|
||||||
ctx.md_bits = 256
|
ctx.md_bits = 256
|
||||||
_init(ctx)
|
_init(ctx)
|
||||||
@@ -114,6 +151,7 @@ _init :: proc(ctx: ^$T) {
|
|||||||
ctx.is_initialized = true
|
ctx.is_initialized = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update adds more data to the Context.
|
||||||
update :: proc(ctx: ^$T, data: []byte) {
|
update :: proc(ctx: ^$T, data: []byte) {
|
||||||
assert(ctx.is_initialized)
|
assert(ctx.is_initialized)
|
||||||
|
|
||||||
@@ -145,6 +183,11 @@ update :: proc(ctx: ^$T, data: []byte) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// final finalizes the Context, writes the digest to hash, and calls
|
||||||
|
// reset on the Context.
|
||||||
|
//
|
||||||
|
// 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) {
|
final :: proc(ctx: ^$T, hash: []byte, finalize_clone: bool = false) {
|
||||||
assert(ctx.is_initialized)
|
assert(ctx.is_initialized)
|
||||||
|
|
||||||
@@ -203,10 +246,13 @@ final :: proc(ctx: ^$T, hash: []byte, finalize_clone: bool = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clone clones the Context other into ctx.
|
||||||
clone :: proc(ctx, other: ^$T) {
|
clone :: proc(ctx, other: ^$T) {
|
||||||
ctx^ = other^
|
ctx^ = other^
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reset sanitizes the Context. The Context must be re-initialized to
|
||||||
|
// be used again.
|
||||||
reset :: proc(ctx: ^$T) {
|
reset :: proc(ctx: ^$T) {
|
||||||
if !ctx.is_initialized {
|
if !ctx.is_initialized {
|
||||||
return
|
return
|
||||||
@@ -219,29 +265,11 @@ reset :: proc(ctx: ^$T) {
|
|||||||
SHA2 implementation
|
SHA2 implementation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@(private)
|
||||||
SHA256_BLOCK_SIZE :: 64
|
SHA256_BLOCK_SIZE :: 64
|
||||||
|
@(private)
|
||||||
SHA512_BLOCK_SIZE :: 128
|
SHA512_BLOCK_SIZE :: 128
|
||||||
|
|
||||||
Context_256 :: struct {
|
|
||||||
block: [SHA256_BLOCK_SIZE]byte,
|
|
||||||
h: [8]u32,
|
|
||||||
bitlength: u64,
|
|
||||||
length: u64,
|
|
||||||
md_bits: int,
|
|
||||||
|
|
||||||
is_initialized: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
Context_512 :: struct {
|
|
||||||
block: [SHA512_BLOCK_SIZE]byte,
|
|
||||||
h: [8]u64,
|
|
||||||
bitlength: u64,
|
|
||||||
length: u64,
|
|
||||||
md_bits: int,
|
|
||||||
|
|
||||||
is_initialized: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
sha256_k := [64]u32 {
|
sha256_k := [64]u32 {
|
||||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
/*
|
||||||
|
package sha3 implements the SHA3 hash algorithm family.
|
||||||
|
|
||||||
|
The SHAKE XOF can be found in crypto/shake. While discouraged if the
|
||||||
|
pre-standardization Keccak algorithm is required, it can be found in
|
||||||
|
crypto/legacy/keccak.
|
||||||
|
|
||||||
|
See:
|
||||||
|
- https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.202.pdf
|
||||||
|
*/
|
||||||
package sha3
|
package sha3
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6,36 +16,41 @@ package sha3
|
|||||||
|
|
||||||
List of contributors:
|
List of contributors:
|
||||||
zhibog, dotbmp: Initial implementation.
|
zhibog, dotbmp: Initial implementation.
|
||||||
|
|
||||||
Interface for the SHA3 hashing algorithm. The SHAKE functionality can
|
|
||||||
be found in package shake. If you wish to compute a Keccak hash, you
|
|
||||||
can use the legacy/keccak package, it will use the original padding.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import "../_sha3"
|
import "../_sha3"
|
||||||
|
|
||||||
|
// DIGEST_SIZE_224 is the SHA3-224 digest size.
|
||||||
DIGEST_SIZE_224 :: 28
|
DIGEST_SIZE_224 :: 28
|
||||||
|
// DIGEST_SIZE_256 is the SHA3-256 digest size.
|
||||||
DIGEST_SIZE_256 :: 32
|
DIGEST_SIZE_256 :: 32
|
||||||
|
// DIGEST_SIZE_384 is the SHA3-384 digest size.
|
||||||
DIGEST_SIZE_384 :: 48
|
DIGEST_SIZE_384 :: 48
|
||||||
|
// DIGEST_SIZE_512 is the SHA3-512 digest size.
|
||||||
DIGEST_SIZE_512 :: 64
|
DIGEST_SIZE_512 :: 64
|
||||||
|
|
||||||
|
// Context is a SHA3 instance.
|
||||||
Context :: distinct _sha3.Context
|
Context :: distinct _sha3.Context
|
||||||
|
|
||||||
|
// init_224 initializes a Context for SHA3-224.
|
||||||
init_224 :: proc(ctx: ^Context) {
|
init_224 :: proc(ctx: ^Context) {
|
||||||
ctx.mdlen = DIGEST_SIZE_224
|
ctx.mdlen = DIGEST_SIZE_224
|
||||||
_init(ctx)
|
_init(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init_256 initializes a Context for SHA3-256.
|
||||||
init_256 :: proc(ctx: ^Context) {
|
init_256 :: proc(ctx: ^Context) {
|
||||||
ctx.mdlen = DIGEST_SIZE_256
|
ctx.mdlen = DIGEST_SIZE_256
|
||||||
_init(ctx)
|
_init(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init_384 initializes a Context for SHA3-384.
|
||||||
init_384 :: proc(ctx: ^Context) {
|
init_384 :: proc(ctx: ^Context) {
|
||||||
ctx.mdlen = DIGEST_SIZE_384
|
ctx.mdlen = DIGEST_SIZE_384
|
||||||
_init(ctx)
|
_init(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init_512 initializes a Context for SHA3-512.
|
||||||
init_512 :: proc(ctx: ^Context) {
|
init_512 :: proc(ctx: ^Context) {
|
||||||
ctx.mdlen = DIGEST_SIZE_512
|
ctx.mdlen = DIGEST_SIZE_512
|
||||||
_init(ctx)
|
_init(ctx)
|
||||||
@@ -46,18 +61,27 @@ _init :: proc(ctx: ^Context) {
|
|||||||
_sha3.init(transmute(^_sha3.Context)(ctx))
|
_sha3.init(transmute(^_sha3.Context)(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update adds more data to the Context.
|
||||||
update :: proc(ctx: ^Context, data: []byte) {
|
update :: proc(ctx: ^Context, data: []byte) {
|
||||||
_sha3.update(transmute(^_sha3.Context)(ctx), data)
|
_sha3.update(transmute(^_sha3.Context)(ctx), data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// final finalizes the Context, writes the digest to hash, and calls
|
||||||
|
// reset on the Context.
|
||||||
|
//
|
||||||
|
// 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(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
|
||||||
_sha3.final(transmute(^_sha3.Context)(ctx), hash, finalize_clone)
|
_sha3.final(transmute(^_sha3.Context)(ctx), hash, finalize_clone)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clone clones the Context other into ctx.
|
||||||
clone :: proc(ctx, other: ^Context) {
|
clone :: proc(ctx, other: ^Context) {
|
||||||
_sha3.clone(transmute(^_sha3.Context)(ctx), transmute(^_sha3.Context)(other))
|
_sha3.clone(transmute(^_sha3.Context)(ctx), transmute(^_sha3.Context)(other))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reset sanitizes the Context. The Context must be re-initialized to
|
||||||
|
// be used again.
|
||||||
reset :: proc(ctx: ^Context) {
|
reset :: proc(ctx: ^Context) {
|
||||||
_sha3.reset(transmute(^_sha3.Context)(ctx))
|
_sha3.reset(transmute(^_sha3.Context)(ctx))
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-11
@@ -1,3 +1,9 @@
|
|||||||
|
/*
|
||||||
|
package sm3 implements the SM3 hash algorithm.
|
||||||
|
|
||||||
|
See:
|
||||||
|
- https://datatracker.ietf.org/doc/html/draft-sca-cfrg-sm3-02
|
||||||
|
*/
|
||||||
package sm3
|
package sm3
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6,16 +12,26 @@ package sm3
|
|||||||
|
|
||||||
List of contributors:
|
List of contributors:
|
||||||
zhibog, dotbmp: Initial implementation.
|
zhibog, dotbmp: Initial implementation.
|
||||||
|
|
||||||
Implementation of the SM3 hashing algorithm, as defined in <https://datatracker.ietf.org/doc/html/draft-sca-cfrg-sm3-02>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import "core:encoding/endian"
|
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 :: 32
|
DIGEST_SIZE :: 32
|
||||||
|
|
||||||
|
// Context is a SM3 instance.
|
||||||
|
Context :: struct {
|
||||||
|
state: [8]u32,
|
||||||
|
x: [BLOCK_SIZE]byte,
|
||||||
|
bitlength: u64,
|
||||||
|
length: u64,
|
||||||
|
|
||||||
|
is_initialized: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
// init initializes a Context.
|
||||||
init :: proc(ctx: ^Context) {
|
init :: proc(ctx: ^Context) {
|
||||||
ctx.state[0] = IV[0]
|
ctx.state[0] = IV[0]
|
||||||
ctx.state[1] = IV[1]
|
ctx.state[1] = IV[1]
|
||||||
@@ -32,6 +48,7 @@ init :: proc(ctx: ^Context) {
|
|||||||
ctx.is_initialized = true
|
ctx.is_initialized = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update adds more data to the Context.
|
||||||
update :: proc(ctx: ^Context, data: []byte) {
|
update :: proc(ctx: ^Context, data: []byte) {
|
||||||
assert(ctx.is_initialized)
|
assert(ctx.is_initialized)
|
||||||
|
|
||||||
@@ -57,6 +74,11 @@ update :: proc(ctx: ^Context, data: []byte) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// final finalizes the Context, writes the digest to hash, and calls
|
||||||
|
// reset on the Context.
|
||||||
|
//
|
||||||
|
// 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(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
|
||||||
assert(ctx.is_initialized)
|
assert(ctx.is_initialized)
|
||||||
|
|
||||||
@@ -92,10 +114,13 @@ final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clone clones the Context other into ctx.
|
||||||
clone :: proc(ctx, other: ^Context) {
|
clone :: proc(ctx, other: ^Context) {
|
||||||
ctx^ = other^
|
ctx^ = other^
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reset sanitizes the Context. The Context must be re-initialized to
|
||||||
|
// be used again.
|
||||||
reset :: proc(ctx: ^Context) {
|
reset :: proc(ctx: ^Context) {
|
||||||
if !ctx.is_initialized {
|
if !ctx.is_initialized {
|
||||||
return
|
return
|
||||||
@@ -108,17 +133,9 @@ reset :: proc(ctx: ^Context) {
|
|||||||
SM3 implementation
|
SM3 implementation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@(private)
|
||||||
BLOCK_SIZE :: 64
|
BLOCK_SIZE :: 64
|
||||||
|
|
||||||
Context :: struct {
|
|
||||||
state: [8]u32,
|
|
||||||
x: [BLOCK_SIZE]byte,
|
|
||||||
bitlength: u64,
|
|
||||||
length: u64,
|
|
||||||
|
|
||||||
is_initialized: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
IV := [8]u32 {
|
IV := [8]u32 {
|
||||||
0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600,
|
0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600,
|
||||||
|
|||||||
Reference in New Issue
Block a user