ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
chacha20.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_CHACHA20_H
5#define PROTOCORE_CHACHA20_H
6
7#include "protocore_config.h" // the entry point: protocore_types.h for the widths
8
10
11/**
12 * @file chacha20.h
13 * @brief ChaCha20 stream cipher (D. J. Bernstein; RFC 8439).
14 *
15 * The 20-round ARX permutation used by the chacha20-poly1305@openssh.com cipher. Two views of the
16 * same core are exposed:
17 *
18 * - @ref Chacha20Ns::xor_ : the original ChaCha layout OpenSSH uses - a 64-bit little-endian block
19 * counter (state words 12-13) and a 64-bit nonce/IV (words 14-15). This is what the SSH AEAD
20 * drives; the counter increments per 64-byte block.
21 * - @ref Chacha20Ns::block_ietf : the RFC 8439 layout (32-bit counter in word 12, 96-bit nonce in
22 * words 13-15), exposed so the core can be checked against the published RFC 8439 Section 2.3.2
23 * block test vector.
24 *
25 * Pure ARX (add-rotate-xor): naturally constant-time, no tables, ~64-byte state. No heap.
26 *
27 * The member is spelled `xor_` because `xor` is an alternative token in C++, and this header reaches
28 * the C++ translation units.
29 *
30 * @c work is PROTOCORE_CHACHA20_BORROW secure bytes the CALLER took, at an address it knows. It is not held past the
31 * call, so nothing here aliases it. The caller releases it, and the pool wipes on release; this module neither takes
32 * it, holds it, releases it, nor wipes it. The borrow IS the working state, so two keystreams in flight are two borrows
33 * and never collide.
34 *
35 * @author Douglas Quigg (dstroy0)
36 * @date 2026
37 */
38
39/** @brief ChaCha20 key length in bytes. */
40#define PROTOCORE_CHACHA20_KEY_LEN 32
41
42/** @brief ChaCha20 keystream block length in bytes. */
43#define PROTOCORE_CHACHA20_BLOCK_LEN 64
44
45/** @brief Dispatch table. Addressed by offset, so the layout is asserted below. */
46typedef struct
47{
48 proto_bool (*xor_)(uint8_t *, const uint8_t *, const uint8_t *, uint64_t, const uint8_t *, uint8_t *, size_t);
49 proto_bool (*block_ietf)(uint8_t *, const uint8_t *, uint32_t, const uint8_t *, uint8_t *);
52
53/**
54 * @brief XOR the OpenSSH-layout keystream over in into out.
55 * @param work PROTOCORE_CHACHA20_BORROW bytes the caller took. Not held past the call.
56 * @param key PROTOCORE_CHACHA20_KEY_LEN bytes
57 * @param iv 8-byte nonce; OpenSSH uses the packet sequence number, big-endian
58 * @param counter initial 64-bit block counter, stepping once per 64-byte block
59 * @param in plaintext, or ciphertext when decrypting; nullptr emits raw keystream
60 * @param out len bytes; may alias in
61 * @param len how many
62 * @return PROTO_TRUE on success.
63 */
64proto_bool protocore_chacha20_xor_(uint8_t *work, const uint8_t *key, const uint8_t *iv, uint64_t counter,
65 const uint8_t *in, uint8_t *out, size_t len);
66/**
67 * @brief One 64-byte keystream block in the RFC 8439 layout.
68 * @param work PROTOCORE_CHACHA20_BORROW bytes the caller took. Not held past the call.
69 * @param key PROTOCORE_CHACHA20_KEY_LEN bytes
70 * @param counter 32-bit block counter, state word 12
71 * @param nonce 12-byte nonce, state words 13-15
72 * @param out PROTOCORE_CHACHA20_BLOCK_LEN bytes
73 * @return PROTO_TRUE on success.
74 */
75proto_bool protocore_chacha20_block_ietf(uint8_t *work, const uint8_t *key, uint32_t counter, const uint8_t *nonce,
76 uint8_t *out);
77
78/** @brief Module namespace. */
81
83
84#endif // PROTOCORE_CHACHA20_H
PROTOCORE_NS Chacha20Ns Chacha20 PROTOCORE_UNUSED
Module namespace.
Definition chacha20.h:79
proto_bool protocore_chacha20_xor_(uint8_t *work, const uint8_t *key, const uint8_t *iv, uint64_t counter, const uint8_t *in, uint8_t *out, size_t len)
XOR the OpenSSH-layout keystream over in into out.
proto_bool protocore_chacha20_block_ietf(uint8_t *work, const uint8_t *key, uint32_t counter, const uint8_t *nonce, uint8_t *out)
One 64-byte keystream block in the RFC 8439 layout.
#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 chacha20.h:47
proto_bool(* xor_)(uint8_t *, const uint8_t *, const uint8_t *, uint64_t, const uint8_t *, uint8_t *, size_t)
Definition chacha20.h:48
#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