mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-18 12:30:28 +00:00
Update tests\core\crypto
This commit is contained in:
committed by
Feoramund
parent
a463e282db
commit
a0b2ea6d6e
@@ -42,15 +42,15 @@ compress_test:
|
||||
container_test:
|
||||
$(ODIN) test container $(COMMON) -define:test_progress_width=4 -out:test_core_container
|
||||
|
||||
crypto_test:
|
||||
$(ODIN) test crypto $(COMMON) -define:test_progress_width=18 -o:speed -out:test_crypto
|
||||
|
||||
strings_test:
|
||||
$(ODIN) run strings $(COMMON) -out:test_core_strings
|
||||
|
||||
hash_test:
|
||||
$(ODIN) run hash $(COMMON) -o:speed -out:test_hash
|
||||
|
||||
crypto_test:
|
||||
$(ODIN) run crypto $(COMMON) $(COLLECTION) -o:speed -out:test_crypto
|
||||
|
||||
noise_test:
|
||||
$(ODIN) run math/noise $(COMMON) -out:test_noise
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ echo ---
|
||||
echo ---
|
||||
echo Running core:crypto tests
|
||||
echo ---
|
||||
%PATH_TO_ODIN% run crypto %COMMON% %COLLECTION% -out:test_crypto.exe || exit /b
|
||||
%PATH_TO_ODIN% test crypto %COMMON% define:test_progress_width=18 -o:speed -out:test_crypto.exe || exit /b
|
||||
|
||||
echo ---
|
||||
echo Running core:encoding tests
|
||||
|
||||
@@ -13,41 +13,20 @@ package test_core_crypto
|
||||
*/
|
||||
|
||||
import "core:encoding/hex"
|
||||
import "core:fmt"
|
||||
import "core:mem"
|
||||
import "core:testing"
|
||||
import "base:runtime"
|
||||
import "core:log"
|
||||
|
||||
import "core:crypto"
|
||||
import "core:crypto/chacha20"
|
||||
import "core:crypto/chacha20poly1305"
|
||||
|
||||
import tc "tests:common"
|
||||
|
||||
main :: proc() {
|
||||
t := testing.T{}
|
||||
|
||||
test_rand_bytes(&t)
|
||||
|
||||
test_hash(&t)
|
||||
test_mac(&t)
|
||||
test_kdf(&t) // After hash/mac tests because those should pass first.
|
||||
test_ecc25519(&t)
|
||||
|
||||
test_aes(&t)
|
||||
test_chacha20(&t)
|
||||
test_chacha20poly1305(&t)
|
||||
test_sha3_variants(&t)
|
||||
|
||||
bench_crypto(&t)
|
||||
|
||||
tc.report(&t)
|
||||
}
|
||||
|
||||
_PLAINTEXT_SUNSCREEN_STR := "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."
|
||||
|
||||
@(test)
|
||||
test_chacha20 :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing (X)ChaCha20")
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
// Test cases taken from RFC 8439, and draft-irtf-cfrg-xchacha-03
|
||||
plaintext := transmute([]byte)(_PLAINTEXT_SUNSCREEN_STR)
|
||||
@@ -90,14 +69,12 @@ test_chacha20 :: proc(t: ^testing.T) {
|
||||
chacha20.xor_bytes(&ctx, derived_ciphertext[:], plaintext[:])
|
||||
|
||||
derived_ciphertext_str := string(hex.encode(derived_ciphertext[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
derived_ciphertext_str == ciphertext_str,
|
||||
fmt.tprintf(
|
||||
"Expected %s for xor_bytes(plaintext_str), but got %s instead",
|
||||
ciphertext_str,
|
||||
derived_ciphertext_str,
|
||||
),
|
||||
"Expected %s for xor_bytes(plaintext_str), but got %s instead",
|
||||
ciphertext_str,
|
||||
derived_ciphertext_str,
|
||||
)
|
||||
|
||||
xkey := [chacha20.KEY_SIZE]byte {
|
||||
@@ -137,21 +114,17 @@ test_chacha20 :: proc(t: ^testing.T) {
|
||||
chacha20.xor_bytes(&ctx, derived_ciphertext[:], plaintext[:])
|
||||
|
||||
derived_ciphertext_str = string(hex.encode(derived_ciphertext[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
derived_ciphertext_str == xciphertext_str,
|
||||
fmt.tprintf(
|
||||
"Expected %s for xor_bytes(plaintext_str), but got %s instead",
|
||||
xciphertext_str,
|
||||
derived_ciphertext_str,
|
||||
),
|
||||
"Expected %s for xor_bytes(plaintext_str), but got %s instead",
|
||||
xciphertext_str,
|
||||
derived_ciphertext_str,
|
||||
)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_chacha20poly1305 :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing chacha20poly1205")
|
||||
|
||||
plaintext := transmute([]byte)(_PLAINTEXT_SUNSCREEN_STR)
|
||||
|
||||
aad := [12]byte {
|
||||
@@ -209,25 +182,21 @@ test_chacha20poly1305 :: proc(t: ^testing.T) {
|
||||
)
|
||||
|
||||
derived_ciphertext_str := string(hex.encode(derived_ciphertext[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
derived_ciphertext_str == ciphertext_str,
|
||||
fmt.tprintf(
|
||||
"Expected ciphertext %s for encrypt(aad, plaintext), but got %s instead",
|
||||
ciphertext_str,
|
||||
derived_ciphertext_str,
|
||||
),
|
||||
"Expected ciphertext %s for encrypt(aad, plaintext), but got %s instead",
|
||||
ciphertext_str,
|
||||
derived_ciphertext_str,
|
||||
)
|
||||
|
||||
derived_tag_str := string(hex.encode(derived_tag[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
derived_tag_str == tag_str,
|
||||
fmt.tprintf(
|
||||
"Expected tag %s for encrypt(aad, plaintext), but got %s instead",
|
||||
tag_str,
|
||||
derived_tag_str,
|
||||
),
|
||||
"Expected tag %s for encrypt(aad, plaintext), but got %s instead",
|
||||
tag_str,
|
||||
derived_tag_str,
|
||||
)
|
||||
|
||||
derived_plaintext: [114]byte
|
||||
@@ -240,15 +209,13 @@ test_chacha20poly1305 :: proc(t: ^testing.T) {
|
||||
ciphertext[:],
|
||||
)
|
||||
derived_plaintext_str := string(derived_plaintext[:])
|
||||
tc.expect(t, ok, "Expected true for decrypt(tag, aad, ciphertext)")
|
||||
tc.expect(
|
||||
testing.expect(t, ok, "Expected true for decrypt(tag, aad, ciphertext)")
|
||||
testing.expectf(
|
||||
t,
|
||||
derived_plaintext_str == _PLAINTEXT_SUNSCREEN_STR,
|
||||
fmt.tprintf(
|
||||
"Expected plaintext %s for decrypt(tag, aad, ciphertext), but got %s instead",
|
||||
_PLAINTEXT_SUNSCREEN_STR,
|
||||
derived_plaintext_str,
|
||||
),
|
||||
"Expected plaintext %s for decrypt(tag, aad, ciphertext), but got %s instead",
|
||||
_PLAINTEXT_SUNSCREEN_STR,
|
||||
derived_plaintext_str,
|
||||
)
|
||||
|
||||
derived_ciphertext[0] ~= 0xa5
|
||||
@@ -260,7 +227,7 @@ test_chacha20poly1305 :: proc(t: ^testing.T) {
|
||||
aad[:],
|
||||
derived_ciphertext[:],
|
||||
)
|
||||
tc.expect(t, !ok, "Expected false for decrypt(tag, aad, corrupted_ciphertext)")
|
||||
testing.expect(t, !ok, "Expected false for decrypt(tag, aad, corrupted_ciphertext)")
|
||||
|
||||
aad[0] ~= 0xa5
|
||||
ok = chacha20poly1305.decrypt(
|
||||
@@ -271,15 +238,13 @@ test_chacha20poly1305 :: proc(t: ^testing.T) {
|
||||
aad[:],
|
||||
ciphertext[:],
|
||||
)
|
||||
tc.expect(t, !ok, "Expected false for decrypt(tag, corrupted_aad, ciphertext)")
|
||||
testing.expect(t, !ok, "Expected false for decrypt(tag, corrupted_aad, ciphertext)")
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_rand_bytes :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing rand_bytes")
|
||||
|
||||
if !crypto.HAS_RAND_BYTES {
|
||||
tc.log(t, "rand_bytes not supported - skipping")
|
||||
log.info("rand_bytes not supported - skipping")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -307,10 +272,5 @@ test_rand_bytes :: proc(t: ^testing.T) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
tc.expect(
|
||||
t,
|
||||
seems_ok,
|
||||
"Expected to randomize the head and tail of the buffer within a handful of attempts",
|
||||
)
|
||||
testing.expect(t, seems_ok, "Expected to randomize the head and tail of the buffer within a handful of attempts")
|
||||
}
|
||||
|
||||
@@ -2,19 +2,17 @@ package test_core_crypto
|
||||
|
||||
import "base:runtime"
|
||||
import "core:encoding/hex"
|
||||
import "core:fmt"
|
||||
import "core:log"
|
||||
import "core:testing"
|
||||
|
||||
import "core:crypto/aes"
|
||||
import "core:crypto/sha2"
|
||||
|
||||
import tc "tests:common"
|
||||
|
||||
@(test)
|
||||
test_aes :: proc(t: ^testing.T) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
tc.log(t, "Testing AES")
|
||||
log.info("Testing AES")
|
||||
|
||||
impls := make([dynamic]aes.Implementation, 0, 2)
|
||||
append(&impls, aes.Implementation.Portable)
|
||||
@@ -29,9 +27,8 @@ test_aes :: proc(t: ^testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_aes_ecb :: proc(t: ^testing.T, impl: aes.Implementation) {
|
||||
tc.log(t, fmt.tprintf("Testing AES-ECB/%v", impl))
|
||||
log.infof("Testing AES-ECB/%v", impl)
|
||||
|
||||
test_vectors := []struct {
|
||||
key: string,
|
||||
@@ -111,39 +108,34 @@ test_aes_ecb :: proc(t: ^testing.T, impl: aes.Implementation) {
|
||||
|
||||
aes.encrypt_ecb(&ctx, dst[:], plaintext)
|
||||
dst_str := string(hex.encode(dst[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == v.ciphertext,
|
||||
fmt.tprintf(
|
||||
"AES-ECB/%v: Expected: %s for encrypt(%s, %s), but got %s instead",
|
||||
impl,
|
||||
v.ciphertext,
|
||||
v.key,
|
||||
v.plaintext,
|
||||
dst_str,
|
||||
),
|
||||
"AES-ECB/%v: Expected: %s for encrypt(%s, %s), but got %s instead",
|
||||
impl,
|
||||
v.ciphertext,
|
||||
v.key,
|
||||
v.plaintext,
|
||||
dst_str,
|
||||
)
|
||||
|
||||
aes.decrypt_ecb(&ctx, dst[:], ciphertext)
|
||||
dst_str = string(hex.encode(dst[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == v.plaintext,
|
||||
fmt.tprintf(
|
||||
"AES-ECB/%v: Expected: %s for decrypt(%s, %s), but got %s instead",
|
||||
impl,
|
||||
v.plaintext,
|
||||
v.key,
|
||||
v.ciphertext,
|
||||
dst_str,
|
||||
),
|
||||
"AES-ECB/%v: Expected: %s for decrypt(%s, %s), but got %s instead",
|
||||
impl,
|
||||
v.plaintext,
|
||||
v.key,
|
||||
v.ciphertext,
|
||||
dst_str,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_aes_ctr :: proc(t: ^testing.T, impl: aes.Implementation) {
|
||||
tc.log(t, fmt.tprintf("Testing AES-CTR/%v", impl))
|
||||
log.infof("Testing AES-CTR/%v", impl)
|
||||
|
||||
test_vectors := []struct {
|
||||
key: string,
|
||||
@@ -185,18 +177,16 @@ test_aes_ctr :: proc(t: ^testing.T, impl: aes.Implementation) {
|
||||
aes.xor_bytes_ctr(&ctx, dst, plaintext)
|
||||
|
||||
dst_str := string(hex.encode(dst[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == v.ciphertext,
|
||||
fmt.tprintf(
|
||||
"AES-CTR/%v: Expected: %s for encrypt(%s, %s, %s), but got %s instead",
|
||||
impl,
|
||||
v.ciphertext,
|
||||
v.key,
|
||||
v.iv,
|
||||
v.plaintext,
|
||||
dst_str,
|
||||
),
|
||||
"AES-CTR/%v: Expected: %s for encrypt(%s, %s, %s), but got %s instead",
|
||||
impl,
|
||||
v.ciphertext,
|
||||
v.key,
|
||||
v.iv,
|
||||
v.plaintext,
|
||||
dst_str,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -224,21 +214,18 @@ test_aes_ctr :: proc(t: ^testing.T, impl: aes.Implementation) {
|
||||
digest_str := string(hex.encode(digest[:], context.temp_allocator))
|
||||
|
||||
expected_digest_str := "d4445343afeb9d1237f95b10d00358aed4c1d7d57c9fe480cd0afb5e2ffd448c"
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
expected_digest_str == digest_str,
|
||||
fmt.tprintf(
|
||||
"AES-CTR/%v: Expected %s for keystream digest, but got %s instead",
|
||||
impl,
|
||||
expected_digest_str,
|
||||
digest_str,
|
||||
),
|
||||
"AES-CTR/%v: Expected %s for keystream digest, but got %s instead",
|
||||
impl,
|
||||
expected_digest_str,
|
||||
digest_str,
|
||||
)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_aes_gcm :: proc(t: ^testing.T, impl: aes.Implementation) {
|
||||
tc.log(t, fmt.tprintf("Testing AES-GCM/%v", impl))
|
||||
log.infof("Testing AES-GCM/%v", impl)
|
||||
|
||||
// NIST did a reorg of their site, so the source of the test vectors
|
||||
// is only available from an archive. The commented out tests are
|
||||
@@ -422,41 +409,37 @@ test_aes_gcm :: proc(t: ^testing.T, impl: aes.Implementation) {
|
||||
dst_str := string(hex.encode(dst[:], context.temp_allocator))
|
||||
tag_str := string(hex.encode(tag_[:], context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == v.ciphertext && tag_str == v.tag,
|
||||
fmt.tprintf(
|
||||
"AES-GCM/%v: Expected: (%s, %s) for seal(%s, %s, %s, %s), but got (%s, %s) instead",
|
||||
impl,
|
||||
v.ciphertext,
|
||||
v.tag,
|
||||
v.key,
|
||||
v.iv,
|
||||
v.aad,
|
||||
v.plaintext,
|
||||
dst_str,
|
||||
tag_str,
|
||||
),
|
||||
"AES-GCM/%v: Expected: (%s, %s) for seal(%s, %s, %s, %s), but got (%s, %s) instead",
|
||||
impl,
|
||||
v.ciphertext,
|
||||
v.tag,
|
||||
v.key,
|
||||
v.iv,
|
||||
v.aad,
|
||||
v.plaintext,
|
||||
dst_str,
|
||||
tag_str,
|
||||
)
|
||||
|
||||
ok := aes.open_gcm(&ctx, dst, iv, aad, ciphertext, tag)
|
||||
dst_str = string(hex.encode(dst[:], context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok && dst_str == v.plaintext,
|
||||
fmt.tprintf(
|
||||
"AES-GCM/%v: Expected: (%s, true) for open(%s, %s, %s, %s, %s), but got (%s, %s) instead",
|
||||
impl,
|
||||
v.plaintext,
|
||||
v.key,
|
||||
v.iv,
|
||||
v.aad,
|
||||
v.ciphertext,
|
||||
v.tag,
|
||||
dst_str,
|
||||
ok,
|
||||
),
|
||||
"AES-GCM/%v: Expected: (%s, true) for open(%s, %s, %s, %s, %s), but got (%s, %s) instead",
|
||||
impl,
|
||||
v.plaintext,
|
||||
v.key,
|
||||
v.iv,
|
||||
v.aad,
|
||||
v.ciphertext,
|
||||
v.tag,
|
||||
dst_str,
|
||||
ok,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package test_core_crypto
|
||||
|
||||
import "base:runtime"
|
||||
import "core:encoding/hex"
|
||||
import "core:fmt"
|
||||
import "core:testing"
|
||||
|
||||
import field "core:crypto/_fiat/field_curve25519"
|
||||
@@ -10,25 +8,8 @@ import "core:crypto/ed25519"
|
||||
import "core:crypto/ristretto255"
|
||||
import "core:crypto/x25519"
|
||||
|
||||
import tc "tests:common"
|
||||
|
||||
@(test)
|
||||
test_ecc25519 :: proc(t: ^testing.T) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
tc.log(t, "Testing curve25519 ECC")
|
||||
|
||||
test_sqrt_ratio_m1(t)
|
||||
test_ristretto255(t)
|
||||
|
||||
test_ed25519(t)
|
||||
test_x25519(t)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_sqrt_ratio_m1 :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing sqrt_ratio_m1")
|
||||
|
||||
test_vectors := []struct {
|
||||
u: string,
|
||||
v: string,
|
||||
@@ -90,25 +71,21 @@ test_sqrt_ratio_m1 :: proc(t: ^testing.T) {
|
||||
field.fe_relax_cast(&vee),
|
||||
)
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
(was_square == 1) == v.was_square && field.fe_equal_bytes(&r, r_) == 1,
|
||||
fmt.tprintf(
|
||||
"Expected (%v, %s) for SQRT_RATIO_M1(%s, %s), got %s",
|
||||
v.was_square,
|
||||
v.r,
|
||||
v.u,
|
||||
v.v,
|
||||
fe_str(&r),
|
||||
),
|
||||
"Expected (%v, %s) for SQRT_RATIO_M1(%s, %s), got %s",
|
||||
v.was_square,
|
||||
v.r,
|
||||
v.u,
|
||||
v.v,
|
||||
fe_str(&r),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_ristretto255 :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing ristretto255")
|
||||
|
||||
ge_gen: ristretto255.Group_Element
|
||||
ristretto255.ge_generator(&ge_gen)
|
||||
|
||||
@@ -158,7 +135,7 @@ test_ristretto255 :: proc(t: ^testing.T) {
|
||||
|
||||
ge: ristretto255.Group_Element
|
||||
ok := ristretto255.ge_set_bytes(&ge, b)
|
||||
tc.expect(t, !ok, fmt.tprintf("Expected false for %s", x))
|
||||
testing.expectf(t, !ok, "Expected false for %s", x)
|
||||
}
|
||||
|
||||
generator_multiples := []string {
|
||||
@@ -185,22 +162,20 @@ test_ristretto255 :: proc(t: ^testing.T) {
|
||||
|
||||
ge := &ges[i]
|
||||
ok := ristretto255.ge_set_bytes(ge, b)
|
||||
tc.expect(t, ok, fmt.tprintf("Expected true for %s", x))
|
||||
testing.expectf(t, ok, "Expected true for %s", x)
|
||||
|
||||
x_check := ge_str(ge)
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
x == x_check,
|
||||
fmt.tprintf(
|
||||
"Expected %s (round-trip) but got %s instead",
|
||||
x,
|
||||
x_check,
|
||||
),
|
||||
"Expected %s (round-trip) but got %s instead",
|
||||
x,
|
||||
x_check,
|
||||
)
|
||||
|
||||
if i == 1 {
|
||||
tc.expect(
|
||||
testing.expect(
|
||||
t,
|
||||
ristretto255.ge_equal(ge, &ge_gen) == 1,
|
||||
"Expected element 1 to be the generator",
|
||||
@@ -217,41 +192,35 @@ test_ristretto255 :: proc(t: ^testing.T) {
|
||||
|
||||
ristretto255.ge_scalarmult_generator(&ge_check, &sc)
|
||||
x_check := ge_str(&ge_check)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
x_check == generator_multiples[i],
|
||||
fmt.tprintf(
|
||||
"Expected %s for G * %d (specialized), got %s",
|
||||
generator_multiples[i],
|
||||
i,
|
||||
x_check,
|
||||
),
|
||||
"Expected %s for G * %d (specialized), got %s",
|
||||
generator_multiples[i],
|
||||
i,
|
||||
x_check,
|
||||
)
|
||||
|
||||
ristretto255.ge_scalarmult(&ge_check, &ges[1], &sc)
|
||||
x_check = ge_str(&ge_check)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
x_check == generator_multiples[i],
|
||||
fmt.tprintf(
|
||||
"Expected %s for G * %d (generic), got %s (slow compare)",
|
||||
generator_multiples[i],
|
||||
i,
|
||||
x_check,
|
||||
),
|
||||
"Expected %s for G * %d (generic), got %s (slow compare)",
|
||||
generator_multiples[i],
|
||||
i,
|
||||
x_check,
|
||||
)
|
||||
|
||||
ristretto255.ge_scalarmult_vartime(&ge_check, &ges[1], &sc)
|
||||
x_check = ge_str(&ge_check)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
x_check == generator_multiples[i],
|
||||
fmt.tprintf(
|
||||
"Expected %s for G * %d (generic vartime), got %s (slow compare)",
|
||||
generator_multiples[i],
|
||||
i,
|
||||
x_check,
|
||||
),
|
||||
"Expected %s for G * %d (generic vartime), got %s (slow compare)",
|
||||
generator_multiples[i],
|
||||
i,
|
||||
x_check,
|
||||
)
|
||||
|
||||
switch i {
|
||||
@@ -261,28 +230,24 @@ test_ristretto255 :: proc(t: ^testing.T) {
|
||||
ristretto255.ge_add(&ge_check, ge_prev, &ge_gen)
|
||||
|
||||
x_check = ge_str(&ge_check)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
x_check == generator_multiples[i],
|
||||
fmt.tprintf(
|
||||
"Expected %s for ges[%d] + ges[%d], got %s (slow compare)",
|
||||
generator_multiples[i],
|
||||
i-1,
|
||||
1,
|
||||
x_check,
|
||||
),
|
||||
"Expected %s for ges[%d] + ges[%d], got %s (slow compare)",
|
||||
generator_multiples[i],
|
||||
i-1,
|
||||
1,
|
||||
x_check,
|
||||
)
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ristretto255.ge_equal(&ges[i], &ge_check) == 1,
|
||||
fmt.tprintf(
|
||||
"Expected %s for ges[%d] + ges[%d], got %s (fast compare)",
|
||||
generator_multiples[i],
|
||||
i-1,
|
||||
1,
|
||||
x_check,
|
||||
),
|
||||
"Expected %s for ges[%d] + ges[%d], got %s (fast compare)",
|
||||
generator_multiples[i],
|
||||
i-1,
|
||||
1,
|
||||
x_check,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -344,22 +309,18 @@ test_ristretto255 :: proc(t: ^testing.T) {
|
||||
ristretto255.ge_set_wide_bytes(&ge, in_bytes)
|
||||
|
||||
ge_check := ge_str(&ge)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ge_check == v.output,
|
||||
fmt.tprintf(
|
||||
"Expected %s for %s, got %s",
|
||||
v.output,
|
||||
ge_check,
|
||||
),
|
||||
"Expected %s for %s, got %s",
|
||||
v.output,
|
||||
ge_check,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_ed25519 :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing ed25519")
|
||||
|
||||
test_vectors_rfc := []struct {
|
||||
priv_key: string,
|
||||
pub_key: string,
|
||||
@@ -401,87 +362,73 @@ test_ed25519 :: proc(t: ^testing.T) {
|
||||
|
||||
priv_key: ed25519.Private_Key
|
||||
ok := ed25519.private_key_set_bytes(&priv_key, priv_bytes)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok,
|
||||
fmt.tprintf(
|
||||
"Expected %s to be a valid private key",
|
||||
v.priv_key,
|
||||
),
|
||||
"Expected %s to be a valid private key",
|
||||
v.priv_key,
|
||||
)
|
||||
|
||||
key_bytes: [32]byte
|
||||
ed25519.private_key_bytes(&priv_key, key_bytes[:])
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok,
|
||||
fmt.tprintf(
|
||||
"Expected private key %s round-trip, got %s",
|
||||
v.priv_key,
|
||||
string(hex.encode(key_bytes[:], context.temp_allocator)),
|
||||
),
|
||||
"Expected private key %s round-trip, got %s",
|
||||
v.priv_key,
|
||||
string(hex.encode(key_bytes[:], context.temp_allocator)),
|
||||
)
|
||||
|
||||
pub_key: ed25519.Public_Key
|
||||
ok = ed25519.public_key_set_bytes(&pub_key, pub_bytes)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok,
|
||||
fmt.tprintf(
|
||||
"Expected %s to be a valid public key (priv->pub: %s)",
|
||||
v.pub_key,
|
||||
string(hex.encode(priv_key._pub_key._b[:], context.temp_allocator)),
|
||||
),
|
||||
"Expected %s to be a valid public key (priv->pub: %s)",
|
||||
v.pub_key,
|
||||
string(hex.encode(priv_key._pub_key._b[:], context.temp_allocator)),
|
||||
)
|
||||
|
||||
ed25519.public_key_bytes(&pub_key, key_bytes[:])
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok,
|
||||
fmt.tprintf(
|
||||
"Expected public key %s round-trip, got %s",
|
||||
v.pub_key,
|
||||
string(hex.encode(key_bytes[:], context.temp_allocator)),
|
||||
),
|
||||
"Expected public key %s round-trip, got %s",
|
||||
v.pub_key,
|
||||
string(hex.encode(key_bytes[:], context.temp_allocator)),
|
||||
)
|
||||
|
||||
sig: [ed25519.SIGNATURE_SIZE]byte
|
||||
ed25519.sign(&priv_key, msg_bytes, sig[:])
|
||||
x := string(hex.encode(sig[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
x == v.sig,
|
||||
fmt.tprintf(
|
||||
"Expected %s for sign(%s, %s), got %s",
|
||||
v.sig,
|
||||
v.priv_key,
|
||||
v.msg,
|
||||
x,
|
||||
),
|
||||
"Expected %s for sign(%s, %s), got %s",
|
||||
v.sig,
|
||||
v.priv_key,
|
||||
v.msg,
|
||||
x,
|
||||
)
|
||||
|
||||
ok = ed25519.verify(&pub_key, msg_bytes, sig_bytes)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok,
|
||||
fmt.tprintf(
|
||||
"Expected true for verify(%s, %s, %s)",
|
||||
v.pub_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
),
|
||||
"Expected true for verify(%s, %s, %s)",
|
||||
v.pub_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
)
|
||||
|
||||
ok = ed25519.verify(&priv_key._pub_key, msg_bytes, sig_bytes)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok,
|
||||
fmt.tprintf(
|
||||
"Expected true for verify(pub(%s), %s %s)",
|
||||
v.priv_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
),
|
||||
"Expected true for verify(pub(%s), %s %s)",
|
||||
v.priv_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
)
|
||||
|
||||
// Corrupt the message and make sure verification fails.
|
||||
@@ -493,15 +440,13 @@ test_ed25519 :: proc(t: ^testing.T) {
|
||||
msg_bytes[0] = msg_bytes[0] ~ 69
|
||||
}
|
||||
ok = ed25519.verify(&pub_key, msg_bytes, sig_bytes)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok == false,
|
||||
fmt.tprintf(
|
||||
"Expected false for verify(%s, %s (corrupted), %s)",
|
||||
v.pub_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
),
|
||||
"Expected false for verify(%s, %s (corrupted), %s)",
|
||||
v.pub_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -634,15 +579,13 @@ test_ed25519 :: proc(t: ^testing.T) {
|
||||
|
||||
pub_key: ed25519.Public_Key
|
||||
ok := ed25519.public_key_set_bytes(&pub_key, pub_bytes)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok == v.pub_key_ok,
|
||||
fmt.tprintf(
|
||||
"speccheck/%d: Expected %s to be a (in)valid public key, got %v",
|
||||
i,
|
||||
v.pub_key,
|
||||
ok,
|
||||
),
|
||||
"speccheck/%d: Expected %s to be a (in)valid public key, got %v",
|
||||
i,
|
||||
v.pub_key,
|
||||
ok,
|
||||
)
|
||||
|
||||
// If A is rejected for being non-canonical, skip signature check.
|
||||
@@ -651,17 +594,15 @@ test_ed25519 :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
ok = ed25519.verify(&pub_key, msg_bytes, sig_bytes)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok == v.sig_ok,
|
||||
fmt.tprintf(
|
||||
"speccheck/%d Expected %v for verify(%s, %s, %s)",
|
||||
i,
|
||||
v.sig_ok,
|
||||
v.pub_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
),
|
||||
"speccheck/%d Expected %v for verify(%s, %s, %s)",
|
||||
i,
|
||||
v.sig_ok,
|
||||
v.pub_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
)
|
||||
|
||||
// If the signature is accepted, skip the relaxed signature check.
|
||||
@@ -670,25 +611,21 @@ test_ed25519 :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
ok = ed25519.verify(&pub_key, msg_bytes, sig_bytes, true)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
ok == v.sig_ok_relaxed,
|
||||
fmt.tprintf(
|
||||
"speccheck/%d Expected %v for verify(%s, %s, %s, true)",
|
||||
i,
|
||||
v.sig_ok_relaxed,
|
||||
v.pub_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
),
|
||||
"speccheck/%d Expected %v for verify(%s, %s, %s, true)",
|
||||
i,
|
||||
v.sig_ok_relaxed,
|
||||
v.pub_key,
|
||||
v.msg,
|
||||
v.sig,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_x25519 :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing X25519")
|
||||
|
||||
// Local copy of this so that the base point doesn't need to be exported.
|
||||
_BASE_POINT: [32]byte = {
|
||||
9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
@@ -720,17 +657,15 @@ test_x25519 :: proc(t: ^testing.T) {
|
||||
x25519.scalarmult(derived_point[:], scalar[:], point[:])
|
||||
derived_point_str := string(hex.encode(derived_point[:], context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
derived_point_str == v.product,
|
||||
fmt.tprintf(
|
||||
"Expected %s for %s * %s, but got %s instead",
|
||||
v.product,
|
||||
v.scalar,
|
||||
v.point,
|
||||
derived_point_str,
|
||||
),
|
||||
)
|
||||
"Expected %s for %s * %s, but got %s instead",
|
||||
v.product,
|
||||
v.scalar,
|
||||
v.point,
|
||||
derived_point_str,
|
||||
)
|
||||
|
||||
// Abuse the test vectors to sanity-check the scalar-basepoint multiply.
|
||||
p1, p2: [x25519.POINT_SIZE]byte
|
||||
@@ -738,15 +673,13 @@ test_x25519 :: proc(t: ^testing.T) {
|
||||
x25519.scalarmult(p2[:], scalar[:], _BASE_POINT[:])
|
||||
p1_str := string(hex.encode(p1[:], context.temp_allocator))
|
||||
p2_str := string(hex.encode(p2[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
p1_str == p2_str,
|
||||
fmt.tprintf(
|
||||
"Expected %s for %s * basepoint, but got %s instead",
|
||||
p2_str,
|
||||
v.scalar,
|
||||
p1_str,
|
||||
),
|
||||
"Expected %s for %s * basepoint, but got %s instead",
|
||||
p2_str,
|
||||
v.scalar,
|
||||
p1_str,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -763,4 +696,4 @@ fe_str :: proc(fe: ^field.Tight_Field_Element) -> string {
|
||||
b: [32]byte
|
||||
field.fe_to_bytes(&b, fe)
|
||||
return string(hex.encode(b[:], context.temp_allocator))
|
||||
}
|
||||
}
|
||||
@@ -3,23 +3,17 @@ package test_core_crypto
|
||||
import "base:runtime"
|
||||
import "core:bytes"
|
||||
import "core:encoding/hex"
|
||||
import "core:fmt"
|
||||
import "core:strings"
|
||||
import "core:testing"
|
||||
|
||||
import "core:crypto/hash"
|
||||
|
||||
import tc "tests:common"
|
||||
|
||||
@(test)
|
||||
test_hash :: proc(t: ^testing.T) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
tc.log(t, "Testing Hashes")
|
||||
|
||||
// TODO:
|
||||
// - Stick the test vectors in a JSON file or something.
|
||||
data_1_000_000_a := strings.repeat("a", 1_000_000)
|
||||
data_1_000_000_a := strings.repeat("a", 1_000_000, context.temp_allocator)
|
||||
|
||||
digest: [hash.MAX_DIGEST_SIZE]byte
|
||||
test_vectors := []struct{
|
||||
@@ -496,16 +490,14 @@ test_hash :: proc(t: ^testing.T) {
|
||||
|
||||
dst_str := string(hex.encode(dst, context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == v.hash,
|
||||
fmt.tprintf(
|
||||
"%s/incremental: Expected: %s for input of %s, but got %s instead",
|
||||
algo_name,
|
||||
v.hash,
|
||||
v.str,
|
||||
dst_str,
|
||||
),
|
||||
"%s/incremental: Expected: %s for input of %s, but got %s instead",
|
||||
algo_name,
|
||||
v.hash,
|
||||
v.str,
|
||||
dst_str,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -521,25 +513,21 @@ test_hash :: proc(t: ^testing.T) {
|
||||
// still correct.
|
||||
digest_sz := hash.DIGEST_SIZES[algo]
|
||||
block_sz := hash.BLOCK_SIZES[algo]
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
digest_sz <= hash.MAX_DIGEST_SIZE,
|
||||
fmt.tprintf(
|
||||
"%s: Digest size %d exceeds max %d",
|
||||
algo_name,
|
||||
digest_sz,
|
||||
hash.MAX_DIGEST_SIZE,
|
||||
),
|
||||
"%s: Digest size %d exceeds max %d",
|
||||
algo_name,
|
||||
digest_sz,
|
||||
hash.MAX_DIGEST_SIZE,
|
||||
)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
block_sz <= hash.MAX_BLOCK_SIZE,
|
||||
fmt.tprintf(
|
||||
"%s: Block size %d exceeds max %d",
|
||||
algo_name,
|
||||
block_sz,
|
||||
hash.MAX_BLOCK_SIZE,
|
||||
),
|
||||
"%s: Block size %d exceeds max %d",
|
||||
algo_name,
|
||||
block_sz,
|
||||
hash.MAX_BLOCK_SIZE,
|
||||
)
|
||||
|
||||
// Exercise most of the happy-path for the high level interface.
|
||||
@@ -553,15 +541,13 @@ test_hash :: proc(t: ^testing.T) {
|
||||
a_str := string(hex.encode(digest_a, context.temp_allocator))
|
||||
b_str := string(hex.encode(digest_b, context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
a_str == b_str,
|
||||
fmt.tprintf(
|
||||
"%s/cmp: Expected: %s (hash_stream) == %s (hash_bytes)",
|
||||
algo_name,
|
||||
a_str,
|
||||
b_str,
|
||||
),
|
||||
"%s/cmp: Expected: %s (hash_stream) == %s (hash_bytes)",
|
||||
algo_name,
|
||||
a_str,
|
||||
b_str,
|
||||
)
|
||||
|
||||
// Exercise the rolling digest functionality, which also covers
|
||||
@@ -571,25 +557,21 @@ test_hash :: proc(t: ^testing.T) {
|
||||
|
||||
api_algo := hash.algorithm(&ctx)
|
||||
api_digest_size := hash.digest_size(&ctx)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
algo == api_algo,
|
||||
fmt.tprintf(
|
||||
"%s/algorithm: Expected: %v but got %v instead",
|
||||
algo_name,
|
||||
algo,
|
||||
api_algo,
|
||||
),
|
||||
"%s/algorithm: Expected: %v but got %v instead",
|
||||
algo_name,
|
||||
algo,
|
||||
api_algo,
|
||||
)
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
hash.DIGEST_SIZES[algo] == api_digest_size,
|
||||
fmt.tprintf(
|
||||
"%s/digest_size: Expected: %d but got %d instead",
|
||||
algo_name,
|
||||
hash.DIGEST_SIZES[algo],
|
||||
api_digest_size,
|
||||
),
|
||||
"%s/digest_size: Expected: %d but got %d instead",
|
||||
algo_name,
|
||||
hash.DIGEST_SIZES[algo],
|
||||
api_digest_size,
|
||||
)
|
||||
|
||||
hash.update(&ctx, digest_a)
|
||||
@@ -604,16 +586,14 @@ test_hash :: proc(t: ^testing.T) {
|
||||
b_str = string(hex.encode(digest_b, context.temp_allocator))
|
||||
c_str := string(hex.encode(digest_c, context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
a_str == b_str && b_str == c_str,
|
||||
fmt.tprintf(
|
||||
"%s/rolling: Expected: %s (first) == %s (second) == %s (third)",
|
||||
algo_name,
|
||||
a_str,
|
||||
b_str,
|
||||
c_str,
|
||||
),
|
||||
"%s/rolling: Expected: %s (first) == %s (second) == %s (third)",
|
||||
algo_name,
|
||||
a_str,
|
||||
b_str,
|
||||
c_str,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,28 +2,14 @@ package test_core_crypto
|
||||
|
||||
import "base:runtime"
|
||||
import "core:encoding/hex"
|
||||
import "core:fmt"
|
||||
import "core:testing"
|
||||
|
||||
import "core:crypto/hash"
|
||||
import "core:crypto/hkdf"
|
||||
import "core:crypto/pbkdf2"
|
||||
|
||||
import tc "tests:common"
|
||||
|
||||
@(test)
|
||||
test_kdf :: proc(t: ^testing.T) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
tc.log(t, "Testing KDFs")
|
||||
|
||||
test_hkdf(t)
|
||||
test_pbkdf2(t)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_hkdf :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing HKDF")
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
tmp: [128]byte // Good enough.
|
||||
|
||||
@@ -70,25 +56,23 @@ test_hkdf :: proc(t: ^testing.T) {
|
||||
|
||||
dst_str := string(hex.encode(dst, context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == v.okm,
|
||||
fmt.tprintf(
|
||||
"HKDF-%s: Expected: %s for input of (%s, %s, %s), but got %s instead",
|
||||
algo_name,
|
||||
v.okm,
|
||||
v.ikm,
|
||||
v.salt,
|
||||
v.info,
|
||||
dst_str,
|
||||
),
|
||||
"HKDF-%s: Expected: %s for input of (%s, %s, %s), but got %s instead",
|
||||
algo_name,
|
||||
v.okm,
|
||||
v.ikm,
|
||||
v.salt,
|
||||
v.info,
|
||||
dst_str,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_pbkdf2 :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing PBKDF2")
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
tmp: [64]byte // 512-bits is enough for every output for now.
|
||||
|
||||
@@ -174,18 +158,16 @@ test_pbkdf2 :: proc(t: ^testing.T) {
|
||||
|
||||
dst_str := string(hex.encode(dst, context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == v.dk,
|
||||
fmt.tprintf(
|
||||
"HMAC-%s: Expected: %s for input of (%s, %s, %d), but got %s instead",
|
||||
algo_name,
|
||||
v.dk,
|
||||
v.password,
|
||||
v.salt,
|
||||
v.iterations,
|
||||
dst_str,
|
||||
),
|
||||
"HMAC-%s: Expected: %s for input of (%s, %s, %d), but got %s instead",
|
||||
algo_name,
|
||||
v.dk,
|
||||
v.password,
|
||||
v.salt,
|
||||
v.iterations,
|
||||
dst_str,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,30 +2,17 @@ package test_core_crypto
|
||||
|
||||
import "base:runtime"
|
||||
import "core:encoding/hex"
|
||||
import "core:fmt"
|
||||
import "core:mem"
|
||||
import "core:testing"
|
||||
|
||||
import "core:crypto/hash"
|
||||
import "core:crypto/hmac"
|
||||
import "core:crypto/poly1305"
|
||||
import "core:crypto/siphash"
|
||||
|
||||
import tc "tests:common"
|
||||
|
||||
@(test)
|
||||
test_mac :: proc(t: ^testing.T) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
tc.log(t, "Testing MACs")
|
||||
|
||||
test_hmac(t)
|
||||
test_poly1305(t)
|
||||
test_siphash_2_4(t)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_hmac :: proc(t: ^testing.T) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
// Test cases pulled out of RFC 6234, note that HMAC is a generic
|
||||
// construct so as long as the underlying hash is correct and all
|
||||
// the code paths are covered the implementation is "fine", so
|
||||
@@ -86,40 +73,36 @@ test_hmac :: proc(t: ^testing.T) {
|
||||
msg_str := string(hex.encode(msg, context.temp_allocator))
|
||||
dst_str := string(hex.encode(dst[:tag_len], context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == expected_str,
|
||||
fmt.tprintf(
|
||||
"%s/incremental: Expected: %s for input of %s - %s, but got %s instead",
|
||||
algo_name,
|
||||
tags_sha256[i],
|
||||
key_str,
|
||||
msg_str,
|
||||
dst_str,
|
||||
),
|
||||
"%s/incremental: Expected: %s for input of %s - %s, but got %s instead",
|
||||
algo_name,
|
||||
tags_sha256[i],
|
||||
key_str,
|
||||
msg_str,
|
||||
dst_str,
|
||||
)
|
||||
|
||||
hmac.sum(algo, dst, msg, key)
|
||||
oneshot_str := string(hex.encode(dst[:tag_len], context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
oneshot_str == expected_str,
|
||||
fmt.tprintf(
|
||||
"%s/oneshot: Expected: %s for input of %s - %s, but got %s instead",
|
||||
algo_name,
|
||||
tags_sha256[i],
|
||||
key_str,
|
||||
msg_str,
|
||||
oneshot_str,
|
||||
),
|
||||
"%s/oneshot: Expected: %s for input of %s - %s, but got %s instead",
|
||||
algo_name,
|
||||
tags_sha256[i],
|
||||
key_str,
|
||||
msg_str,
|
||||
oneshot_str,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_poly1305 :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing poly1305")
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
// Test cases taken from poly1305-donna.
|
||||
key := [poly1305.KEY_SIZE]byte {
|
||||
@@ -157,16 +140,17 @@ test_poly1305 :: proc(t: ^testing.T) {
|
||||
|
||||
// Verify - oneshot + compare
|
||||
ok := poly1305.verify(tag[:], msg[:], key[:])
|
||||
tc.expect(t, ok, "oneshot verify call failed")
|
||||
testing.expect(t, ok, "oneshot verify call failed")
|
||||
|
||||
// Sum - oneshot
|
||||
derived_tag: [poly1305.TAG_SIZE]byte
|
||||
poly1305.sum(derived_tag[:], msg[:], key[:])
|
||||
derived_tag_str := string(hex.encode(derived_tag[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
derived_tag_str == tag_str,
|
||||
fmt.tprintf("Expected %s for sum(msg, key), but got %s instead", tag_str, derived_tag_str),
|
||||
"Expected %s for sum(msg, key), but got %s instead",
|
||||
tag_str, derived_tag_str,
|
||||
)
|
||||
|
||||
// Incremental
|
||||
@@ -182,21 +166,16 @@ test_poly1305 :: proc(t: ^testing.T) {
|
||||
}
|
||||
poly1305.final(&ctx, derived_tag[:])
|
||||
derived_tag_str = string(hex.encode(derived_tag[:], context.temp_allocator))
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
derived_tag_str == tag_str,
|
||||
fmt.tprintf(
|
||||
"Expected %s for init/update/final - incremental, but got %s instead",
|
||||
tag_str,
|
||||
derived_tag_str,
|
||||
),
|
||||
"Expected %s for init/update/final - incremental, but got %s instead",
|
||||
tag_str, derived_tag_str,
|
||||
)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_siphash_2_4 :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing SipHash-2-4")
|
||||
|
||||
// Test vectors from
|
||||
// https://github.com/veorq/SipHash/blob/master/vectors.h
|
||||
test_vectors := [?]u64 {
|
||||
@@ -225,6 +204,7 @@ test_siphash_2_4 :: proc(t: ^testing.T) {
|
||||
|
||||
for i in 0 ..< len(test_vectors) {
|
||||
data := make([]byte, i)
|
||||
defer delete(data)
|
||||
for j in 0 ..< i {
|
||||
data[j] = byte(j)
|
||||
}
|
||||
@@ -232,15 +212,13 @@ test_siphash_2_4 :: proc(t: ^testing.T) {
|
||||
vector := test_vectors[i]
|
||||
computed := siphash.sum_2_4(data[:], key[:])
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
computed == vector,
|
||||
fmt.tprintf(
|
||||
"Expected: 0x%x for input of %v, but got 0x%x instead",
|
||||
vector,
|
||||
data,
|
||||
computed,
|
||||
),
|
||||
"Expected: 0x%x for input of %v, but got 0x%x instead",
|
||||
vector,
|
||||
data,
|
||||
computed,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,30 +2,14 @@ package test_core_crypto
|
||||
|
||||
import "base:runtime"
|
||||
import "core:encoding/hex"
|
||||
import "core:fmt"
|
||||
import "core:testing"
|
||||
|
||||
import "core:crypto/kmac"
|
||||
import "core:crypto/shake"
|
||||
import "core:crypto/tuplehash"
|
||||
|
||||
import tc "tests:common"
|
||||
|
||||
@(test)
|
||||
test_sha3_variants :: proc(t: ^testing.T) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
tc.log(t, "Testing SHA3 derived functions")
|
||||
|
||||
test_shake(t)
|
||||
test_cshake(t)
|
||||
test_tuplehash(t)
|
||||
test_kmac(t)
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_shake :: proc(t: ^testing.T) {
|
||||
tc.log(t, "Testing SHAKE")
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
test_vectors := []struct {
|
||||
sec_strength: int,
|
||||
@@ -67,23 +51,21 @@ test_shake :: proc(t: ^testing.T) {
|
||||
|
||||
dst_str := string(hex.encode(dst, context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
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,
|
||||
),
|
||||
"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) {
|
||||
tc.log(t, "Testing cSHAKE")
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
test_vectors := []struct {
|
||||
sec_strength: int,
|
||||
@@ -135,29 +117,27 @@ test_cshake :: proc(t: ^testing.T) {
|
||||
shake.init_cshake_256(&ctx, domainsep)
|
||||
}
|
||||
|
||||
data, _ := hex.decode(transmute([]byte)(v.str))
|
||||
data, _ := hex.decode(transmute([]byte)(v.str), context.temp_allocator)
|
||||
shake.write(&ctx, data)
|
||||
shake.read(&ctx, dst)
|
||||
|
||||
dst_str := string(hex.encode(dst, context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
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,
|
||||
),
|
||||
"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) {
|
||||
tc.log(t, "Testing TupleHash(XOF)")
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
test_vectors := []struct {
|
||||
sec_strength: int,
|
||||
@@ -317,7 +297,7 @@ test_tuplehash :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
for e in v.tuple {
|
||||
data, _ := hex.decode(transmute([]byte)(e))
|
||||
data, _ := hex.decode(transmute([]byte)(e), context.temp_allocator)
|
||||
tuplehash.write_element(&ctx, data)
|
||||
}
|
||||
|
||||
@@ -332,24 +312,22 @@ test_tuplehash :: proc(t: ^testing.T) {
|
||||
|
||||
dst_str := string(hex.encode(dst, context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
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,
|
||||
),
|
||||
"TupleHash%s%d: Expected: %s for input of %v, but got %s instead",
|
||||
suffix,
|
||||
v.sec_strength,
|
||||
v.output,
|
||||
v.tuple,
|
||||
dst_str,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_kmac :: proc(t:^testing.T) {
|
||||
tc.log(t, "Testing KMAC")
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
test_vectors := []struct {
|
||||
sec_strength: int,
|
||||
@@ -410,7 +388,7 @@ test_kmac :: proc(t:^testing.T) {
|
||||
for v in test_vectors {
|
||||
dst := make([]byte, len(v.output) / 2, context.temp_allocator)
|
||||
|
||||
key, _ := hex.decode(transmute([]byte)(v.key))
|
||||
key, _ := hex.decode(transmute([]byte)(v.key), context.temp_allocator)
|
||||
domainsep := transmute([]byte)(v.domainsep)
|
||||
|
||||
ctx: kmac.Context
|
||||
@@ -421,24 +399,22 @@ test_kmac :: proc(t:^testing.T) {
|
||||
kmac.init_256(&ctx, key, domainsep)
|
||||
}
|
||||
|
||||
data, _ := hex.decode(transmute([]byte)(v.msg))
|
||||
data, _ := hex.decode(transmute([]byte)(v.msg), context.temp_allocator)
|
||||
kmac.update(&ctx, data)
|
||||
kmac.final(&ctx, dst)
|
||||
|
||||
dst_str := string(hex.encode(dst, context.temp_allocator))
|
||||
|
||||
tc.expect(
|
||||
testing.expectf(
|
||||
t,
|
||||
dst_str == v.output,
|
||||
fmt.tprintf(
|
||||
"KMAC%d: Expected: %s for input of (%s, %s, %s), but got %s instead",
|
||||
v.sec_strength,
|
||||
v.output,
|
||||
v.key,
|
||||
v.domainsep,
|
||||
v.msg,
|
||||
dst_str,
|
||||
),
|
||||
"KMAC%d: Expected: %s for input of (%s, %s, %s), but got %s instead",
|
||||
v.sec_strength,
|
||||
v.output,
|
||||
v.key,
|
||||
v.domainsep,
|
||||
v.msg,
|
||||
dst_str,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package test_core_crypto
|
||||
|
||||
import "base:runtime"
|
||||
import "core:encoding/hex"
|
||||
import "core:fmt"
|
||||
import "core:log"
|
||||
import "core:testing"
|
||||
import "core:time"
|
||||
|
||||
@@ -13,16 +13,11 @@ import "core:crypto/ed25519"
|
||||
import "core:crypto/poly1305"
|
||||
import "core:crypto/x25519"
|
||||
|
||||
import tc "tests:common"
|
||||
|
||||
// Cryptographic primitive benchmarks.
|
||||
|
||||
@(test)
|
||||
bench_crypto :: proc(t: ^testing.T) {
|
||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||
|
||||
fmt.println("Starting benchmarks:")
|
||||
|
||||
bench_chacha20(t)
|
||||
bench_poly1305(t)
|
||||
bench_chacha20poly1305(t)
|
||||
@@ -157,8 +152,8 @@ _benchmark_aes256_gcm :: proc(
|
||||
}
|
||||
|
||||
benchmark_print :: proc(name: string, options: ^time.Benchmark_Options) {
|
||||
fmt.printf(
|
||||
"\t[%v] %v rounds, %v bytes processed in %v ns\n\t\t%5.3f rounds/s, %5.3f MiB/s\n",
|
||||
log.infof(
|
||||
"\n\t[%v] %v rounds, %v bytes processed in %v ns\n\t\t%5.3f rounds/s, %5.3f MiB/s",
|
||||
name,
|
||||
options.rounds,
|
||||
options.processed,
|
||||
@@ -179,19 +174,19 @@ bench_chacha20 :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
err := time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "ChaCha20 1024 bytes"
|
||||
options.bytes = 1024
|
||||
err = time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "ChaCha20 65536 bytes"
|
||||
options.bytes = 65536
|
||||
err = time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
}
|
||||
|
||||
@@ -206,13 +201,13 @@ bench_poly1305 :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
err := time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "Poly1305 1024 zero bytes"
|
||||
options.bytes = 1024
|
||||
err = time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
}
|
||||
|
||||
@@ -227,19 +222,19 @@ bench_chacha20poly1305 :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
err := time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "chacha20poly1305 1024 bytes"
|
||||
options.bytes = 1024
|
||||
err = time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "chacha20poly1305 65536 bytes"
|
||||
options.bytes = 65536
|
||||
err = time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
}
|
||||
|
||||
@@ -265,19 +260,19 @@ bench_aes256_gcm :: proc(t: ^testing.T) {
|
||||
context.user_ptr = &ctx
|
||||
|
||||
err := time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "AES256-GCM 1024 bytes"
|
||||
options.bytes = 1024
|
||||
err = time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "AES256-GCM 65536 bytes"
|
||||
options.bytes = 65536
|
||||
err = time.benchmark(options, context.allocator)
|
||||
tc.expect(t, err == nil, name)
|
||||
testing.expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
}
|
||||
|
||||
@@ -293,12 +288,9 @@ bench_ed25519 :: proc(t: ^testing.T) {
|
||||
assert(ok, "private key should deserialize")
|
||||
}
|
||||
elapsed := time.since(start)
|
||||
tc.log(
|
||||
t,
|
||||
fmt.tprintf(
|
||||
"ed25519.private_key_set_bytes: ~%f us/op",
|
||||
time.duration_microseconds(elapsed) / iters,
|
||||
),
|
||||
log.infof(
|
||||
"ed25519.private_key_set_bytes: ~%f us/op",
|
||||
time.duration_microseconds(elapsed) / iters,
|
||||
)
|
||||
|
||||
pub_bytes := priv_key._pub_key._b[:] // "I know what I am doing"
|
||||
@@ -309,12 +301,9 @@ bench_ed25519 :: proc(t: ^testing.T) {
|
||||
assert(ok, "public key should deserialize")
|
||||
}
|
||||
elapsed = time.since(start)
|
||||
tc.log(
|
||||
t,
|
||||
fmt.tprintf(
|
||||
"ed25519.public_key_set_bytes: ~%f us/op",
|
||||
time.duration_microseconds(elapsed) / iters,
|
||||
),
|
||||
log.infof(
|
||||
"ed25519.public_key_set_bytes: ~%f us/op",
|
||||
time.duration_microseconds(elapsed) / iters,
|
||||
)
|
||||
|
||||
msg := "Got a job for you, 621."
|
||||
@@ -325,7 +314,10 @@ bench_ed25519 :: proc(t: ^testing.T) {
|
||||
ed25519.sign(&priv_key, msg_bytes, sig_bytes[:])
|
||||
}
|
||||
elapsed = time.since(start)
|
||||
tc.log(t, fmt.tprintf("ed25519.sign: ~%f us/op", time.duration_microseconds(elapsed) / iters))
|
||||
log.infof(
|
||||
"ed25519.sign: ~%f us/op",
|
||||
time.duration_microseconds(elapsed) / iters,
|
||||
)
|
||||
|
||||
start = time.now()
|
||||
for i := 0; i < iters; i = i + 1 {
|
||||
@@ -333,9 +325,9 @@ bench_ed25519 :: proc(t: ^testing.T) {
|
||||
assert(ok, "signature should validate")
|
||||
}
|
||||
elapsed = time.since(start)
|
||||
tc.log(
|
||||
t,
|
||||
fmt.tprintf("ed25519.verify: ~%f us/op", time.duration_microseconds(elapsed) / iters),
|
||||
log.infof(
|
||||
"ed25519.verify: ~%f us/op",
|
||||
time.duration_microseconds(elapsed) / iters,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -354,8 +346,8 @@ bench_x25519 :: proc(t: ^testing.T) {
|
||||
}
|
||||
elapsed := time.since(start)
|
||||
|
||||
tc.log(
|
||||
t,
|
||||
fmt.tprintf("x25519.scalarmult: ~%f us/op", time.duration_microseconds(elapsed) / iters),
|
||||
log.infof(
|
||||
"x25519.scalarmult: ~%f us/op",
|
||||
time.duration_microseconds(elapsed) / iters,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -23,9 +23,8 @@ import "core:hash"
|
||||
import "core:strings"
|
||||
import "core:mem"
|
||||
import "core:time"
|
||||
import "base:runtime"
|
||||
|
||||
TEST_SUITE_PATH :: "assets/PNG"
|
||||
TEST_SUITE_PATH :: ODIN_ROOT + "tests/core/assets/PNG/"
|
||||
|
||||
I_Error :: image.Error
|
||||
|
||||
@@ -1455,10 +1454,9 @@ png_test_no_postproc :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) {
|
||||
context = runtime.default_context()
|
||||
|
||||
for file in suite {
|
||||
test_file := strings.concatenate({TEST_SUITE_PATH, "/", file.file, ".png"}, context.temp_allocator)
|
||||
test_file := strings.concatenate({TEST_SUITE_PATH, file.file, ".png"})
|
||||
defer delete(test_file)
|
||||
|
||||
img: ^png.Image
|
||||
err: png.Error
|
||||
@@ -1467,10 +1465,6 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) {
|
||||
for test in file.tests {
|
||||
count += 1
|
||||
|
||||
track: mem.Tracking_Allocator
|
||||
mem.tracking_allocator_init(&track, context.allocator)
|
||||
context.allocator = mem.tracking_allocator(&track)
|
||||
|
||||
img, err = png.load(test_file, test.options)
|
||||
|
||||
passed := (test.expected_error == nil && err == nil) || (test.expected_error == err)
|
||||
|
||||
Reference in New Issue
Block a user