mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Merge pull request #3381 from Yawning/fix/chacha20poly1305
core/crypto/poly1305: The final addition is NOT mod p
This commit is contained in:
@@ -9,6 +9,7 @@ package poly1305
|
|||||||
import "core:crypto"
|
import "core:crypto"
|
||||||
import field "core:crypto/_fiat/field_poly1305"
|
import field "core:crypto/_fiat/field_poly1305"
|
||||||
import "core:encoding/endian"
|
import "core:encoding/endian"
|
||||||
|
import "core:math/bits"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
|
|
||||||
// KEY_SIZE is the Poly1305 key size in bytes.
|
// KEY_SIZE is the Poly1305 key size in bytes.
|
||||||
@@ -50,7 +51,7 @@ verify :: proc(tag, msg, key: []byte) -> bool {
|
|||||||
Context :: struct {
|
Context :: struct {
|
||||||
_r: field.Tight_Field_Element,
|
_r: field.Tight_Field_Element,
|
||||||
_a: field.Tight_Field_Element,
|
_a: field.Tight_Field_Element,
|
||||||
_s: field.Tight_Field_Element,
|
_s: [2]u64,
|
||||||
_buffer: [_BLOCK_SIZE]byte,
|
_buffer: [_BLOCK_SIZE]byte,
|
||||||
_leftover: int,
|
_leftover: int,
|
||||||
_is_initialized: bool,
|
_is_initialized: bool,
|
||||||
@@ -66,11 +67,12 @@ init :: proc(ctx: ^Context, key: []byte) {
|
|||||||
// r = le_bytes_to_num(key[0..15])
|
// r = le_bytes_to_num(key[0..15])
|
||||||
// r = clamp(r) (r &= 0xffffffc0ffffffc0ffffffc0fffffff)
|
// r = clamp(r) (r &= 0xffffffc0ffffffc0ffffffc0fffffff)
|
||||||
tmp_lo := endian.unchecked_get_u64le(key[0:]) & 0x0ffffffc0fffffff
|
tmp_lo := endian.unchecked_get_u64le(key[0:]) & 0x0ffffffc0fffffff
|
||||||
tmp_hi := endian.unchecked_get_u64le(key[8:]) & 0xffffffc0ffffffc
|
tmp_hi := endian.unchecked_get_u64le(key[8:]) & 0x0ffffffc0ffffffc
|
||||||
field.fe_from_u64s(&ctx._r, tmp_lo, tmp_hi)
|
field.fe_from_u64s(&ctx._r, tmp_lo, tmp_hi)
|
||||||
|
|
||||||
// s = le_bytes_to_num(key[16..31])
|
// s = le_bytes_to_num(key[16..31])
|
||||||
field.fe_from_bytes(&ctx._s, key[16:32], 0)
|
ctx._s[0] = endian.unchecked_get_u64le(key[16:])
|
||||||
|
ctx._s[1] = endian.unchecked_get_u64le(key[24:])
|
||||||
|
|
||||||
// a = 0
|
// a = 0
|
||||||
field.fe_zero(&ctx._a)
|
field.fe_zero(&ctx._a)
|
||||||
@@ -138,14 +140,20 @@ final :: proc(ctx: ^Context, dst: []byte) {
|
|||||||
_blocks(ctx, ctx._buffer[:], true)
|
_blocks(ctx, ctx._buffer[:], true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// a += s
|
// a += s (NOT mod p)
|
||||||
field.fe_add(field.fe_relax_cast(&ctx._a), &ctx._a, &ctx._s) // _a unreduced
|
|
||||||
field.fe_carry(&ctx._a, field.fe_relax_cast(&ctx._a)) // _a reduced
|
|
||||||
|
|
||||||
// return num_to_16_le_bytes(a)
|
|
||||||
tmp: [32]byte = ---
|
tmp: [32]byte = ---
|
||||||
field.fe_to_bytes(&tmp, &ctx._a)
|
field.fe_to_bytes(&tmp, &ctx._a)
|
||||||
copy_slice(dst, tmp[0:16])
|
|
||||||
|
c: u64
|
||||||
|
lo := endian.unchecked_get_u64le(tmp[0:])
|
||||||
|
hi := endian.unchecked_get_u64le(tmp[8:])
|
||||||
|
|
||||||
|
lo, c = bits.add_u64(lo, ctx._s[0], 0)
|
||||||
|
hi, _ = bits.add_u64(hi, ctx._s[1], c)
|
||||||
|
|
||||||
|
// return num_to_16_le_bytes(a)
|
||||||
|
endian.unchecked_put_u64le(dst[0:], lo)
|
||||||
|
endian.unchecked_put_u64le(dst[8:], hi)
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset sanitizes the Context. The Context must be re-initialized to
|
// reset sanitizes the Context. The Context must be re-initialized to
|
||||||
|
|||||||
Reference in New Issue
Block a user