mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-10 05:11:37 -07: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'}
|
||||
@@ -40,6 +40,7 @@ import sha2 "core:crypto/sha2"
|
||||
import sha3 "core:crypto/sha3"
|
||||
import shake "core:crypto/shake"
|
||||
import sm3 "core:crypto/sm3"
|
||||
import tuplehash "core:crypto/tuplehash"
|
||||
import x25519 "core:crypto/x25519"
|
||||
|
||||
import pe "core:debug/pe"
|
||||
@@ -159,6 +160,7 @@ _ :: sha2
|
||||
_ :: sha3
|
||||
_ :: shake
|
||||
_ :: sm3
|
||||
_ :: tuplehash
|
||||
_ :: x25519
|
||||
_ :: pe
|
||||
_ :: dynlib
|
||||
|
||||
@@ -22,7 +22,6 @@ import "core:crypto"
|
||||
import "core:crypto/chacha20"
|
||||
import "core:crypto/chacha20poly1305"
|
||||
|
||||
import "core:crypto/shake"
|
||||
import "core:crypto/x25519"
|
||||
|
||||
TEST_count := 0
|
||||
@@ -57,8 +56,8 @@ main :: proc() {
|
||||
|
||||
test_chacha20(&t)
|
||||
test_chacha20poly1305(&t)
|
||||
test_shake(&t)
|
||||
test_x25519(&t)
|
||||
test_sha3_variants(&t)
|
||||
|
||||
bench_crypto(&t)
|
||||
|
||||
@@ -412,132 +411,3 @@ test_rand_bytes :: proc(t: ^testing.T) {
|
||||
"Expected to randomize the head and tail of the buffer within a handful of attempts",
|
||||
)
|
||||
}
|
||||
|
||||
TestXOF :: struct {
|
||||
sec_strength: int,
|
||||
domainsep: string,
|
||||
output: string,
|
||||
str: string,
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_shake :: proc(t: ^testing.T) {
|
||||
test_vectors := [?]TestXOF {
|
||||
// SHAKE128
|
||||
{
|
||||
128,
|
||||
"",
|
||||
"7f9c2ba4e88f827d616045507605853e",
|
||||
"",
|
||||
},
|
||||
{
|
||||
128,
|
||||
"",
|
||||
"f4202e3c5852f9182a0430fd8144f0a7",
|
||||
"The quick brown fox jumps over the lazy dog",
|
||||
},
|
||||
{
|
||||
128,
|
||||
"",
|
||||
"853f4538be0db9621a6cea659a06c110",
|
||||
"The quick brown fox jumps over the lazy dof",
|
||||
},
|
||||
|
||||
// SHAKE256
|
||||
{
|
||||
256,
|
||||
"",
|
||||
"46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f",
|
||||
"",
|
||||
},
|
||||
{
|
||||
256,
|
||||
"",
|
||||
"2f671343d9b2e1604dc9dcf0753e5fe15c7c64a0d283cbbf722d411a0e36f6ca",
|
||||
"The quick brown fox jumps over the lazy dog",
|
||||
},
|
||||
{
|
||||
256,
|
||||
"",
|
||||
"46b1ebb2e142c38b9ac9081bef72877fe4723959640fa57119b366ce6899d401",
|
||||
"The quick brown fox jumps over the lazy dof",
|
||||
},
|
||||
|
||||
// cSHAKE128
|
||||
// - https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/cSHAKE_samples.pdf
|
||||
{
|
||||
128,
|
||||
"Email Signature",
|
||||
"c1c36925b6409a04f1b504fcbca9d82b4017277cb5ed2b2065fc1d3814d5aaf5",
|
||||
"00010203",
|
||||
},
|
||||
{
|
||||
128,
|
||||
"Email Signature",
|
||||
"c5221d50e4f822d96a2e8881a961420f294b7b24fe3d2094baed2c6524cc166b",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7",
|
||||
},
|
||||
|
||||
// cSHAKE256
|
||||
// - https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/cSHAKE_samples.pdf
|
||||
{
|
||||
256,
|
||||
"Email Signature",
|
||||
"d008828e2b80ac9d2218ffee1d070c48b8e4c87bff32c9699d5b6896eee0edd164020e2be0560858d9c00c037e34a96937c561a74c412bb4c746469527281c8c",
|
||||
"00010203",
|
||||
},
|
||||
{
|
||||
256,
|
||||
"Email Signature",
|
||||
"07dc27b11e51fbac75bc7b3c1d983e8b4b85fb1defaf218912ac86430273091727f42b17ed1df63e8ec118f04b23633c1dfb1574c8fb55cb45da8e25afb092bb",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7",
|
||||
},
|
||||
}
|
||||
for v in test_vectors {
|
||||
dst := make([]byte, len(v.output)/2, context.temp_allocator)
|
||||
|
||||
data := transmute([]byte)(v.str)
|
||||
domainsep := transmute([]byte)(v.domainsep)
|
||||
|
||||
alg_prefix := ""
|
||||
ctx: shake.Context
|
||||
if len(domainsep) == 0 {
|
||||
switch v.sec_strength {
|
||||
case 128:
|
||||
shake.init_128(&ctx)
|
||||
case 256:
|
||||
shake.init_256(&ctx)
|
||||
}
|
||||
} else {
|
||||
alg_prefix = "c"
|
||||
|
||||
// The cSHAKE samples from NIST are binary data.
|
||||
data, _ = hex.decode(data)
|
||||
|
||||
switch v.sec_strength {
|
||||
case 128:
|
||||
shake.init_cshake_128(&ctx, domainsep)
|
||||
case 256:
|
||||
shake.init_cshake_256(&ctx, domainsep)
|
||||
}
|
||||
}
|
||||
|
||||
shake.write(&ctx, data)
|
||||
shake.read(&ctx, dst)
|
||||
|
||||
dst_str := string(hex.encode(dst, context.temp_allocator))
|
||||
|
||||
expect(
|
||||
t,
|
||||
dst_str == v.output,
|
||||
fmt.tprintf(
|
||||
"%sSHAKE%d: Expected: %s for input of %s, but got %s instead",
|
||||
alg_prefix,
|
||||
v.sec_strength,
|
||||
v.output,
|
||||
v.str,
|
||||
dst_str,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,341 @@
|
||||
package test_core_crypto
|
||||
|
||||
import "core:encoding/hex"
|
||||
import "core:fmt"
|
||||
import "core:testing"
|
||||
|
||||
import "core:crypto/shake"
|
||||
import "core:crypto/tuplehash"
|
||||
|
||||
@(test)
|
||||
test_sha3_variants :: proc(t: ^testing.T) {
|
||||
log(t, "Testing SHA3 derived functions")
|
||||
|
||||
test_shake(t)
|
||||
test_cshake(t)
|
||||
test_tuplehash(t)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_shake :: proc(t: ^testing.T) {
|
||||
log(t, "Testing SHAKE")
|
||||
|
||||
test_vectors := []struct {
|
||||
sec_strength: int,
|
||||
output: string,
|
||||
str: string,
|
||||
} {
|
||||
// SHAKE128
|
||||
{128, "7f9c2ba4e88f827d616045507605853e", ""},
|
||||
{128, "f4202e3c5852f9182a0430fd8144f0a7", "The quick brown fox jumps over the lazy dog"},
|
||||
{128, "853f4538be0db9621a6cea659a06c110", "The quick brown fox jumps over the lazy dof"},
|
||||
|
||||
// SHAKE256
|
||||
{256, "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f", ""},
|
||||
{
|
||||
256,
|
||||
"2f671343d9b2e1604dc9dcf0753e5fe15c7c64a0d283cbbf722d411a0e36f6ca",
|
||||
"The quick brown fox jumps over the lazy dog",
|
||||
},
|
||||
{
|
||||
256,
|
||||
"46b1ebb2e142c38b9ac9081bef72877fe4723959640fa57119b366ce6899d401",
|
||||
"The quick brown fox jumps over the lazy dof",
|
||||
},
|
||||
}
|
||||
|
||||
for v in test_vectors {
|
||||
dst := make([]byte, len(v.output) / 2, context.temp_allocator)
|
||||
|
||||
ctx: shake.Context
|
||||
switch v.sec_strength {
|
||||
case 128:
|
||||
shake.init_128(&ctx)
|
||||
case 256:
|
||||
shake.init_256(&ctx)
|
||||
}
|
||||
|
||||
shake.write(&ctx, transmute([]byte)(v.str))
|
||||
shake.read(&ctx, dst)
|
||||
|
||||
dst_str := string(hex.encode(dst, context.temp_allocator))
|
||||
|
||||
expect(
|
||||
t,
|
||||
dst_str == v.output,
|
||||
fmt.tprintf(
|
||||
"SHAKE%d: Expected: %s for input of %s, but got %s instead",
|
||||
v.sec_strength,
|
||||
v.output,
|
||||
v.str,
|
||||
dst_str,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_cshake :: proc(t: ^testing.T) {
|
||||
log(t, "Testing cSHAKE")
|
||||
|
||||
test_vectors := []struct {
|
||||
sec_strength: int,
|
||||
domainsep: string,
|
||||
output: string,
|
||||
str: string,
|
||||
} {
|
||||
// cSHAKE128
|
||||
// - https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/cSHAKE_samples.pdf
|
||||
{
|
||||
128,
|
||||
"Email Signature",
|
||||
"c1c36925b6409a04f1b504fcbca9d82b4017277cb5ed2b2065fc1d3814d5aaf5",
|
||||
"00010203",
|
||||
},
|
||||
{
|
||||
128,
|
||||
"Email Signature",
|
||||
"c5221d50e4f822d96a2e8881a961420f294b7b24fe3d2094baed2c6524cc166b",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7",
|
||||
},
|
||||
|
||||
// cSHAKE256
|
||||
// - https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/cSHAKE_samples.pdf
|
||||
{
|
||||
256,
|
||||
"Email Signature",
|
||||
"d008828e2b80ac9d2218ffee1d070c48b8e4c87bff32c9699d5b6896eee0edd164020e2be0560858d9c00c037e34a96937c561a74c412bb4c746469527281c8c",
|
||||
"00010203",
|
||||
},
|
||||
{
|
||||
256,
|
||||
"Email Signature",
|
||||
"07dc27b11e51fbac75bc7b3c1d983e8b4b85fb1defaf218912ac86430273091727f42b17ed1df63e8ec118f04b23633c1dfb1574c8fb55cb45da8e25afb092bb",
|
||||
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7",
|
||||
},
|
||||
}
|
||||
|
||||
for v in test_vectors {
|
||||
dst := make([]byte, len(v.output) / 2, context.temp_allocator)
|
||||
|
||||
domainsep := transmute([]byte)(v.domainsep)
|
||||
|
||||
ctx: shake.Context
|
||||
switch v.sec_strength {
|
||||
case 128:
|
||||
shake.init_cshake_128(&ctx, domainsep)
|
||||
case 256:
|
||||
shake.init_cshake_256(&ctx, domainsep)
|
||||
}
|
||||
|
||||
data, _ := hex.decode(transmute([]byte)(v.str))
|
||||
shake.write(&ctx, data)
|
||||
shake.read(&ctx, dst)
|
||||
|
||||
dst_str := string(hex.encode(dst, context.temp_allocator))
|
||||
|
||||
expect(
|
||||
t,
|
||||
dst_str == v.output,
|
||||
fmt.tprintf(
|
||||
"cSHAKE%d: Expected: %s for input of %s, but got %s instead",
|
||||
v.sec_strength,
|
||||
v.output,
|
||||
v.str,
|
||||
dst_str,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_tuplehash :: proc(t: ^testing.T) {
|
||||
log(t, "Testing TupleHash(XOF)")
|
||||
|
||||
test_vectors := []struct {
|
||||
sec_strength: int,
|
||||
domainsep: string,
|
||||
output: string,
|
||||
tuple: []string,
|
||||
is_xof: bool,
|
||||
} {
|
||||
// TupleHash128
|
||||
// - https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/TupleHash_samples.pdf
|
||||
{
|
||||
128,
|
||||
"",
|
||||
"c5d8786c1afb9b82111ab34b65b2c0048fa64e6d48e263264ce1707d3ffc8ed1",
|
||||
[]string{
|
||||
"000102",
|
||||
"101112131415",
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
128,
|
||||
"My Tuple App",
|
||||
"75cdb20ff4db1154e841d758e24160c54bae86eb8c13e7f5f40eb35588e96dfb",
|
||||
[]string{
|
||||
"000102",
|
||||
"101112131415",
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
128,
|
||||
"My Tuple App",
|
||||
"e60f202c89a2631eda8d4c588ca5fd07f39e5151998deccf973adb3804bb6e84",
|
||||
[]string{
|
||||
"000102",
|
||||
"101112131415",
|
||||
"202122232425262728",
|
||||
},
|
||||
false,
|
||||
},
|
||||
|
||||
// TupleHash256
|
||||
// - https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/TupleHash_samples.pdf
|
||||
{
|
||||
256,
|
||||
"",
|
||||
"cfb7058caca5e668f81a12a20a2195ce97a925f1dba3e7449a56f82201ec607311ac2696b1ab5ea2352df1423bde7bd4bb78c9aed1a853c78672f9eb23bbe194",
|
||||
[]string{
|
||||
"000102",
|
||||
"101112131415",
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
256,
|
||||
"My Tuple App",
|
||||
"147c2191d5ed7efd98dbd96d7ab5a11692576f5fe2a5065f3e33de6bba9f3aa1c4e9a068a289c61c95aab30aee1e410b0b607de3620e24a4e3bf9852a1d4367e",
|
||||
[]string{
|
||||
"000102",
|
||||
"101112131415",
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
256,
|
||||
"My Tuple App",
|
||||
"45000be63f9b6bfd89f54717670f69a9bc763591a4f05c50d68891a744bcc6e7d6d5b5e82c018da999ed35b0bb49c9678e526abd8e85c13ed254021db9e790ce",
|
||||
[]string{
|
||||
"000102",
|
||||
"101112131415",
|
||||
"202122232425262728",
|
||||
},
|
||||
false,
|
||||
},
|
||||
|
||||
// TupleHashXOF128
|
||||
// - https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/TupleHashXOF_samples.pdf
|
||||
{
|
||||
128,
|
||||
"",
|
||||
"2f103cd7c32320353495c68de1a8129245c6325f6f2a3d608d92179c96e68488",
|
||||
[]string{
|
||||
"000102",
|
||||
"101112131415",
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
128,
|
||||
"My Tuple App",
|
||||
"3fc8ad69453128292859a18b6c67d7ad85f01b32815e22ce839c49ec374e9b9a",
|
||||
[]string{
|
||||
"000102",
|
||||
"101112131415",
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
128,
|
||||
"My Tuple App",
|
||||
"900fe16cad098d28e74d632ed852f99daab7f7df4d99e775657885b4bf76d6f8",
|
||||
[]string{
|
||||
"000102",
|
||||
"101112131415",
|
||||
"202122232425262728",
|
||||
},
|
||||
true,
|
||||
},
|
||||
|
||||
// TupleHashXOF256
|
||||
// - https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/TupleHashXOF_samples.pdf
|
||||
{
|
||||
256,
|
||||
"",
|
||||
"03ded4610ed6450a1e3f8bc44951d14fbc384ab0efe57b000df6b6df5aae7cd568e77377daf13f37ec75cf5fc598b6841d51dd207c991cd45d210ba60ac52eb9",
|
||||
[]string{
|
||||
"000102",
|
||||
"101112131415",
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
256,
|
||||
"My Tuple App",
|
||||
"6483cb3c9952eb20e830af4785851fc597ee3bf93bb7602c0ef6a65d741aeca7e63c3b128981aa05c6d27438c79d2754bb1b7191f125d6620fca12ce658b2442",
|
||||
[]string{
|
||||
"000102",
|
||||
"101112131415",
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
256,
|
||||
"My Tuple App",
|
||||
"0c59b11464f2336c34663ed51b2b950bec743610856f36c28d1d088d8a2446284dd09830a6a178dc752376199fae935d86cfdee5913d4922dfd369b66a53c897",
|
||||
[]string{
|
||||
"000102",
|
||||
"101112131415",
|
||||
"202122232425262728",
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for v in test_vectors {
|
||||
dst := make([]byte, len(v.output) / 2, context.temp_allocator)
|
||||
|
||||
domainsep := transmute([]byte)(v.domainsep)
|
||||
|
||||
ctx: tuplehash.Context
|
||||
switch v.sec_strength {
|
||||
case 128:
|
||||
tuplehash.init_128(&ctx, domainsep)
|
||||
case 256:
|
||||
tuplehash.init_256(&ctx, domainsep)
|
||||
}
|
||||
|
||||
for e in v.tuple {
|
||||
data, _ := hex.decode(transmute([]byte)(e))
|
||||
tuplehash.write_element(&ctx, data)
|
||||
}
|
||||
|
||||
suffix: string
|
||||
switch v.is_xof {
|
||||
case true:
|
||||
suffix = "XOF"
|
||||
tuplehash.read(&ctx, dst)
|
||||
case false:
|
||||
tuplehash.final(&ctx, dst)
|
||||
}
|
||||
|
||||
dst_str := string(hex.encode(dst, context.temp_allocator))
|
||||
|
||||
expect(
|
||||
t,
|
||||
dst_str == v.output,
|
||||
fmt.tprintf(
|
||||
"TupleHash%s%d: Expected: %s for input of %v, but got %s instead",
|
||||
suffix,
|
||||
v.sec_strength,
|
||||
v.output,
|
||||
v.tuple,
|
||||
dst_str,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user