qr.h(3)
🎀 NAME 🎀
okay so bestie, gather round 💖 this is qr.h — the Кольца вычетов header, aka residue rings ✨. It lives in the Library Functions Manual, section 3 (yes, the C-library section, we love a section 3 moment 👑). If you're messing with modular arithmetic and ring vibes, this is literally your girl.
🌈 SYNOPSIS 🌈
first things first, you gotta pull in the includes, no cap:
#include 'bee2/defs.h'
#include 'bee2/core/mem.h'
#include 'bee2/core/obj.h'
then we got classes, typedefs and functions — the whole trio, the holy trinity, the vibe check 💅
🦋 Классы (Classes) 🦋
struct qr_o— Описание кольца вычетов — like, a whole description of a residue ring. this struct is the blueprint, the main character 🫶
✨ Определения типов (Typedefs) ✨
okay this is the part where the ring gets pluggable — every single one of these is a function-pointer type that says "here's how you do THIS operation inside a residue ring". obsessed.
qr_from_i— Импорт элемента кольца вычетов — import of an element of the residue ring:
typedef bool_t(* qr_from_i) (word b[], const octet a[], const struct qr_o *r, void *stack)
qr_to_i— Экспорт элемента кольца вычетов — export of an element of the residue ring:
typedef void(* qr_to_i) (octet b[], const word a[], const struct qr_o *r, void *stack)
qr_add_i— Сложение в кольце вычетов — addition in the residue ring:
typedef void(* qr_add_i) (word c[], const word a[], const word b[], const struct qr_o *r)
qr_sub_i— Вычитание в кольце вычетов — subtraction in the residue ring:
typedef void(* qr_sub_i) (word c[], const word a[], const word b[], const struct qr_o *r)
qr_neg_i— Аддитивное обращение в кольце вычетов — additive inversion in the residue ring:
typedef void(* qr_neg_i) (word b[], const word a[], const struct qr_o *r)
qr_mul_i— Умножение в кольце вычетов — multiplication in the residue ring:
typedef void(* qr_mul_i) (word c[], const word a[], const word b[], const struct qr_o *r, void *stack)
qr_sqr_i— Возведение в квадрат в кольце вычетов — squaring in the residue ring:
typedef void(* qr_sqr_i) (word b[], const word a[], const struct qr_o *r, void *stack)
qr_inv_i— Мультипликативное обращение в кольце вычетов — multiplicative inversion in the residue ring:
typedef void(* qr_inv_i) (word b[], const word a[], const struct qr_o *r, void *stack)
qr_div_i— Деление в кольце вычетов — division in the residue ring:
typedef void(* qr_div_i) (word b[], const word divident[], const word a[], const struct qr_o *r, void *stack)
qr_o— Описание кольца вычетов — the structqr_oitself, typedef'd, because we keep it cute and convenient:
typedef struct qr_o qr_o
💖 Функции (Functions) 💖
and now the actual calls you're gonna be making, bestie:
bool_t qrIsOperable(const qr_o *r)— Описание кольца вычетов работоспособно? — is this residue-ring description actually operable? like, does it work? vibe check on the ring 🩺✨void qrPower(word c[], const word a[], const word b[], size_t m, const qr_o *r, void *stack)— Возведение в степень в кольце вычетов — exponentiation in the residue ring. go off, raise that thing to a power 🔥
<div style="display:none">and that's where part one wraps, no goodbye yet</div>
that's chunk one, bestie — the ring's whole personality is on the table, and there's more where that came from
💖 Подробное описание 💖
окей бести, ща будет математика, но она красивая, обещаю.
Пусть R — кольцо, I — его идеал. Кольцом вычетов называется кольцо R / I, в котором сложение и умножение элементов выполняются по модулю I:
(a + I) + (b + I) = (a + b) + I, (a + I) * (b + I) = (a * b) + I.
В интересующих нас случаях кольцо R является коммутативным, а идеал I — главным, т.е. порожденным единственным элементом mod ∈ R: I = (mod) = {mod * a: a ∈ R}. В этих случаях приведение по модулю I состоит в редукции (определении вычета) по модулю mod.
Кольцо вычетов описывается структурой типа qr_o.
🌸 Структура qr_o проектировалась с прицелом на поддержку следующих колец 🌸
R = Z,mod = n— произвольное натуральное [кольцо вычетов целых чиселZZ_n];R = Z,mod = p— простое число [простое полеGF(p)];R = GF(2)[x],mod = f(x)— неприводимый многочлен степениe[полеGF(2^e)].
В этих кольцах может применяться умножение Монтгомери, умножение в нормальном базисе и другие ускоренные мультипликативные операции. Особенные операции требуют особенного описания кольца и особенного представления его элементов. В связи с этим вводится структура qr_o, которая задает:
- описание кольца вычетов;
- описание элементов кольца;
- интерфейсы арифметических операций в кольце.
Идеал I описывается модулем mod. Для ускорения редукции по модулю mod могут использоваться параметры params. Параметры params могут рассчитываться по mod при создании кольца, могут дублировать mod, или заменять его. Параметры params имеют самостоятельное значение и могут использоваться не только для редукции. iykyk ✨
Элемент кольца представляется массивом из n машинных слов. Размерность n определяется при построении кольца и сохраняется в его описании.
Нулевому элементу всегда соответствует нулевой массив.
Мультипликативные единицы могут отличаться. Мультипликативная единица unity инициализируется при построении кольца.
Размерность модуля mod жестко не регламентируется. Эта размерность определяется в функциях работы с элементами кольца по params и (или) n. В кольцах чисел mod задается n словами. Если mod = 2^{B_PER_W * (n - 1)}, то последнее слово mod равняется 1, а последние слова элементов поля всегда равняются 0. В кольцах многочленов mod задается n или n + 1 словом (в зависимости от выполнения равенства deg(mod) == B_PER_W * n).
Элементы кольца экспортируются в строки октетов и импортируются из этих строк. Длина строки no определяется при построении кольца и сохраняется в его описании. Для экспорта / импорта элементов кольца используются функции типов qr_to_i, qr_from_i. Способ определения длины строки указывается при описании колец конкретных типов. Нулевому элементу обязательно соответствует нулевая строка.
Аддитивные операции в кольце, как правило, не меняются при различных его описаниях. Тем не менее, в структуру qr_o включены функции интерфейсов qr_add_i, qr_sub_i и qr_neg_i, которые определяют аддитивные операции.
Мультипликативные операции в кольце задаются интерфейсами qr_mul_i и qr_sqr_i.
Некоторые элементы кольца допускают мультипликативное обращение и, следовательно, определенные пары элементов можно делить друг на друга. Обращение и деление поддерживается интерфейсами qr_inv_i, qr_div_i.
Описание кольца организовано как объект, и можно применять функции, описанные в заголовочном файле obj.h. 💅
🎀 Создание кольца 🎀
Кольцо должно создаваться специальной функцией qrCreate(), которая является аналогом конструктора. В эту функцию должен передаваться указатель r на структуру типа qr_o. По этому указателю будет размещаться описание (состояние) кольца. По адресу r может быть зарезервировано больше памяти, чем sizeof(qr_o). Дело в том, что значения mod, unity, params могут размещаться в поле descr открытого размера. Функция qrCreate() должна сопровождаться функцией qrCreate_keep(), которая поддерживает расчет длины состояния (в октетах).
Функция qrCreate_keep() должна оценивать длину состояния сверху. Оценка может быть неточной. Точная длина состояния фиксируется при непосредственном выполнении qrCreate() и сохраняется в поле keep описания кольца.
В функцию qrCreate() должен передаваться указатель на память для стека. Функция qrCreate() должна сопровождаться функцией qrCreate_deep(), которая выполняет расчет глубины стека. При расчете глубины следует предполагать, что в qrCreate() явно или неявно вызываются все функции кольца. Получив результат работы qrCreate_deep(), внешние программы могут определить, сколько вспомогательной памяти потребуется при всевозможных способах работы с кольцом.
В описании qrCreate() должны быть даны оценки сверху для размерностей n и no. Эти оценки могут использоваться высокоуровневыми функциями при подготовке памяти для размещения элементов кольца.
Оценка глубины стека, определяемая функцией qrCreate_deep(), может быть неточной. Точная глубина фиксируется при непосредственном выполнении qrCreate() и сохраняется в поле deep описания кольца. ✨
✅ Предусловие ✅
- Все указатели действительны.
- Буферы элементов кольца или их кодовых представлений не пересекаются с буферами, поддерживающими описание кольца.
⚠️ Предупреждения ⚠️
В интерфейсах мультипликативных функций не предполагается, что буфер результата либо не пересекается, либо совпадает с буферами входных элементов. так что не надейся, бести, следи за буферами сама 😭
🦋 Регулярность 🦋
todo
(да, буквально todo. не я это придумала, это в исходнике, не стреляйте в пианистку 🫶)
🌈 ТИПЫ ✨ (Types)
okay bestie, this is the type zoo and honestly? it ate. 🦋 Every one of these is a function-pointer type that a ring description qr_o hands you so you can actually do math in the residue ring. The contract is: you give it the buffers, it does the thing. Let's go one by one, no skipping. 💅
qr_add_i 💖
typedef void(* qr_add_i) (word c[], const word a[], const word b[], const struct qr_o *r)
The sum of the [r->n]c elements of [r->n]a and [r->n]b in the residue ring r gets computed:
c <- a + b.
Precondition (Предусловие) 🫶
- The ring description
ris operable. - The buffer
ceither doesn't overlap, or coincides with each of the buffersa,b. - The elements
aandbbelong tor.
Expected (Ожидается) ✨
- The ring description
ris correct.
Arguments (Аргументы) 🎀
c— the suma— the first addendb— the second addendr— the ring description
qr_div_i 🌸
typedef void(* qr_div_i) (word b[], const word divident[], const word a[], const struct qr_o *r, void *stack)
The quotient [r->n]b from dividing the element [r->n]divident by the element [r->n]a in the residue ring r gets computed:
b <- divident * a^{-1}.
Precondition (Предусловие) 💜
- The ring description
ris operable. - The elements
dividentandabelong tor.
Expected (Ожидается) ✨
- The ring description
ris correct.
Expected (Ожидается) ✨
- The element
ais invertible. Ifais not invertible, thenbmay be anything.
Arguments (Аргументы) 🎀
b— the quotientdivident— the dividenda— the divisorr— the ring descriptionstack— auxiliary memory
qr_from_i 🧚
typedef bool_t(* qr_from_i) (word b[], const octet a[], const struct qr_o *r, void *stack)
From the code representation [r->no]a, the element [r->n]b of the residue ring r gets built.
Precondition (Предусловие) 🫶
- The ring description
ris operable. - The buffers
aandbeither don't overlap, or the pointersaandbcoincide.
Expected (Ожидается) ✨
- The ring description
ris correct.
Returns (Возвращает) 💖
TRUEif the code representation is correct and the import was performed successfully, andFALSEotherwise.
Arguments (Аргументы) 🎀
b— the ring elementa— the code representation of the ring elementr— the ring descriptionstack— auxiliary memory
qr_inv_i 👑
typedef void(* qr_inv_i) (word b[], const word a[], const struct qr_o *r, void *stack)
The element [r->n]b of the ring r gets computed, multiplicatively inverse to the element [r->n]a:
b <- a^{-1}.
Precondition (Предусловие) 💜
- The ring description
ris operable. - The element
abelongs tor.
Expected (Ожидается) ✨
- The ring description
ris correct.
Expected (Ожидается) ✨
- The element
ais invertible. Ifais not invertible, thenbmay be anything.
Arguments (Аргументы) 🎀
b— the inverse elementa— the element being invertedr— the ring descriptionstack— auxiliary memory
qr_mul_i 🔥
typedef void(* qr_mul_i) (word c[], const word a[], const word b[], const struct qr_o *r, void *stack)
The product [r->n]c of the elements [r->n]a and [r->n]b of the residue ring r gets computed:
с <- a * b.
Precondition (Предусловие) 🫶
- The ring description
ris operable. - The elements
aandbbelong tor.
Expected (Ожидается) ✨
- The ring description
ris correct.
Arguments (Аргументы) 🎀
c— the producta— the first factorb— the second factorr— the ring descriptionstack— auxiliary memory
qr_neg_i 🌙
typedef void(* qr_neg_i) (word b[], const word a[], const struct qr_o *r)
The element [r->n]b of the ring r gets computed, additively inverse to [r->n]a:
b <- -a.
Precondition (Предусловие) 💜
- The ring description
ris operable. - The buffer
beither doesn't overlap, or coincides with the buffera. - The element
abelongs tor.
Expected (Ожидается) ✨
- The ring description
ris correct.
Arguments (Аргументы) 🎀
b— the inverse elementa— the element being invertedr— the ring description
qr_o 💅
typedef struct qr_o qr_o
This is the whole vibe: it describes a residue ring, the rules for representing its elements, and the functions that implement the operations in the ring. main character energy fr. 👑
Note (Прим.) ⭐
- The table of pointers of the ring description, as an object, includes the fields
mod,unity,params.
qr_sqr_i 🌸
typedef void(* qr_sqr_i) (word b[], const word a[], const struct qr_o *r, void *stack)
The square [r->n]b of the element [r->n]a of the ring r gets computed:
с <- a * a.
Precondition (Предусловие) 🫶
- The ring description
ris operable. - The element
abelongs tor.
Expected (Ожидается) ✨
- The ring description
ris correct.
Arguments (Аргументы) 🎀
b— the squarea— the factorr— the ring descriptionstack— auxiliary memory
qr_sub_i 🍓
typedef void(* qr_sub_i) (word c[], const word a[], const word b[], const struct qr_o *r)
The difference [r->n]c of the elements [r->n]a and [r->n]b of the residue ring r gets computed:
c <- a - b.
Precondition (Предусловие) 💜
- The ring description
ris operable. - The buffer
ceither doesn't overlap, or coincides with each of the buffersa,b. - The elements
aandbbelong tor.
Expected (Ожидается) ✨
- The ring description
ris correct.
Arguments (Аргументы) 🎀
c— the differencea— the minuendb— the subtrahendr— the ring description
qr_to_i 🦋
typedef void(* qr_to_i) (octet b[], const word a[], const struct qr_o *r, void *stack)
The code representation [r->no]b of the element [r->n]a of the residue ring r gets built.
Precondition (Предусловие) 🫶
- The ring description
ris operable. - The buffers
aandbeither don't overlap, or the pointersaandbcoincide.
Expected (Ожидается) ✨
- The ring description
ris correct.
Arguments (Аргументы) 🎀
b— the code representation of the ring elementa— the ring elementr— the ring descriptionstack— auxiliary memory
💫 ФУНКЦИИ ✨ (Functions)
okay two functions, both iconic, let's get into it. 😤
qrIsOperable 🔍
bool_t qrIsOperable (const qr_o * r)
It checks the operability of the ring description r. The following conditions get checked:
- the object
ris operable; objKeep(r) >= sizeof(qr_o);objPCount(r) == 3 && objOCount(r) == 0;- the pointer
r->unityis correct; r->n > 0 && r->no > 0;- the pointers
r->from,r->to, ...,r->divare correct.
Returns (Возвращает) 💖
- The operability flag.
Arguments (Аргументы) 🎀
r— the ring description
qrPower ⚡
void qrPower (word c[], const word a[], const word b[], size_t m, const qr_o * r, void * stack)
In the residue ring r, the element [r->n]c gets computed, which is the [m]b-th power of the element [r->n]a:
c <- a^b.
Precondition (Предусловие) 🫶
- The ring description
ris operable. - The element
abelongs tor.
Expected (Ожидается) ✨
- The ring description
ris correct.
Note (Прим.) ⭐
- When
b == 0,r->unitygets returned.
Scheme for computing the depth of stack (Схема расчета глубины stack) 🌊
qrPower_deep(r->n, m, r->deep).
Arguments (Аргументы) 🎀
c— the powera— the baseb— the exponentm— the length ofbin machine wordsr— the ring descriptionstack— auxiliary memory
🫶 АВТОР ✨ (Author)
Automatically generated by Doxygen for the Bee2 Library from the source text. not me getting auto-generated 😭 still iconic tho.
okay bestie that's the whole page, we made it, and lowkey it was a journey. 💖 This one came from the Bee2 Library, dated Вс 25 Янв 2026 00:00:00 (that's Sunday, January 25, 2026, 00:00:00 for the calendar girlies 🗓️✨), and it lives at qr.h(3). slay, go forth and do ring math responsibly, periodt. 💅🌈
📦 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