Работа с координатами точек

В библиотеке jsrsasign координаты точек используются преимущественно при работе с эллиптическими кривыми (ECC). Точка на кривой определяется парой значений (x, y), которые представляют собой большие целые числа, принадлежащие конечному полю.

Внутренне координаты хранятся в виде объектов класса BigInteger, что позволяет выполнять арифметические операции с числами произвольной длины. Это критично для криптографии, где стандартные типы JavaScript (например, Number) не обеспечивают необходимую точность.


Форматы представления координат

Координаты точек могут быть представлены в нескольких форматах:

1. Шестнадцатеричный формат (Hex) Наиболее распространённый способ хранения:

var xHex = "18b18ac0...";
var yHex = "12345678...";

2. BigInteger

var x = new BigInteger(xHex, 16);
var y = new BigInteger(yHex, 16);

3. ASN.1 / DER-кодировка Используется при сериализации ключей и подписей:

var pointHex = "04" + xHex + yHex;

Префикс 04 означает несжатую форму точки.


Создание точки на эллиптической кривой

В jsrsasign работа с точками выполняется через класс ECPointFp. Для создания точки требуется:

  • объект кривой
  • координаты x и y
var ec = new KJUR.crypto.ECDSA({"curve": "secp256r1"});
var curve = ec.ecparams.curve;

var x = new BigInteger(xHex, 16);
var y = new BigInteger(yHex, 16);

var point = new ECPointFp(curve, curve.fromBigInteger(x), curve.fromBigInteger(y));

Особенности:

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

Проверка принадлежности точки кривой

Корректность координат проверяется через подстановку в уравнение кривой:

[ y^2 x^3 + ax + b ]

В jsrsasign:

var isValid = curve.validate(point);

Если точка не принадлежит кривой:

  • она не может использоваться в криптографических операциях
  • возможны ошибки при подписи и проверке

Сжатие и восстановление координат

Для уменьшения размера данных применяется сжатие точки:

Несжатый формат:

04 || X || Y

Сжатый формат:

02/03 || X
  • 02 — если Y чётное
  • 03 — если Y нечётное

Пример сжатия:

var compressed = point.getEncoded(true);

Восстановление:

var decompressedPoint = curve.decodePointHex(compressedHex);

При восстановлении координата Y вычисляется из X с использованием уравнения кривой.


Арифметика точек

Координаты используются при выполнении операций:

Сложение точек

var result = point1.add(point2);

Удвоение точки

var doubled = point.twice();

Умножение на скаляр

var k = new BigInteger("12345", 10);
var multiplied = point.multiply(k);

Все операции выполняются в поле по модулю p.


Работа с координатами при генерации ключей

Публичный ключ в ECC — это точка:

var ec = new KJUR.crypto.ECDSA({"curve": "secp256r1"});
var keypair = ec.generateKeyPairHex();

var pubKeyHex = keypair.ecpubhex;

Извлечение координат:

var x = pubKeyHex.substr(2, 64);
var y = pubKeyHex.substr(66, 64);
  • первые 2 символа — префикс (04)
  • далее идут X и Y

Работа с координатами в цифровой подписи

При создании подписи ECDSA используются промежуточные точки:

  • вычисляется точка kG
  • берётся её X-координата
  • используется в параметре r
var sig = new KJUR.crypto.Signature({"alg": "SHA256withECDSA"});
sig.init(privateKey);
sig.updateString("data");
var signature = sig.sign();

Внутренне:

  • X координата точки влияет на результат подписи
  • ошибки в вычислениях координат приводят к недействительным подписям

Конвертация координат

Преобразование между форматами:

Hex → BigInteger

var bi = new BigInteger(hex, 16);

BigInteger → Hex

var hex = bi.toString(16);

Hex → ByteArray

var bytes = KJUR.crypto.Util.hexToBytes(hex);

Частые ошибки при работе с координатами

1. Неверная длина

  • координаты должны иметь фиксированную длину
  • для secp256r1 — 32 байта

2. Отсутствие ведущих нулей

// Неправильно
"1a2b"

// Правильно
"001a2b"

3. Несоответствие кривой

  • координаты от одной кривой нельзя использовать в другой

4. Нарушение формата точки

  • отсутствие префикса (04, 02, 03)

Оптимизация работы с координатами

Использование Jacobian-координат

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

  • уменьшение числа операций деления
  • ускорение умножения точки

Это прозрачно для разработчика, но влияет на производительность.


Безопасность при работе с координатами

  • проверка входных точек обязательна
  • использование неподтверждённых координат может привести к атакам
  • рекомендуется всегда вызывать validate()

Особое внимание уделяется:

  • атакам с некорректными точками (invalid curve attack)
  • подмене публичных ключей

Пример полного цикла работы

var ec = new KJUR.crypto.ECDSA({"curve": "secp256r1"});
var keypair = ec.generateKeyPairHex();

var pub = keypair.ecpubhex;

// Извлечение координат
var xHex = pub.substr(2, 64);
var yHex = pub.substr(66, 64);

// Создание точки
var curve = ec.ecparams.curve;
var x = new BigInteger(xHex, 16);
var y = new BigInteger(yHex, 16);

var point = new ECPointFp(curve, curve.fromBigInteger(x), curve.fromBigInteger(y));

// Проверка
if (curve.validate(point)) {
    console.log("Точка корректна");
}

Роль координат в криптографических протоколах

Координаты точек используются в:

  • ECDSA (подписи)
  • ECDH (обмен ключами)
  • ECIES (шифрование)

Во всех случаях:

  • X и Y определяют положение точки
  • точка является основой криптографической стойкости
  • ошибки в обработке координат приводят к компрометации системы