Gnupg secp256k1 署名が他の実装と一致しません。

Gnupg secp256k1 署名が他の実装と一致しません。

暗号通貨の目的でgpgエージェントに署名しようとしています。複数のハッシュ署名と署名を試しました。一つそれらのいくつかは得た。その他 rs他の実装と同じ効果を達成しながら。

elliptic結果をnodejsライブラリとcの結果と比較したが、libsecp256k1結果は互いに一致した。

おそらく、これは私の立場では明らかで愚かな間違いだったでしょう。

そのバージョンのCソースコードは次のとおりですlibsecp256k1

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <secp256k1.h>

const unsigned char msg[32] = {0xc3, 0xaf, 0xca, 0x60, 0x84, 0xa5, 0x8f, 0x5b, 0x06, 0x0d, 0x0a, 0x4a, 0xaa, 0x6e, 0xd9, 0x06, 0x3a, 0x9b, 0xa7, 0x0f, 0x2b, 0xd4, 0xa7, 0x68, 0xf4, 0xad, 0x41, 0x41, 0x74, 0x28, 0xf8, 0x02};
const unsigned char pk[32] = {0xEC, 0x5D, 0xCC, 0xE1, 0x3E, 0xA0, 0xC5, 0xF4, 0x50, 0x0C, 0x31, 0x5C, 0x96, 0x4C, 0xDE, 0xE1, 0x0A, 0x05, 0x53, 0x13, 0xEA, 0x71, 0xB7, 0x55, 0x82, 0x00, 0xE9, 0x8B, 0x1D, 0xF7, 0x7F, 0x38};


int main() {
    int r;
    int fd;
    secp256k1_context *ctx;
    secp256k1_ecdsa_signature sig;
    unsigned char *serialized_signature;

    ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
    r = secp256k1_ecdsa_sign(ctx, &sig, (const unsigned char*)msg, (const unsigned char*)pk, NULL, NULL);
    if (r != 1) {
        return 1;
    }

    serialized_signature = malloc(64);  
    r = secp256k1_ecdsa_signature_serialize_compact(ctx, serialized_signature, &sig);
    if (r != 1) {
        return 1;
    }
    fwrite(serialized_signature, 1, 64, stdout);
    free(serialized_signature);
    secp256k1_context_destroy(ctx);

    return 0;
}

---

