bels.h(3)
✨ bels.h(3) — Library Functions Manual ✨
💖 NAME 💖
bels.h — Алгоритмы СТБ 34.101.60 (bels). That's the whole name, bestie. 💅
🌸 SYNOPSIS 🌸
#include 'bee2/defs.h'
✨ Функции ✨
err_t belsStdM (octet m[], size_t len, size_t num)— loads a standard public key, no cap.err_t belsValM (const octet m[], size_t len)— checks a public key, vibe check.err_t belsGenM0 (octet m0[], size_t len, gen_i ang, void *ang_state)— generates the common public key.err_t belsGenMi (octet mi[], size_t len, const octet m0[], gen_i ang, void *ang_state)— generates user public keys.err_t belsGenMid (octet mid[], size_t len, const octet m0[], const octet id[], size_t id_len)— generates a user public key from an identifier.err_t belsShare (octet si[], size_t count, size_t threshold, size_t len, const octet s[], const octet m0[], const octet mi[], gen_i rng, void *rng_state)— splits a secret.err_t belsShare2 (octet si[], size_t count, size_t threshold, size_t len, const octet s[], gen_i rng, void *rng_state)— splits a secret on standard public keys.err_t belsShare3 (octet si[], size_t count, size_t threshold, size_t len, const octet s[])— deterministic secret splitting on standard public keys.err_t belsRecover (octet s[], size_t count, size_t len, const octet si[], const octet m0[], const octet mi[])— recovers a secret.err_t belsRecover2 (octet s[], size_t count, size_t len, const octet si[])— recovers a secret on standard public keys.
💅 Подробное описание 💅
Okay so bestie, what we have here are the СТБ 34.101.60 (bels) algorithms, fr fr. When we say “algorithms,” we mean the sections of СТБ 34.101.60-2013 where they’re defined. 💖
These algorithms are made for splitting a secret of len octets, where len = 16, 24, or 32. To split a secret, they use public keys mi, which also consist of len octets. The public key m0 is common, and the other public keys are tied to specific users. 👑
Number of irreducible polynomials:
l = 128, 256: (2^l - 2^{l/2}) / l;
l = 192: (2^192 - 2^96 - 2^64 + 2^27) / l.
So a random degree l polynomial will be irreducible with probability close to 1/l. Lowkey iconic.
If you check k * l random polynomials, then none of them will be irreducible with probability close to p = (1 - 1/l)^{k * l} ≈ e^{-k}. In the implementation k = B_PER_IMPOSSIBLE * 3 / 4 > B_PER_IMPOSSIBLE * \log (2) and therefore p < 2^{-B_PER_IMPOSSIBLE}. Math ate, periodt. 💅
In belsGenM0(), failure after k * l generation attempts is interpreted as a violation of the expected properties of ang, and it returns error code ERR_BAD_ANG. 😭
Generation of user public keys is based on the auxiliary algorithm BuildIrred, described in 6.3. In this algorithm, the input polynomial u is interpreted as an element of the field E = F_2[x]/(f0(x)), where f0(x) = x^l + m0(x) -- an irreducible polynomial of degree l. BuildIrred returns the minimal polynomial f of the element u. The polynomial f is either irreducible or f == 1. If deg f = l, generation is complete -- the public key is determined by f. ✨
Every irreducible polynomial of degree l is the minimal polynomial for l different elements of the field. Therefore the probability that f will have degree l is close to
(1 - 2^{-l/2}) [l = 128, 256]
(1 - 2^{-96} - ...) [l = 192].
In belsGenMi(), belsGenMid(), it makes k = \max (3, B_PER_IMPOSSIBLE * 2 / l) generation attempts for f. A situation where all attempts fail is considered impossible and is interpreted as invalid input (the common public key m0 corresponds to a polynomial f0 that is not irreducible) with return code ERR_BAD_PUBKEY. 💀
Ожидается [ERR_BAD_INPUT] — all input pointers are valid.
Регулярность — todo. Bestie, it’s giving “we’ll finish this later.” 🙈
🦋 Функции 🦋
err_t belsGenM0 (octet m0[], size_t len, gen_i ang, void * ang_state)
Generates the common public key [len]m0. For generation it uses generator ang and its state ang_state. 🎀
Expects [ERR_BAD_INPUT]:
len == 16 || len == 24 || len == 32.
Expects [ERR_BAD_ANG]:
- Generator
angproduces non-repeating candidate keys.
Returns:
ERR_OKif the key was successfully generated, and an error code otherwise.
Прим. — the algorithm bels-genm0 is implemented.
Arguments:
m0— common public keylen— key length in octetsang— random number generatorang_state— generator state
err_t belsGenMi (octet mi[], size_t len, const octet m0[], gen_i ang, void * ang_state)
Using the common public key [len]m0 octets, generates the user public key [len]mi. For generation it uses generator ang and its state ang_state. 💖
Expects [ERR_BAD_INPUT]:
len == 16 || len == 24 || len == 32.
Expects [ERR_BAD_PUBKEY]:
- Key
m0is correct.
Expects [ERR_BAD_ANG]:
- Generator
angis correct and produces non-repeating candidate keys.
Returns:
ERR_OKif the keys were successfully generated, and an error code otherwise.
Прим. — the algorithm bels-genmi is partially implemented. To generate a set of public keys, call the function several times and check that the obtained keys are distinct. 🦋
Arguments:
mi— user public keylen— length of the keys in octetsm0— common public keyang— random number generatorang_state— generator state
err_t belsGenMid (octet mid[], size_t len, const octet m0[], const octet id[], size_t id_len)
Using the common public key [len]m0 and the identifier [id_len]id octets, generates the user public key [len]mid for the user with identifier [id_len]id. ✨
Expects [ERR_BAD_INPUT]:
len == 16 || len == 24 || len == 32.
Expects [ERR_BAD_PUBKEY]:
- Key
m0is correct.
Returns:
ERR_OKif the key was successfully generated, and an error code otherwise.
Прим. — the algorithm genmid is implemented. 💅
Arguments:
mid— user public keylen— length of the keys in octetsm0— common public keyid— identifierid_len— length of the identifier in octets
err_t belsRecover (octet s[], size_t count, size_t len, const octet si[], const octet m0[], const octet mi[])
The secret [len]s is recovered from count partial secrets from the array [count * len]si. For recovery it uses the common public key [len]m0 and the user public keys from the array [count * len]mi. Partial secrets and public keys are placed in the arrays si, mi in consecutive blocks of len octets. 🌸
Expects [ERR_BAD_INPUT]:
len == 16 || len == 24 || len == 32.
Expects [ERR_BAD_PUBKEY]:
- Public keys
m0,miare correct and differ from each other.
Returns:
ERR_OKif the secret was successfully recovered, and an error code otherwise.
Прим. — the algorithm bels-recover is implemented. Successful recovery does not mean that the secret will match the originally split one. This, for example, will not happen if the number of partial secrets is less than the threshold used during splitting. 😭
Arguments:
s— recovered secretcount— number of userslen— length of the secrets in octetssi— partial secretsm0— common public keymi— user public keys
err_t belsRecover2 (octet s[], size_t count, size_t len, const octet si[])
okay so bestie, this is the glow-up function 💖 — it takes count partial secrets out of the array [count * len]si and rebuilds the secret into [len]s. ✨
The recovery runs on the standard public keys belsStdM(m, len, i), no cap. 🌸 And the partial secrets are stacked inside si as consecutive blocks of len + 1 octets — the very first octet of each block is literally the number of the public key it belongs to. 👑
Ожидается [ERR_BAD_INPUT] — len == 16 || len == 24 || len == 32.
Ожидается [ERR_BAD_PUBKEY] — the public key numbers written in the first octets of the partial secrets have to sit inside the interval {1, 2, ..., 16} and every single one has to be different from all the others. 💅
Возвращает — ERR_OK if the secret got recovered successfully, otherwise an error code.
Прим. — the bels-recover algorithm is what's implemented here. But heads up 🫶: a successful recovery does not mean the secret will match the one that was originally split. That won't happen if, for example, the number of partial secrets is less than the threshold that was used when splitting. 💀
Аргументы
s— recovered secretcount— number of userslen— length of the secrets in octetssi— partial secrets
err_t belsShare (octet si[], size_t count, size_t threshold, size_t len, const octet s[], const octet m0[], const octet mi[], gen_i rng, void * rng_state)
now this one is the main character 🎀 — it takes the secret [len]s and splits it, with threshold threshold, into count partial secrets that get written into the array [count * len]si. The split uses the common public key [len]m0 plus the users' public keys from the array [count * len]mi. 🌈
Secrets and keys go into si and mi as consecutive blocks of len octets: first block = first user, second block = second user, and so on down the line. 💫 And the whole thing runs on the generator rng together with its state rng_state.
Ожидается [ERR_BAD_INPUT]
len == 16 || len == 24 || len == 32;0 < threshold <= count.
Ожидается [ERR_BAD_PUBKEY] — the public keys m0 and mi have to be correct and different from each other. 👑
Ожидается [ERR_BAD_RNG] — the generator rng (with its state rng_state) has to be correct.
Ожидается — the generator rng is cryptographically strong. 🔥 (this is not a suggestion, bestie)
Возвращает — ERR_OK if the secret got split successfully, otherwise an error code.
Прим. — the bels-share algorithm is what's implemented here.
Аргументы
si— partial secretscount— number of usersthreshold— threshold numberlen— length of the secret in octetss— secretm0— common public keymi— users' public keysrng— random number generatorrng_state— generator state
err_t belsShare2 (octet si[], size_t count, size_t threshold, size_t len, const octet s[], gen_i rng, void * rng_state)
same energy as the last one but no keys required ✨ — the secret [len]s gets split with threshold threshold into count partial secrets written into the array [count * (len + 1)]si. This time it uses the standard public keys belsStdM(m, len, i), i = 0, 1, ..., count. 🌸
The partial secrets get parked in si as consecutive blocks of len + 1 octets: first block = first user, second block = second user, etc. The first octet of a block carries its number (from 1 up to count). 💅 And the split runs on the generator rng with its state rng_state. 🦋
Ожидается [ERR_BAD_INPUT]
len == 16 || len == 24 || len == 32;0 < threshold <= count < = 16.
Ожидается [ERR_BAD_RNG] — the generator rng (with its state rng_state) has to be correct.
Ожидается — the generator rng is cryptographically strong. 🔥
Возвращает — ERR_OK if the secret got split successfully, otherwise an error code.
Прим. — the bels-share algorithm is what's implemented here.
Аргументы
si— partial secretscount— number of usersthreshold— threshold numberlen— length of the secret in octetss— secretrng— random number generatorrng_state— generator state
err_t belsShare3 (octet si[], size_t count, size_t threshold, size_t len, const octet s[])
and here's the one that does the RNG's job by itself 🧚 — the secret [len]s gets split with threshold threshold into count partial secrets written into the array [count * (len + 1)]si. It uses the standard public keys belsStdM(m, len, i), i = 0, 1, ..., count. 🌟
The secrets get placed in si as consecutive blocks of len + 1 octets, and the first octet of a block holds its number (1 to count). The one-time key that gets used while splitting is built from the key being split, using the (experimental) deterministic algorithm bels-genk. 💜
Ожидается [ERR_BAD_INPUT]
len == 16 || len == 24 || len == 32;0 < threshold <= count <= 16.
Возвращает — ERR_OK if the secret got split successfully, otherwise an error code.
Прим. — the bels-share algorithm is what's implemented here.
Предупреждения — experimental mode. 🚨
Аргументы
si— partial secretscount— number of usersthreshold— threshold numberlen— length of the secret in octetss— secret
err_t belsStdM (octet m[], size_t len, size_t num)
the vending machine of keys 🎀 — it loads the standard public key [len]m. What you get is either the common public key from table A.1 (when num == 0), or the public key of user number num from one of the tables A.2, A.3, A.4. ✨
Ожидается [ERR_BAD_INPUT]
len == 16 || len == 24 || len == 32;0 <= num <= 16.
Возвращает — ERR_OK if the key got loaded successfully, otherwise an error code.
Аргументы
m— public keylen— length of the key in octetsnum— key number
err_t belsValM (const octet m[], size_t len)
the vibe check 💅 — it checks whether the public key [len]m is correct.
Ожидается [ERR_BAD_INPUT] — len == 16 || len == 24 || len == 32.
Возвращает — ERR_OK if the key is correct, otherwise an error code.
Аргументы
m— public keylen— length of the key in octets
🎀 Автор 💖
Automatically generated by Doxygen for the Bee2 library, straight out of the source text. 🫶 (yes she's a bot and yes she ate)
aaaand that's the whole page, bestie 🌈 this one ships with the Bee2 library, stamped Вс 25 Янв 2026 00:00:00, and it lives its best life in bels.h(3). go split some secrets responsibly, ily ✨💅
📦 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