mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
core/crypto/tuplehash: Initial import
This commit is contained in:
@@ -28,6 +28,20 @@ init_cshake :: proc(ctx: ^Context, n, s: []byte, sec_strength: int) {
|
||||
bytepad(ctx, [][]byte{n, s}, rate)
|
||||
}
|
||||
|
||||
final_cshake :: proc(ctx: ^Context, dst: []byte, finalize_clone: bool = false) {
|
||||
ctx := ctx
|
||||
if finalize_clone {
|
||||
tmp_ctx: Context
|
||||
clone(&tmp_ctx, ctx)
|
||||
ctx = &tmp_ctx
|
||||
}
|
||||
defer reset(ctx)
|
||||
|
||||
encode_byte_len(ctx, len(dst), false) // right_encode
|
||||
shake_xof(ctx)
|
||||
shake_out(ctx, dst)
|
||||
}
|
||||
|
||||
// right_encode and left_encode are defined to support 0 <= x < 2^2040
|
||||
// however, the largest value we will ever need to encode is `max(int) * 8`.
|
||||
//
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
package tuplehash implements the TupleHash and TupleHashXOF algorithms.
|
||||
|
||||
See:
|
||||
- https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-185.pdf
|
||||
*/
|
||||
package tuplehash
|
||||
|
||||
import "../_sha3"
|
||||
|
||||
// Context is a TupleHash or TupleHashXOF instance.
|
||||
Context :: distinct _sha3.Context
|
||||
|
||||
// init_128 initializes a Context for TupleHash128 or TupleHashXOF128.
|
||||
init_128 :: proc(ctx: ^Context, domain_sep: []byte) {
|
||||
_sha3.init_cshake(transmute(^_sha3.Context)(ctx), N_TUPLEHASH, domain_sep, 128)
|
||||
}
|
||||
|
||||
// init_256 initializes a Context for TupleHash256 or TupleHashXOF256.
|
||||
init_256 :: proc(ctx: ^Context, domain_sep: []byte) {
|
||||
_sha3.init_cshake(transmute(^_sha3.Context)(ctx), N_TUPLEHASH, domain_sep, 256)
|
||||
}
|
||||
|
||||
// write_element writes a tuple element into the TupleHash or TupleHashXOF
|
||||
// instance. This MUST not be called after any reads have been done, and
|
||||
// any attempts to do so will panic.
|
||||
write_element :: proc(ctx: ^Context, data: []byte) {
|
||||
_, _ = _sha3.encode_string(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) {
|
||||
_sha3.final_cshake(transmute(^_sha3.Context)(ctx), hash, finalize_clone)
|
||||
}
|
||||
|
||||
// read reads output from the TupleHashXOF instance. There is no practical
|
||||
// upper limit to the amount of data that can be read from TupleHashXOF.
|
||||
// After read has been called one or more times, further calls to
|
||||
// write_element will panic.
|
||||
read :: proc(ctx: ^Context, dst: []byte) {
|
||||
ctx_ := transmute(^_sha3.Context)(ctx)
|
||||
if !ctx.is_finalized {
|
||||
_sha3.encode_byte_len(ctx_, 0, false) // right_encode
|
||||
_sha3.shake_xof(ctx_)
|
||||
}
|
||||
|
||||
_sha3.shake_out(ctx_, dst)
|
||||
}
|
||||
|
||||
// clone clones the Context other into ctx.
|
||||
clone :: proc(ctx, other: ^Context) {
|
||||
_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) {
|
||||
_sha3.reset(transmute(^_sha3.Context)(ctx))
|
||||
}
|
||||
|
||||
@(private)
|
||||
N_TUPLEHASH := []byte{'T', 'u', 'p', 'l', 'e', 'H', 'a', 's', 'h'}
|
||||
Reference in New Issue
Block a user