如何从发件人那里恢复压缩的 y 值?
Posted
技术标签:
【中文标题】如何从发件人那里恢复压缩的 y 值?【英文标题】:How can I recover compressed y value from sender? 【发布时间】:2013-12-26 08:23:25 【问题描述】:我正在处理以下场景:
-
生成私钥和公钥
生成压缩公钥:
PublicKey.AccessGroupParameters().SetPointCompression(true)
签署一些数据并使用压缩的公钥发送到另一端。
[在另一端]使用公钥验证签名
对于第 4 步,我需要恢复 y 值。 Crypto++中是否有一些我可以使用的API?
【问题讨论】:
【参考方案1】:对于第 4 步,我需要恢复 y 值。 Crypto++中是否有一些我可以使用的API?
在验证过程中,将点压缩设置为true
后,您将加载持久化或序列化的密钥。
下面是一个小程序来试验点压缩。你可以在 Point Compression 下的 Crypto++ wiki 上找到它。
它生成一个随机密钥,然后创建两个公钥 - 一个带压缩和不带压缩。他们的两个公钥是序列化的。然后,它加载两个带有序列化值的新公钥。
Key 1(无压缩)和 Key 2(压缩)并保存,然后从保存的值中加载 Key 3(无压缩)和 Key 4(无压缩)。键相同,输出为:
$ ./cryptopp-test.exe
Key 1 size (no compression): 214
3081D33081A406072A8648CE3D0201308198020101302006072A8648CE3D0101021500FFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFF7FFFFFFF302C0414FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC0414
1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA450429044A96B5688EF573284664698968C38BB913CB
FC8223A628553168947D59DCC912042351377AC5FB3202150100000000000000000001F4C8F927AED3
CA752257020101032A0004CBFD13CEB20D677D9D3781AFA2E66B7BD5BC0E3C4EB8702144AA62BE5235
DFC691567AA2A7101AB1
Key 2 size (compression): 174
3081AB30819006072A8648CE3D0201308184020101302006072A8648CE3D0101021500FFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFF7FFFFFFF302C0414FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC0414
1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA450415024A96B5688EF573284664698968C38BB913CB
FC8202150100000000000000000001F4C8F927AED3CA75225702010103160003CBFD13CEB20D677D9D
3781AFA2E66B7BD5BC0E3C
Key 3 (after deserialization of Key 1):
y3.x: cbfd13ceb20d677d9d3781afa2e66b7bd5bc0e3ch
y3.y: 4eb8702144aa62be5235dfc691567aa2a7101ab1h
Key 4 (after deserialization of Key 2):
y4.x: cbfd13ceb20d677d9d3781afa2e66b7bd5bc0e3ch
y4.y: 4eb8702144aa62be5235dfc691567aa2a7101ab1h
这是创建、复制、保存、加载、压缩、解压缩和序列化键和点的程序。
#include <iostream>
using std::cout;
using std::endl;
#include <string>
using std::string;
#include <cryptopp/osrng.h>
using CryptoPP::AutoSeededRandomPool;
#include <cryptopp/secblock.h>
using CryptoPP::SecByteBlock;
#include <cryptopp/filters.h>
using CryptoPP::StringSource;
using CryptoPP::StringSink;
#include <cryptopp/hex.h>
using CryptoPP::HexEncoder;
#include <cryptopp/sha.h>
using CryptoPP::SHA1;
#include <cryptopp/integer.h>
using CryptoPP::Integer;
#include <cryptopp/eccrypto.h>
using CryptoPP::ECP;
using CryptoPP::ECDSA;
#include <cryptopp/oids.h>
using CryptoPP::ASN1::secp160r1;
int main(int argc, char* argv[])
AutoSeededRandomPool prng;
// Generate a private key, and two public keys.
// One with and one without compression
ECDSA<ECP, SHA1>::PrivateKey privateKey;
privateKey.Initialize(prng, secp160r1());
ECDSA<ECP, SHA1>::PublicKey publicKey1;
privateKey.MakePublicKey(publicKey1);
ECDSA<ECP, SHA1>::PublicKey publicKey2;
privateKey.MakePublicKey(publicKey2);
publicKey2.AccessGroupParameters().SetPointCompression(true);
// Save the public keys
string p1, p2;
publicKey1.Save(StringSink(p1).Ref());
publicKey2.Save(StringSink(p2).Ref());
// Print some stuff about them
string s3, s4;
StringSource ss3(p1, true, new HexEncoder(new StringSink(s3)));
StringSource ss4(p2, true, new HexEncoder(new StringSink(s4)));
cout << "Key 1 (not compressed): " << p1.size() << " bytes" << endl;
cout << " " << s3 << endl;
cout << "Key 2 (compressed): " << p2.size() << " bytes" << endl;
cout << " " << s4 << endl;
cout << endl;
// Two new keys to load up the persisted keys
ECDSA<ECP, SHA1>::PublicKey publicKey3, publicKey4;
publicKey4.AccessGroupParameters().SetPointCompression(true);
publicKey3.Load(StringSource(p1, true).Ref());
publicKey4.Load(StringSource(p2, true).Ref());
// And validate them
publicKey3.Validate(prng, 3);
publicKey4.Validate(prng, 3);
// Get the public elements of the loaded keys
const ECP::Point& y3 = publicKey3.GetPublicElement();
const Integer& y3_x = y3.x;
const Integer& y3_y = y3.y;
const ECP::Point& y4 = publicKey4.GetPublicElement();
const Integer& y4_x = y4.x;
const Integer& y4_y = y4.y;
// Print some stuff about them
cout << "Key 3 (after deserialization of Key 1):" << endl;
cout << " y3.x: " << std::hex << y3_x << endl;
cout << " y3.y: " << std::hex << y3_y << endl;
cout << "Key 4 (after deserialization of Key 2):" << endl;
cout << " y4.x: " << std::hex << y4_x << endl;
cout << " y4.y: " << std::hex << y4_y << endl;
cout << endl;
return 0;
您甚至可以在加载序列化密钥时跨接线,它就可以正常工作。下面,压缩密钥是从非压缩序列化加载的(反之亦然):
//////////////////////////////////////////////////////////////////////
// Two new keys to load up the persisted keys, but crossing wires
// so so there's a compress/uncompressed mismatch
ECDSA<ECP, SHA1>::PublicKey publicKey5, publicKey6;
publicKey6.AccessGroupParameters().SetPointCompression(true);
// This should be `p1`
publicKey5.Load(StringSource(p2, true).Ref());
// This should be `p2`
publicKey6.Load(StringSource(p1, true).Ref());
// Get the public elemnts of the loaded keys
const ECP::Point& y5 = publicKey5.GetPublicElement();
const Integer& y5_x = y5.x;
const Integer& y5_y = y5.y;
const ECP::Point& y6 = publicKey6.GetPublicElement();
const Integer& y6_x = y6.x;
const Integer& y6_y = y6.y;
// Print some stuff about them
cout << "Key 5 (after deserialization of Key 1):" << endl;
cout << " y5.x: " << std::hex << y5_x << endl;
cout << " y5.y: " << std::hex << y5_y << endl;
cout << "Key 6 (after deserialization of Key 2):" << endl;
cout << " y6.x: " << std::hex << y6_x << endl;
cout << " y6.y: " << std::hex << y6_y << endl;
cout << endl;
如果您想获取底层域参数(如基点),请使用:
const DL_GroupParameters_EC< ECP >& params = publicKey.GetGroupParameters()
【讨论】:
非常感谢!你摇滚! :)以上是关于如何从发件人那里恢复压缩的 y 值?的主要内容,如果未能解决你的问题,请参考以下文章