outputs:
$ ./a.out | hexdump -C
00000000  26 0d c8 ab 01 f0 79 64  0b dd 8d 5b 5b 43 76 bd  |&.....yd...[[Cv.|
00000010  d2 db 1d 66 fa ce 87 57  6e f1 1f 04 df 54 24 67  |...f...Wn....T$g|
00000020  0f 50 01 c3 3c 17 b5 5e  a1 c7 dc cb 2a 38 af 69  |.P..<..^....*8.i|
00000030  7c a1 8e 38 48 6c b4 7a  9b d7 f3 24 c9 99 17 b3  ||..8Hl.z...$....|

以下はgnupgを使った試みです:

keyid=D5C4AD7CC2A40CA64860ACA504450BED5A1D56D6
keygrip=A6D4B5C57143CE15C07D0DDEA5986B13B5F7ED72
hsh=c3afca6084a58f5b060d0a4aaa6ed9063a9ba70f2bd4a768f4ad41417428f802

cat <<EOF | gpg --import
-----BEGIN PGP PRIVATE KEY BLOCK-----

lHQEXs4mIhMFK4EEAAoCAwTZvUk3CNXg/KYqfIbkNkZZXeD+yBE5X7AJ7IEYkpA9
SSks1IOQqws0M3U7YhhJt6sgsBQSjR9y/kUHHSSXHjRjAAEA7F3M4T6gxfRQDDFc
lkze4QoFUxPqcbdVggDpix33fzgPtbQgTWVsdmluIGVyZCA8bWVsdmluQHNlY2hv
c3QuaW5mbz6IkAQTEwgAOBYhBNXErXzCpAymSGCspQRFC+1aHVbWBQJeziYiAhsD
BQsJCAcDBRUKCQgLBRYCAwEAAh4BAheAAAoJEARFC+1aHVbWTzoA/AqL6dSHIr0+
lfRNSSo1a2WiKZpnCna9j9Kiiv7UylMqAQDCXnK+2gZM9xPsXOe0jrCyvc2qhqMN
/X5TObkVg5f1jg==
=OhY5
-----END PGP PRIVATE KEY BLOCK-----
EOF

gpg-connect-agent <<EOF | hexdump -C
SIGKEY $keygrip
SETHASH --hash=sha256 $hsh
PKSIGN
EOF

---

outputs:

$ bash agent-sign.sh 
gpg: key 04450BED5A1D56D6: "Melvin erd <[email protected]>" not changed
gpg: key 04450BED5A1D56D6: secret key imported
gpg: Total number processed: 1
gpg:              unchanged: 1
gpg:       secret keys read: 1
gpg:  secret keys unchanged: 1
00000000  4f 4b 0a 4f 4b 0a 44 20  28 37 3a 73 69 67 2d 76  |OK.OK.D (7:sig-v|
00000010  61 6c 28 35 3a 65 63 64  73 61 28 31 3a 72 33 32  |al(5:ecdsa(1:r32|
00000020  3a 26 25 30 44 c8 ab 01  f0 79 64 0b dd 8d 5b 5b  |:&%0D....yd...[[|
00000030  43 76 bd d2 db 1d 66 fa  ce 87 57 6e f1 1f 04 df  |Cv....f...Wn....|
00000040  54 24 67 29 28 31 3a 73  33 32 3a 0f 50 01 c3 3c  |T$g)(1:s32:.P..<|
00000050  17 b5 5e a1 c7 dc cb 2a  38 af 69 7c a1 8e 38 48  |..^....*8.i|..8H|
00000060  6c b4 7a 9b d7 f3 24 c9  99 17 b3 29 29 29 0a 4f  |l.z...$....))).O|
00000070  4b 0a                                             |K.|
00000072

(signature itself; r at 0x21 and, s at `0x4b`)

ベストアンサー1

gpg secp256k1曲線記号式(S-EXP)出力は16進ダンプに表示されます(上記の質問の一番下の2番目のプログラムgpgスクリプト)。 0x28 "("および0x29 ")"は、R&S署名コンポーネントの32バイトS-EXPエンコーディングを構成する角括弧を表します。

libsecp256k1 Code Output:

R署名コンポーネント=26 0d c8 ab 01 f0 79 64 0b dd 8d 5b 5b 43 76 bd d2 db 1d 66 側 87 57 6e f1 1f 04 df 54 24 67

S署名コンポーネント=0f 50 01 c3 3c 17 b5 5e a1 c7 dc CB 2a 38 af 69 7c a1 8e 38 48 6c b4 7a 9b d7 f3 24 c9 99 17 b3

GPG Script S-EXP Output:

R署名コンポーネント=2625 30 44c8 ab 01 f0 79 64 0b dd 8d 5b 5b 43 76 bd d2 db 1d 66 サイド ce 87 57 6e f1 1f 04 df 54 24 67

S署名コンポーネント=0f 50 01 c3 3c 17 b5 5e a1 c7 dc CB 2a 38 af 69 7c a1 8e 38 48 6c b4 7a 9b d7 f3 24 c9 99 17 b3

S署名コンポーネントはlibsecp256k1が出力するものと正確に一致しているようです。 Rコンポーネントの2番目のバイトだけが異なるように見えますが、S-EXPでは、「25 30 44」の%0Dデコードが2番目のプログラムのRコンポーネント出力バイト出力の0x0dに似ていることに注意してください。

%猫melvin_5a1d56d6.asc

-----BEGIN PGP PRIVATE KEY BLOCK-----

lHQEXs4mIhMFK4EEAAoCAwTZvUk3CNXg/KYqfIbkNkZZXeD+yBE5X7AJ7IEYkpA9
SSks1IOQqws0M3U7YhhJt6sgsBQSjR9y/kUHHSSXHjRjAAEA7F3M4T6gxfRQDDFc
lkze4QoFUxPqcbdVggDpix33fzgPtbQgTWVsdmluIGVyZCA8bWVsdmluQHNlY2hv
c3QuaW5mbz6IkAQTEwgAOBYhBNXErXzCpAymSGCspQRFC+1aHVbWBQJeziYiAhsD
BQsJCAcDBRUKCQgLBRYCAwEAAh4BAheAAAoJEARFC+1aHVbWTzoA/AqL6dSHIr0+
lfRNSSo1a2WiKZpnCna9j9Kiiv7UylMqAQDCXnK+2gZM9xPsXOe0jrCyvc2qhqMN
/X5TObkVg5f1jg==
=OhY5
-----END PGP PRIVATE KEY BLOCK-----

gpg計算(S署名コンポーネント)の最後の出力がBitcoin secp256k1署名を適用した後の手動計算とどのように異なるかを確認してください。

%猫melvin_5a1d56d6.asc gpg --list-packets --verbose |

# off=0 ctb=94 tag=5 hlen=2 plen=116
:secret key packet:
    version 4, algo 19, created 1590568482, expires 0
    pkey[0]: 052B8104000A secp256k1 (1.3.132.0.10)
    pkey[1]: 04D9BD493708D5E0FCA62A7C86E43646595DE0FEC811395FB009EC811892903D49292CD48390AB0B3433753B621849B7AB20B014128D1F72FE45071D24971E3463
    skey[2]: EC5DCCE13EA0C5F4500C315C964CDEE10A055313EA71B7558200E98B1DF77F38
    checksum: 0fb5
    keyid: 04450BED5A1D56D6
# off=118 ctb=b4 tag=13 hlen=2 plen=32
:user ID packet: "Melvin erd <[email protected]>"
# off=152 ctb=88 tag=2 hlen=2 plen=144
:signature packet: algo 19, keyid 04450BED5A1D56D6
    version 4, created 1590568482, md5len 0, sigclass 0x13
    digest algo 8, begin of digest 4f 3a
    hashed subpkt 33 len 21 (issuer fpr v4 D5C4AD7CC2A40CA64860ACA504450BED5A1D56D6)
    hashed subpkt 2 len 4 (sig created 2020-05-27)
    hashed subpkt 27 len 1 (key flags: 03)
    hashed subpkt 11 len 4 (pref-sym-algos: 9 8 7 3)
    hashed subpkt 21 len 4 (pref-hash-algos: 10 9 8 11)
    hashed subpkt 22 len 4 (pref-zip-algos: 2 3 1 0)
    hashed subpkt 30 len 1 (features: 01)
    hashed subpkt 23 len 1 (keyserver preferences: 80)
    subpkt 16 len 8 (issuer key ID 04450BED5A1D56D6)
    data: 0A8BE9D48722BD3E95F44D492A356B65A2299A670A76BD8FD2A28AFED4CA532A
    data: C25E72BEDA064CF713EC5CE7B48EB0B2BDCDAA86A30DFD7E5339B9158397F58E
% cat melvin_5a1d56d6.asc | sed 's/\[GNUPG:\].*$//' | sed 's/-----BEGIN PGP PRIVATE KEY BLOCK-----//' | sed 's/-----END PGP PRIVATE KEY BLOCK-----//' | sed 's/-----BEGIN PGP PUBLIC KEY BLOCK-----//' | sed 's/-----END PGP PUBLIC KEY BLOCK-----//' | sed 's/-----BEGIN PGP SIGNATURE-----//' | sed 's/-----END PGP SIGNATURE-----//' | sed '/^$/d' | sed '/^=.*$/d' |  tr -d '\n' | bx base64-decode | bx base16-encode
9474045ece262213052b8104000a020304d9bd493708d5e0fca62a7c86e43646595de0fec811395fb009ec811892903d49292cd48390ab0b3433753b621849b7ab20b014128d1f72fe45071d24971e3463000100ec5dcce13ea0c5f4500c315c964cdee10a055313ea71b7558200e98b1df77f380fb5b4204d656c76696e20657264203c6d656c76696e40736563686f73742e696e666f3e8890041313080038162104d5c4ad7cc2a40ca64860aca504450bed5a1d56d605025ece2622021b03050b0908070305150a09080b051602030100021e01021780000a091004450bed5a1d56d64f3a00fc0a8be9d48722bd3e95f44d492a356b65a2299a670a76bd8fd2a28afed4ca532a0100c25e72beda064cf713ec5ce7b48eb0b2bdcdaa86a30dfd7e5339b9158397f58e

1. ECCキーパッケージ(ラベル5):0x94 元のパケット: 9474045ece262213052b8104000a020304d9bd493708d5e0fca62a7c86e43646595de0fec811395fb009ec811892903d434 b7ab20b014128d1f72fe45071d24971e3463000100ec5dcce13ea0c5f4500c315c964cdee10a055313ea71b7558200e98b1df753

% エコ7 ab20b014128d1f72fe45071d24971e3463 |トイレ-c

 158 / 2 = 79 = 0x004f

$MasterFingerprintBasis =99004f045ece262213052b8104000a020304d9bd493708d5e0fca62a7c86e43646595de0fec811395fb009ec811892903d4939 b 7ab20b014128d1f72fe45071d24971e3463

2. ユーザー ID パケット (タグ 13): 0xb4 元のパケット: b4204d656c76696e20657264203c6d656c76696e40736563686f73742e696e666f3e

%エコー-n 4d656c76696e20657264203c6d656c76696e40736563686f73742e696e666f3eトイレ-c |

  64 / 2 = 32 = 0x00000020

$UserIDFingerprintBasis =b4000000204d656c76696e20657264203c6d656c76696e40736563686f73742e696e666f3e

3. ECCシグネチャパッケージ(ラベル2):0x88 元のパケット: 8890041313080038162104d5c4ad7cc2a40ca64860aca504450bed5a1d56d605025ece2622021b03050b090807030510001 780000a091004450bed5a1d56d64f3a00fc0a8be9d48722bd3e95f44d492a356b65a2299a670a76bd8fd2a28afed4ca532a4 dcdaa86a30dfd7e5339b9158397f58e

%エコー-n |

 124 / 2 = 62 = 0x0000003e

$MasterMagicBasis =041313080038162104d5c4ad7cc2a40ca64860aca504450bed5a1d56d605025ece2622021b03050b0908070305150a0908000000000 00003e

4. SHA256($MasterFingerprintBasis + $UserIDFingerprintBasis + $MasterMagicBasis)

% 에코 99004f045ece262213052b8104000a020304d9bd493708d5e0fca62a7c86e43646595de0fec811395fb009ec811892903d49292cd48390ab0b3433753b62 849b7ab20b014128d1f72fe45071d24971e3463b4000000204d656c76696e 20657264203c6d656c76696e40736563686f73742e696e666f3e04131308003 8162104d5c4ad7cc2a40ca64860aca504450bed5a1d56d605025ece2622021b03050b0908070305150a09080b051602030100021e0102178004FF0000003e |sha256 4f3a4cc1a8f4bea91ddca5688b73b9379edd80876a1b5ed47543f33939f3b7cf

5. 計算されたハッシュ値に署名します。

./btc_sign_secp256k1 -k EC5DCCE13EA0C5F4500C315C964CDEE10A055313EA71B7558200E98B1DF77F38 -m 4f3a4cc1a8f4bea93d7 543 f33939f3b7cf

 secp256k1 Uncompressed Pubkey : 04d9bd493708d5e0fca62a7c86e43646595de0fec811395fb009ec811892903d49292cd48390ab0b3433753b621849b7ab20b014128d1f72fe45071d24971e3463

 Message is binary encoded as HEX        : 4f3a4cc1a8f4bea91ddca5688b73b9379edd80876a1b5ed47543f33939f3b7cf
         secp256k1 R Signature Component : 0a8be9d48722bd3e95f44d492a356b65a2299a670a76bd8fd2a28afed4ca532a
         secp256k1 S Signature Component : 3da18d4125f9b308ec13a3184b714f4bfce132600c3aa2bd6c98a5774c9e4bb3

それでは、秘密鍵なしで計算できる補完署名を計算してみましょう。 (r1,s1) の保守署名は (r1,s2) です。ここで "s1+s2=n" で sep256k1 曲線の場合 n = FFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 です。

% エコ 3da18d4125f9b308ec13a3184b714f4bfce132600c3aa2bd6c98a5774c9e4bb3 tr "af" "AF"

3DA18D4125F9B308EC13A3184B714F4BFCE132600C3AA2BD6C98A5774C9E4BB3

%echo "obase = 16; ibase = 16;

C25E72BEDA064CF713EC5CE7B48EB0B2BDCDAA86A30DFD7E5339B9158397F58E

上記で計算されたs2値を使用すると、数学的な署名を明確にし、ビットコインのようにs1 <s2などの慣例的に正しい署名を指定する規則を選択しない限り、署名をマレーシア化できます。ビットコインの場合、これは「取引の可鍛性」の以前の形でした。 OpenPGPの場合、これはある種の「証明書の可断性」につながる可能性があり、これは複数の署名が公開鍵ブロックの一部になるとさらに悪化する。 OpenPGPの場合、相互運用性合意規則はIETF RFCに文書化されています。開発中現在、証明書のスケーラビリティに対する対策についての言及はありません。

追加情報:

下のキーは上記の秘密パケットの最後にあります。圧縮されていない公開鍵(デフォルトでは、関連する圧縮公開鍵のサイズの2倍)は示されているように計算でき、結果として公開鍵は次のように網掛けされた出力です。ㅏ%。 "-u"パラメーターを削除すると、関連する非圧縮公開鍵が強制的に計算されます。これは短い答えであり、現在GPGでは機能しません。

ㅏ%エコec5dcce13ea0c5f4500c315c964cdee10a055313ea71b7558200e98b1df77f38 |BxEUを大衆に- ゆう

04d9bd493708d5e0fca62a7c86e43646595de0fec811395fb009ec811892903d49292cd48390ab0b3433753b621849b7ab20b014128d1f72fe45071d24971e3463

第二%echo99004f045ece262213052b8104000a020304d9bd493708d5e0fca62a7c86e43646595de0fec811395fb009ec811892903d49 b7ab20b014128d1f72fe45071d24971e3463 |BxBase16デコード|シャスム-

d5c4ad7cc2a40ca64860aca504450bed5a1d56d6 -

おすすめ記事