2018/01/08

ECDSAの署名+αから公開鍵を算出したい (2)

前回は、EXHAUSTIVE_TEST_ORDERの値がわからんというところで終わった。

bitcoindのソースをgrepしたが、やはり「13」のしか出てこない。
「tests_」とファイル名に付いているから、さすがに違うだろう。


少し戻って、secp256k1_scalar_set_b32()をgrepした。
githubで検索したときには出てこなかったのだが、「scalar_low_impl.h」だけでなく「scalar_4x64_impl.h」「scalar_8x32_impl.h」にも同じAPIが出てきている。

ああ、そうか。。。
ここを見逃していたのか。
https://github.com/bitcoin/bitcoin/blob/9ccafb1d7bdd172a9b963444072a844da379c4f7/src/secp256k1/src/scalar_impl.h#L17-L25

テスト時にはEXHAUSTIVE_TEST_ORDERが定義されているが、通常はUSE_SCALAR_4X64かUSE_SCALAR_8X32が使われるということだ。
config.logにマクロ名が出てきているので、configureとかで決まるのだろう。
CPUが64bitか32bitかで使い分けているのかと思ったが、uint64_tが使えるかどうかなのかもしれない。


改めて4x64の方を見てみよう。

https://github.com/bitcoin/bitcoin/blob/9ccafb1d7bdd172a9b963444072a844da379c4f7/src/secp256k1/src/scalar_4x64_impl.h#L117-L127

単に、エンディアンに考慮しながら32byteの配列をsecp256k1_scalar型に詰めているだけように見える。
overflowは・・・Gの値と見比べているのか。
楕円曲線に詳しくないのだが、Gより大きかったらGで剰余を取るという処理を作った記憶がある。



では、secp256k1_ecdsa_sign_recoverable()がやっているのはこういうことか。

  1. messageとsecretとのハッシュを取ってnonceとする(順に連結して、SHA256をcounter回実施?)
  2. nonceに値が入っていてオーバーフローもしていなければ、署名をとって4へ
  3. counterをインクリメントして、1へ
  4. 署名のr, s、recovery idを連結

意外とあっさりしているが、署名を取るときにrecovery idなるものが返ってきている。
これは、通常の署名にはない値だ。


署名を取っているsecp256k1_ecdsa_sig_sign()はこちら。

https://github.com/bitcoin/bitcoin/blob/9ccafb1d7bdd172a9b963444072a844da379c4f7/src/secp256k1/src/ecdsa_impl.h#L271-L311

geとかfeとか、よくわからん文字が出てくる。
group elementと、field elementかもしれんが、助けにならん。。


関数名からすると、これはrecovery専用というわけではなく、署名のsigrとsigsを求めるのだろう。
recidは、おまけだ。
ということは、これを実装したいとして、recidだけを別途求められるのか、あるいは署名の計算中じゃないと求められないのかがポイントとなる。

見た感じでは、sigr, sigsの処理前にも後にもrecidに代入する箇所があるので、うまいことやればrecidは自分で計算できるかもしれん。
しかし・・・それには署名計算自体を多少は理解しないと、できるかどうかもわからん。

遠い道のりだ。。。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。