mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-28 18:30:06 +00:00
core/crypto: Add poly1305
This package implements the Poly1305 MAC algorithm as specified in RFC 8439, using routines taked from fiat-crypto and poly1305-donna.
This commit is contained in:
@@ -116,6 +116,7 @@ main :: proc() {
|
||||
test_haval_256(&t)
|
||||
|
||||
// "modern" crypto tests
|
||||
test_poly1305(&t)
|
||||
test_x25519(&t)
|
||||
|
||||
bench_modern(&t)
|
||||
|
||||
@@ -4,6 +4,7 @@ import "core:testing"
|
||||
import "core:fmt"
|
||||
import "core:time"
|
||||
|
||||
import "core:crypto/poly1305"
|
||||
import "core:crypto/x25519"
|
||||
|
||||
_digit_value :: proc(r: rune) -> int {
|
||||
@@ -27,6 +28,70 @@ _decode_hex32 :: proc(s: string) -> [32]byte{
|
||||
return b
|
||||
}
|
||||
|
||||
@(test)
|
||||
test_poly1305 :: proc(t: ^testing.T) {
|
||||
log(t, "Testing poly1305")
|
||||
|
||||
// Test cases taken from poly1305-donna.
|
||||
key := [poly1305.KEY_SIZE]byte{
|
||||
0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91,
|
||||
0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25,
|
||||
0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65,
|
||||
0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80,
|
||||
}
|
||||
|
||||
msg := [131]byte{
|
||||
0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73,
|
||||
0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce,
|
||||
0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4,
|
||||
0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a,
|
||||
0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b,
|
||||
0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72,
|
||||
0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2,
|
||||
0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38,
|
||||
0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a,
|
||||
0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae,
|
||||
0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea,
|
||||
0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda,
|
||||
0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde,
|
||||
0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3,
|
||||
0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6,
|
||||
0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74,
|
||||
0xe3,0x55,0xa5,
|
||||
}
|
||||
|
||||
tag := [poly1305.TAG_SIZE]byte{
|
||||
0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5,
|
||||
0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9,
|
||||
}
|
||||
tag_str := hex_string(tag[:])
|
||||
|
||||
// Verify - oneshot + compare
|
||||
ok := poly1305.verify(tag[:], msg[:], key[:])
|
||||
expect(t, ok, "oneshot verify call failed")
|
||||
|
||||
// Sum - oneshot
|
||||
derived_tag: [poly1305.TAG_SIZE]byte
|
||||
poly1305.sum(derived_tag[:], msg[:], key[:])
|
||||
derived_tag_str := hex_string(derived_tag[:])
|
||||
expect(t, derived_tag_str == tag_str, fmt.tprintf("Expected %s for sum(msg, key), but got %s instead", tag_str, derived_tag_str))
|
||||
|
||||
// Incremental
|
||||
mem.zero(&derived_tag, size_of(derived_tag))
|
||||
ctx: poly1305.Context = ---
|
||||
poly1305.init(&ctx, key[:])
|
||||
read_lengths := [11]int{32, 64, 16, 8, 4, 2, 1, 1, 1, 1, 1}
|
||||
off := 0
|
||||
for read_length in read_lengths {
|
||||
to_read := msg[off:off+read_length]
|
||||
poly1305.update(&ctx, to_read)
|
||||
off = off + read_length
|
||||
}
|
||||
poly1305.final(&ctx, derived_tag[:])
|
||||
derived_tag_str = hex_string(derived_tag[:])
|
||||
expect(t, derived_tag_str == tag_str, fmt.tprintf("Expected %s for init/update/final - incremental, but got %s instead", tag_str, derived_tag_str))
|
||||
}
|
||||
|
||||
TestECDH :: struct {
|
||||
scalar: string,
|
||||
point: string,
|
||||
@@ -76,9 +141,75 @@ test_x25519 :: proc(t: ^testing.T) {
|
||||
bench_modern :: proc(t: ^testing.T) {
|
||||
fmt.println("Starting benchmarks:")
|
||||
|
||||
bench_poly1305(t)
|
||||
bench_x25519(t)
|
||||
}
|
||||
|
||||
_setup_poly1305 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
|
||||
assert(options != nil)
|
||||
|
||||
options.input = make([]u8, options.bytes, allocator)
|
||||
return nil if len(options.input) == options.bytes else .Allocation_Error
|
||||
}
|
||||
|
||||
_teardown_poly1305 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
|
||||
assert(options != nil)
|
||||
|
||||
delete(options.input)
|
||||
return nil
|
||||
}
|
||||
|
||||
_benchmark_poly1305 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
|
||||
buf := options.input
|
||||
key := [poly1305.KEY_SIZE]byte{
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
|
||||
}
|
||||
|
||||
tag: [poly1305.TAG_SIZE]byte = ---
|
||||
for _ in 0..=options.rounds {
|
||||
poly1305.sum(tag[:], buf, key[:])
|
||||
}
|
||||
options.count = options.rounds
|
||||
options.processed = options.rounds * options.bytes
|
||||
//options.hash = u128(h)
|
||||
return nil
|
||||
}
|
||||
|
||||
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",
|
||||
name,
|
||||
options.rounds,
|
||||
options.processed,
|
||||
time.duration_nanoseconds(options.duration),
|
||||
options.rounds_per_second,
|
||||
options.megabytes_per_second,
|
||||
)
|
||||
}
|
||||
|
||||
bench_poly1305 :: proc(t: ^testing.T) {
|
||||
name := "Poly1305 64 zero bytes"
|
||||
options := &time.Benchmark_Options{
|
||||
rounds = 1_000,
|
||||
bytes = 64,
|
||||
setup = _setup_poly1305,
|
||||
bench = _benchmark_poly1305,
|
||||
teardown = _teardown_poly1305,
|
||||
}
|
||||
|
||||
err := time.benchmark(options, context.allocator)
|
||||
expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
|
||||
name = "Poly1305 1024 zero bytes"
|
||||
options.bytes = 1024
|
||||
err = time.benchmark(options, context.allocator)
|
||||
expect(t, err == nil, name)
|
||||
benchmark_print(name, options)
|
||||
}
|
||||
|
||||
bench_x25519 :: proc(t: ^testing.T) {
|
||||
point := _decode_hex32("deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef")
|
||||
scalar := _decode_hex32("cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe")
|
||||
|
||||
Reference in New Issue
Block a user