2

Crypto++ で圧縮された ECDSA キーを生成するにはどうすればよいですか?

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 クラスの操作方法の適切な説明にリンクできますか?

4

1 に答える 1

4

CryptoPP で圧縮された ECDSA キーを生成するにはどうすればよいですか?

圧縮キーは作成しません。公開鍵を生成し、必要に応じて圧縮します。ポイント圧縮を有効にして公開 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);

キーは ASN.1 の DER エンコーディングでダンプされ、Certicom のSEC 1: 楕円曲線暗号(さらに、それほどではありませんが、ANSI 9.62およびRFC 5480、ECC SubjectPublicKeyInfo 形式- Field 要素のOCTET STRINGvsについては以下を参照BIT STRING) に準拠しています。

dumpasn1それらに対してPeter Gutmann を実行できます。

$ 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
       :   }

1 つ目は 2 つの整数がエンコードされており、2 つ目は 1 つの整数がエンコードされています。共通の値は41 A9 BC 93 ... 97 58 EA 34であり、それがpub x上記の値です。key-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

EDIT 1 : これはANSI 9.62の Crypto++ バグでもあるようです。セクション 6.2、有限体要素と楕円曲線点の構文 (p. 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

EDIT 2 : Crypto++ は、Certicom のSEC 1: Elliptic Curve Cryptographyで指定された形式を使用しています。付録 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.
于 2013-10-02T07:24:37.297 に答える