ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
ed25519.h
Go to the documentation of this file.
1// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4#ifndef PROTOCORE_ED25519_H
5#define PROTOCORE_ED25519_H
6
7#include "protocore_config.h" // the entry point: protocore_types.h for the widths
8
10
11/**
12 * @file ed25519.h
13 * @brief Ed25519 signatures (RFC 8032) for ssh-ed25519 host keys + client auth.
14 *
15 * PureEdDSA over edwards25519. Deterministic signing (RFC 8032 §5.1.6) - no RNG - and
16 * verification, built on the shared Curve25519 field arithmetic (protocore_curve25519) and the
17 * @ref Sha512Ns entries, so which arm hashes is not visible here. Correctness is pinned to the
18 * RFC 8032 §7.1 vectors and to a reference implementation (test_ed25519).
19 *
20 * The server signs the KEX exchange hash with its ssh-ed25519 host key, and verifies a
21 * client's ed25519 public-key authentication signature.
22 *
23 * @c work is PROTOCORE_ED25519_BORROW secure bytes the CALLER took, at an address it knows. It is not held past the
24 * call, so nothing here aliases it. The caller releases it, and the pool wipes on release; this module neither takes
25 * it, holds it, releases it, nor wipes it. That is what keeps the expanded seed, the nonce and the challenge from
26 * outliving the caller.
27 *
28 * @author Douglas Quigg (dstroy0)
29 * @date 2026
30 */
31
32/** @brief Ed25519 seed (private key) length. */
33#define PROTOCORE_ED25519_SEED_LEN 32
34
35/** @brief Ed25519 public key length. */
36#define PROTOCORE_ED25519_PUBKEY_LEN 32
37
38/** @brief Ed25519 signature length (R || S). */
39#define PROTOCORE_ED25519_SIG_LEN 64
40
41/** @brief Dispatch table. Addressed by offset, so the layout is asserted below. */
42typedef struct
43{
44 proto_bool (*pubkey)(uint8_t *, const uint8_t *, uint8_t *);
45 proto_bool (*sign)(uint8_t *, const uint8_t *, const uint8_t *, size_t, uint8_t *);
46 proto_bool (*verify)(uint8_t *, const uint8_t *, const uint8_t *, size_t, const uint8_t *);
47} Ed25519Ns;
48PROTOCORE_NS_LAYOUT(Ed25519Ns, pubkey, sign, verify);
49
50/**
51 * @brief Derive the 32-byte public key A from the seed.
52 * @param work PROTOCORE_ED25519_BORROW bytes the caller took. Not held past the call.
53 * @param seed PROTOCORE_ED25519_SEED_LEN bytes
54 * @param pub PROTOCORE_ED25519_PUBKEY_LEN bytes
55 * @return PROTO_TRUE on success.
56 */
57proto_bool protocore_ed25519_pubkey(uint8_t *work, const uint8_t *seed, uint8_t *pub);
58/**
59 * @brief Sign deterministically (RFC 8032 §5.1.6), writing R || S.
60 * @param work PROTOCORE_ED25519_BORROW bytes the caller took. Not held past the call.
61 * @param seed PROTOCORE_ED25519_SEED_LEN bytes
62 * @param msg the message
63 * @param msg_len its length
64 * @param sig PROTOCORE_ED25519_SIG_LEN bytes, R || S
65 * @return PROTO_TRUE on success.
66 */
67proto_bool protocore_ed25519_sign(uint8_t *work, const uint8_t *seed, const uint8_t *msg, size_t msg_len, uint8_t *sig);
68/**
69 * @brief Check a signature (RFC 8032 §5.1.7); the answer is Ed25519Ns::ok.
70 * @param work PROTOCORE_ED25519_BORROW bytes the caller took. Not held past the call.
71 * @param pub PROTOCORE_ED25519_PUBKEY_LEN bytes
72 * @param msg the message
73 * @param msg_len its length
74 * @param sig PROTOCORE_ED25519_SIG_LEN bytes, R || S
75 * @return PROTO_TRUE on success.
76 */
77proto_bool protocore_ed25519_verify(uint8_t *work, const uint8_t *pub, const uint8_t *msg, size_t msg_len,
78 const uint8_t *sig);
79
80/** @brief Module namespace. */
83
85
86#endif // PROTOCORE_ED25519_H
proto_bool protocore_ed25519_verify(uint8_t *work, const uint8_t *pub, const uint8_t *msg, size_t msg_len, const uint8_t *sig)
Check a signature (RFC 8032 §5.1.7); the answer is Ed25519Ns::ok.
PROTOCORE_NS Ed25519Ns Ed25519 PROTOCORE_UNUSED
Module namespace.
Definition ed25519.h:81
proto_bool protocore_ed25519_sign(uint8_t *work, const uint8_t *seed, const uint8_t *msg, size_t msg_len, uint8_t *sig)
Sign deterministically (RFC 8032 §5.1.6), writing R || S.
proto_bool protocore_ed25519_pubkey(uint8_t *work, const uint8_t *seed, uint8_t *pub)
Derive the 32-byte public key A from the seed.
#define PROTOCORE_NS_LAYOUT(T,...)
Pin every dispatch slot of a table that is nothing but function pointers.
#define PROTOCORE_NS
Storage for a dispatch table. The const is load bearing.
Dispatch table. Addressed by offset, so the layout is asserted below.
Definition ed25519.h:43
proto_bool(* pubkey)(uint8_t *, const uint8_t *, uint8_t *)
Definition ed25519.h:44
#define PROTOCORE_BEGIN_DECLS
Give a header's declarations C linkage, so their symbol names carry no parameter types.
Definition types.h:96
_Bool proto_bool
The truth value.
Definition types.h:64
#define PROTOCORE_END_DECLS
Definition types.h:97