Ключи Crypto++ и сжатые EC
Как я могу генерировать сжатые ключи ECDSA в Crypto++?
AutoSeededRandomPool prng;
ECDSA<ECP, SHA1>::PrivateKey privateKey;
ECDSA<ECP, SHA1>::PublicKey publicKey;
privateKey.Initialize( prng, CryptoPP::ASN1::secp256r1());
const Integer& x1 = privateKey.GetPrivateExponent();
cout << "priv: " << std::hex << x1 << endl;
privateKey.MakePublicKey( publicKey );
const ECP::Point& q = publicKey.GetPublicElement();
const Integer& qx = q.x;
const Integer& qy = q.y;
cout << "pub x: " << std::hex << qx << endl;
cout << "pub y: " << std::hex << qy << endl;
Этот код генерирует пару ключей и печатает компоненты X и Y открытого ключа.
Мне нужно знать, есть ли способ распечатать компонент Y сжатого ключа, или мне нужно сгенерировать его из несжатого компонента y. Если мне нужно его сгенерировать, может кто-нибудь связать меня с хорошим объяснением того, как работать с классом Integer?
1 ответ
Как я могу создать сжатые ключи ECDSA в CryptoPP?
Вы не создаете сжатый ключ. Вы генерируете открытый ключ, а затем сжимаете его, если это то, что требуется. Из Как создать открытый ключ ECDSA с включенным сжатием точек? в группе пользователей Crpyto++:
ECDSA<ECP, SHA1>::Verifier verifier(...);
verifier.AccessKey().AccessGroupParameters().SetPointCompression(true);
В вашем случае это будет:
publicKey.AccessGroupParameters().SetPointCompression(true);
поскольку verifier.AccessKey()
возвращает открытый ключ ECDSA.
Мне нужно знать, есть ли способ распечатать компонент Y сжатого ключа
Сжатие - это опция формата презентации или оптимизации. Вы не можете напечатать компонент Y на сериализованном ключе со сжатием, потому что его там нет (см. Дампы ASN.1 ниже).
При включенном сжатии "сокращение" Y будет равно 1 или -1, в зависимости от знака компонента (знак указывает, в каком квадранте находится точка). Идея в том, что кто-то посылает вам пару {1,X} или пару {-1,X}, и вы можете решить для Y, потому что вы знаете, в каком квадранте он должен быть. Если Y допускается только быть положительным, вам нужно только сериализовать {X} (а не {-1,X} или {1,X}). (Я не углублялся в книги или стандарты, поэтому здесь могут быть некоторые ошибки).
... или если мне нужно сгенерировать его из несжатого компонента y. Если мне нужно его сгенерировать, может кто-нибудь связать меня с хорошим объяснением того, как работать с классом Integer?
Я понятия не имею, о чем ты говоришь здесь. Точка сжатия влияет на представление. Если вы включите сжатие точек и получите Y, вы все равно получите Y. Вы не можете вычислить сжатую точку. Вам нужны координаты X и Y.
Добавьте следующее в вашу программу:
publicKey.AccessGroupParameters().SetPointCompression(false);
ByteQueue q1;
publicKey.Save(q1);
cout << "Uncompressed size: " << dec << q1.MaxRetrievable() << endl;
publicKey.AccessGroupParameters().SetPointCompression(true);
ByteQueue q2;
publicKey.Save(q2);
cout << "Compressed size: " << dec << q2.MaxRetrievable() << endl;
Вот что я получил за вывод:
$ ./cryptopp-test.exe
priv: 4ce30d22d9593d9c7f4406eda1ce0740c7486106374d0abe7e352e1d5b1d5622h
pub x: 41a9bc936b6d1dd3a1ded997d7da08f1df990e9b50f9b58e9e4fd9319758ea34h
pub y: 4ad39ffb79c402063a99ecbc0cac8fde606db6764ace90933feee5f8d65937a2h
Uncompressed size: 311
Compressed size: 246
Если вы получите Y после включения точечного сжатия, вы все равно получите 4ad39ffb79c402063a99ecbc0cac8fde606db6764ace90933feee5f8d65937a2h, потому что сжатие влияет на представление.
Теперь добавьте следующее, чтобы выгрузить несжатый и сжатый ключ:
FileSink fs1("key-1.der", true);
q1.TransferTo(fs1);
FileSink fs2("key-2.der", true);
q2.TransferTo(fs2);
Ключи выгружаются в кодировке DER в ASN.1 и соответствуют SEC 1: криптографии с эллиптическими кривыми (и в меньшей степени ANSI 9.62 и RFC 5480, формат ECC SubjectPublicKeyInfo) - см. Ниже об элементах поля OCTET STRING
против BIT STRING
).
Вы можете запустить Питера Гутмана dumpasn1
на них:
$ dumpasn1.exe key-1.der
0 307: SEQUENCE {
4 236: SEQUENCE {
7 7: OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1)
16 224: SEQUENCE {
19 1: INTEGER 1
22 44: SEQUENCE {
24 7: OBJECT IDENTIFIER prime-field (1 2 840 10045 1 1)
33 33: INTEGER
: 00 FF FF FF FF 00 00 00 01 00 00 00 00 00 00 00
: 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF
: FF
: }
68 68: SEQUENCE {
70 32: OCTET STRING
: FF FF FF FF 00 00 00 01 00 00 00 00 00 00 00 00
: 00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FC
104 32: OCTET STRING
: 5A C6 35 D8 AA 3A 93 E7 B3 EB BD 55 76 98 86 BC
: 65 1D 06 B0 CC 53 B0 F6 3B CE 3C 3E 27 D2 60 4B
: }
138 65: OCTET STRING
: 04 6B 17 D1 F2 E1 2C 42 47 F8 BC E6 E5 63 A4 40
: F2 77 03 7D 81 2D EB 33 A0 F4 A1 39 45 D8 98 C2
: 96 4F E3 42 E2 FE 1A 7F 9B 8E E7 EB 4A 7C 0F 9E
: 16 2B CE 33 57 6B 31 5E CE CB B6 40 68 37 BF 51
: F5
205 33: INTEGER
: 00 FF FF FF FF 00 00 00 00 FF FF FF FF FF FF FF
: FF BC E6 FA AD A7 17 9E 84 F3 B9 CA C2 FC 63 25
: 51
240 1: INTEGER 1
: }
: }
243 66: BIT STRING
: 04 41 A9 BC 93 6B 6D 1D D3 A1 DE D9 97 D7 DA 08
: F1 DF 99 0E 9B 50 F9 B5 8E 9E 4F D9 31 97 58 EA
: 34 4A D3 9F FB 79 C4 02 06 3A 99 EC BC 0C AC 8F
: DE 60 6D B6 76 4A CE 90 93 3F EE E5 F8 D6 59 37
: A2
: }
$ dumpasn1.exe key-2.der
0 243: SEQUENCE {
3 204: SEQUENCE {
6 7: OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1)
15 192: SEQUENCE {
18 1: INTEGER 1
21 44: SEQUENCE {
23 7: OBJECT IDENTIFIER prime-field (1 2 840 10045 1 1)
32 33: INTEGER
: 00 FF FF FF FF 00 00 00 01 00 00 00 00 00 00 00
: 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF
: FF
: }
67 68: SEQUENCE {
69 32: OCTET STRING
: FF FF FF FF 00 00 00 01 00 00 00 00 00 00 00 00
: 00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FC
103 32: OCTET STRING
: 5A C6 35 D8 AA 3A 93 E7 B3 EB BD 55 76 98 86 BC
: 65 1D 06 B0 CC 53 B0 F6 3B CE 3C 3E 27 D2 60 4B
: }
137 33: OCTET STRING
: 03 6B 17 D1 F2 E1 2C 42 47 F8 BC E6 E5 63 A4 40
: F2 77 03 7D 81 2D EB 33 A0 F4 A1 39 45 D8 98 C2
: 96
172 33: INTEGER
: 00 FF FF FF FF 00 00 00 00 FF FF FF FF FF FF FF
: FF BC E6 FA AD A7 17 9E 84 F3 B9 CA C2 FC 63 25
: 51
207 1: INTEGER 1
: }
: }
210 34: BIT STRING
: 02 41 A9 BC 93 6B 6D 1D D3 A1 DE D9 97 D7 DA 08
: F1 DF 99 0E 9B 50 F9 B5 8E 9E 4F D9 31 97 58 EA
: 34
: }
Обратите внимание на различия:
# key-1.der
243 66: BIT STRING
: 04 41 A9 BC 93 6B 6D 1D D3 A1 DE D9 97 D7 DA 08
: F1 DF 99 0E 9B 50 F9 B5 8E 9E 4F D9 31 97 58 EA
: 34 4A D3 9F FB 79 C4 02 06 3A 99 EC BC 0C AC 8F
: DE 60 6D B6 76 4A CE 90 93 3F EE E5 F8 D6 59 37
: A2
против:
# key-2.der
210 34: BIT STRING
: 02 41 A9 BC 93 6B 6D 1D D3 A1 DE D9 97 D7 DA 08
: F1 DF 99 0E 9B 50 F9 B5 8E 9E 4F D9 31 97 58 EA
: 34
: }
В первом кодируются два целых числа, а во втором - одно целое число. Общая ценность 41 A9 BC 93 ... 97 58 EA 34
и это твое pub x
выше. Недостающая строка из ключа-2 4A D3 9F FB ... D6 59 37 A2
и это pub y
выше. Для полноты значения кодируются как {X,Y} или {X}, а не как кодировка целых чисел в ASN.1.
Последнее различие - первый октет BIT STRING: 02 против 04 (или 03). 04 указывает на несжатую точку. Из RFC 5480, раздел 2.2:
The first octet of the OCTET STRING indicates whether the key is compressed or uncompressed. The uncompressed form is indicated by 0x04 and the compressed form is indicated by either 0x02 or 0x03 (see 2.3.3 in [SEC1]). The public key MUST be rejected if any other value is included in the first octet.
И после просмотра стандарта и раздела 2.2, в Crypto++ может быть ошибка: BIT STRING
, но стандарт четко обсуждает OCTET STRING
,
РЕДАКТИРОВАТЬ 1: Кажется, это ошибка Crypto++ под ANSI 9.62, тоже. Раздел 6.2, Синтаксис для конечных элементов поля и точек эллиптической кривой (стр. 20)
A finite field element shall be represented by a value of type FieldElement: FieldElement ::= OCTET STRING The value of FieldElement shall be the octet string representation of a field elementfollowing the conversion routine in Section 4.3.1. An elliptic curve point shall be represented by a value of type ECPoint: ECPoint ::= OCTET STRING
РЕДАКТИРОВАТЬ 2: Crypto++ использует формат, указанный в SEC 1: Криптография по эллиптической кривой. Приложение C (страница 77) гласит:
Finally, a specific field element is represented by the following type FieldElement ::= OCTET STRING whose value is the octet string obtained from the conversion routines given in Section 2.3.5.