New freestanding, verify-only Ed25519 (RFC 8032) implementation:
include/starkernel/{sha512,fe25519,scalar25519,ed25519}.h +
src/starkernel/crypto/{sha512,fe25519,scalar25519,ed25519}.c, wired into
Makefile.starkernel. Kernel never signs or generates keys -- only
ed25519_verify() is needed; signing happens in the host-side mkcapsule
build tool via libsodium/OpenSSL.
Confirmed __int128 multiply/add/shift-by-constant compile with zero
undefined symbols on all three target toolchains (only division needs
libgcc's __udivti3, per timer.c's existing documented finding -- that
file's comment updated to narrow the claim, since it had been read as
"avoid __int128 entirely"). This enabled the standard 5-limb radix-2^51
field arithmetic representation.
An abandoned first attempt (10-limb radix-2^26, avoiding __int128 out of
premature caution) hit two real bugs, both invisible on inspection and
found only by property-based testing against Python's own bignum
arithmetic: a non-uniform-radix limb misalignment in multiplication, and
a double-counted carry. Verification chain: SHA-512 against known +
boundary vectors (7/7); field arithmetic property-tested 25,045 cases;
scalar-mod-L arithmetic 300 cases (L confirmed prime via Miller-Rabin
first); full verify() end-to-end against 110 real signatures from
Python's cryptography library, including tampered inputs and the RFC
8032 S>=L malleability attack -- all correctly accepted/rejected.
Compiles clean (zero warnings) and links on all three architectures,
confirmed via the mandatory three-arch QEMU boot. The code is linked but
not yet called from anywhere -- wiring into capsule_birth.c needs a
from-scratch X.509/DER parser first (Captain Bob chose real X.509 over a
raw-blob cert format this session), which is the next open item.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HZ8kNoTuP63pbQtro4qvrm
24 lines
975 B
C
24 lines
975 B
C
/* ed25519.h -- EdDSA signature VERIFICATION only (RFC 8032), freestanding
|
|
* C99. No signing, no key generation, no RNG -- this kernel never signs;
|
|
* signing happens in the host-side build tool, which can link
|
|
* libsodium/OpenSSL because it's a normal Linux binary. That halves the
|
|
* implementation surface here: no scalar clamping, no key derivation, no
|
|
* constant-time discipline (verify operates only on public data --
|
|
* public key, message, signature -- there's no secret-dependent branch
|
|
* to leak).
|
|
*/
|
|
#ifndef ED25519_H
|
|
#define ED25519_H
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
|
|
/* Returns 1 if signature (64 bytes: R || S) is a valid Ed25519 signature
|
|
* by pubkey (32 bytes, compressed point) over msg, else 0. Rejects
|
|
* malformed inputs (S >= L, an undecodable point) as invalid rather than
|
|
* faulting. */
|
|
int ed25519_verify(const uint8_t pubkey[32], const uint8_t *msg, size_t msg_len,
|
|
const uint8_t sig[64]);
|
|
|
|
#endif /* ED25519_H */
|