aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen van Rijn <Kelimion@users.noreply.github.com>2024-04-05 16:57:31 +0200
committerGitHub <noreply@github.com>2024-04-05 16:57:31 +0200
commit280adc8a854af2712238e346daf0db56f7ee707f (patch)
tree6b6f23cc6d1b7a3147837171e741fdc931f44772
parent1422e5bc2635debce2c6d1e48b7256f868f61ab7 (diff)
parenta45721e9ad0a48198533434acbca0fbfb974e115 (diff)
Merge pull request #3381 from Yawning/fix/chacha20poly1305
core/crypto/poly1305: The final addition is NOT mod p
-rw-r--r--core/crypto/poly1305/poly1305.odin26
1 files changed, 17 insertions, 9 deletions
diff --git a/core/crypto/poly1305/poly1305.odin b/core/crypto/poly1305/poly1305.odin
index fa57c6c06..4ca4f75e1 100644
--- a/core/crypto/poly1305/poly1305.odin
+++ b/core/crypto/poly1305/poly1305.odin
@@ -9,6 +9,7 @@ package poly1305
import "core:crypto"
import field "core:crypto/_fiat/field_poly1305"
import "core:encoding/endian"
+import "core:math/bits"
import "core:mem"
// KEY_SIZE is the Poly1305 key size in bytes.
@@ -50,7 +51,7 @@ verify :: proc(tag, msg, key: []byte) -> bool {
Context :: struct {
_r: field.Tight_Field_Element,
_a: field.Tight_Field_Element,
- _s: field.Tight_Field_Element,
+ _s: [2]u64,
_buffer: [_BLOCK_SIZE]byte,
_leftover: int,
_is_initialized: bool,
@@ -66,11 +67,12 @@ init :: proc(ctx: ^Context, key: []byte) {
// r = le_bytes_to_num(key[0..15])
// r = clamp(r) (r &= 0xffffffc0ffffffc0ffffffc0fffffff)
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)
// 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
field.fe_zero(&ctx._a)
@@ -138,14 +140,20 @@ final :: proc(ctx: ^Context, dst: []byte) {
_blocks(ctx, ctx._buffer[:], true)
}
- // a += s
- 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)
+ // a += s (NOT mod p)
tmp: [32]byte = ---
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