1zz.h(3)                    Library Functions Manual                    zz.h(3)
2
3
4

NAME

6       zz.h - Большие неотрицательные целые числа
7
8

SYNOPSIS

10       #include 'bee2/defs.h'
11       #include 'bee2/core/safe.h'
12
13
14   Функции
15       bool_t zzIsEven (const word a[], size_t n)
16           Четное число?
17       bool_t zzIsOdd (const word a[], size_t n)
18           Нечетное число?
19       word zzAdd (word c[], const word a[], const word b[], size_t n)
20           Сложение чисел
21       word zzAdd2 (word b[], const word a[], size_t n)
22           Добавление числа
23       word zzAdd3 (word c[], const word a[], size_t n, const word b[], size_t
24           m)
25           Сложение чисел проивольной длины
26       word zzAddW (word b[], const word a[], size_t n, register word w)
27           Сложение числа со словом
28       word zzAddW2 (word a[], size_t n, register word w)
29           Добавление слова
30       bool_t zzIsSumEq (const word c[], const word a[], const word b[],
31           size_t n)
32           Сумма чисел равняется числу?
33       bool_t zzIsSumWEq (const word b[], const word a[], size_t n, register
34           word w)
35           Сумма числа и слова равняется числу?
36       word zzSub (word c[], const word a[], const word b[], size_t n)
37           Вычитание чисел
38       word zzSub2 (word b[], const word a[], size_t n)
39           Уменьшение числа
40       word zzSubW (word b[], const word a[], size_t n, register word w)
41           Вычитание из числа слова
42       word zzSubW2 (word a[], size_t n, register word w)
43           Уменьшение числа на слова
44       void zzNeg (word b[], const word a[], size_t n)
45           Минус
46       word zzMulW (word b[], const word a[], size_t n, register word w)
47           Умножение числа на слово
48       word zzAddMulW (word b[], const word a[], size_t n, register word w)
49           Сложение с произведением числа на слово
50       word zzSubMulW (word b[], const word a[], size_t n, register word w)
51           Вычитание произведения числа на слово
52       void zzMul (word c[], const word a[], size_t n, const word b[], size_t
53           m, void *stack)
54           Умножение чисел
55       void zzSqr (word b[], const word a[], size_t n, void *stack)
56           Возведение числа в квадрат
57       bool_t zzSqrt (word b[], const word a[], size_t n, void *stack)
58           Извлечение квадратного корня
59       word zzDivW (word q[], const word a[], size_t n, register word w)
60           Деление числа на машинное слово
61       word zzModW (const word a[], size_t n, register word w)
62           Остаток от деления числа на машинное слово
63       word zzModW2 (const word a[], size_t n, register word w)
64           Остаток от деления числа на малое машинное слово
65       void zzDiv (word q[], word r[], const word a[], size_t n, const word
66           b[], size_t m, void *stack)
67           Деление чисел
68       void zzMod (word r[], const word a[], size_t n, const word b[], size_t
69           m, void *stack)
70           Остаток от деления чисел
71       void zzGCD (word d[], const word a[], size_t n, const word b[], size_t
72           m, void *stack)
73           Наибольший общий делитель
74       bool_t zzIsCoprime (const word a[], size_t n, const word b[], size_t m,
75           void *stack)
76           Взаимная простота
77       void zzLCM (word d[], const word a[], size_t n, const word b[], size_t
78           m, void *stack)
79           Наименьшее общее кратное
80       void zzExGCD (word d[], word da[], word db[], const word a[], size_t n,
81           const word b[], size_t m, void *stack)
82           Расширенный алгоритм Евклида
83       int zzJacobi (const word a[], size_t n, const word b[], size_t m, void
84           *stack)
85           Символ Якоби
86       void zzAddMod (word c[], const word a[], const word b[], const word
87           mod[], size_t n)
88           Сложение чисел по модулю
89       void zzAddWMod (word b[], const word a[], register word w, const word
90           mod[], size_t n)
91           Сложение числа со словом по модулю
92       void zzSubMod (word c[], const word a[], const word b[], const word
93           mod[], size_t n)
94           Вычитание чисел по модулю
95       void zzSubWMod (word b[], const word a[], register word w, const word
96           mod[], size_t n)
97           Вычитание из числа слова по модулю
98       void zzNegMod (word b[], const word a[], const word mod[], size_t n)
99           Аддитивное обращение чисел по модулю
100       void zzMulMod (word c[], const word a[], const word b[], const word
101           mod[], size_t n, void *stack)
102           Умножение чисел по модулю
103       void zzSqrMod (word b[], const word a[], const word mod[], size_t n,
104           void *stack)
105           Возведение чисел в квадрат по модулю
106       void zzInvMod (word b[], const word a[], const word mod[], size_t n,
107           void *stack)
108           Обращение по модулю
109       void zzDivMod (word b[], const word divident[], const word a[], const
110           word mod[], size_t n, void *stack)
111           Деление по модулю
112       void zzDoubleMod (word b[], const word a[], const word mod[], size_t n)
113           Удвоение числа по модулю
114       void zzHalfMod (word b[], const word a[], const word mod[], size_t n)
115           Половина числа по модулю
116       size_t zzAlmostInvMod (word b[], const word a[], const word mod[],
117           size_t n, void *stack)
118           Почти-обращение по модулю
119       bool_t zzRandMod (word a[], const word mod[], size_t n, gen_i rng, void
120           *rng_state)
121           Случайный вычет по модулю
122       bool_t zzRandNZMod (word a[], const word mod[], size_t n, gen_i rng,
123           void *rng_state)
124           Случайный ненулевой вычет по модулю
125       void zzRed (word a[], const word mod[], size_t n, void *stack)
126           Стандартная редукция
127       void zzRedCrand (word a[], const word mod[], size_t n, void *stack)
128           Редукция Крэндалла
129       void zzRedBarrStart (word barr_param[], const word mod[], size_t n,
130           void *stack)
131           Инициализация редукции Барретта
132       void zzRedBarr (word a[], const word mod[], size_t n, const word
133           barr_param[], void *stack)
134           Редукция Барретта
135       void zzRedMont (word a[], const word mod[], size_t n, register word
136           mont_param, void *stack)
137           Редукция Монтгомери
138       void zzRedCrandMont (word a[], const word mod[], size_t n, register
139           word mont_param, void *stack)
140           Редукция Монтгомери по модулю Крэндалла
141       void zzPowerMod (word c[], const word a[], size_t n, const word b[],
142           size_t m, const word mod[], void *stack)
143           Возведение в степень по модулю
144       word zzPowerModW (register word a, register word b, register word mod,
145           void *stack)
146           Возведение в степень по модулю машинного слова
147

