Работа с BigInteger через jsbn

BigInteger в jsbn представляет собой реализацию длинной арифметики на основе массивов 28–32-битных “слов”, что позволяет выполнять операции над числами произвольной длины, выходящей за пределы стандартного Number в JavaScript. В контексте jsrsasign эта реализация используется для всех криптографических вычислений, включая RSA, DSA, ECDSA (в части вспомогательных операций), а также для работы с большими модулями и экспонентами.

В jsbn число хранится в виде массива, где каждый элемент — это фрагмент числа в базе 2^26 или 2^28 (в зависимости от конфигурации). Такая схема позволяет эффективно выполнять операции переноса разрядов.

Ключевые особенности представления:

  • знак хранится отдельно (sign)
  • данные представлены в little-endian виде (младшие слова первыми)
  • используется оптимизация для малых чисел (smi-подобные случаи)
  • операции переполнения обрабатываются вручную

Создание экземпляра BigInteger:

var n1 = new BigInteger("12345678901234567890", 10);
var n2 = new BigInteger("deadbeef", 16);
var n3 = new BigInteger([1, 2, 3]); // внутренний формат

Поддерживаемые системы счисления:

  • 2 (двоичная)
  • 8 (восьмеричная)
  • 10 (десятичная)
  • 16 (шестнадцатеричная)

Базовые арифметические операции

BigInteger в jsbn реализует классические операции длинной арифметики.

Сложение и вычитание

var a = new BigInteger("999999999999999999");
var b = new BigInteger("123456789");

var sum = a.add(b);
var diff = a.subtract(b);

Алгоритм основан на поразрядном сложении с переносом. В случае вычитания выполняется borrow-логика.

Умножение

var prod = a.multiply(b);

Используется классический алгоритм O(n²), оптимизированный для малых значений. В некоторых сборках jsrsasign возможны ускоренные варианты для определённых размеров чисел.

Деление и остаток

var div = a.divide(b);
var mod = a.mod(b);

Алгоритм деления основан на нормализованном long division с оценкой частного по старшим разрядам.

Часто используется комбинированная операция:

var result = a.divRem(b);

Модульная арифметика

Модульные операции — ключевой компонент криптографии RSA.

var mod = new BigInteger("1000000007");
var result = a.mod(mod);

Модульное возведение в степень

Одна из наиболее важных операций:

var base = new BigInteger("12345");
var exp = new BigInteger("6789");
var mod = new BigInteger("10007");

var res = base.modPow(exp, mod);

Это основа RSA-шифрования и подписи.

Алгоритм:

  • бинарное возведение в степень (square-and-multiply)
  • постоянная редукция по модулю
  • оптимизации для отрицательных степеней не применяются

НОД и расширенный алгоритм Евклида

var g = a.gcd(b);

Расширенная версия:

var eg = a.egcd(b);

Результат содержит:

  • gcd
  • коэффициенты Безу (x, y)

Используется для вычисления мультипликативных обратных элементов:

var inv = a.modInverse(m);

Побитовые операции

Хотя BigInteger не является битовым типом, jsbn поддерживает базовые операции:

a.shiftLeft(5);
a.shiftRight(3);

Также доступны:

  • bitLength() — длина в битах
  • testBit(n) — проверка бита
  • setBit(n) — установка бита
  • clearBit(n) — сброс бита

Эти операции критически важны для криптографических проверок и генерации ключей.

Конвертация форматов

В строку

a.toString(10);
a.toString(16);

В байты

var bytes = a.toByteArray();

Массив байтов используется в DER/ASN.1 структурах, сертификатах и подписях.

Из байтов

var a = new BigInteger(bytes);

Работа с отрицательными числами

BigInteger поддерживает знаковую арифметику:

var neg = a.negate();
var abs = a.abs();

В криптографическом контексте отрицательные значения используются редко, но важны при промежуточных вычислениях.

Сравнение больших чисел

a.compareTo(b); // -1, 0, 1
a.equals(b);
a.signum();

Сравнение выполняется по длине массива и затем поразрядно.

Использование в RSA

BigInteger является основой RSA-операций в jsrsasign:

  • генерация ключей
  • вычисление n = p * q
  • вычисление d ≡ e⁻¹ mod φ(n)
  • шифрование: c = m^e mod n
  • дешифрование: m = c^d mod n

Пример схемы:

var m = new BigInteger("42");
var c = m.modPow(e, n);
var decrypted = c.modPow(d, n);

Оптимизация вычислений

В jsbn присутствуют оптимизации:

  • использование Karatsuba-подобных подходов в некоторых версиях
  • кеширование промежуточных значений при modPow
  • оптимизация малых чисел через native number path
  • сокращение количества операций mod через предварительную нормализацию

Генерация случайных BigInteger

var rnd = new BigInteger(256, new SecureRandom());

Используется для:

  • генерации ключей RSA
  • создания простых чисел (probable primes)
  • криптографических nonce

Простые числа и тест Миллера–Рабина

var p = new BigInteger("...");
p.isProbablePrime(10);

Генерация простых чисел:

var prime = new BigInteger(1024, 1, random);

Параметры управляют:

  • размером
  • вероятностью простоты
  • источником случайности

Взаимодействие с jsrsasign

В jsrsasign BigInteger интегрирован в:

  • RSAKey
  • KJUR.crypto
  • X.509 обработку сертификатов
  • CMS/PKCS#7 структуры

Типичный поток данных:

  1. ASN.1 → байты
  2. байты → BigInteger
  3. операции modPow / modInverse
  4. BigInteger → байты
  5. байты → DER структура

Особенности реализации jsbn

  • отсутствие зависимости от BigInt (ES2020)
  • кросс-браузерная совместимость
  • чистая JavaScript-реализация
  • ориентация на криптографическую точность, а не скорость

Ограничения:

  • сравнительно низкая производительность по сравнению с native BigInt
  • высокая стоимость операций multiply и modPow на больших числах
  • отсутствие SIMD/низкоуровневых оптимизаций

Типичные ошибки при работе

  • использование Number вместо BigInteger для криптографии
  • неверная база при парсинге строки
  • потеря ведущих нулей при конвертации в байты
  • смешивание BigInteger разных реализаций (jsbn vs native BigInt)

Роль BigInteger в криптографическом стеке

BigInteger выступает фундаментальным уровнем абстракции, на котором строится:

  • модульная арифметика
  • асимметричное шифрование
  • цифровые подписи
  • работа с сертификатами X.509
  • реализация протоколов TLS/PKI

Без этой реализации невозможна корректная работа RSA-алгоритмов в чистом JavaScript окружении.