/* Одна Ed25519-подпись пачки до RS, части переменного размера без отдельных подписей. * Контексты одного uasync-потока; descriptor и ключ источника уже проверены членством группы. * encode возвращает заимствованные блоки до следующего encode/destroy; ошибочные результаты не публикуют. * parse проверяет только формат части; подпись источника проверяется после RS в batch_verify. * Заимствованные части действуют до следующего encode/destroy; ошибочный результат не публикуют. */ #ifndef STREAM_BLOCK_H #define STREAM_BLOCK_H #include "stream_proto.h" #ifdef __cplusplus extern "C" { #endif struct stream_encoder; struct stream_batch_info { uint64_t seq; uint32_t data_length; uint16_t timestamp_ms; uint16_t block_size; /* Фактический размер RS-кодограммы одной пачки. */ uint8_t flags; }; struct stream_block_view { struct stream_batch_info batch; uint8_t subblock; const uint8_t *rs; /* Заимствованный диапазон batch.block_size байт. */ }; int stream_descriptor_validate(const struct stream_descriptor *descriptor); size_t stream_block_capacity(const struct stream_descriptor *descriptor); /* Максимальная длина содержимого без подписанных метаданных/подписи. */ size_t stream_input_size(const struct stream_descriptor *descriptor); /* out заранее NULL; ключ копируется и очищается при destroy. */ int stream_encoder_create(struct stream_encoder **out, const struct stream_descriptor *descriptor, const uint8_t private_key[SC_PRIVKEY_SIZE]); void stream_encoder_destroy(struct stream_encoder *encoder); /* Заимствованный публичный ключ, полученный из private_key этого encoder. */ const uint8_t *stream_encoder_public_key(const struct stream_encoder *encoder); /* blocks — массив descriptor.n указателей; input не перекрывается с рабочими буферами encoder. * 0 < length <= stream_input_size; подпись входит в RS, дополнение не превышает n-r-1 байт. * block_length получает общий фактический размер частей. seq != UINT64_MAX. * При ошибке blocks/block_length не изменяются; собственная рабочая память может измениться. */ int stream_encoder_encode(struct stream_encoder *encoder, uint64_t seq, uint16_t timestamp_ms, uint8_t flags, const uint8_t *input, size_t length, const uint8_t **blocks, size_t *block_length); /* Формат, дескриптор и канонический размер; криптографической проверки части нет. view не меняется при отказе. */ int stream_block_parse(const struct stream_descriptor *descriptor, const uint8_t *wire, size_t length, struct stream_block_view *view); /* После RS сверить подписанные поля с ожидаемой пачкой, нулевой хвост и одну подпись источника. * decoded_length — полный восстановленный размер с padding; содержимое начинается с STREAM_BATCH_HEADER. */ int stream_batch_verify(const struct stream_descriptor *descriptor, const uint8_t public_key[SC_PUBKEY_SIZE], const struct stream_batch_info *expected, const uint8_t *decoded, size_t decoded_length); #ifdef __cplusplus } #endif #endif