Подробное описание

Общие положения

150       Реализованы операции с большими неотрицательными целыми числами.
151
152       Число задается массивом машинных слов: word w[n]. Машинное слово w[0]
153       -- младшее, машинное слово w[n - 1] -- старшее.
154
155       Пустое число (n = 0) считается нулевым.
156
157       В описаниях функций B = 2^{B_PER_W} --- основание системы счисления.
158
159       Функция zzDoubleMod() совместно с функциями zzAddMod() и zzSubMod()
160       позволяет организовать быстрое модулярное умножение числа на малую
161       константу. Например, вычисление b <- 7 a \mod mod может быть
162       организовано следующим образом:
163
164       zzDoubleMod(b, a, mod, n);
165       zzDoubleMod(b, b, mod, n);
166       zzDoubleMod(b, b, mod, n);
167       zzSubMod(b, a, mod, n);
168
169
170        Аналогично, функция zzHalfMod() позволяет организовать быстрое
171       модулярное деление на определенные константы.
172
173       Предусловие
174           Все входные указатели действительны.
175
176           В функциях работы с числами по адресам памяти для чисел
177           зарезервировано ясное из конекста либо уточняемое в описаниях
178           функций число машинных слов.
179
180           Вспомогательный буфер stack не пересекается с другими буферами.
181

Редукция

183       Редукция состоит в определении вычета числа [2n]a по модулю [n]mod.
184       Обрабатываемое число всегда состоит из 2n машинных слов и результат
185       всегда возвращается на месте а (ср. с zzMod()). Чтобы подчеркнуть
186       данные соглашения вместо Mod (остаток от деления) пишется Red
187       (редукция).
188
189       Кроме обычной редукции реализованы быстрые редукции по специальным
190       модулям.
191

Функции

193   word zzAdd (word c[], const word a[], const word b[], size_t n)
194       Определяется сумма [n]с чисел [n]a и [n]b:
195
196       c <- (a + b) \mod B^n, carry <- (a + b) \div B^n,
197       c + B^n * carry == a + b.
198
199
200       Предусловие
201           Буфер c либо не пересекается, либо совпадает с каждым из буферов a,
202           b.
203
204       Возвращает
205           Слово переноса carry.
206
207       Аргументы
208           c сумма
209           a первое слагаемое
210           b второе слагаемое
211           n длина a, b в машинных словах
212
213   word zzAdd2 (word b[], const word a[], size_t n)
214       К числу [n]b добавляется число [n]a:
215
216       b <- (a + b) \mod B^n, carry <- (a + b) \div B^n.
217
218
219       Предусловие
220           Буфер b либо не пересекается, либо совпадает с буфером a.
221
222       Возвращает
223           Слово переноса carry.
224
225       Аргументы
226           b первое слагаемое / сумма
227           a второе слагаемое
228           n длина a, b в машинных словах
229
230   word zzAdd3 (word c[], const word a[], size_t n, const word b[], size_t m)
231       Определяется сумма [max(n, m)]с чисел [n]a и [m]b:
232
233       c <- (a + b) \mod B^{max(n,m)}, carry <- (a + b) \div B^{max(n,m)}.
234
235
236       Предусловие
237           Буфер c либо не пересекается, либо совпадает с каждым из буферов a,
238           b.
239
240       Возвращает
241           Слово переноса carry.
242
243       Аргументы
244           c сумма
245           a первое слагаемое
246           n длина a в машинных словах
247           b второе слагаемое
248           m длина b в машинных словах
249
250   void zzAddMod (word c[], const word a[], const word b[], const word mod[],
251       size_t n)
252       Определяется сумма [n]c чисел [n]a и [n]b по модулю [n]mod:
253
254       с <- (b + a) \mod mod.
255
256
257       Предусловие
258           a < mod && b < mod.
259
260           Буфер c либо не пересекается, либо совпадает с каждым из буферов a,
261           b.
262
263           Буфер с не пересекается с буфером mod.
264
265       Регулярность
266           Имеется ускоренная нерегулярная редакция.
267
268       Аргументы
269           c сумма
270           a первое слагаемое
271           b второе слагаемое
272           mod модуль
273           n длина чисел в машинных словах
274
275   word zzAddMulW (word b[], const word a[], size_t n, register word w)
276       К числу [n]b добавляется произведение числа [n]a на машинное слово w:
277
278       b <- (b + a * w) \mod B^n, carry <- (b + a * w) \div B^n.
279
280
281       Предусловие
282           Буфер b либо не пересекается, либо совпадает с буфером a.
283
284       Возвращает
285           Слово переноса carry.
286
287       Аргументы
288           b слагаемое / сумма
289           a первый множитель
290           n длина a, b в машинных словах
291           w второй множитель
292
293   word zzAddW (word b[], const word a[], size_t n, register word w)
294       Определяется сумма [n]b числа [n]a и слова w:
295
296       b <- (a + w) \mod B^n, carry <- (a + w) \div B^n.
297
298
299       Предусловие
300           Буфер b либо не пересекается, либо совпадает с буфером a.
301
302       Возвращает
303           Слово переноса carry.
304
305       Аргументы
306           b сумма
307           a первое слагаемое
308           n длина a в машинных словах
309           w второе слагаемое
310
311   word zzAddW2 (word a[], size_t n, register word w)
312       К числу [n]a добавляется слово w:
313
314       a <- (a + w) \mod B^n, carry <- (a + w) \div B^n.
315
316
317       Возвращает
318           Слово переноса carry.
319
320       Аргументы
321           a слагаемое / сумма
322           n длина a в машинных словах
323           w второе слагаемое
324
325   void zzAddWMod (word b[], const word a[], register word w, const word
326       mod[], size_t n)
327       Определяется сумма [n]b числа [n]a и слова w по модулю [n]mod:
328
329       b <- (a + w) \mod mod.
330
331
332       Предусловие
333           a < mod && w < mod.
334
335           Буфер b либо не пересекается, либо совпадает с буфером a.
336
337           Буфер b не пересекается с буфером mod.
338
339       Регулярность
340           Имеется ускоренная нерегулярная редакция.
341
342       Аргументы
343           b сумма
344           a первое слагаемое
345           w второе слагаемое
346           mod модуль
347           n длина чисел в машинных словах
348
349   size_t zzAlmostInvMod (word b[], const word a[], const word mod[], size_t
350       n, void * stack)
351       Определяется число [n]b, почти-мультипликативно обратное к [n]a по
352       модулю [n]mod:
353
354       b <- a^{-1} * 2^k \mod mod,
355
356
357        где wwBitSize(mod) <= k <= 2 * wwBitSize(mod).
358
359       Предусловие
360           mod -- нечетное && mod[n - 1] != 0.
361
362           0 < a < mod.
363
364           Буфер b не пересекается с буфером mod.
365
366       Ожидается
367           \gcd(a, mod) == 1.
368
369       Возвращает
370           Параметр k.
371
372       Прим.
373           Если \gcd(a, mod) != 1, то b <- 0.
374
375           Применяя k раз zzHalfMod(), можно определить по b обычный обратный
376           элемент. Применяя n * B_PER_W - k раз zzDoubleMod(), можно
377           определить по b обратный элемент относительно умножения Монтгомери.
378
379       Схема расчета глубины stack
380           zzAlmostInvMod_deep(n).
381
382       Регулярность
383           Функция нерегулярна.
384
385       Аргументы
386           b обратное число
387           a обращаемое число
388           mod модуль
389           n длина чисел в машинных словах
390           stack вспомогательная память
391
392   void zzDiv (word q[], word r[], const word a[], size_t n, const word b[],
393       size_t m, void * stack)
394       Определяются частное [n - m + 1]q и остаток [m]r от деления числа [n]a
395       на число [m]b:
396
397       q <- a \div b, r <- r \mod b,
398       a == q * b + r, r < b.
399
400
401       Предусловие
402           n >= m.
403
404           m > 0 && b[m - 1] != 0.
405
406           Буферы q и r не пересекаются.
407
408           Буфер r либо не пересекается с буфером a, либо r == a.
409
410       Схема расчета глубины stack
411           zzDiv_deep(n, m).
412
413       Регулярность
414           Функция нерегулярна.
415
416       Аргументы
417           q частное
418           r остаток
419           a делимое
420           n длина a в машинных словах
421           b делитель
422           m длина b в машинных словах
423           stack вспомогательная память
424
425   void zzDivMod (word b[], const word divident[], const word a[], const word
426       mod[], size_t n, void * stack)
427       Определяется частное [n]b от деления числа [n]divident на число [n]a по
428       модулю [n]mod:
429
430       b <- divident * a^{-1} \mod mod.
431
432
433       Предусловие
434           mod -- нечетное && mod[n - 1] != 0.
435
436           a, divident < mod.
437
438           Буфер b не пересекается с буфером mod.
439
440       Ожидается
441           \gcd(a, mod) = 1.
442
443       Прим.
444           Если \gcd(a, mod) != 1, то b <- 0.
445
446       Схема расчета глубины stack
447           zzDivMod_deep(n).
448
449       Регулярность
450           Функция нерегулярна.
451
452       Аргументы
453           b частное
454           divident делимое
455           a делитель
456           mod модуль
457           n длина чисел в машинных словах
458           stack вспомогательная память
459
460   word zzDivW (word q[], const word a[], size_t n, register word w)
461       Определяется частное [n]q от деления числа [n]a на машинное слово w:
462
463       q <- a \div w.
464
465
466       Предусловие
467           w != 0.
468
469           Буфер q либо не пересекается, либо совпадает с буфером a.
470
471       Возвращает
472           Остаток от деления.
473
474       Аргументы
475           q частное
476           a делимое
477           n длина a в машинных словах
478           w делитель
479
480   void zzDoubleMod (word b[], const word a[], const word mod[], size_t n)
481       Определяется произведение [n]b числа [n]a на число 2 по модулю [n]mod:
482
483       b <- 2 * a \mod mod.
484
485
486       Предусловие
487           a < mod.
488
489           Буфер b либо не пересекается, либо совпадает с буфером a.
490
491           Буфер b не пересекается с буфером mod.
492
493       Регулярность
494           Имеется ускоренная нерегулярная реализация.
495
496       Аргументы
497           b произведение
498           a множитель
499           mod модуль
500           n длина чисел в машинных словах
501
502   void zzExGCD (word d[], word da[], word db[], const word a[], size_t n,
503       const word b[], size_t m, void * stack)
504       Определяется наибольший общий делитель [min(n, m)]d чисел [n]a и [m]b:
505
506       d <- \gcd(a, b),
507
508
509        а также положительные числа [m]da и [n]db (коэффициенты Безу) такие,
510       что
511
512       da * a - db * b == d
513
514
515       Предусловие
516           a != 0 && b != 0.
517
518           Буферы d, da, db не пересекаются между собой и с буферами a, b.
519
520       Схема расчета глубины stack
521           zzExGCD_deep(n, m).
522
523       Регулярность
524           Функция нерегулярна.
525
526       Аргументы
527           d н.о.д.
528           da первый коэффициент Безу
529           db второй коэффициент Безу
530           a первое число
531           n длина a в машинных словах
532           b второе число
533           m длина b в машинных словах
534           stack вспомогательная память
535
536   void zzGCD (word d[], const word a[], size_t n, const word b[], size_t m,
537       void * stack)
538       Определяется наибольший общий делитель [min(n, m)]d чисел [n]a и [m]b:
539
540       d <- \gcd(a, b).
541
542
543       Предусловие
544           a != 0 && b != 0.
545
546           Буфер d не пересекается с буферами a и b.
547
548       Прим.
549           Использование нулевых a и b запрещается для того, чтобы наибольший
550           общий делитель d укладывался в [min(n, m)] слов.
551
552           Считается, что \gcd(0, b) = b, в частности, \gcd(0, 0) = 0.
553
554       Схема расчета глубины stack
555           zzGCD_deep(n, m).
556
557       Регулярность
558           Функция нерегулярна.
559
560       Аргументы
561           d н.о.д.
562           a первое число
563           n длина a в машинных словах
564           b второе число
565           m длина b в машинных словах
566           stack вспомогательная память
567
568   void zzHalfMod (word b[], const word a[], const word mod[], size_t n)
569       Определяется частное [n]b от деления числа [n]a на число 2 по модулю
570       [n]mod:
571
572       b <- a * 2^{-1} \mod mod.
573
574
575       Предусловие
576           mod -- нечетное && mod[n - 1] != 0.
577
578           a < mod.
579
580           Буфер b либо не пересекается, либо совпадает с буфером a.
581
582           Буфер b не пересекается с буфером mod.
583
584       Регулярность
585           Имеется ускоренная нерегулярная реализация.
586
587       Аргументы
588           b частное
589           a делимое
590           mod модуль
591           n длина чисел в машинных словах
592
593   void zzInvMod (word b[], const word a[], const word mod[], size_t n, void *
594       stack)
595       Определяется число [n]b, мультипликативно обратное к [n]a по модулю
596       [n]mod:
597
598       b <- a^{-1} \mod mod.
599
600
601       Предусловие
602           mod -- нечетное && mod[n - 1] != 0.
603
604           a < mod.
605
606           Буфер b не пересекается с буфером mod.
607
608       Ожидается
609           \gcd(a, mod) == 1.
610
611       Прим.
612           Если \gcd(a, mod) != 1, то b <- 0.
613
614       Схема расчета глубины stack
615           zzInvMod_deep(n).
616
617       Регулярность
618           Функция нерегулярна.
619
620       Аргументы
621           b обратное число
622           a обращаемое число
623           mod модуль
624           n длина чисел в машинных словах
625           stack вспомогательная память
626
627   bool_t zzIsCoprime (const word a[], size_t n, const word b[], size_t m,
628       void * stack)
629       Проверяется, что числа [n]a и [m]b взаимно просты:
630
631       \gcd(a, b) == 1?
632
633
634       Возвращает
635           Признак взаимной простоты a и b.
636
637       Схема расчета глубины stack
638           zzIsCoprime_deep(n, m).
639
640       Регулярность
641           Функция нерегулярна.
642
643       Аргументы
644           a первое число
645           n длина a в машинных словах
646           b второе число
647           m длина b в машинных словах
648           stack вспомогательная память
649
650   bool_t zzIsEven (const word a[], size_t n)
651       Проверяется, что число [n]a является четным.
652
653       Возвращает
654           Признак четности.
655
656       Аргументы
657           a число
658           n длина a в машинных словах
659
660   bool_t zzIsOdd (const word a[], size_t n)
661       Проверяется, что число [n]a является нечетным.
662
663       Возвращает
664           Признак нечетности.
665
666       Аргументы
667           a число
668           n длина a в машинных словах
669
670   bool_t zzIsSumEq (const word c[], const word a[], const word b[], size_t n)
671       Проверяется, что сумма чисел [n]a и [n]b равняется числу [n]c:
672
673       a + b == c?
674
675
676       Прим.
677           Переставляя операнды, можно проверять не только суммы, но и
678           разности.
679
680       Возвращает
681           Признак равенства.
682
683       Регулярность
684           Имеется ускоренная нерегулярная редакция.
685
686       Аргументы
687           c сумма
688           a первое слагаемое
689           b второе слагаемое
690           n длина a, b, c в машинных словах
691
692   bool_t zzIsSumWEq (const word b[], const word a[], size_t n, register word
693       w)
694       Проверяется, что сумма числа [n]a и слова w равняется числу [n]b:
695
696       a + w == b?
697
698
699       Возвращает
700           Признак равенства.
701
702       Регулярность
703           Имеется ускоренная нерегулярная редакция.
704
705       Аргументы
706           b сумма
707           a первое слагаемое
708           n длина a, b в машинных словах
709           w второе слагаемое
710
711   int zzJacobi (const word a[], size_t n, const word b[], size_t m, void *
712       stack)
713       Определяется символ Якоби (a / b) чисел [n]a и [m]b.
714
715       Предусловие
716           b -- нечетное.
717
718       Прим.
719           Если b является произведением простых p_1, p_2,.., p_k, то (a / b)
720           = (a / p_1) * (a / p_2) *... * (a / p_k). Здесь (a / p_i) ---
721           символ Лежандра: (a / p) равняется 0, если a делится на p,
722           равняется 1, если a -- квадратичный вычет \mod p, и равняется -1 в
723           остальных случаях.
724
725       Возвращает
726           Символ Якоби (a / b): 0, 1 или -1.
727
728       Схема расчета глубины stack
729           zzJacobi_deep(n, m).
730
731       Регулярность
732           Функция нерегулярна.
733
734       Аргументы
735           a первое число
736           n длина a в машинных словах
737           b второе число
738           m длина b в машинных словах
739           stack вспомогательная память
740
741   void zzLCM (word d[], const word a[], size_t n, const word b[], size_t m,
742       void * stack)
743       Определяется наименьшее общее кратное [n + m]d чисел [n]a и [m]b:
744
745       d <- \lcm[a, b].
746
747
748       Предусловие
749           a != 0 && b != 0.
750
751           Буфер d не пересекается с буферами a и b.
752
753       Прим.
754           Использование нулевых a и b запрещается для согласованости с
755           zzGCD() и избежания разбора редких, неиспользуемых на практике
756           случаев.
757
758       Схема расчета глубины stack
759           zzLCM_deep(n, m).
760
761       Регулярность
762           Функция нерегулярна.
763
764       Аргументы
765           d н.о.к.
766           a первое число
767           n длина a в машинных словах
768           b второе число
769           m длина b в машинных словах
770           stack вспомогательная память
771
772   void zzMod (word r[], const word a[], size_t n, const word b[], size_t m,
773       void * stack)
774       Определяется остаток [m]r от деления числа [n]a на число [m]b:
775
776       a <- a \mod b.
777
778
779       Предусловие
780           m > 0 && b[m - 1] != 0.
781
782           Буфер r либо не пересекается с буфером a, либо r == a.
783
784       Схема расчета глубины stack
785           zzMod_deep(n, m).
786
787       Регулярность
788           Функция нерегулярна.
789
790       Аргументы
791           r остаток
792           a делимое
793           n длина a в машинных словах
794           b делитель
795           m длина b в машинных словах
796           stack вспомогательная память
797
798   word zzModW (const word a[], size_t n, register word w)
799       Определяется остаток от деления числа [n]a на машинное слово w:
800
801       r <- a \mod w.
802
803
804       Предусловие
805           w != 0.
806
807       Возвращает
808           Остаток от деления r.
809
810       Аргументы
811           a делимое
812           n длина a в машинных словах
813           w делитель
814
815   word zzModW2 (const word a[], size_t n, register word w)
816       Определяется остаток от деления числа [n]a на малое машинное слово w:
817
818       r <- a \mod w.
819
820
821       Предусловие
822           w != 0 && w^2 <= B.
823
824       Возвращает
825           Остаток от деления r.
826
827       Прим.
828           Функция zzModW2() работает быстрее zzModW() на тех платформах, где
829           деление не менее чем в 2 раза медленнее умножения.
830
831       Аргументы
832           a делимое
833           n длина a в машинных словах
834           w делитель
835
836   void zzMul (word c[], const word a[], size_t n, const word b[], size_t m,
837       void * stack)
838       Определяется произведение [n + m]c чисел [n]a на [m]b:
839
840       c <- a * b.
841
842
843       Предусловие
844           Буфер c не пересекается с буферами a и b.
845
846       Схема расчета глубины stack
847           zzMul_deep(n, m).
848
849       Аргументы
850           c произведение
851           a первый множитель
852           n длина a в машинных словах
853           b второй множитель
854           m длина b в машинных словах
855           stack вспомогательная память
856
857   void zzMulMod (word c[], const word a[], const word b[], const word mod[],
858       size_t n, void * stack)
859       Определяется произведение [n]c чисел [n]a и [n]b по модулю [n]mod:
860
861       c <- a * b \mod mod.
862
863
864       Предусловие
865           n > 0 && mod[n - 1] != 0.
866
867           a < mod && b < mod.
868
869       Схема расчета глубины stack
870           zzMulMod_deep(n).
871
872       Аргументы
873           c произведение
874           a первый множитель
875           b второй множитель
876           mod модуль
877           n длина чисел в машинных словах
878           stack вспомогательная память
879
880   word zzMulW (word b[], const word a[], size_t n, register word w)
881       Определяется произведение [n]b числа [n]a на слово w:
882
883       b <- (a * w) \mod B^n, carry <- (a * w) \div B^n.
884
885
886       Предусловие
887           Буфер b либо не пересекается, либо совпадает с буфером a.
888
889       Возвращает
890           Слово переноса carry.
891
892       Аргументы
893           b произведение
894           a первый множитель
895           n длина a, b в машинных словах
896           w второй множитель
897
898   void zzNeg (word b[], const word a[], size_t n)
899       Определяется число [n]b, отрицательное к [n]a по модулю B^n:
900
901       b <- B^n - a.
902
903
904       Предусловие
905           Буфер b либо не пересекается, либо совпадает с буфером a.
906
907       Аргументы
908           b отрицательное число
909           a число
910           n длина a в машинных словах
911
912   void zzNegMod (word b[], const word a[], const word mod[], size_t n)
913       Определяется число [n]b, аддитивно обратное к [n]a по модулю [n]mod:
914
915       b <- -a \mod mod.
916
917
918       Предусловие
919           n > 0 && mod[n - 1] != 0.
920
921           a < mod.
922
923           Буфер b либо не пересекается, либо совпадает с буфером a.
924
925           Буфер b не пересекается с буфером mod.
926
927       Регулярность
928           Имеется ускоренная нерегулярная редакция.
929
930       Аргументы
931           b обратное число
932           a число
933           mod модуль
934           n длина чисел в машинных словах
935
936   void zzPowerMod (word c[], const word a[], size_t n, const word b[], size_t
937       m, const word mod[], void * stack)
938       Определяется число [n]c, которое является [m]b-ой степенью числа [n]a
939       по модулю [n]mod:
940
941       c <- a^b \mod mod.
942
943
944       Предусловие
945           n > 0 && mod[n - 1] != 0.
946
947           a < mod.
948
949       Прим.
950           0^0 == 1.
951
952       Схема расчета глубины stack
953           zzPowerMod_deep(n, m).
954
955       Регулярность
956           todo
957
958       Аргументы
959           c степень
960           a основание
961           n длина a, mod в машинных словах
962           b показатель
963           m длина b в машинных словах
964           mod модуль
965           stack вспомогательная память
966
967   word zzPowerModW (register word a, register word b, register word mod, void
968       * stack)
969       Определяется b-ая степень числа a по модулю машинного слова mod.
970
971       Предусловие
972           mod != 0.
973
974       Возвращает
975           Степень.
976
977       Схема расчета глубины stack
978           zzPowerModW_deep().
979
980       Регулярность
981           todo
982
983       Аргументы
984           a основание
985           b показатель
986           mod модуль
987           stack вспомогательная память
988
989   bool_t zzRandMod (word a[], const word mod[], size_t n, gen_i rng, void *
990       rng_state)
991       С помощью генератора rng с состоянием rng_state определяется случайный
992       вычет [n]a по модулю [n]mod:
993
994       a <-R {0, 1,..., mod - 1}.
995
996
997       Предусловие
998           n > 0 && mod[n - 1] != 0.
999
1000           Буфер a не пересекается с буфером mod.
1001
1002       Возвращает
1003           Признак успеха.
1004
1005       Прим.
1006           Если 2^{l - 1} <= mod < 2^l, то для генерации a потребуется
1007           O_OF_B(l) * 2^l / mod <= 2 * O_OF_B(l) случайных октетов rng в
1008           среднем.
1009
1010           Если rng выдает данные низкого статистического качества, то для
1011           генерации может потребоваться больше октетов, чем указано выше.
1012           Более того, как только количество потребовавшихся октетов превысит
1013           определенный порог d, будет возвращен отрицательный результат.
1014           Порог d выбирается так, что вероятность события 'для генерации
1015           потребуется d истинно случайных октетов' не превосходит
1016           2^{-B_PER_IMPOSSIBLE}.
1017
1018       Регулярность
1019           Время выполнения может флуктуировать. По времени выполнения можно
1020           судить о выходных данных rng, но не тех, которые используются для
1021           формирования a.
1022
1023       Аргументы
1024           a случайное число
1025           mod модуль
1026           n длина a и mod в машинных словах
1027           rng генератор случайных чисел
1028           rng_state состояние генератора
1029
1030   bool_t zzRandNZMod (word a[], const word mod[], size_t n, gen_i rng, void *
1031       rng_state)
1032       С помощью генератора rng с состоянием rng_state определяется случайный
1033       ненулевой вычет [n]a по модулю [n]mod:
1034
1035       a <-R {1, 2,..., mod - 1}.
1036
1037
1038       Предусловие
1039           n > 0 && mod[n - 1] != 0 && mod != 1.
1040
1041           Буфер a не пересекается с буфером mod.
1042
1043       Возвращает
1044           Признак успеха.
1045
1046       Прим.
1047           Если 2^{l - 1} <= mod < 2^l, то для генерации a потребуется
1048           O_OF_B(l) * 2^l / (mod - 1) ≤ 2^l / (2^{l - 1} - 1) O_OF_B(l)
1049           случайных октетов rng в среднем.
1050
1051           Повторяется последнее замечание по функции zzRandMod().
1052
1053       Регулярность
1054           Время выполнения может флуктуировать. По времени выполнения можно
1055           судить о выходных данных rng, но не тех, которые используются для
1056           формирования a.
1057
1058       Аргументы
1059           a случайное число
1060           mod модуль
1061           n длина a и mod в машинных словах
1062           rng генератор случайных чисел
1063           rng_state состояние генератора
1064
1065   void zzRed (word a[], const word mod[], size_t n, void * stack)
1066       Определяется остаток [n]a от деления числа [2n]a на модуль [n]mod.
1067
1068       Предусловие
1069           n >= 1 && mod[n - 1] != 0.
1070
1071           Буферы a и mod не пересекаются.
1072
1073       Схема расчета глубины stack
1074           zzRed_deep(n).
1075
1076       Регулярность
1077           Функция нерегулярна.
1078
1079       Аргументы
1080           a делимое / остаток
1081           mod модуль
1082           n длина mod в машинных словах
1083           stack вспомогательная память
1084
1085   void zzRedBarr (word a[], const word mod[], size_t n, const word
1086       barr_param[], void * stack)
1087       Определяется остаток [n]a от деления числа [2n]a на модуль [n]mod. При
1088       вычислениях используется параметр Барретта [n + 2]barr_param.
1089
1090       Предусловие
1091           n > 0 && mod[n - 1] != 0.
1092
1093           Буфер a не пересекается с буфером mod.
1094
1095       Ожидается
1096           barr_param рассчитан с помощью функции zzRedBarrStart().
1097
1098       Схема расчета глубины stack
1099           zzRedBarr_deep(n).
1100
1101       Регулярность
1102           Имеется ускоренная нерегулярная редакция.
1103
1104       Аргументы
1105           a делимое / остаток
1106           mod модуль
1107           n длина mod в машинных словах
1108           barr_param параметр Барретта
1109           stack вспомогательная память
1110
1111   void zzRedBarrStart (word barr_param[], const word mod[], size_t n, void *
1112       stack)
1113       По модулю [n]mod определяется параметр [n + 2]barr_param:
1114
1115       barr_param <- B^{2n} \div mod.
1116
1117
1118        Этот параметр используется в редукции Барретта.
1119
1120       Предусловие
1121           n > 0 && mod[n] != 0.
1122
1123           Буферы barr_param и mod не пересекаются.
1124
1125       Схема расчета глубины stack
1126           zzRedBarrStart_deep(n).
1127
1128       Аргументы
1129           barr_param параметр Барретта
1130           mod модуль
1131           n длина mod в машинных словах
1132           stack вспомогательная память
1133
1134   void zzRedCrand (word a[], const word mod[], size_t n, void * stack)
1135       Определяется остаток [n]a от деления числа [2n]a на модуль [n]mod,
1136       который близок снизу к B^n.
1137
1138       Предусловие
1139           n >= 2 && mod[n - 1] != 0.
1140
1141           Модуль mod имеет вид B^n - c, где 0 < c < B.
1142
1143           Буферы a и mod не пересекаются.
1144
1145       Схема расчета глубины stack
1146           zzRedCrand_deep(n).
1147
1148       Регулярность
1149           Имеется ускоренная нерегулярная редакция.
1150
1151       Аргументы
1152           a делимое / остаток
1153           mod модуль Крэндалла
1154           n длина mod в машинных словах
1155           stack вспомогательная память (не исп.)
1156
1157   void zzRedCrandMont (word a[], const word mod[], size_t n, register word
1158       mont_param, void * stack)
1159       Определяется результат [n]a редукции Монтгомери числа [2n]a по модулю
1160       [n]mod, который близок снизу к B^n:
1161
1162       a <- a * R^{-1} \mod mod, R == B^n.
1163
1164
1165        При вычислениях используется параметр Монтгомери mont_param.
1166
1167       Предусловие
1168           n >= 2 && mod -- нечетное && mod имеет вид B^n - c, где 0 < c < B.
1169
1170           a < mod * R.
1171
1172           mont_param рассчитан с помощью функции wordNegInv().
1173
1174           Буфер a не пересекается с буфером mod.
1175
1176       Схема расчета глубины stack
1177           zzRedCrandMont_deep(n).
1178
1179       Регулярность
1180           Имеется ускоренная нерегулярная редакция.
1181
1182       Аргументы
1183           a входное число / результат
1184           mod модуль
1185           n длина mod в машинных словах
1186           mont_param параметр Монтгомери
1187           stack вспомогательная память
1188
1189   void zzRedMont (word a[], const word mod[], size_t n, register word
1190       mont_param, void * stack)
1191       Определяется результат [n]a редукции Монтгомери числа [2n]a по модулю
1192       [n]mod:
1193
1194       a <- a * R^{-1} \mod mod, R == B^n.
1195
1196
1197        При вычислениях используется параметр Монтгомери mont_param.
1198
1199       Предусловие
1200           mod -- нечетное && mod[n - 1] != 0.
1201
1202           a < mod * R.
1203
1204           mont_param рассчитан с помощью функции wordNegInv().
1205
1206           Буфер a не пересекается с буфером mod.
1207
1208       Прим.
1209           Редукция предложена в статье [Montgomery P. L. Modular
1210           multiplication without trial division. Mathematics of Computation,
1211           44(170): 519–521, 1985].
1212
1213       Схема расчета глубины stack
1214           zzRedMont_deep(n).
1215
1216       Регулярность
1217           Имеется ускоренная нерегулярная редакция.
1218
1219       Аргументы
1220           a входное число / результат
1221           mod модуль
1222           n длина mod в машинных словах
1223           mont_param параметр Монтгомери
1224           stack вспомогательная память
1225
1226   void zzSqr (word b[], const word a[], size_t n, void * stack)
1227       Определяется квадрат [2n]b числа [n]a:
1228
1229       b <- a * a.
1230
1231
1232       Предусловие
1233           Буфер b не пересекается с буфером a.
1234
1235       Схема расчета глубины stack
1236           zzSqr_deep(n).
1237
1238       Аргументы
1239           b квадрат
1240           a множитель
1241           n длина a в машинных словах
1242           stack вспомогательная память
1243
1244   void zzSqrMod (word b[], const word a[], const word mod[], size_t n, void *
1245       stack)
1246       Определяется квадрат [n]b числа [n]a по модулю [n]mod:
1247
1248       b <- a * a \mod mod.
1249
1250
1251       Предусловие
1252           n > 0 && mod[n - 1] != 0.
1253
1254           a < mod.
1255
1256       Схема расчета глубины stack
1257           zzSqrMod_deep(n).
1258
1259       Аргументы
1260           b квадрат
1261           a множитель
1262           mod модуль
1263           n длина чисел в машинных словах
1264           stack вспомогательная память
1265
1266   bool_t zzSqrt (word b[], const word a[], size_t n, void * stack)
1267       Определяется максимальное целое [(n + 1) / 2]b, квадрат которого не
1268       превосходит [n]a:
1269
1270       b <- \floor(\sqrt(a)).
1271
1272
1273       Возвращает
1274           Признак того, что a является полным квадратом (a == b * b).
1275
1276       Предусловие
1277           Буфер b не пересекается с буфером a.
1278
1279       Схема расчета глубины stack
1280           zzSqrt_deep(n).
1281
1282       Регулярность
1283           Функция нерегулярна: условные переходы, нерегулярные блоки.
1284
1285       Аргументы
1286           b квадратный корень
1287           a число
1288           n длина a в машинных словах
1289           stack вспомогательная память
1290
1291   word zzSub (word c[], const word a[], const word b[], size_t n)
1292       Определяется разность [n]c чисел [n]a и [n]b:
1293
1294       c <- (a - b) \mod B^n, borrow <- (a < b),
1295       c - B^n * borrow == a - b.
1296
1297
1298       Предусловие
1299           Буфер c либо не пересекается, либо совпадает с каждым из буферов a,
1300           b.
1301
1302       Возвращает
1303           Слово заема borrow.
1304
1305       Аргументы
1306           c разность
1307           a уменьшаемое
1308           b вычитаемое
1309           n длина a, b в машинных словах
1310
1311   word zzSub2 (word b[], const word a[], size_t n)
1312       Число [n]b уменьшается на число [n]a:
1313
1314       b <- (b - a) \mod B^n, borrow <- (b < a).
1315
1316
1317       Предусловие
1318           Буфер c либо не пересекается, либо совпадает с каждым из буферов a,
1319           b.
1320
1321       Возвращает
1322           Слово заема borrow.
1323
1324       Аргументы
1325           b уменьшаемое / разность
1326           a вычитаемое
1327           n длина a, b в машинных словах
1328
1329   void zzSubMod (word c[], const word a[], const word b[], const word mod[],
1330       size_t n)
1331       Определяется разность [n]с чисел [n]a и [n]b по модулю [n]mod:
1332
1333       c <- (a - b) \mod mod.
1334
1335
1336       Предусловие
1337           n > 0 && mod[n - 1] != 0.
1338
1339           a < mod && b < mod.
1340
1341           Буфер c либо не пересекается, либо совпадает с каждым из буферов a,
1342           b.
1343
1344           Буфер с не пересекается с буфером mod.
1345
1346       Регулярность
1347           Имеется ускоренная нерегулярная редакция.
1348
1349       Аргументы
1350           c разность
1351           a уменьшаемое
1352           b вычитаемое
1353           mod модуль
1354           n длина чисел в машинных словах
1355
1356   word zzSubMulW (word b[], const word a[], size_t n, register word w)
1357       Из числа [n]b вычитается произведение числа [n]a на машинное слово w:
1358
1359       b <- (b - a * w) \mod B^n, carry <- (b < a * w).
1360
1361
1362       Предусловие
1363           Буфер b либо не пересекается, либо совпадает с буфером a.
1364
1365       Возвращает
1366           Слово заема borrow.
1367
1368       Аргументы
1369           b вычитаемое / разность
1370           a первый множитель
1371           n длина a, b в машинных словах
1372           w второй множитель
1373
1374   word zzSubW (word b[], const word a[], size_t n, register word w)
1375       Определяется разность [n]b числа [n]a и слова w:
1376
1377       b <- (a - w) \mod B^n, borrow <- (a < w).
1378
1379
1380       Предусловие
1381           Буфер b либо не пересекается, либо совпадает с буфером a.
1382
1383       Возвращает
1384           Слово заема borrow.
1385
1386       Аргументы
1387           b разность
1388           a уменьшаемое
1389           n длина a в машинных словах
1390           w вычитаемое
1391
1392   word zzSubW2 (word a[], size_t n, register word w)
1393       Число [n]a уменьшается на слово w:
1394
1395       a <- (a - w) \mod B^n, borrow <- (a < w).
1396
1397
1398       Возвращает
1399           Слово заема borrow.
1400
1401       Аргументы
1402           a уменьшаемое / разность
1403           n длина a в машинных словах
1404           w вычитаемое
1405
1406   void zzSubWMod (word b[], const word a[], register word w, const word
1407       mod[], size_t n)
1408       Определяется разность [n]b числа [n]a и слова w по модулю [n]mod:
1409
1410       b <- (a - w) \mod mod.
1411
1412
1413       Предусловие
1414           a < mod && w < mod.
1415
1416           Буфер b либо не пересекается, либо совпадает с буфером a.
1417
1418           Буфер b не пересекается с буфером mod.
1419
1420       Регулярность
1421           Имеется ускоренная нерегулярная редакция.
1422
1423       Аргументы
1424           b разность
1425           a уменьшаемое
1426           w вычитаемое
1427           mod модуль
1428           n длина чисел в машинных словах
1429

Автор

1431       Автоматически создано Doxygen для Библиотека Bee2 из исходного текста.
1432
1433
1434
1435Библиотека Bee2                 Пт 23 Июн 2023                         zz.h(3)
Impressum