Использование координаты открытого ключа с классом ECDH Crypto ++

Я использую crypto ++ для согласования ключей ECDH

ECDH.Agree(key, privateKey, outherpublicKey);

Учитывая, что для открытого ключа у меня есть только координаты X и Y. Как сгенерировать publicKey из этих значений?

ECDH.Agree(key,privateKey, getPublicKey(X,Y))

заранее спасибо

1

Решение

Учитывая, что для открытого ключа у меня есть только координаты X и Y. Как сгенерировать publicKey из этих значений?
ECDH.Agree(key,privateKey, getPublicKey(X,Y))

{x,y} это точка на кривой, но с ней никогда не было так легко работать напрямую.

Это все, что мы действительно хотим сделать, но это не работает. Проблема в ECDH::Domain только параметры домена. Публичная точка и частный показатель расположены сверху.

OID curve = ASN1::secp256r1();
DL_GroupParameters_EC<ECP> params(curve);

Integer x("...");
Integer y("...");
ECP::Point q(x, y);

DL_PublicKey_EC<ECP> pubKey;
pubKey.Initialize(params, q);

ECDH < ECP >::Domain theirs(pubKey);

Чтобы еще больше усложнить ситуацию, ключи, создаваемые протоколом ECDH, являются временными или эфемерными. Они не предназначены для сохранения; скорее они предназначены для однократного использования и выбрасываются. Таким образом, Crypto ++ не позволяет легко их сохранять (например, предоставляя DEREncode).

Анализ

Чтобы использовать {x,y} координат, нам нужно выяснить, как библиотека использует его. Эфемерный открытый и закрытый ключи создаются в pubkey.h вокруг строки 1380. Код для них ниже:

void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey)
{
Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
x.Encode(privateKey, PrivateKeyLength());
}

void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey)
{
const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
Integer x(privateKey, PrivateKeyLength());
Element y = params.ExponentiateBase(x);
params.EncodeElement(true, y, publicKey);
}

Интересующая линия выше — это params.EncodeElement(true, y, publicKey), Чтобы увидеть, что там происходит, нам нужно посмотреть на eccrypto.h вокруг линии 70, и обратите внимание, что reversible является true:

void EncodeElement(bool reversible, const Element &element, byte *encoded)
{
if (reversible)
GetCurve().EncodePoint(encoded, element, m_compress);
else
element.x.Encode(encoded, GetEncodedElementSize(false));
}

params.EncodeElement звонки ECP::EncodePoint, Чтобы увидеть, что это делает, мы можем изучить ecp.cpp вокруг линии 120. Процедура записывает несжатую точку, но блокирует x а также y на максимальный размер публичного элемента, который должен быть размером поля или порядком подгруппы.

void ECP::EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed)
{
if (P.identity)
NullStore().TransferTo(bt, EncodedPointSize(compressed));
else if (compressed)
{
bt.Put(2 + P.y.GetBit(0));
P.x.Encode(bt, GetField().MaxElementByteLength());
}
else
{
unsigned int len = GetField().MaxElementByteLength();
bt.Put(4);      // uncompressed
P.x.Encode(bt, len);
P.y.Encode(bt, len);
}
}

Не беспокойся о BufferedTransformation, Есть способы превратить byte[] в один, и это произошло до кода, показанного выше. Если вы проследите код, вы увидите его преобразованный через ArraySource:

byte myArray[PublicEphemeralKeyLength()];
ArraySource as(myArray, COUNTOF(myArray));

Выше, as это BufferedTransformation это оборачивает byte[] Вы прошли в функцию.

Последний открытый вопрос — это максимальный размер элемента поля. Похоже, что это размер модуля меньше единицы в байтах:

$ grep -I -A 1 MaxElementByteLength modarith.h
unsigned int MaxElementByteLength() const
{return (m_modulus-1).ByteCount();}

соглашение

Учитывая вышеизложенную информацию, вот что вы должны сделать. Вы должны предоставить значения для x а также y в ECP::Point q(x,y), Это просто целые числа Crypto ++.

OID curve = ASN1::secp256r1();
DL_GroupParameters_EC<ECP> params(curve);

size_t size = params.GetEncodedElementSize(true);
vector<byte> othersPublicKey(size);

ECP::Point q(x,y);
params.EncodeElement(true, q, &othersPublicKey[0]);

Тогда вы можете позвонить:

ecdh.Agree(key, myPrivateKey, &othersPublicKey[0]);

Одна запись: params.GetEncodedElementSize(true) должен равняться PublicEphemeralKeyLength(), Если они не равны, значит что-то не так.


Если вам нужно изменить сжатие, то вы можете:

params.SetPointCompression(true);

Я добавлю это в Crypto ++ Эллиптическая кривая Диффи-Хеллмана вики-страница, так что другие не должны искать ее.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector