1

私は次のシナリオに取り組んでいます:

  1. 秘密鍵と公開鍵を生成する
  2. 以下を使用して圧縮された公開鍵を生成します。

    PublicKey.AccessGroupParameters().SetPointCompression(true)

  3. 一部のデータに署名し、圧縮された公開鍵で相手に送信します。

  4. 【相手側】公開鍵で署名を検証

ステップ 4 では、y 値を回復する必要があります。Crypto++ で使用できる API はありますか?

4

1 に答える 1

3

ステップ 4 では、y 値を回復する必要があります。Crypto++ で使用できる API はありますか?

検証中に、ポイント圧縮を に設定した後、永続化またはシリアル化されたキーを読み込みますtrue


以下は、ポイント圧縮を試すための小さなプログラムです。これは、Crypto++ wiki のPoint Compressionにあります。

ランダムなキーを生成し、2 つの公開キーを作成します。1 つは圧縮ありとなしです。これらの 2 つの公開鍵はシリアル化されています。次に、シリアル化された値を含む 2 つの新しい公開キーを読み込みます。

キー 1 (圧縮なし) とキー 2 (圧縮) が保存され、次にキー 3 (圧縮なし) とキー 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()
于 2014-01-10T05:44:55.560 に答える