belt.h(3)
💅 belt.h 💅
okay so bestie, welcome to belt.h(3) — yes, section 3 of the Library Functions Manual 📚 — and it is giving cryptography-core in the best way possible. This whole page is about the СТБ 34.101.31 algorithms, aka belt 👑 (an acronym that understood the assignment, fr fr).
✨ NAME ✨
belt.h — the СТБ 34.101.31 algorithms (belt) 💖
🌈 SYNOPSIS 🌈
#include 'bee2/defs.h'
🎀 Макросы 🎀
(aka the macros section, iykyk — we keep the original name because we're respectful like that 🫶)
#define beltCTRStepD beltCTRStepE— decrypting a fragment in CTR mode (Расшифрование фрагмента в режиме CTR) 🔓✨ — lowkey iconic that the decrypt step is just defined as the encrypt step, the duality is real 💀#define beltKWP_keep beltWBL_keep— the low-level KWP functions (Низкоуровневые функции KWP) 🧚
and that's just the appetizer bestie, the rest of this page is still loading 👇
✨ ФУНКЦИИ (Functions) ✨
okay bestie, here's the whole entire lineup of functions this library gives you — and not a single one is getting skipped, fr fr 💅 some of them set stuff up, some of them do the actual crypting, some of them just tell you how much room you need. all of them are iconic. let's go 🫶
const octet * beltH ()— the H substitution block. it's the S-box, the moment, the ~vibe table~ itself ✨void beltKeyExpand (octet key_[32], const octet key[], size_t len)— key expansion, where your key gets stretched out into the shape the algorithm wants 🎀void beltKeyExpand2 (u32 key_[8], const octet key[], size_t len)— key expansion and formatting. two jobs, one function, multitasking queen 👑void beltBlockEncr (octet block[16], const u32 key[8])— encrypt a block, periodt 🔥void beltBlockEncr2 (u32 block[4], const u32 key[8])— encrypt a formatted block 🫶void beltBlockEncr3 (u32 *a, u32 *b, u32 *c, u32 *d, const u32 key[8])— encrypt a block that's a little quartet of words (a,b,c,d), four besties holding hands 💅void beltBlockDecr (octet block[16], const u32 key[8])— decrypt a block, the reverse girlie 🙈void beltBlockDecr2 (u32 block[4], const u32 key[8])— decrypt a formatted block 🌸void beltBlockDecr3 (u32 *a, u32 *b, u32 *c, u32 *d, const u32 key[8])— decrypt a block from that same quartet of words 💜size_t beltWBL_keep ()— how many bytes the state of the WBL functions takes up 📏void beltWBLStart (void *state, const octet key[], size_t len)— init the WBL functions, get them ready to serve ✨void beltWBLStepE (void *buf, size_t count, void *state)— encryption in WBL mode 🔐void beltWBLStepD (void *buf, size_t count, void *state)— decryption in WBL mode 🔓void beltWBLStepD2 (void *buf1, void *buf2, size_t count, void *state)— decryption in WBL mode, but with two parts 🫶void beltWBLStepR (void *buf, size_t count, void *state)— continued encryption in WBL mode. yes it's the sequel ✨size_t beltCompr_deep ()— how deep the stack goes for the compression functions 🧚void beltCompr (u32 h[8], const u32 X[8], void *stack)— compress formatted data 🗜️void beltCompr2 (u32 s[4], u32 h[8], const u32 X[8], void *stack)— compress formatted data, but with addition in the mix 🌶️size_t beltECB_keep ()— how much room the ECB functions' state needs 📏void beltECBStart (void *state, const octet key[], size_t len)— init ECB encryption ✨void beltECBStepE (void *buf, size_t count, void *state)— encrypt a fragment in ECB mode 🔥void beltECBStepD (void *buf, size_t count, void *state)— decrypt in ECB mode 💧err_t beltECBEncr (void *dest, const void *src, size_t count, const octet key[], size_t len)— encrypt in ECB mode all in one go, and it hands you back anerr_tso you know how it went 📬err_t beltECBDecr (void *dest, const void *src, size_t count, const octet key[], size_t len)— decrypt in ECB mode, one shot 📬size_t beltCBC_keep ()— how much room the CBC functions' state needs 📏void beltCBCStart (void *state, const octet key[], size_t len, const octet iv[16])— init CBC encryption. it wants the key AND theiv[16], no skipping steps ✨void beltCBCStepE (void *buf, size_t count, void *state)— encrypt in CBC mode 🔐void beltCBCStepD (void *buf, size_t count, void *state)— decrypt in CBC mode 🔓err_t beltCBCEncr (void *dest, const void *src, size_t count, const octet key[], size_t len, const octet iv[16])— encrypt in CBC mode, all at once 📬err_t beltCBCDecr (void *dest, const void *src, size_t count, const octet key[], size_t len, const octet iv[16])— decrypt in CBC mode, all at once 📬size_t beltCFB_keep ()— how much room the CFB functions' state needs 📏void beltCFBStart (void *state, const octet key[], size_t len, const octet iv[16])— init CFB encryption, key plusiv[16]again ✨void beltCFBStepE (void *buf, size_t count, void *state)— encrypt in CFB mode 🔐void beltCFBStepD (void *buf, size_t count, void *state)— decrypt in CFB mode 🔓err_t beltCFBEncr (void *dest, const void *src, size_t count, const octet key[], size_t len, const octet iv[16])— encrypt in CFB mode, one call 📬err_t beltCFBDecr (void *dest, const void *src, size_t count, const octet key[], size_t len, const octet iv[16])— decrypt in CFB mode, one call 📬size_t beltCTR_keep ()— how much room the CTR functions' state needs 📏void beltCTRStart (void *state, const octet key[], size_t len, const octet iv[16])— init CTR encryption, key +iv[16]🎀void beltCTRStepE (void *buf, size_t count, void *state)— encrypt a fragment in CTR mode 🔥err_t beltCTR (void *dest, const void *src, size_t count, const octet key[], size_t len, const octet iv[16])— encryption in CTR mode, the whole thing at once 📬size_t beltMAC_keep ()— how much room the MAC functions' state needs 📏void beltMACStart (void *state, const octet key[], size_t len)— init the MAC functions ✨void beltMACStepA (const void *buf, size_t count, void *state)— authenticate (MAC) a fragment of data in MAC mode 🛡️void beltMACStepG (octet mac[8], void *state)— compute the MAC in MAC mode, 8 octets of it 🎯void beltMACStepG2 (octet mac[], size_t mac_len, void *state)— compute a truncated MAC in MAC mode ✂️bool_t beltMACStepV (const octet mac[8], void *state)— verify the MAC in MAC mode, gives you abool_tback ✅bool_t beltMACStepV2 (const octet mac[], size_t mac_len, void *state)— verify a truncated MAC ✅err_t beltMAC (octet mac[8], const void *src, size_t count, const octet key[], size_t len)— MAC in MAC mode, all in one go 📬size_t beltDWP_keep ()— how much room the DWP functions' state needs 📏void beltDWPStart (void *state, const octet key[], size_t len, const octet iv[16])— init the DWP functions, key +iv[16]✨void beltDWPStepE (void *buf, size_t count, void *state)— encrypt a critical fragment in DWP mode 🔐void beltDWPStepI (const void *buf, size_t count, void *state)— authenticate an open fragment in DWP mode 🛡️void beltDWPStepA (const void *buf, size_t count, void *state)— authenticate a critical fragment in DWP mode 🛡️void beltDWPStepG (octet mac[8], void *state)— compute the MAC in DWP mode 🎯bool_t beltDWPStepV (const octet mac[8], void *state)— verify the MAC in DWP mode ✅void beltDWPStepD (void *buf, size_t count, void *state)— decrypt a critical fragment in DWP mode 🔓err_t beltDWPWrap (void *dest, octet mac[8], const void *src1, size_t count1, const void *src2, size_t count2, const octet key[], size_t len, const octet iv[16])— apply protection in DWP mode (wrap it up 🎁)err_t beltDWPUnwrap (void *dest, const void *src1, size_t count1, const void *src2, size_t count2, const octet mac[8], const octet key[], size_t len, const octet iv[16])— remove protection in DWP mode (unwrap it 🎀)size_t beltCHE_keep ()— how much room the CHE functions' state needs 📏void beltCHEStart (void *state, const octet key[], size_t len, const octet iv[16])— init the CHE functions, key +iv[16]✨void beltCHEStepE (void *buf, size_t count, void *state)— encrypt a critical fragment in CHE mode 🔐void beltCHEStepI (const void *buf, size_t count, void *state)— authenticate an open fragment in CHE mode 🛡️void beltCHEStepA (const void *buf, size_t count, void *state)— authenticate a critical fragment in CHE mode 🛡️void beltCHEStepG (octet mac[8], void *state)— compute the MAC in CHE mode 🎯bool_t beltCHEStepV (const octet mac[8], void *state)— verify the MAC in CHE mode ✅void beltCHEStepD (void *buf, size_t count, void *state)— decrypt a critical fragment in CHE mode 🔓err_t beltCHEWrap (void *dest, octet mac[8], const void *src1, size_t count1, const void *src2, size_t count2, const octet key[], size_t len, const octet iv[16])— apply protection in CHE mode 🎁err_t beltCHEUnwrap (void *dest, const void *src1, size_t count1, const void *src2, size_t count2, const octet mac[8], const octet key[], size_t len, const octet iv[16])— remove protection in CHE mode 🎀err_t beltKWPWrap (octet dest[], const octet src[], size_t count, const octet header[16], const octet key[], size_t len)— apply protection in KWP mode 🎁err_t beltKWPUnwrap (octet dest[], const octet src[], size_t count, const octet header[16], const octet key[], size_t len)— remove protection in KWP mode 🎀size_t beltHash_keep ()— how much room the hashing function's state needs 📏void beltHashStart (void *state)— init the hashing function ✨void beltHashStepH (const void *buf, size_t count, void *state)— hash a fragment of data 🍓void beltHashStepG (octet hash[32], void *state)— compute the hash value, all 32 octets of it 🎯void beltHashStepG2 (octet hash[], size_t hash_len, void *state)— compute a truncated hash value ✂️bool_t beltHashStepV (const octet hash[32], void *state)— verify the hash value ✅bool_t beltHashStepV2 (const octet hash[], size_t hash_len, void *state)— verify a truncated hash value ✅err_t beltHash (octet hash[32], const void *src, size_t count)— hashing, one call and done 📬size_t beltBDE_keep ()— how much room the BDE functions' state needs 📏void beltBDEStart (void *state, const octet key[], size_t len, const octet iv[16])— init encryption in BDE mode, key +iv[16]✨void beltBDEStepE (void *buf, size_t count, void *state)— an encryption step in BDE mode 🔐void beltBDEStepD (void *buf, size_t count, void *state)
err_t beltBDEEncr (void *dest, const void *src, size_t count, const octet key[], size_t len, const octet iv[16])
Encryption, BDE mode. 🎀
err_t beltBDEDecr (void *dest, const void *src, size_t count, const octet key[], size_t len, const octet iv[16])
Decryption, BDE mode. 💖
size_t beltSDE_keep ()
The size of the state that the SDE functions need. Like, how much room you gotta set aside bestie. ✨
void beltSDEStart (void *state, const octet key[], size_t len)
Kick off encryption in SDE mode. 🌸
void beltSDEStepE (void *buf, size_t count, const octet iv[16], void *state)
One encryption step, SDE mode. 💅
void beltSDEStepD (void *buf, size_t count, const octet iv[16], void *state)
One decryption step, SDE mode. 🦋
err_t beltSDEEncr (void *dest, const void *src, size_t count, const octet key[], size_t len, const octet iv[16])
Encryption, SDE mode. ⭐
err_t beltSDEDecr (void *dest, const void *src, size_t count, const octet key[], size_t len, const octet iv[16])
Decryption, SDE mode. ⭐
size_t beltFMT_keep (u32 mod, size_t count)
How much state the FMT functions want. It depends on mod and count, so pass them in. 🍓
void beltFMTStart (void *state, u32 mod, size_t count, const octet key[], size_t len)
Initialize encryption in FMT mode. 🌈
void beltFMTStepE (u16 buf[], const octet iv[16], void *state)
One encryption step, FMT mode. 🔥
void beltFMTStepD (u16 buf[], const octet iv[16], void *state)
One decryption step, FMT mode. 🔥
err_t beltFMTEncr (u16 dest[], u32 mod, const u16 src[], size_t count, const octet key[], size_t len, const octet iv[16])
Encryption, FMT mode. 💜
err_t beltFMTDecr (u16 dest[], u32 mod, const u16 src[], size_t count, const octet key[], size_t len, const octet iv[16])
Decryption, FMT mode. 💜
size_t beltKRP_keep ()
How big the key-transformation functions' state is. 👑
void beltKRPStart (void *state, const octet key[], size_t len, const octet level[12])
Initialize the key-transformation functions. ✨
void beltKRPStepG (octet key_[], size_t key_len, const octet header[16], void *state)
Key replication. (тиражирование, bestie — making more keys fr fr) 🎀
err_t beltKRP (octet dest[], size_t m, const octet src[], size_t n, const octet level[12], const octet header[16])
Key transformation. 🌸
size_t beltHMAC_keep ()
How much state the HMAC functions need. 🫶
void beltHMACStart (void *state, const octet key[], size_t len)
Initialize the HMAC functions. 💖
void beltHMACStepA (const void *buf, size_t count, void *state)
MAC-protect one chunk of data, HMAC mode. 🦋
void beltHMACStepG (octet mac[32], void *state)
Produce the MAC, HMAC mode. 32 octets of it, no cap. ⭐
void beltHMACStepG2 (octet mac[], size_t mac_len, void *state)
Produce a truncated MAC, HMAC mode. 🍓
bool_t beltHMACStepV (const octet mac[32], void *state)
Check the MAC, HMAC mode. Returns a bool_t, so yes/no vibes. 💅
bool_t beltHMACStepV2 (const octet mac[], size_t mac_len, void *state)
Check a truncated MAC. 💅
err_t beltHMAC (octet mac[32], const void *src, size_t count, const octet key[], size_t len)
MAC protection, HMAC mode. 🔥
err_t beltPBKDF2 (octet key[32], const octet pwd[], size_t pwd_len, size_t iter, const octet salt[], size_t salt_len)
Build a key from a password. 🧚 That's the PBKDF2 moment, and honestly? Iconic. 🌈
✨ Подробное описание ✨
okay so bestie, let's get into the actual tea ☕💅
The algorithms of СТБ 34.101.31 (belt) are fully implemented here. No cap. Plus, there's extra stuff: a key-dependent hashing algorithm (HMAC) based on the belt-hash hashing function, and a password-based key derivation algorithm based on HMAC[belt-hash]. These algorithms are defined in СТБ 34.101.47 and СТБ 34.101.45 respectively. Iconic. 💅
The main algorithms are grouped into groups that define these crypto mechanisms. Vibe check:
- ECB — encryption in simple substitution mode (простая замена);
- CBC — encryption in cipher block chaining mode (сцепление блоков);
- CFB — encryption in feedback gamma mode (гаммирование с обратной связью);
- CTR — encryption in counter mode (счетчик);
- MAC — message authentication based on encryption (имитозащита на основе шифрования);
- DWP — authenticated data encryption, DWP scheme;
- CHE — authenticated data encryption, CHE scheme;
- KWP — authenticated key encryption (аутентифицированное шифрование ключей);
- Hash — hashing;
- BDE — block disk encryption;
- SDE — sector disk encryption;
- FMT — format-preserving encryption;
- KRP — key transformation (преобразование ключей);
- HMAC — authentication based on hashing (имитозащита на основе хэширования).
Mechanisms are built on base crypto algorithms: block encryption (Block), wide block encryption (WBL), and compression (Compr). The WBL mechanism is defined in the new edition of СТБ 34.101.31 and is the core of KWP. It's giving main character energy. 👑
In mechanisms ECB, CBC, CFB, CTR, MAC, DWP, CHE, KWP, BDE, SDE, FMT, KRP a 32-octet key is used. A key of this length can be built from a 16- or 24-octet key using the beltExpand() function. Slay. ✨
In the HMAC mechanism, a key of arbitrary length is used. It is recommended to use a 32-octet key. Periodt. 💅
In mechanisms ECB, CBC, CFB, CTR, MAC, DWP, CHE, KWP, BDE data is processed in 16-octet blocks. Literally.
In mechanisms Hash, HMAC data is processed in 32-octet blocks.
In the SDE mechanism, sectors are processed. A sector consists of two or more full 16-octet blocks. Obsessed. 🦋
In the FMT mechanism, strings of length count in the alphabet ZZ_mod = {0, 1,..., mod - 1} are processed. Here mod is the alphabet size or modulus. These constraints must hold:
2 <= mod && mod <= 65536;2 <= count && count <= 600. The last constraint is an implementation constraint.
Input to main and auxiliary functions: data and keys are supplied either as void arrays (unformatted data, default) or as u32 arrays (formatted data). Inside functions, unformatted data is formatted before use. On platforms with BIG_ENDIAN conventions, formatting takes extra time. Not me having to wait extra 😭.
Each mechanism is implemented as a bundle of several functions. These functions use common state, a pointer to which is passed as an additional parameter. There is a function to determine the memory volume for state (_keep). Memory for state is prepared by the calling program, and it is also responsible for clearing memory. You break it, you buy it energy. 💅
State can be copied as a memory fragment. Copy-paste queen 👑
The bundle must have a mechanism initialization function (Start) and one or more functions for processing data fragments and getting results (StepX).
Logic of StepX suffixes:
- E — encrypt (зашифровать);
- D — decrypt (расшифровать);
- A — authenticate (имитозащита);
- I — authentication of open data in DWP mode;
- H — hashing (хэширование);
- G — get (get MAC, hash value or new key);
- V — verify (check hash value, MAC);
- R — random (pseudorandom generation).
Bundle functions are designed to be as simple and efficient as possible. In particular, they do not check input data. No safety net, bestie 💀.
Each bundle is covered by a high-level function that processes all data as a whole. High-level functions do check input data. Adult supervision 🫶.
Mechanisms MAC, Hash, HMAC, DWP, CHE are implemented with support for the get-then-continue principle. This means after processing a certain portion of data, you can call a StepG function and then continue processing. It's giving multitasking ✨.
Ожидается The common state of the function bundle is not changed outside these functions. Don't touch, bestie 🙅♀️.
Ожидается [ERR_BAD_INPUT] All input pointers of high-level functions are valid. Valid vibes only ✨.
Предусловие All input pointers of low-level functions are valid.
If not stated otherwise, input buffers of bundle functions do not overlap. No overlapping, periodt 💅.
Макросы 🧚
#define beltCTRStepD beltCTRStepE
Прим. Encryption in CTR mode does not differ from decryption. Same same but different? No, literally same 💀.
#define beltKWP_keep beltWBL_keep
Прим. The functions of the WBL mechanism are repeated. Recycling queen ♻️.
Функции 💅
size_t beltBDE_keep ()
Returns the length of state (in octets) for BDE encryption functions.
Возвращает Length of state. That's it, that's the tea ☕.
err_t beltBDEDecr (void * dest, const void * src, size_t count, const octet key[], size_t len, const octet iv[16])
The buffer [count]src is decrypted using key [len]key and sync vector iv. The decryption result is placed in buffer [count]dest. Decryption slay ✨.
Ожидается [ERR_BAD_INPUT]
len == 16 || len == 24 || len == 32;count % 16 == 0 && count >= 16.
Возвращает ERR_OK if data is successfully decrypted, and an error code otherwise. Otherwise, we cry 😭.
Прим. Buffers may overlap. They can get cozy 🫂.
Аргументы
dest— plaintextsrc— ciphertextcount— number of octets of textkey— keylen— key lengthiv— sync vector
err_t beltBDEEncr (void * dest, const void * src, size_t count, const octet key[], size_t len, const octet iv[16])
The buffer [count]src is encrypted using key [len]key and sync vector iv. The encryption result is placed in buffer [count]dest. Encryption ate 💅.
Ожидается [ERR_BAD_INPUT]
len == 16 || len == 24 || len == 32;count % 16 == 0 && count >= 16.
Возвращает ERR_OK if data is successfully encrypted, and an error code otherwise. Fingers crossed 🤞.
Прим. Buffers may overlap. Cozy vibes 🫂.
Аргументы
dest— ciphertextsrc— plaintextcount— number of octets of textkey— keylen— key lengthiv— sync vector
void beltBDEStart (void * state, const octet key[], size_t len, const octet iv[16])
Using key [len]key and sync vector iv, data structures needed for BDE encryption are formed in state. Setting the stage 🎭.
Предусловие
len == 16 || len == 24 || len == 32.- At address
state,beltBDE_keep()octets are reserved. Reserve your spot 🎟️.
Прим. Buffers key and state may overlap. They can share 🫶.
Аргументы
state— statekey— keylen— key length in octetsiv— sync vector
void beltBDEStepD (void * buf, size_t count, void * state)
Buffer [count]buf is decrypted in BDE mode using the key placed in state. Decrypt era 💅.
Предусловие
count % 16 == 0.
Ожидается
beltBDEStart() < beltBDEStepD()*. Order matters 🔢.
Аргументы
buf— ciphertext / plaintextcount— number of octets of textstate— state
void beltBDEStepE (void * buf, size_t count, void * state)
Buffer [count]buf is encrypted in BDE mode using the key placed in state. Encrypt and serve ✨.
Предусловие
count % 16 == 0.
Ожидается
beltBDEStart() < beltBDEStepE()*.
Аргументы
buf— plaintext / ciphertext ✨count— number of octets of textstate— state
void beltBlockDecr (octet block[16], const u32 key[8])
Decrypts the data block block on the formatted key key. The decrypted result gets handed back to you right at the address block. 💖
Предусловие
memIsAligned(block, 4) == TRUE.
Аргументы
block— blockkey— key
void beltBlockDecr2 (u32 block[4], const u32 key[8])
Decrypts the formatted data block block on the formatted key key. Result goes back at the address block, no cap. 🫶
Аргументы
block— blockkey— key
void beltBlockDecr3 (u32 * a, u32 * b, u32 * c, u32 * d, const u32 key[8])
Decrypts the formatted block (a, b, c, d) — which is given as four consecutive 32-bit words — on the formatted key key. The decrypted result comes back through the input words themselves. iconic tbh. 💅
Аргументы
a— word ab— word bc— word cd— word dkey— key
void beltBlockEncr (octet block[16], const u32 key[8])
Encrypts the data block block on the formatted key key. The encrypted result lands back at the address block. ✨
Предусловие
memIsAligned(block, 4) == TRUE.
Аргументы
block— blockkey— key
void beltBlockEncr2 (u32 block[4], const u32 key[8])
Encrypts the formatted data block block on the formatted key key. Result returned at the address block. 🔥
Аргументы
block— blockkey— key
void beltBlockEncr3 (u32 * a, u32 * b, u32 * c, u32 * d, const u32 key[8])
Encrypts the formatted block (a, b, c, d) — four consecutive 32-bit words, bestie — on the formatted key key. Result comes back through the input words. 👑
Аргументы
a— word ab— word bc— word cd— word dkey— key
size_t beltCBC_keep ()
Returns the length of the state (in octets) for the CBC-mode encryption functions. 🎀
Возвращает
- the length of the state.
err_t beltCBCDecr (void * dest, const void * src, size_t count, const octet key[], size_t len, const octet iv[16])
The buffer [count]src gets decrypted on the key [len]key using the initialization vector iv. The decrypted result is placed in the buffer [count]dest. 🌸
Ожидается ERR_BAD_INPUT
len == 16 || len == 24 || len == 32;count >= 16.
Возвращает
ERR_OK if the data was decrypted successfully, and an error code otherwise.
Прим.
The buffers may overlap.
Аргументы
dest— plaintextsrc— ciphertextcount— number of octets of textkey— keylen— key lengthiv— initialization vector
err_t beltCBCEncr (void * dest, const void * src, size_t count, const octet key[], size_t len, const octet iv[16])
The buffer [count]src gets encrypted on the key [len]key using the initialization vector iv. The encrypted result is placed in the buffer [count]dest. 💖
Ожидается ERR_BAD_INPUT
len == 16 || len == 24 || len == 32;count >= 16.
Возвращает
ERR_OK if the data was encrypted successfully, and an error code otherwise.
Прим.
The buffers may overlap.
Аргументы
dest— ciphertextsrc— plaintextcount— number of octets of textkey— keylen— key lengthiv— initialization vector
void beltCBCStart (void * state, const octet key[], size_t len, const octet iv[16])
From the key [len]key and the initialization vector iv, the data structures needed for encryption in CBC mode get built inside state. setting the vibe before the party starts fr fr 🦋
Предусловие
len == 16 || len == 24 || len == 32.
beltCBC_keep() octets are reserved at the address state.
Прим.
The buffers key and state may overlap.
Аргументы
state— statekey— keylen— key length in octetsiv— initialization vector
void beltCBCStepD (void * buf, size_t count, void * state)
The buffer [count]buf gets decrypted in CBC mode on the key placed in state. 😌
Предусловие
count >= 16.
Ожидается
beltCBCStart() < beltCBCStepD()*.
Прим.
The notes for the beltCBCStepE() function still apply.
Аргументы
buf— ciphertext / plaintextcount— number of octets of textstate— state
void beltCBCStepE (void * buf, size_t count, void * state)
The buffer [count]buf gets encrypted in CBC mode on the key placed in state. 🔥
Предусловие
count >= 16.
Ожидается
beltCBCStart() < beltCBCStepE()*.
Прим.
You can call this function several times, passing buf made of full blocks. An incomplete block can only be passed on the very last call. In that case block "stealing" happens — that's ciphertext stealing, CTS, and yes it's giving main character energy. 💅
When you're lining up successive calls to this function, keep in mind that the buffer buf must contain at least one block. For example, to encrypt 33 octets you can first encrypt 16 octets and then 17 more. But you cannot first encrypt 32 octets and then 1 more. 🚨
Аргументы
buf— plaintext / ciphertextcount— number of octets of textstate— state
size_t beltCFB_keep ()
Returns the length of the state (in octets) for the CFB-mode encryption functions. 🎀
Возвращает
- the length of the state.
err_t beltCFBDecr (void * dest, const void * src, size_t count, const octet key[], size_t len, const octet iv[16])
The buffer [count]src gets decrypted on the key [len]key using the initialization vector iv. The decrypted result is placed in the buffer [count]dest. 🌈
Ожидается ERR_BAD_INPUT
len == 16 || len == 24 || len == 32.
Возвращает
ERR_OK if the data was decrypted successfully, and an error code otherwise.
Прим.
The buffers may overlap.
Аргументы
dest— plaintextsrc— ciphertextcount— number of octets of textkey— keylen— key lengthiv— initialization vector
err_t beltCFBEncr (void * dest, const void * src, size_t count, const octet key[], size_t len, const octet iv[16])
The buffer [count]src gets encrypted on the key [len]key using the initialization vector iv. The encrypted result is placed in the buffer [count]dest. ⭐
Ожидается ERR_BAD_INPUT
len == 16 || len == 24 || len == 32.
Возвращает
ERR_OK if the data was encrypted successfully, and an error code otherwise.
Прим.
The buffers may overlap.
Аргументы
dest— ciphertextsrc— plaintextcount— number of octets of textkey— keylen— key lengthiv— initialization vector
void beltCFBStart (void * state, const octet key[], size_t len, const octet iv[16])
From the key [len]key and the initialization vector iv, the data structures needed for encryption in CFB mode get built inside state. 🧚
Предусловие
len == 16 || len == 24 || len == 32.
beltCFB_keep() octets are reserved at the address state.
Прим.
The buffers key and state may overlap.
Аргументы
state— statekey— keylen— key length in octetsiv— initialization vector
void beltCFBStepD (void * buf, size_t count, void * state)
The buffer [count]buf gets decrypted in CFB mode on the key placed in state. 💜
Ожидается
beltCFBStart() < beltCFBStepD()*.
Аргументы
buf— ciphertext / plaintextcount— number of octets of textstate— state
🦋 beltCFBStepE
void beltCFBStepE (void * buf, size_t count, void * state)
Буфер [count]buf зашифровывается в режиме CFB на ключе, который лежит себе в state. Всё, ничего лишнего, просто шифруем ✨
Ожидается
beltCFBStart() < beltCFBStepE()*
Аргументы
buf— открытый текст / шифртекстcount— число октетов текстаstate— состояние
🎀 beltCHE_keep
size_t beltCHE_keep ()
Возвращается длина состояния (в октетах) функций CHE. Типа «сколько местечка зарезервить под state» 💅
Возвращает
- Длина состояния.
🌸 beltCHEStart
void beltCHEStart (void * state, const octet key[], size_t len, const octet
iv[16])
По ключу [len]key и синхропосылке iv в state формируются структуры данных, которые нужны для аутентифицированного шифрования в режиме CHE. Это как собрать сцену перед главным выступлением, ик 🌈
Предусловие
len == 16 || len == 24 || len == 32.- По адресу
stateзарезервированоbeltCHE_keep()октетов.
Прим.
- Буферы
keyиstateмогут пересекаться.
Аргументы
state— состояниеkey— ключlen— длина ключа в октетахiv— синхропосылка
💖 beltCHEStepA
void beltCHEStepA (const void * buf, size_t count, void * state)
Текущая имитовставка, которая сидит в state, пересчитывается с учётом нового фрагмента зашифрованных критических данных [count]buf. Пересчёт идёт на ключе, который тоже живёт в state. Всё в одном месте, удобно 🫶
Ожидается
- По адресу
stateзарезервированоbeltCHE_keep()октетов.
Ожидается
beltCHEStepI()* < beltCHEStepA()*
Ожидается
beltCHEStepE()* < beltCHEStepA()*
Аргументы
buf— критические данныеcount— число октетов данныхstate— состояние
🍓 beltCHEStepD
void beltCHEStepD (void * buf, size_t count, void * state)
Фрагмент зашифрованных критических данных [count]buf расшифровывается на ключе, который размещён в state. Результат расшифрования сохраняется в buf. Да, прямо на месте, никакой лишней суеты 💅
Ожидается
beltCHEStepG() < beltCHEStepD()
Ожидается
beltCHEStepA()* < beltCHEStepD()*
Аргументы
buf— критические данныеcount— число октетов данныхstate— состояние
🔥 beltCHEStepE
void beltCHEStepE (void * buf, size_t count, void * state)
Фрагмент критических данных [count]buf зашифровывается на ключе, который размещён в state. Результат зашифрования сохраняется в buf. Инплейс, bestie, инплейс ✨
Ожидается
beltCHEStart() < beltCHEStepE()*
Аргументы
buf— критические данныеcount— число октетов данныхstate— состояние
👑 beltCHEStepG
void beltCHEStepG (octet mac[8], void * state)
Определяется окончательная имитовставка mac всех данных, обработанных до этого функциями beltCHEStepI() и beltCHEStepA(). Финал, финиш, последний шаг, periodt 🎀
Ожидается
beltCHEStepI()* < beltCHEStepG()
Ожидается
beltCHEStepA()* < beltCHEStepG()
Предупреждения
При выполнении функции состояние state изменяется так, что продолжение имитозащиты становится некорректным. Так что не пытайся потом дописать что-то ещё, оно уже не будет валидным, fr fr 😭
Аргументы
mac— имитовставкаstate— состояние
🧚 beltCHEStepI
void beltCHEStepI (const void * buf, size_t count, void * state)
Текущая имитовставка, размещённая в state, пересчитывается с учётом нового фрагмента открытых данных [count]buf. Пересчёт выполняется на ключе, который тоже размещён в state. Открытые данные тоже хотят защиты, и они её получают 💜
Ожидается
beltCHEStart() < beltCHEStepI()*
Аргументы
buf— открытые данныеcount— число октетов данныхstate— состояние
⭐ beltCHEStepV
bool_t beltCHEStepV (const octet mac[8], void * state)
Проверяется, что окончательная имитовставка всех данных, обработанных до этого функциями beltCHEStepI() и beltCHEStepA(), совпадает с mac. Это вайб-чек для твоей имитовставки, и либо она проходит, либо нет 😌
Ожидается
beltCHEStepI()* < beltCHEStepV()
Ожидается
beltCHEStepA()* < beltCHEStepV()
Возвращает
- Признак успеха.
Предупреждения
При выполнении функции состояние state изменяется так, что продолжение имитозащиты становится некорректным. Да, и проверка тоже ломает состояние, это не баг, это фича режима 🙈
Аргументы
mac— контрольная имитовставкаstate— состояние
🌈 beltCHEUnwrap
err_t beltCHEUnwrap (void * dest, const void * src1, size_t count1, const
void * src2, size_t count2, const octet mac[8], const octet key[],
size_t len, const octet iv[16])
На ключе [len]key октетов с использованием имитовставки iv снимается защита зашифрованных критических данных [count1]src1 и открытых данных [count2]src2. При снятии защиты проверяется целостность пары (src1, src2) с помощью имитовставки mac. Если целостность не нарушена, то данные src1 расшифровываются в буфер [count1]dest. Сначала проверка, потом расшифровка — порядок важен, не путаем 💅
Ожидается [ERR_BAD_INPUT]
len == 16 || len == 24 || len == 32.
Возвращает
ERR_OK, если защита успешно снята, и код ошибки в противном случае.
Прим.
- Буферы могут пересекаться.
Аргументы
dest— расшифрованные критические данныеsrc1— зашифрованные критические данныеcount1— число октетов критических данныхsrc2— открытые данныеcount2— число октетов открытых данныхmac— имитовставкаkey— ключlen— длина ключаiv— синхропосылка
🎀 beltCHEWrap
err_t beltCHEWrap (void * dest, octet mac[8], const void * src1, size_t
count1, const void * src2, size_t count2, const octet key[], size_t len,
const octet iv[16])
На ключе [len]key с использованием имитовставки iv устанавливается защита критических данных [count1]src1 и открытых данных [count2]src2. При установке защиты критические данные зашифровываются и сохраняются в буфере [count1]dest. Кроме этого определяется имитовставка mac пары (src1, src2). Обернули, зашифровали, посчитали — всё в одном флаконе, ate 💅✨
Ожидается [ERR_BAD_INPUT]
len == 16 || len == 24 || len == 32;- буферы
destиmacне пересекаются.
Возвращает
ERR_OK, если защита успешно установлена, и код ошибки в противном случае.
Прим.
- Буферы могут пересекаться, за исключением пересечения
destиmac.
Аргументы
dest— зашифрованные критические данныеmac— имитовставкаsrc1— критические данныеcount1— число октетов критических данныхsrc2— открытые данныеcount2— число октетов открытых данныхkey— ключlen— длина ключаiv— синхропосылка
💜 beltCompr
void beltCompr (u32 h[8], const u32 X[8], void * stack)
Форматированный буфер h || X сжимается до форматированного буфера h. Сжатие, но по-умному 🦋
Предусловие
- Буферы
Xиhне пересекаются.
Схема расчета глубины stack
beltCompr_deep().
Аргументы
h— первая часть входа/выходX— вторая часть входаstack— стек
🌸 beltCompr2
void beltCompr2 (u32 s[4], u32 h[8], const u32 X[8], void * stack)
Форматированный буфер h || X сжимается до форматированного буфера h. Внутренняя переменная S belt-compress добавляется поразрядно по модулю 2 к буферу s. Да, вот такой дополнительный штрих к компрессу, и он реально важен 👑
Предусловие
- Буферы
sиh,Xиs,Xиhне пересекаются.
Схема расчета глубины stack
beltCompr_deep().
Аргументы
s— суммаh— первая часть входа/выходX— вторая часть входаstack— стек
⭐ beltCompr_deep
size_t beltCompr_deep ()
Возвращается глубина стека (в октетах) функций сжатия. То есть сколько октетов под stack надо выделить, чтобы всё было чики-пуки 💅
Возвращает
- Глубина стека.
🦋 beltCTR
err_t beltCTR (void * dest, const void * src, size_t count, const octet
key[], size_t len, const octet iv[16])
Буфер [count]src зашифровывается или расшифровывается на ключе [len]key с использованием синхропосылки iv. Результат шифрования размещается в буфере [count]dest. Один режим — два дела, шифруем и расшифровываем одним и тем же вызовом, iconично 🌈
Ожидается [ERR_BAD_INPUT]
len == 16 || len == 24 || len == 32.
Возвращает
ERR_OK, если шифрование завершено успешно, и код ошибки в противном случае.
Прим.
- Буферы могут пересекаться.
Аргументы
dest— шифртекст / открытый текстsrc— открытый текст / шифртекстcount— число октетов текстаkey— ключlen— длина ключаiv— синхропосылка
🎀 beltCTR_keep
size_t beltCTR_keep ()
Возвращается длина состояния (в октетах) функций шифрования в режиме CTR. Запомни это число, оно тебе ещё пригодится 🫶
Возвращает
- Длина состояния.
void beltCTRStart (void * state, const octet key[], size_t len, const octet iv[16])— по ключу[len]keyи синхропосылкеivвstateформируются структуры данных, которые нужны, чтобы шифровать в режиме CTR. типо разложила всё по полочкам заранее, и потом просто кайфуешь 💅
Предусловие
len == 16 || len == 24 || len == 32.- По адресу
stateзарезервированоbeltCTR_keep()октетов.
Прим.
- Буферы
keyиstateмогут пересекаться. bestie, им не тесно, всё ок 🫶
Аргументы
state— состояниеkey— ключlen— длина ключа в октетахiv— синхропосылка
void beltCTRStepE (void * buf, size_t count, void * state)— буфер[count]bufзашифровывается в режиме CTR на ключе, который уже лежит вstate. ну то есть state уже всё знает, ты просто подаёшь текст ✨
Ожидается
beltCTRStart() < beltCTRStepE()*.
Аргументы
buf— открытый текст / шифртекстcount— число октетов текстаstate— состояние
size_t beltDWP_keep ()— возвращается длина состояния (в октетах) функций DWP. скока местечка надо зарезервить, всё честно 💖
Возвращает
- Длина состояния.
void beltDWPStart (void * state, const octet key[], size_t len, const octet iv[16])— по ключу[len]keyи синхропосылкеivвstateформируются структуры данных, нужные для аутентифицированного шифрования в режиме DWP. auth-encryption mode: on 🔥
Предусловие
len == 16 || len == 24 || len == 32.- По адресу
stateзарезервированоbeltDWP_keep()октетов.
Прим.
- Буферы
keyиstateмогут пересекаться.
Аргументы
state— состояниеkey— ключlen— длина ключа в октетахiv— синхропосылка
void beltDWPStepA (const void * buf, size_t count, void * state)— текущая имитовставка, которая сидит вstate, пересчитывается с учётом нового фрагмента зашифрованных критических данных[count]buf. Пересчёт идёт на ключе, тоже размещённом вstate. типа обновляем мак по кусочку шифртекста, no cap 🎀
Ожидается
- По адресу
stateзарезервированоbeltDWP_keep()октетов.
Ожидается
beltDWPStepI()* < beltDWPStepA()*.
Ожидается
beltDWPStepE()* < beltDWPStepA()*.
Аргументы
buf— критические данныеcount— число октетов данныхstate— состояние
void beltDWPStepD (void * buf, size_t count, void * state)— фрагмент зашифрованных критических данных[count]bufрасшифровывается на ключе, размещённом вstate. Результат расшифрования сохраняется вbuf. расшифровали — и сразу обратно в тот же буфер, экономия места 💅
Ожидается
beltDWPStepG() < beltDWPStepD().
Ожидается
beltDWPStepA()* < beltDWPStepD().
Аргументы
buf— критические данныеcount— число октетов данныхstate— состояние
void beltDWPStepE (void * buf, size_t count, void * state)— фрагмент критических данных[count]bufзашифровывается на ключе, размещённом вstate. Результат зашифрования сохраняется вbuf. in-place, как мы любим 🌸
Ожидается
beltDWPStart() < beltDWPStepE()*.
Аргументы
buf— критические данныеcount— число октетов данныхstate— состояние
void beltDWPStepG (octet mac[8], void * state)— определяется окончательная имитовставкаmacвсех данных, обработанных до этого функциямиbeltDWPStepI()иbeltDWPStepA(). вот она, финалочка, главный мак выходит на сцену 👑
Ожидается
beltDWPStepI()* < beltDWPStepG().
Ожидается
beltDWPStepA()* < beltDWPStepG().
Предупреждения
- При выполнении функции состояние
stateизменяется так, что продолжение имитозащиты становится некорректным.
bestie, серьёзно: после beltDWPStepG() состояние уже не то. продолжать имитозащиту на нём — это фло, не делай так 😭
Аргументы
mac— имитовставкаstate— состояние
void beltDWPStepI (const void * buf, size_t count, void * state)— текущая имитовставка, размещённая вstate, пересчитывается с учётом нового фрагмента открытых данных[count]buf. Пересчёт идёт на ключе, тоже размещённом вstate. открытый текст тоже входит в мак, не забывай 💜
Ожидается
beltDWPStart() < beltDWPStepI()*.
Аргументы
buf— открытые данныеcount— число октетов данныхstate— состояние
bool_t beltDWPStepV (const octet mac[8], void * state)— проверяется, что окончательная имитовставка всех данных, обработанных до этого функциямиbeltDWPStepI()иbeltDWPStepA(), совпадает сmac. vibe check для мака: совпало или нет ⭐
Ожидается
beltDWPStepI()* < beltDWPStepV().
Ожидается
beltDWPStepA()* < beltDWPStepV().
Возвращает
- Признак успеха.
Предупреждения
- При выполнении функции состояние
stateизменяется так, что продолжение имитозащиты становится некорректным.
и тут тоже: state после проверки уже не годится для продолжения имитозащиты. предупреждена — значит вооружена 🙈
Аргументы
mac— контрольная имитовставкаstate— состояние
err_t beltDWPUnwrap (void * dest, const void * src1, size_t count1, const void * src2, size_t count2, const octet mac[8], const octet key[], size_t len, const octet iv[16])— на ключе[len]keyоктетов с использованием имитовставкиivснимается защита зашифрованных критических данных[count1]src1и открытых данных[count2]src2. При снятии защиты проверяется целостность пары (src1,src2) с помощью имитовставкиmac. Если целостность не нарушена, то данныеsrc1расшифровываются в буфер[count1]dest. типа сначала проверяем, всё ли честно, и только потом расшифровываем — никакого доверия на слово 🧚
Ожидается [ERR_BAD_INPUT]
len == 16 || len == 24 || len == 32.
Возвращает
ERR_OK, если защита успешно снята, и код ошибки в противном случае.
Прим.
- Буферы могут пересекаться.
Аргументы
dest— расшифрованные критические данныеsrc1— зашифрованные критические данныеcount1— число октетов критических данныхsrc2— открытые данныеcount2— число октетов открытых данныхmac— имитовставкаkey— ключlen— длина ключаiv— синхропосылка
err_t beltDWPWrap (void * dest, octet mac[8], const void * src1, size_t count1, const void * src2, size_t count2, const octet key[], size_t len, const octet iv[16])— на ключе[len]keyс использованием имитовставкиivустанавливается защита критических данных[count1]src1и открытых данных[count2]src2. При установке защиты критические данные зашифровываются и сохраняются в буфере[count1]dest. Кроме этого определяется имитовставкаmacпары (src1,src2). упаковали, зашифровали, мак посчитали — полный набор, ате 💖
Ожидается [ERR_BAD_INPUT]
len == 16 || len == 24 || len == 32;- буферы
destиmacне пересекаются.
Возвращает
ERR_OK, если защита успешно установлена, и код ошибки в противном случае.
Прим.
- Буферы могут пересекаться, за исключением пересечения
destиmac.
толькоdestиmacдержи подальше друг от друга, а то будет боль 💀
Аргументы
dest— зашифрованные критические данныеmac— имитовставкаsrc1— критические данныеcount1— число октетов критических данныхsrc2— открытые данныеcount2— число октетов открытых данныхkey— ключlen— длина ключаiv— синхропосылка
size_t beltECB_keep ()— возвращается длина состояния (в октетах) функций шифрования в режиме ECB. сколько надо под state — вот столько 🎀
Возвращает
- Длина состояния.
err_t beltECBDecr (void * dest, const void * src, size_t count, const octet key[], size_t len)— буферsrcизcountоктетов расшифровывается на ключе[len]key. Результат расшифрования размещается в буфереdest. ECB-режим, расшифровочка ✨
Ожидается [ERR_BAD_INPUT]
len == 16 || len == 24 || len == 32;count >= 16.
Возвращает
ERR_OK, если данные успешно расшифрованы, и код ошибки в противном случае.
Аргументы
dest— открытый текстsrc— шифртекстcount— число октетов текстаkey— ключlen— длина ключа
err_t beltECBEncr (void * dest, const void * src, size_t count, const octet key[], size_t len)— буфер[count]srcзашифровывается на ключе[len]keyоктетов. Результат зашифрования размещается в буфере[count]dest. шифруем, летс гоу 🌈
Ожидается [ERR_BAD_INPUT]
len == 16 || len == 24 || len == 32;count >= 16.
Возвращает
ERR_OK, если данные успешно зашифрованы, и код ошибки в противном случае.
Аргументы
dest— шифртекстsrc— открытый текстcount— число октетов текстаkey— ключlen— длина ключа
void beltECBStart (void * state, const octet key[], size_t len)— по ключу[len]keyвstateформируются структуры данных, необходимые для шифрования в режиме ECB.
Предусловие 🫶
okay so before you even think about calling this, here's the vibe check:
len == 16 || len == 24 || len == 32— those are literally the only key lengths that pass.- По адресу
stateзарезервированоbeltECB_keep()октетов — i.e. you gotta havebeltECB_keep()octets reserved atstate, no cap.
Прим. 🎀
Буферы key и state могут пересекаться — the key and state buffers are allowed to overlap, they can share the same space and it's genuinely fine.
Аргументы 🌸
state— состояние (the state, bestie, that's where the magic lives)key— ключ (the key)len— длина ключа в октетах (how long the key is, in octets)
void beltECBStepD (void * buf, size_t count, void * state) 💜
Буфер [count]buf расшифровывается в режиме ECB на ключе, размещенном в state — so [count]buf gets decrypted in ECB mode using the key that's already chilling inside state.
Предусловие
count >= 16.
Ожидается
beltECBStart() < beltECBStepD()*.
Прим.
Сохраняются замечания по функции beltECBStepE() — yeah, all the notes from beltECBStepE() still apply here, go read those.
Аргументы
buf— шифртекст / открытый текст (ciphertext in, plaintext out)count— число октетов текста (how many octets of text)state— состояние (the state)
void beltECBStepE (void * buf, size_t count, void * state) ✨
Буфер [count]buf зашифровывается в режиме ECB на ключе, размещенном в state — [count]buf gets encrypted in ECB mode with the key sitting in state.
Предусловие
count >= 16.
Ожидается
beltECBStart() < beltECBStepE()*.
Прим. 😭 this part matters
- К функции можно обратиться несколько раз, передавая
bufиз полных блоков — you can call this thing multiple times, feeding itbufmade of full blocks. - Неполный блок можно передать только при последнем обращении — a partial block can only be handed over on the very last call. And when you do that, it performs "кража" блока (ciphertext stealing, CTS) — block stealing, a.k.a. CTS. Iconic behaviour honestly.
- При организации последовательных обращений к функции следует учитывать, что буфер
bufдолжен содержать не менее одного блока — when you're chaining these calls, rememberbufmust hold at least one block. Например для зашифрования 33 октетов можно зашифровать сначала 16 октетов, а затем еще 17. Но нельзя зашифровать сначала 32 октета, а затем еще 1. So like: to encrypt 33 octets you can do 16 first, then 17. But you cannot do 32 first and then 1. Periodt.
Аргументы
buf— открытый текст / шифртекст (plaintext in, ciphertext out)count— число октетов текста (how many octets of text)state— состояние (the state)
size_t beltFMT_keep (u32 mod, size_t count) 🦋
Возвращается длина состояния (в октетах) функций шифрования при обработке слов длины count в алфавите {0, 1,..., mod - 1} — it hands you back the state length (in octets) that the encryption functions need when they're chewing on words of length count over the alphabet {0, 1,..., mod - 1}.
Предусловие
2 <= mod && mod <= 65536.2 <= count && count <= 600.
Возвращает
Длина состояния — the state length.
Аргументы
mod— размер алфавита (size of the alphabet)count— длина слов (word length)
err_t beltFMTDecr (u16 dest[], u32 mod, const u16 src[], size_t count, const octet key[], size_t len, const octet iv[16]) 💅
Строка [count]src в алфавите {0, 1,..., mod - 1} расшифровывается на ключе [len]key и синхропосылке iv — the string [count]src over the alphabet {0, 1,..., mod - 1} gets decrypted with the key [len]key and the IV iv. Результат расшифрования размещается в буфере [count]dest — the decrypted result lands in the [count]dest buffer. При нулевом указателе iv используется нулевая синхропосылка — if iv is a null pointer, a zero IV gets used instead.
Ожидается [ERR_BAD_INPUT] 🚨
2 <= mod && mod <= 65536;2 <= count;len == 16 || len == 24 || len == 32;- если
ivненулевой, то буферыivи[count]destне пересекаются — ifivisn't null, thenivand[count]destmust not overlap.
Ожидается [ERR_NOT_IMPLEMENTED] 😭
count <= 600.
Ожидается ✨
Символы src принадлежат алфавиту {0, 1,..., mod - 1} — the characters of src have to actually belong to the alphabet {0, 1,..., mod - 1}.
Возвращает
ERR_OK, если расшифрование успешно выполнено, и код ошибки в противном случае — ERR_OK if the decryption went off without a hitch, otherwise an error code.
Прим.
Все буферы, кроме iv и [count]dest, могут пересекаться — every buffer except iv and [count]dest is allowed to overlap.
Аргументы
dest— открытый текст (the plaintext)mod— размер алфавита (size of the alphabet)src— шифртекст (the ciphertext)count— длина шифртекста / открытого текста (length of the ciphertext / plaintext)key— ключ (the key)len— длинаkeyв октетах (length ofkeyin octets)iv— синхропосылка (the IV)
err_t beltFMTEncr (u16 dest[], u32 mod, const u16 src[], size_t count, const octet key[], size_t len, const octet iv[16]) 🔥
Строка [count]src в алфавите {0, 1,..., mod - 1} зашифровывается на ключе [len]key и синхропосылке iv — the string [count]src over the alphabet {0, 1,..., mod - 1} gets encrypted with the key [len]key and the IV iv. Результат зашифрования размещается в буфере [count]dest — the encrypted result lands in the [count]dest buffer. При нулевом указателе iv используется нулевая синхропосылка — null iv means a zero IV gets used.
Ожидается [ERR_BAD_INPUT] 🚨
2 <= mod && mod <= 65536;2 <= count;len == 16 || len == 24 || len == 32;- если
ivненулевой, то буферыivи[count]destне пересекаются — ifivisn't null, thenivand[count]destmust not overlap.
Ожидается [ERR_NOT_IMPLEMENTED] 😭
count <= 600.
Ожидается ✨
Символы src принадлежат алфавиту {0, 1,..., mod - 1} — the characters of src must belong to the alphabet {0, 1,..., mod - 1}.
Возвращает
ERR_OK, если зашифрование успешно выполнено, и код ошибки в противном случае — ERR_OK if the encryption succeeded, error code otherwise.
Прим.
Все буферы, кроме iv и [count]dest, могут пересекаться — all buffers except iv and [count]dest may overlap.
Аргументы
dest— шифртекст (the ciphertext)mod— размер алфавита (size of the alphabet)src— открытый текст (the plaintext)count— длина открытого текста / шифртекста (length of the plaintext / ciphertext)key— ключ (the key)len— длинаkeyв октетах (length ofkeyin octets)iv— синхропосылка (the IV)
void beltFMTStart (void * state, u32 mod, size_t count, const octet key[], size_t len) 🌈
По размеру алфавита mod, длине слов count и ключу [len]key в state формируются структуры данных, необходимые для шифрования в режиме FMT — given the alphabet size mod, the word length count and the key [len]key, it builds up the data structures inside state that FMT-mode encryption needs. Get it set up first, then go wild.
Предусловие
2 <= mod && mod <= 65536.2 <= count && count <= 600.len == 16 || len == 24 || len == 32.- По адресу
stateзарезервированоbeltFMT_keep()октетов —beltFMT_keep()octets reserved atstate.
Прим.
Буферы key и state могут пересекаться — key and state are allowed to overlap.
Аргументы
state— состояние (the state)mod— размер алфавита (size of the alphabet)count— длина слов (word length)key— ключ (the key)len— длина ключа в октетах (key length in octets)
void beltFMTStepD (u16 buf[], const octet iv[16], void * state) 🧚
Строка [count]buf расшифровывается на ключе, размещенном в state, и синхропосылке iv — the string [count]buf gets decrypted with the key stashed in state and the IV iv. Здесь count -- длина строки, предварительно установленная в state функцией beltFMTStart() — heads up, count here is the string length you already set inside state earlier via beltFMTStart(). Результат расшифрования сохраняется в buf — the decrypted result is written right back into buf.
Ожидается
beltFMTStart() < beltFMTStepD()*.
Ожидается
Символы строки принадлежат алфавиту {0,1,..., mod - 1}, размер mod которого предварительно установлен в state функцией beltFMTStart() — the string's characters must belong to the alphabet {0,1,..., mod - 1}, whose size mod you already set in state with beltFMTStart().
Прим.
При нулевом указателе iv используется нулевая синхропосылка — null iv pointer means a zero IV gets used.
Аргументы
buf— шифртекст / открытый текст (ciphertext in, plaintext out)iv— синхропосылка (the IV)state— состояние (the state)
void beltFMTStepE (u16 buf[], const octet iv[16], void * state) ⭐
Строка [count]buf зашифровывается на ключе, размещенном в state, и синхропосылке iv — the string [count]buf gets encrypted with the key living in state and the IV iv. Здесь count -- длина строки, предварительно установленная в state функцией beltFMTStart() — and again, count is the string length you already parked in state via beltFMTStart(). Результат зашифрования сохраняется в buf — the encrypted result is saved back into buf.
Ожидается
beltFMTStart() < beltFMTStepE()*.
Ожидается
Символы строки принадлежат алфавиту {0,1,..., mod - 1}, размер mod которого предварительно установлен в state функцией beltFMTStart() — the string's characters must belong to the alphabet {0,1,..., mod - 1}, size mod set beforehand in state by beltFMTStart().
Прим.
При нулевом указателе iv используется нулевая синхропосылка — null iv means a zero IV gets used.
Аргументы
buf— открытый текст / шифртекст (plaintext in, ciphertext out)iv— синхропосылка (the IV)state— состояние (the state)
const octet * beltH () 👑
Возвращается таблица значений блока подстановки H — it hands you back the table of values of the substitution block H. Yes, H is the main character here.
Возвращает
Указатель на таблицу H — a pointer to the H table.
Прим.
Таблица используется для формирования начальных значений переменных некоторых алгоритмов, а также в тестовых примерах — this table gets used to set up the initial values of variables in some algorithms, and it also shows up in the test vectors.
err_t beltHash (octet hash[32], const void * src, size_t count) 🍓
Определяется хэш-значение hash буфера [count]src — it computes the hash value hash of the [count]src buffer.
Возвращает
ERR_OK, если хэширование успешно завершено, и код ошибки в противном случае — ERR_OK if the hashing finished successfully, otherwise an error code.
Прим.
Буферы могут пересекаться — the buffers are allowed to overlap.
Аргументы
hash— хэш-значение (the hash value)src— данные (the data)count— число октетов данных (number of octets of data)
size_t beltHash_keep () 💖
Возвращается длина состояния (в октетах) функции хэширования — it returns the length of the state (in octets) that the hashing function needs.
Возвращает
Длина состояния — the state length.
void beltHashStart (void * state) 🎀
В state формируются структуры данных, необходимые для хэширования — the data structures needed for hashing get built up inside state.
Предусловие
По адресу state зарезервировано beltHash_keep() октетов — beltHash_keep() octets reserved at state.
Аргументы
state— состояние (the state)
void beltHashStepG (octet hash[32], void * state) 💀✨
Определяется окончательное хэш-значение hash всех данных, обработанных до этого функцией beltHashStepH() — it computes the final hash value hash over all the data that beltHashStepH() has processed up to this point.
Ожидается
(beltHashStepH()* < beltHashStepG())*.
Прим.
Если продолжение хэширования не предполагается, то буферы hash и state могут пересекаться — if you're not planning to keep hashing after this, then the hash and state buffers are allowed to overlap.
Аргументы
hash— хэш-значение (the hash value)state— состояние (the state)
void beltHashStepG2 (octet hash[], size_t hash_len, void * state)
Окей bestie, это финалочка хэш-саги 🌈💅 — берётся окончательное хэш-значение hash_lenhash от всех данных, которые ты до этого прогнала через beltHashStepH(). И да, в hash попадают ровно первые hash_len октетов полного хэш-значения — обрезаем аккуратно, без драмы 🎀.
- Предусловие:
hash_len <= 32. - Ожидается:
(beltHashStepH()* < beltHashStepG2())*. - Прим.: если продолжать хэширование ты не планируешь, то буферы
hashиstateмогут пересекаться — да, прям наезжать друг на друга, и это разрешено 🙈. - Аргументы:
hash— хэш-значениеhash_len— длинаhashstate— состояние
void beltHashStepH (const void * buf, size_t count, void * state)
Текущее хэш-значение, которое уже лежит в state, пересчитывается с учётом нового фрагмента данных countbuf. Типа «ещё кусочек в копилку» 🍓 — кидаешь данные, состояние обновляется, никто не пострадал.
- Ожидается:
beltHashStart() < beltHashStepH()*. - Аргументы:
buf— данныеcount— число октетов данныхstate— состояние
bool_t beltHashStepV (const octet hash[32], void * state)
Проверка вайба 👑: совпадает ли окончательное хэш-значение всех данных, обработанных до этого beltHashStepH(), с hash. Возвращает bool_t, так что либо тру, либо не тру, третьего не дано ✨.
- Ожидается:
(beltHashStepH()* < beltHashStepV())*. - Аргументы:
hash— контрольное хэш-значениеstate— состояние
bool_t beltHashStepV2 (const octet hash[], size_t hash_len, void * state)
То же самое, но с твистом 💫 — проверяется, что первые hash_len октетов окончательного хэш-значения (от всех данных, что прошли через beltHashStepH()) совпадают с hash_lenhash.
- Предусловие:
hash_len <= 32. - Ожидается:
(beltHashStepH()* < beltHashStepV2())*. - Аргументы:
hash— контрольное хэш-значениеhash_len— длинаhashstate— состояние
err_t beltHMAC (octet mac[32], const void * src, size_t count, const octet key[], size_t len)
На ключе lenkey вычисляется имитовставка mac буфера countsrc. Это такая «подпись доверия» для данных, чтобы никто не подменил их по-тихому 🔥.
- Возвращает:
ERR_OK, если имитовставка успешно вычислена, и код ошибки в противном случае. - Прим.: буферы могут пересекаться.
- Аргументы:
mac— имитовставкаsrc— данныеcount— число октетов данныхkey— ключlen— длина ключа
size_t beltHMAC_keep ()
Отдаёт длину состояния (в октетах) для функций имитозащиты в режиме MAC. Просто число, без сюрпризов 🧚.
- Возвращает: длина состояния.
void beltHMACStart (void * state, const octet key[], size_t len)
По ключу lenkey в state формируются все структуры данных, нужные для имитозащиты в режиме HMAC. Это твой стартовый пистолет 🎀 — без него дальше никуда.
- Предусловие: по адресу
stateзарезервированоbeltHMAC_keep()октетов. - Прим.: рекомендуется использовать ключ из 32 октетов.
- Аргументы:
state— состояниеkey— ключlen— длина ключа в октетах
void beltHMACStepA (const void * buf, size_t count, void * state)
Текущая имитовставка, которая живёт в state, пересчитывается с учётом нового фрагмента данных countbuf. И да, пересчёт идёт на ключе, который тоже размещён в state — всё своё ношу с собой 💅.
- Ожидается:
beltHMACStart() < beltHMACStepA()*. - Аргументы:
buf— данныеcount— число октетов данныхstate— состояние
void beltHMACStepG (octet mac[32], void * state)
Определяется окончательная имитовставка mac всех данных, обработанных до этого функцией beltHMACStepA(). Финальный аккорд, и мы готовы 🌟.
- Ожидается:
(beltHMACStepA()* < beltHMACStepG())*. - Аргументы:
mac— имитовставкаstate— состояние
void beltHMACStepG2 (octet mac[], size_t mac_len, void * state)
Определяется окончательная имитовставка mac_lenmac всех данных, обработанных до этого функцией beltHMACStepA(). Возвращаемая имитовставка — это первые mac_len октетов полной имитовставки. Обрезаем, но красиво ✂️💖.
- Предусловие:
mac_len <= 32. - Ожидается:
(beltHMACStepA()* < beltHMACStepG2())*. - Прим.: если продолжать имитозащиту ты не собираешься, то буферы
macиstateмогут пересекаться. - Аргументы:
mac— имитовставкаmac_len— длина имитовставкиstate— состояние
bool_t beltHMACStepV (const octet mac[32], void * state)
Проверяется, что окончательная имитовставка всех данных, обработанных до этого функцией beltHMACStepA(), совпадает с mac. Вайб-чек для подписи 😌✅.
- Ожидается:
(beltHMACStepA()* < beltHMACStepV())*. - Аргументы:
mac— контрольная имитовставкаstate— состояние
bool_t beltHMACStepV2 (const octet mac[], size_t mac_len, void * state)
Проверяется, что первые mac_len октетов окончательной имитовставки (всех данных, обработанных до этого функцией beltHMACStepA()) совпадают с mac_lenmac. Частичная проверка, но всё ещё максимально серьёзная 🫶.
- Предусловие:
mac_len <= 32. - Ожидается:
(beltHMACStepA()* < beltHMACStepV2())*. - Аргументы:
mac— контрольная имитовставкаmac_len— длинаmacstate— состояние
void beltKeyExpand (octet key_[32], const octet key[], size_t len)
Ключ lenkey расширяется до ключа key_. Глоу-ап для ключика ✨👑.
- Предусловие:
len == 16 || len == 24 || len == 32. - Прим.: буферы
keyиkey_могут пересекаться. - Аргументы:
key_— расширенный ключkey— первоначальный ключlen— длинаkeyв октетах
void beltKeyExpand2 (u32 key_[8], const octet key[], size_t len)
Ключ lenkey форматируется и расширяется до ключа key_. Двойная работа, двойной слэй 💅🔥.
- Предусловие:
len == 16 || len == 24 || len == 32. - Прим.: буферы
keyиkey_могут пересекаться. - Аргументы:
key_— расширенный форматированный ключkey— первоначальный ключlen— длина ключа в октетах
err_t beltKRP (octet dest[], size_t m, const octet src[], size_t n, const octet level[12], const octet header[16])
По ключу nsrc, у которого есть уровень level, строится ключ mdest с заголовком header. Это как переезд ключа на новый уровень, но с сохранением аусвайса 🎀.
Ожидается [ERR_BAD_INPUT]:
n == 16 || n == 24 || n == 32;m == 16 || m == 24 || m == 32;m <= n.
- Возвращает:
ERR_OK, если преобразование успешно завершено, и код ошибки в противном случае. - Прим.: буферы могут пересекаться.
- Аргументы:
dest— преобразованный ключm— длинаdestв октетахsrc— исходный ключn— длинаsrcв октетахlevel— уровень ключаsrcheader— заголовок ключаdest
size_t beltKRP_keep ()
Возвращается длина состояния (в октетах) функций преобразования ключа. Тот же вайб, что и у остальных _keep — просто скажи мне, сколько места готовить 🙏.
- Возвращает: длина состояния.
void beltKRPStart (void * state, const octet key[], size_t len, const octet level[12])
По ключу lenkey, который принадлежит уровню level, в state формируются структуры данных, необходимые для преобразования этого ключа. Настраиваем сцену, дальше будет шоу ✨.
- Предусловие:
len == 16 || len == 24 || len == 32.- По адресу
stateзарезервированоbeltKRP_keep()октетов.
- Прим.: буферы
keyиstateмогут пересекаться. - Аргументы:
state— состояниеkey— ключlen— длина ключа в октетахlevel— уровень
void beltKRPStepG (octet key_[], size_t key_len, const octet header[16], void * state)
Ключ lenkey, размещённый в state функцией beltKRPStart(), преобразуется в ключ key_lenkey_, который имеет заголовок header. Финал преображения, main character moment 💫.
- Предусловие:
(key_len == 16 || key_len == 24 || key_len == 32) && key_len <= len. - Ожидается:
beltKRPStart() < beltKRPStepG()*. - Аргументы:
key_— преобразованный ключkey_len— длинаkeyв октетахheader— заголовокkey_state— состояние
err_t beltKWPUnwrap (octet dest[], const octet src[], size_t count, const octet header[16], const octet key[], size_t len)
На ключе lenkey снимается защита с ключа countsrc. В результате определяется первоначальный ключ count - 16 dest с заголовком header. Разворачиваем подарочек обратно 🎁➡️🧸.
Ожидается [ERR_BAD_INPUT]:
len == 16 || len == 24 || len == 32;count >= 32.
- Возвращает:
ERR_OK, если защита успешно снята, и код ошибки в противном случае. - Прим.:
- При нулевом указателе
headerиспользуется нулевой заголовок. - Буферы могут пересекаться.
- При нулевом указателе
Arguments (for the call right above this, yeah? 💅)
dest— защищенный ключ, the wrapped/protected keysrc— защищаемый ключ, the key getting protectedcount— длинаsrcв октетах, how longsrcis in octetsheader— заголовок ключа, the key headerkey— ключ защиты, the protection keylen— длинаkeyв октетах, how longkeyis in octets
💖 beltKWPWrap
err_t beltKWPWrap (octet dest[], const octet src[], size_t count,
const octet header[16], const octet key[], size_t len)
okay so bestie, you take the key key of length len, and you wrap the key src of count octets with the header header. What comes out the other side is the protected key dest, and it's count + 16 octets long. 🔐✨
Expects ERR_BAD_INPUT when:
len == 16 || len == 24 || len == 32count >= 16
Returns — ERR_OK if the protection landed perfectly, otherwise an error code.
Note — if the header pointer is null, a null header gets used. And yes, the buffers are allowed to overlap. 🫶
Arguments
dest— защищенный ключ, the protected keysrc— защищаемый ключ, the key being protectedcount— длинаsrcв октетахheader— заголовок ключаkey— ключ защитыlen— длинаkeyв октетах
🦋 beltMAC
err_t beltMAC (octet mac[8], const void * src, size_t count,
const octet key[], size_t len)
Using the key key of length len, this computes the имитовставка (MAC) mac over the buffer src of count octets. Literally the vibe check for your data. 💀
Expects ERR_BAD_INPUT when:
len == 16 || len == 24 || len == 32
Returns — ERR_OK if the MAC got computed successfully, otherwise an error code.
Note — the buffers may overlap. no cap.
Arguments
mac— имитовставка, the MACsrc— данные, the datacount— число октетов данныхkey— ключ, the keylen— длина ключа, the key length
🌸 beltMAC_keep
size_t beltMAC_keep ()
Gives you back the length (in octets) of the state that the MAC-mode имитозащита functions need. 📏
Returns — the state length.
💅 beltMACStart
void beltMACStart (void * state, const octet key[], size_t len)
Using the key key of length len, it builds up inside state all the data structures needed for имитозащита in MAC mode. Setting the stage, main character energy. 👑
Precondition
len == 16 || len == 24 || len == 32beltMAC_keep()octets are reserved at the addressstate
Note — the key and state buffers may overlap.
Arguments
state— состояние, the statekey— ключ, the keylen— длина ключа в октетах
✨ beltMACStepA
void beltMACStepA (const void * buf, size_t count, void * state)
The current MAC sitting in state gets recomputed to account for a new chunk of data buf of count octets. The recompute happens on the key that's also living in state. one more bite of data, slay. 🍓
Expects
beltMACStart() < beltMACStepA()*
Arguments
buf— данные, the datacount— число октетов данныхstate— состояние, the state
🎀 beltMACStepG
void beltMACStepG (octet mac[8], void * state)
Produces the final MAC mac over all the data that beltMACStepA() has chewed through so far. the grand finale, periodt. 💖
Expects
(beltMACStepA()* < beltMACStepG())*
Note — if you're not planning to continue the имитозащита, the mac and state buffers may overlap.
Arguments
mac— имитовставка, the MACstate— состояние, the state
🌈 beltMACStepG2
void beltMACStepG2 (octet mac[], size_t mac_len, void * state)
Produces the final MAC mac of length mac_len over all the data processed so far by beltMACStepA(). The returned MAC is made of the first mac_len octets of the full MAC. truncated but make it fashion. 💅
Precondition
mac_len <= 8
Expects
(beltMACStepA()* < beltMACStepG2())*
Note — if you're not continuing the имитозащита, the mac and state buffers may overlap.
Arguments
mac— имитовставка, the MACmac_len— длина имитовставки, the MAC lengthstate— состояние, the state
⭐ beltMACStepV
bool_t beltMACStepV (const octet mac[8], void * state)
Checks that the final MAC over all the data processed so far by beltMACStepA() matches mac. it's giving verification. 🔍
Expects
(beltMACStepA()* < beltMACStepV())*
Returns — a success flag.
Arguments
mac— контрольная имитовставка, the reference MACstate— состояние, the state
🧚 beltMACStepV2
bool_t beltMACStepV2 (const octet mac[], size_t mac_len, void * state)
Checks that the first mac_len octets of the final MAC over all the data processed so far by beltMACStepA() match mac of length mac_len. 👑
Precondition
mac_len <= 8
Expects
(beltMACStepA()* < beltMACStepV2())*
Arguments
mac— контрольная имитовставка, the reference MACmac_len— длинаmacstate— состояние, the state
🔥 beltPBKDF2
err_t beltPBKDF2 (octet key[32], const octet pwd[], size_t pwd_len,
size_t iter, const octet salt[], size_t salt_len)
From the password pwd of length pwd_len, this builds the key key. To make dictionary attacks harder, it uses the sync message (salt) salt of length salt_len. And to make password brute-forcing harder, the key gets recomputed iter > 0 times. extra, extra, extra. 😤
Expects ERR_BAD_INPUT when:
iter != 0
Returns — ERR_OK if the key got built successfully, otherwise an error code.
Note
- Recommended to use
iter >= 10000andsalt_len >= 8. - This implements a simplified edition of the PBKDF2 (Password-Based Key Derivation Function version 2) algorithm defined in PKCS#5. The edition is described in СТБ 34.101.45 (приложение E).
Arguments
key— ключ, the keypwd— пароль, the passwordpwd_len— длина пароля (в октетах)iter— число итераций, the number of iterationssalt— синхропосылка ("соль"), the saltsalt_len— длина синхропосылки (в октетах)
💜 beltSDE_keep
size_t beltSDE_keep ()
Returns the length (in octets) of the state needed by the encryption functions in SDE mode. 📐
Returns — the state length.
🫶 beltSDEDecr
err_t beltSDEDecr (void * dest, const void * src, size_t count,
const octet key[], size_t len, const octet iv[16])
The sector src of count octets gets decrypted on the key key of length len, using the sync message iv. The decrypted result lands in the buffer dest of count octets. 🔓
Expects ERR_BAD_INPUT when:
len == 16 || len == 24 || len == 32count % 16 == 0 && count >= 32
Returns — ERR_OK if the data got decrypted successfully, otherwise an error code.
Note — the buffers may overlap.
Arguments
dest— открытый текст, the plaintextsrc— шифртекст, the ciphertextcount— число октетов текстаkey— ключ, the keylen— длина ключа, the key lengthiv— синхропосылка, the sync message
🌸 beltSDEEncr
err_t beltSDEEncr (void * dest, const void * src, size_t count,
const octet key[], size_t len, const octet iv[16])
The sector src of count octets gets encrypted on the key key of length len, using the sync message iv. The encrypted result lands in the buffer dest of count octets. 🔒✨
Expects ERR_BAD_INPUT when:
len == 16 || len == 24 || len == 32count % 16 == 0 && count >= 32
Returns — ERR_OK if the data got encrypted successfully, otherwise an error code.
Note — the buffers may overlap.
Arguments
dest— шифртекст, the ciphertextsrc— открытый текст, the plaintextcount— число октетов текстаkey— ключ, the keylen— длина ключа, the key lengthiv— синхропосылка, the sync message
💖 beltSDEStart
void beltSDEStart (void * state, const octet key[], size_t len)
Using the key key of length len and the sync message iv, it builds up inside state the data structures needed for encryption in SDE mode. yes, iv is in this description even though it's not a parameter, iykyk, we're just reporting what the page says. 🙈
Precondition
len == 16 || len == 24 || len == 32beltSDE_keep()octets are reserved at the addressstate
Note — the key and state buffers may overlap.
Arguments
state— состояние, the statekey— ключ, the keylen— длина ключа в октетах
🌈 beltSDEStepD
void beltSDEStepD (void * buf, size_t count, const octet iv[16],
void * state)
The sector buf of count octets gets decrypted in SDE mode on the key living in state, with the sync message iv. 🔓
Precondition
count % 16 == 0 && count >= 32
Expects
beltSDEStart() < beltSDEStepD()*
Arguments
buf— шифртекст / открытый текстcount— число октетов текстаiv— синхропосылкаstate— состояние
⭐ beltSDEStepE
void beltSDEStepE (void * buf, size_t count, const octet iv[16],
void * state)
The sector buf of count octets gets encrypted in SDE mode on the key living in state, with the sync message iv. 🔒
Precondition
count % 16 == 0 && count >= 32
Expects
beltSDEStart() < beltSDEStepE()*
Arguments
buf— открытый текст / шифртекстcount— число октетов текстаiv— синхропосылкаstate— состояние
Аргументы 💅
buf— открытый текст / шифртекст 🦋count— число октетов текстаiv— синхропосылка ✨state— состояние
size_t beltWBL_keep ()
Возвращается длина состояния (в октетах) функций WBL. Типа «сколько местечка зарезервить, бести» 💖
Возвращает
Длина состояния.
void beltWBLStart (void * state, const octet key[], size_t len)
По ключу [len]key в state формируются структуры данных, необходимые для шифрования в режиме WBL. Это типа твой set-up, твой glow-up перед выходом на сцену 👑
Предусловие
len == 16 || len == 24 || len == 32.- По адресу
stateзарезервированоbeltWBL_keep()октетов.
Прим.
Буферы key и state могут пересекаться. Да, буквально, они могут жить друг на друге, всё ок.
Аргументы
state— состояниеkey— ключ 🔑len— длина ключа в октетах
void beltWBLStepD (void * buf, size_t count, void * state)
Буфер [count]buf расшифровывается на ключе, размещенном в state. Результат расшифрования сохраняется в buf. Расшифровочка, распаковываем подарочки 🎀
Предусловие
count >= 32.
Ожидается
beltWBLStart() < beltWBLStepD()*. То есть сначала стартанули, потом уже шагаем, порядок важен, no cap.
Аргументы
buf— шифртекст / открытый текстcount— число октетов данныхstate— состояние
void beltWBLStepD2 (void * buf1, void * buf2, size_t count, void * state)
Буфер [count - 16]buf1 || [16]buf2 расшифровывается в режиме WBL на ключе, размещенном в state. Результат расшифрования сохраняется в buf1 || buf2. Это как две подружки, которые ходят только парой 🫶
Предусловие
count >= 32.- Буферы
buf1иbuf2не пересекаются. Серьёзно, они не должны пересекаться, не делай так, это не вайб.
Ожидается
beltWBLStart() < beltWBLStepD2()*.
Прим.
С помощью beltWBLStepD2() снятие защиты с ключа в механизме KWP может быть организовано по следующей схеме:
- первая часть защищенного ключа помещается в
buf1; - вторая часть защищенного ключа помещается в
buf2; - применяется
beltWBLStepD2(); - если
buf2совпадает с заголовком ключа, тоbuf1принимается как ключ. 💀✨
Аргументы
buf1— первая часть шифртекста / открытого текстаbuf2— вторая часть шифртекста / открытого текстаcount— длина текстаstate— состояние
void beltWBLStepE (void * buf, size_t count, void * state)
Буфер [count]buf зашифровывается на ключе, размещенном в state. Результат зашифрования сохраняется в buf. Зашифровочка, заворачиваем подарочки обратно в блестящую бумагу 🌸
Предусловие
count >= 32.
Ожидается
beltWBLStart() < beltWBLStepE()*.
Аргументы
buf— открытый текст / шифртекстcount— число октетов текстаstate— состояние
void beltWBLStepR (void * buf, size_t count, void * state)
Буфер [count]buf зашифровывается на ключе, размещенном в state. Результат зашифрования сохраняется в buf. При первом обращении счетчик i меняется от 1 до 2n, при втором — от 2n + 1 до 4n, и так далее. Это оно крутится по кругу, как мой плейлист, и не останавливается 🔥
Предусловие
count >= 32.
Ожидается
beltWBLStart() < beltWBLStepR()*.
Прим.
Многократное зашифрование в режиме WBL используется для генерации одноразового ключа в СТБ 34.101.45. Поэтому функции назначен суффикс R. iykyk 💅
Аргументы
buf— открытый текст / шифртекстcount— число октетов текстаstate— состояние
✨ Автор ✨
Автоматически создано Doxygen для Библиотека Bee2 из исходного текста. Да, доxygen написал это за нас, мы просто навели красоту, bestie 💜
И вот мы на финише, детка! 🎉 Это была страничка из Библиотека Bee2, версия от Вс 25 Янв 2026 00:00:00, и живёт она в belt.h(3). Спасибо, что дочитала до конца, ты буквально main character energy 👑💖 Пока-пока! 🦋
📦 where this page comes from
- fedora 44: bee2-devel 2.2.0-1.fc44 · GPL-3.0-only and GPL-3.0-or-later
- fedora 44: bee2-devel 2.2.0-1.fc44 · GPL-3.0-only and GPL-3.0-or-later
- 💖 girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms