Files
utun2/src/dm/dm_crypto.h
T

50 lines
2.6 KiB
C

/*
* dm_crypto.h — криптография прямого чата (DM)
*
* conv_id выводится из ID двух узлов, content_key — из своего X25519-ключа и
* публичного ключа пира. Переговоров нет; nonce сообщения зависит от conv_id/author/seq.
* CCM и файловые примитивы предоставляет общий media_crypto.h.
*/
#ifndef DM_CRYPTO_H
#define DM_CRYPTO_H
#include <stdint.h>
#include <stddef.h>
#include "../media_async/media_crypto.h"
#ifdef __cplusplus
extern "C" {
#endif
#define DM_CONTENT_KEY_SIZE 32
#define DM_NONCE_SIZE 13 /* AES-CCM требует ровно 13 байт */
#define DM_TAG_SIZE 16
#define DM_CCM_PLAIN_MAX 65535u
#define DM_MEDIA_PLAIN_SIZE 32768u
/* conv_id: SHA256("utun_dm_v" || min(a,b) || max(a,b)), префикс — 9 ASCII-байт без NUL.
* ID узлов хешируются в порядке байтов хоста; первые 8 байт SHA256 читаются как uint64_t того же порядка.
* Снимается старший бит (маска 0x7FFFFFFFFFFFFFFF), нулевой результат заменяется на 1.
* Положительное 63-битное число, одинаковое для обоих направлений пары узлов. */
uint64_t dm_derive_conv_id(uint64_t a, uint64_t b);
/* content_key = SHA256(X25519(my_priv, peer_pub) || "utun_dm_content"), суффикс — 15 байт без NUL.
* my_priv/peer_pub — по 32 байта, out — 32 байта. Возвращает 0 при успехе, -1 при ошибке.
* При ошибке out не меняется; NULL-аргументы отклоняются. */
int dm_derive_content_key(const uint8_t my_priv[32], const uint8_t peer_pub[32],
uint8_t out[DM_CONTENT_KEY_SIZE]);
/* Детерминированный nonce: первые 13 байт SHA256(conv_id || author || seq).
* Все три uint64_t хешируются в порядке байтов хоста; nonce — обязательный буфер 13 байт.
* author разделяет направления; вызывающий не должен повторять seq при том же ключе/авторе/conv_id.
* Усечение хеша не даёт математической гарантии отсутствия коллизий. */
void dm_build_nonce(uint64_t conv_id, uint64_t author, uint64_t seq, uint8_t nonce[DM_NONCE_SIZE]);
#ifdef __cplusplus
}
#endif
#endif /* DM_CRYPTO_H */