commit c9f625de9349f34b63cf277ed7d08c4a10bb8b73
parent 913cef345e46ea44aee5e08bb35d9d242ba98356
Author: MikoĊaj Lenczewski <mikolaj@lenczewski.org>
Date: Sun, 20 Sep 2026 23:38:45 +0100
Clean up implementations
Diffstat:
15 files changed, 265 insertions(+), 239 deletions(-)
diff --git a/hkdf.c b/hkdf.c
@@ -1,6 +1,6 @@
#include "hkdf.h"
-#include <stdio.h>
+#include <assert.h>
size_t
hkdf_digest_size(struct hmac_hash const *hash, size_t rounds)
diff --git a/hmac.c b/hmac.c
@@ -1,5 +1,7 @@
#include "hmac.h"
+#include <assert.h>
+
void
hmac_gen_iv_block(struct hmac_ctx *ctx,
struct hmac_hash const *hash, void *restrict hash_ctx,
diff --git a/hmac.h b/hmac.h
@@ -3,9 +3,7 @@
#ifndef HMAC_H
#define HMAC_H
-#include <assert.h>
-#include <stdint.h>
-#include <string.h>
+#include <stddef.h>
#define HMAC_BLOCK_SIZE 64
#define HMAC_IPAD_BYTE 0x36
diff --git a/sha.c b/sha.c
@@ -1,5 +1,36 @@
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+
#include "sha.h"
+#include <assert.h>
+#include <endian.h>
+#include <string.h>
+
+// sha operations
+// ===========================================================================
+
+#define SHA_ROTR32(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
+#define SHA_ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
+#define SHA_SHR(x, n) ((x) >> (n))
+
+// sha functions
+// ===========================================================================
+
+#define SHA_Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
+#define SHA_Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+#define SHA256_S0(x) (SHA_ROTR32((x), 2) ^ SHA_ROTR32((x), 13) ^ SHA_ROTR32((x), 22))
+#define SHA256_S1(x) (SHA_ROTR32((x), 6) ^ SHA_ROTR32((x), 11) ^ SHA_ROTR32((x), 25))
+#define SHA256_s0(x) (SHA_ROTR32((x), 7) ^ SHA_ROTR32((x), 18) ^ SHA_SHR((x), 3))
+#define SHA256_s1(x) (SHA_ROTR32((x), 17) ^ SHA_ROTR32((x), 19) ^ SHA_SHR((x), 10))
+
+#define SHA512_S0(x) (SHA_ROTR64((x), 28) ^ SHA_ROTR64((x), 34) ^ SHA_ROTR64((x), 39))
+#define SHA512_S1(x) (SHA_ROTR64((x), 14) ^ SHA_ROTR64((x), 18) ^ SHA_ROTR64((x), 41))
+#define SHA512_s0(x) (SHA_ROTR64((x), 1) ^ SHA_ROTR64((x), 8) ^ SHA_SHR((x), 7))
+#define SHA512_s1(x) (SHA_ROTR64((x), 19) ^ SHA_ROTR64((x), 61) ^ SHA_SHR((x), 6))
+
// sha constants
// ===========================================================================
@@ -63,7 +94,7 @@ sha256_init(struct sha256_ctx *ctx)
ctx->digest[7] = 0x5be0cd19;
}
-static inline void
+static void
_sha256_block(struct sha256_ctx *ctx)
{
sha256_word_t a, b, c, d, e, f, g, h, t, t1, t2;
@@ -139,7 +170,7 @@ sha256_push(struct sha256_ctx *ctx, void const *buf, size_t len)
}
}
-static inline void
+static void
_sha256_digest_bswap(struct sha256_ctx *ctx, void *digest, size_t words)
{
sha256_word_t *out = digest;
@@ -252,7 +283,7 @@ sha512_init(struct sha512_ctx *ctx)
ctx->digest[7] = 0x5be0cd19137e2179;
}
-static inline void
+static void
_sha512_block(struct sha512_ctx *ctx)
{
sha512_word_t a, b, c, d, e, f, g, h, t, t1, t2;
@@ -328,7 +359,7 @@ sha512_push(struct sha512_ctx *ctx, void const *buf, size_t len)
}
}
-static inline void
+static void
_sha512_digest_bswap(struct sha512_ctx *ctx, void *digest, size_t words)
{
sha512_word_t *out = digest;
diff --git a/sha.h b/sha.h
@@ -3,16 +3,10 @@
#ifndef SHA_H
#define SHA_H
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-
-#include <assert.h>
-#include <endian.h>
#include <limits.h>
#include <stdalign.h>
+#include <stddef.h>
#include <stdint.h>
-#include <string.h>
// sha definitions and constants
// ===========================================================================
@@ -88,29 +82,6 @@ struct sha512_ctx {
#define SHA512_256_DIGEST_WORDS (SHA512_256_DIGEST_BITS / SHA512_WORD_BITS)
#define SHA512_256_DIGEST_SIZE (SHA512_256_DIGEST_BITS / CHAR_BIT)
-// sha operations
-// ===========================================================================
-
-#define SHA_ROTR32(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
-#define SHA_ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
-#define SHA_SHR(x, n) ((x) >> (n))
-
-// sha functions
-// ===========================================================================
-
-#define SHA_Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
-#define SHA_Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
-
-#define SHA256_S0(x) (SHA_ROTR32((x), 2) ^ SHA_ROTR32((x), 13) ^ SHA_ROTR32((x), 22))
-#define SHA256_S1(x) (SHA_ROTR32((x), 6) ^ SHA_ROTR32((x), 11) ^ SHA_ROTR32((x), 25))
-#define SHA256_s0(x) (SHA_ROTR32((x), 7) ^ SHA_ROTR32((x), 18) ^ SHA_SHR((x), 3))
-#define SHA256_s1(x) (SHA_ROTR32((x), 17) ^ SHA_ROTR32((x), 19) ^ SHA_SHR((x), 10))
-
-#define SHA512_S0(x) (SHA_ROTR64((x), 28) ^ SHA_ROTR64((x), 34) ^ SHA_ROTR64((x), 39))
-#define SHA512_S1(x) (SHA_ROTR64((x), 14) ^ SHA_ROTR64((x), 18) ^ SHA_ROTR64((x), 41))
-#define SHA512_s0(x) (SHA_ROTR64((x), 1) ^ SHA_ROTR64((x), 8) ^ SHA_SHR((x), 7))
-#define SHA512_s1(x) (SHA_ROTR64((x), 19) ^ SHA_ROTR64((x), 61) ^ SHA_SHR((x), 6))
-
// sha256
// ===========================================================================
diff --git a/test/test-hkdf.c b/test/test-hkdf.c
@@ -2,6 +2,7 @@
#include "hmac-sha2.h"
#include <stdio.h>
+#include <string.h>
#define HKDF_ROUNDS 2
#define HKDF_DIGEST_SIZE (SHA256_DIGEST_SIZE * HKDF_ROUNDS)
diff --git a/test/test-hmac.c b/test/test-hmac.c
@@ -1,6 +1,7 @@
#include "hmac-sha2.h"
#include <stdio.h>
+#include <string.h>
int
main(void)
diff --git a/test/test-sha224.c b/test/test-sha224.c
@@ -1,5 +1,7 @@
#include "sha.h"
+
#include <stdio.h>
+#include <string.h>
int
main(void)
diff --git a/test/test-sha256.c b/test/test-sha256.c
@@ -1,5 +1,7 @@
#include "sha.h"
+
#include <stdio.h>
+#include <string.h>
int
main(void)
diff --git a/test/test-sha384.c b/test/test-sha384.c
@@ -1,5 +1,7 @@
#include "sha.h"
+
#include <stdio.h>
+#include <string.h>
int
main(void)
diff --git a/test/test-sha512-224.c b/test/test-sha512-224.c
@@ -1,5 +1,7 @@
#include "sha.h"
+
#include <stdio.h>
+#include <string.h>
int
main(void)
diff --git a/test/test-sha512-256.c b/test/test-sha512-256.c
@@ -1,5 +1,7 @@
#include "sha.h"
+
#include <stdio.h>
+#include <string.h>
int
main(void)
diff --git a/test/test-sha512.c b/test/test-sha512.c
@@ -1,5 +1,7 @@
#include "sha.h"
+
#include <stdio.h>
+#include <string.h>
int
main(void)
diff --git a/x25519.c b/x25519.c
@@ -0,0 +1,207 @@
+#include "x25519.h"
+
+static void
+x25519_unpack(struct x25519_field_element *out, struct x25519_point const *in)
+{
+ for (size_t i = 0; i < 16; i++) {
+ out->vs[i] = in->vs[2*i] + ((int64_t) in->vs[(2*i) + 1] << 8);
+ }
+
+ out->vs[15] &= 0x7fff;
+}
+
+static void
+x25519_carry(struct x25519_field_element *elem)
+{
+ int64_t carry;
+ for (size_t i = 0; i < 16; i++) {
+ carry = elem->vs[i] >> 16;
+
+ elem->vs[i] -= carry << 16;
+
+ if (i < 15) {
+ elem->vs[i + 1] += carry;
+ } else { // i == 15
+ elem->vs[0] += 38 * carry;
+ }
+ }
+}
+
+static void
+x25519_fadd(struct x25519_field_element *out,
+ struct x25519_field_element const *a,
+ struct x25519_field_element const *b)
+{
+ for (size_t i = 0; i < 16; i++) {
+ out->vs[i] = a->vs[i] + b->vs[i];
+ }
+}
+
+static void
+x25519_fsub(struct x25519_field_element *out,
+ struct x25519_field_element const *a,
+ struct x25519_field_element const *b)
+{
+ for (size_t i = 0; i < 16; i++) {
+ out->vs[i] = a->vs[i] - b->vs[i];
+ }
+}
+
+static void
+x25519_fmul(struct x25519_field_element *out,
+ struct x25519_field_element const *a,
+ struct x25519_field_element const *b)
+{
+ int64_t product[31];
+ memset(product, 0, sizeof product); // TODO: is this elided?
+
+ for (size_t i = 0; i < 16; i++) {
+ for (size_t j = 0; j < 16; j++) {
+ product[i + j] = a->vs[i] * b->vs[j];
+ }
+ }
+
+ for (size_t i = 0; i < 15; i++) {
+ product[i] += 38 * product[i + 16];
+ }
+
+ memcpy(out->vs, product, sizeof out->vs);
+ x25519_carry(out);
+ x25519_carry(out);
+}
+
+static void
+x25519_finv(struct x25519_field_element *out,
+ struct x25519_field_element const *in)
+{
+ struct x25519_field_element c;
+ memcpy(&c, in, sizeof c);
+
+ for (int i = 253; i >= 0; i--) {
+ x25519_fmul(&c, &c, &c);
+
+ if (i != 2 && i != 4)
+ x25519_fmul(&c, &c, in);
+ }
+
+ memcpy(out, &c, sizeof c);
+}
+
+static void
+x25519_swap(struct x25519_field_element *p,
+ struct x25519_field_element *q,
+ size_t bit)
+{
+ int64_t c = ~(bit - 1);
+ for (size_t i = 0; i < 16; i++) {
+ int64_t t = c & (p->vs[i] ^ q->vs[i]);
+ p->vs[i] ^= t;
+ q->vs[i] ^= t;
+ }
+}
+
+static void
+x25519_pack(struct x25519_point *out, struct x25519_field_element const *in)
+{
+ int carry;
+ struct x25519_field_element m, t;
+ memcpy(&t, in, sizeof t);
+
+ // reduce module p
+ x25519_carry(&t); x25519_carry(&t); x25519_carry(&t);
+
+ for (size_t j = 0; j < 2; j++) {
+ m.vs[0] = t.vs[0] - 0xffed;
+ for (size_t i = 1; i < 15; i++) {
+ m.vs[i] = t.vs[i] - 0xffff - ((m.vs[i - 1] >> 16) & 1);
+ m.vs[i - 1] &= 0xffff;
+ }
+
+ m.vs[15] = t.vs[15] - 0x7fff - ((m.vs[14] >> 16) & 1);
+ carry = (m.vs[15] >> 16) & 1;
+ m.vs[14] &= 0xffff;
+
+ x25519_swap(&t, &m, 1 - carry);
+ }
+
+ for (size_t i = 0; i < 16; i++) {
+ out->vs[2*i] = t.vs[i] & 0xff;
+ out->vs[(2*i) + 1] = t.vs[i] >> 8;
+ }
+}
+
+static void
+x25519_scalarmult(struct x25519_point *restrict out,
+ struct x25519_point const *restrict scalar,
+ struct x25519_point const *restrict point)
+{
+ static const struct x25519_field_element _121665 = {
+ .vs = { 0xdb41, 1 }
+ };
+
+ uint8_t clamped[32];
+ int64_t bit;
+
+ struct x25519_field_element a, b, c, d, e, f, x;
+
+ memcpy(clamped, scalar, sizeof clamped);
+ clamped[0] &= 0xf8;
+ clamped[31] = (clamped[31] & 0x7f) | 0x40;
+
+ x25519_unpack(&x, point);
+
+ memcpy(&b, &x, sizeof b);
+ memset(&d, 0, sizeof d);
+ memset(&c, 0, sizeof c);
+ memset(&a, 0, sizeof a);
+ a.vs[0] = d.vs[0] = 1;
+
+ for (int i = 254; i >= 0; i--) {
+ bit = (clamped[i >> 3] >> (i & 7)) & 1;
+
+ x25519_swap(&a, &b, bit);
+ x25519_swap(&c, &d, bit);
+
+ x25519_fadd(&e, &a, &c);
+ x25519_fsub(&a, &a, &c);
+ x25519_fadd(&c, &b, &d);
+ x25519_fsub(&b, &b, &d);
+ x25519_fmul(&d, &e, &f);
+ x25519_fmul(&f, &a, &a);
+ x25519_fmul(&a, &c, &a);
+ x25519_fmul(&c, &b, &e);
+ x25519_fadd(&e, &a, &c);
+ x25519_fsub(&a, &a, &c);
+ x25519_fmul(&b, &a, &a);
+ x25519_fsub(&c, &d, &f);
+ x25519_fmul(&a, &c, &_121665);
+ x25519_fadd(&a, &a, &d);
+ x25519_fmul(&c, &c, &a);
+ x25519_fmul(&a, &d, &f);
+ x25519_fmul(&d, &b, &x);
+ x25519_fmul(&b, &e, &e);
+
+ x25519_swap(&a, &b, bit);
+ x25519_swap(&c, &d, bit);
+ }
+
+ x25519_finv(&c, &c);
+ x25519_fmul(&a, &a, &c);
+ x25519_pack(out, &a);
+}
+
+void
+x25519_genpubkey(struct x25519_point *restrict pk,
+ struct x25519_point const *restrict sk)
+{
+ static const struct x25519_point _9 = { .vs = {9} };
+ x25519_scalarmult(pk, sk, &_9);
+}
+
+void
+x25519(struct x25519_point *restrict out,
+ struct x25519_point const *restrict pk,
+ struct x25519_point const *restrict sk)
+{
+ x25519_scalarmult(out, sk, pk);
+}
diff --git a/x25519.h b/x25519.h
@@ -11,208 +11,11 @@ struct x25519_field_element {
int64_t vs[16]; // array of 16, 16-bit numbers (stored as 64-bit)
};
-static inline void
-x25519_unpack(struct x25519_field_element *out, struct x25519_point const *in)
-{
- for (size_t i = 0; i < 16; i++) {
- out->vs[i] = in->vs[2*i] + ((int64_t) in->vs[(2*i) + 1] << 8);
- }
-
- out->vs[15] &= 0x7fff;
-}
-
-static inline void
-x25519_carry(struct x25519_field_element *elem)
-{
- int64_t carry;
- for (size_t i = 0; i < 16; i++) {
- carry = elem->vs[i] >> 16;
-
- elem->vs[i] -= carry << 16;
-
- if (i < 15) {
- elem->vs[i + 1] += carry;
- } else { // i == 15
- elem->vs[0] += 38 * carry;
- }
- }
-}
-
-static inline void
-x25519_fadd(struct x25519_field_element *out,
- struct x25519_field_element const *a,
- struct x25519_field_element const *b)
-{
- for (size_t i = 0; i < 16; i++) {
- out->vs[i] = a->vs[i] + b->vs[i];
- }
-}
-
-static inline void
-x25519_fsub(struct x25519_field_element *out,
- struct x25519_field_element const *a,
- struct x25519_field_element const *b)
-{
- for (size_t i = 0; i < 16; i++) {
- out->vs[i] = a->vs[i] - b->vs[i];
- }
-}
-
-static inline void
-x25519_fmul(struct x25519_field_element *out,
- struct x25519_field_element const *a,
- struct x25519_field_element const *b)
-{
- int64_t product[31];
- memset(product, 0, sizeof product); // TODO: is this elided?
-
- for (size_t i = 0; i < 16; i++) {
- for (size_t j = 0; j < 16; j++) {
- product[i + j] = a->vs[i] * b->vs[j];
- }
- }
-
- for (size_t i = 0; i < 15; i++) {
- product[i] += 38 * product[i + 16];
- }
-
- memcpy(out->vs, product, sizeof out->vs);
- x25519_carry(out);
- x25519_carry(out);
-}
-
-static inline void
-x25519_finv(struct x25519_field_element *out,
- struct x25519_field_element const *in)
-{
- struct x25519_field_element c;
- memcpy(&c, in, sizeof c);
-
- for (int i = 253; i >= 0; i--) {
- x25519_fmul(&c, &c, &c);
-
- if (i != 2 && i != 4)
- x25519_fmul(&c, &c, in);
- }
-
- memcpy(out, &c, sizeof c);
-}
-
-static inline void
-x25519_swap(struct x25519_field_element *p,
- struct x25519_field_element *q,
- size_t bit)
-{
- int64_t c = ~(bit - 1);
- for (size_t i = 0; i < 16; i++) {
- int64_t t = c & (p->vs[i] ^ q->vs[i]);
- p->vs[i] ^= t;
- q->vs[i] ^= t;
- }
-}
-
-static inline void
-x25519_pack(struct x25519_point *out, struct x25519_field_element const *in)
-{
- int carry;
- struct x25519_field_element m, t;
- memcpy(&t, in, sizeof t);
-
- // reduce module p
- x25519_carry(&t); x25519_carry(&t); x25519_carry(&t);
-
- for (size_t j = 0; j < 2; j++) {
- m.vs[0] = t.vs[0] - 0xffed;
- for (size_t i = 1; i < 15; i++) {
- m.vs[i] = t.vs[i] - 0xffff - ((m.vs[i - 1] >> 16) & 1);
- m.vs[i - 1] &= 0xffff;
- }
-
- m.vs[15] = t.vs[15] - 0x7fff - ((m.vs[14] >> 16) & 1);
- carry = (m.vs[15] >> 16) & 1;
- m.vs[14] &= 0xffff;
-
- x25519_swap(&t, &m, 1 - carry);
- }
-
- for (size_t i = 0; i < 16; i++) {
- out->vs[2*i] = t.vs[i] & 0xff;
- out->vs[(2*i) + 1] = t.vs[i] >> 8;
- }
-}
-
-static inline void
-x25519_scalarmult(struct x25519_point *restrict out,
- struct x25519_point const *restrict scalar,
- struct x25519_point const *restrict point)
-{
- static const struct x25519_field_element _121665 = {
- .vs = { 0xdb41, 1 }
- };
-
- uint8_t clamped[32];
- int64_t bit;
-
- struct x25519_field_element a, b, c, d, e, f, x;
-
- memcpy(clamped, scalar, sizeof clamped);
- clamped[0] &= 0xf8;
- clamped[31] = (clamped[31] & 0x7f) | 0x40;
-
- x25519_unpack(&x, point);
-
- memcpy(&b, &x, sizeof b);
- memset(&d, 0, sizeof d);
- memset(&c, 0, sizeof c);
- memset(&a, 0, sizeof a);
- a.vs[0] = d.vs[0] = 1;
-
- for (int i = 254; i >= 0; i--) {
- bit = (clamped[i >> 3] >> (i & 7)) & 1;
-
- x25519_swap(&a, &b, bit);
- x25519_swap(&c, &d, bit);
-
- x25519_fadd(&e, &a, &c);
- x25519_fsub(&a, &a, &c);
- x25519_fadd(&c, &b, &d);
- x25519_fsub(&b, &b, &d);
- x25519_fmul(&d, &e, &f);
- x25519_fmul(&f, &a, &a);
- x25519_fmul(&a, &c, &a);
- x25519_fmul(&c, &b, &e);
- x25519_fadd(&e, &a, &c);
- x25519_fsub(&a, &a, &c);
- x25519_fmul(&b, &a, &a);
- x25519_fsub(&c, &d, &f);
- x25519_fmul(&a, &c, &_121665);
- x25519_fadd(&a, &a, &d);
- x25519_fmul(&c, &c, &a);
- x25519_fmul(&a, &d, &f);
- x25519_fmul(&d, &b, &x);
- x25519_fmul(&b, &e, &e);
-
- x25519_swap(&a, &b, bit);
- x25519_swap(&c, &d, bit);
- }
-
- x25519_finv(&c, &c);
- x25519_fmul(&a, &a, &c);
- x25519_pack(out, &a);
-}
-
-static inline void
+void
x25519_genpubkey(struct x25519_point *restrict pk,
- struct x25519_point const *restrict sk)
-{
- static const struct x25519_point _9 = { .vs = {9} };
- x25519_scalarmult(pk, sk, &_9);
-}
+ struct x25519_point const *restrict sk);
-static inline void
+void
x25519(struct x25519_point *restrict out,
struct x25519_point const *restrict pk,
- struct x25519_point const *restrict sk)
-{
- x25519_scalarmult(out, sk, pk);
-}
+ struct x25519_point const *restrict sk);