Пакет crypto/elliptic
Пакет crypto/elliptic реализует стандартные эллиптические кривые NIST
(P-256, P-384, P-521), которые широко применяются для создания цифровых подписей
и обмена ключами. Основная задача пакета — предоставить кривые, безопасные
для использования в криптографических протоколах, таких как ECDSA и ECDH.
Работа с кривыми сводится к генерации ключевых пар, умножению точек и
проверке принадлежности точки кривой.
Пакет предоставляет три основные функции для получения кривых:
P256, P384 и P521. Каждая из них возвращает объект
Curve, который поддерживает операции над точками: сложение,
умножение на скаляр и проверку принадлежности точки кривой.
Все операции выполняются над координатами точек, представленными в виде
байтовых срезов или больших целых чисел (big.Int).
Кривая P-256 (secp256r1) является наиболее распространённой и рекомендуется для большинства задач благодаря хорошему балансу между производительностью и уровнем безопасности. P-384 и P-521 обеспечивают более высокую стойкость, но требуют больше вычислительных ресурсов. Выбор кривой зависит от требуемого уровня защиты: P-256 обеспечивает 128-битную стойкость, P-384 — 192-битную, P-521 — 256-битную.
Синтаксис
Функции получения кривых имеют одинаковый синтаксис — они не принимают
аргументов и возвращают реализацию интерфейса elliptic.Curve:
func P256() Curve
func P384() Curve
func P521() Curve
Интерфейс Curve предоставляет методы для работы с точками,
включая IsOnCurve (проверка принадлежности), Add (сложение),
Double (удвоение) и ScalarMult (умножение на скаляр).
Базовое умножение (генерация публичного ключа) выполняется методом
ScalarBaseMult, который умножает точку генератора на приватный ключ.
Пример
Сгенерируем ключевую пару на кривой P-256 и проверим, что публичный ключ принадлежит кривой:
package main
import (
"crypto/elliptic"
"crypto/rand"
"fmt"
"math/big"
)
func main() {
// Выбираем кривую P-256
curve := elliptic.P256()
// Генерируем приватный ключ (случайное число)
privateKey, err := rand.Int(rand.Reader, curve.Params().N)
if err != nil {
panic(err)
}
// Вычисляем публичный ключ (точка на кривой)
publicKeyX, publicKeyY := curve.ScalarBaseMult(privateKey.Bytes())
// Проверяем, что публичный ключ лежит на кривой
isOnCurve := curve.IsOnCurve(publicKeyX, publicKeyY)
fmt.Println("Public key is on curve:", isOnCurve)
}
Результат выполнения кода:
"Public key is on curve: true"
Пример
Выполним умножение точки генератора на скаляр и сложение двух точек на кривой P-384:
package main
import (
"crypto/elliptic"
"crypto/rand"
"fmt"
"math/big"
)
func main() {
curve := elliptic.P384()
params := curve.Params()
// Генерируем два случайных скаляра
scalar1, _ := rand.Int(rand.Reader, params.N)
scalar2, _ := rand.Int(rand.Reader, params.N)
// Вычисляем две точки: P1 = scalar1 * G, P2 = scalar2 * G
x1, y1 := curve.ScalarBaseMult(scalar1.Bytes())
x2, y2 := curve.ScalarBaseMult(scalar2.Bytes())
// Складываем точки P1 и P2
sumX, sumY := curve.Add(x1, y1, x2, y2)
// Проверяем, что результат лежит на кривой
isSumOnCurve := curve.IsOnCurve(sumX, sumY)
fmt.Println("Sum point is on curve:", isSumOnCurve)
}
Результат выполнения кода:
"Sum point is on curve: true"
Пример
Проверим принадлежность случайной точки кривой P-521. Точка, не лежащая на кривой, будет отклонена:
package main
import (
"crypto/elliptic"
"fmt"
"math/big"
)
func main() {
curve := elliptic.P521()
params := curve.Params()
// Координаты точки, которая не лежит на кривой
x := new(big.Int).Add(params.P, big.NewInt(1))
y := new(big.Int).Add(params.P, big.NewInt(1))
// Проверяем принадлежность кривой
isOnCurve := curve.IsOnCurve(x, y)
fmt.Println("Point is on curve:", isOnCurve)
}
Результат выполнения кода:
"Point is on curve: false"
Смотрите также
-
функцию
elliptic.P256,
которая возвращает кривую NIST P-256 -
функцию
elliptic.P384,
которая возвращает кривую NIST P-384 -
функцию
elliptic.P521,
которая возвращает кривую NIST P-521 -
пакет
crypto/ecdsa,
который реализует алгоритм цифровой подписи на эллиптических кривых