Bitcoinで使われる楕円曲線の鍵について、bitcoin-rubyを使って鍵交換(ECDH)と楕円曲線の加算をしてみる。
鍵共有(ECDH)
アリスとボブが持つ鍵を使って共通鍵を生成してみる。
アリスとボブはそれぞれお互いの公開鍵を知っており、秘密鍵をそれぞれa
、b
、楕円曲線のベースポイントP
とすると、
アリスの公開鍵は、
Q(a) = a*P
ボブの公開鍵は
Q(b) = b*P
となる。
この前提でアリスとボブがお互いに相手の公開鍵を自分の秘密鍵を使ってスカラー倍算する。
アリスは
a * Q(b) = ab*P
ボブは、
b * Q(a) = ba*P
楕円曲線上でab*P=ba*P
となるため、お互いが計算した値は同じ点を指す。この時アリスはa
をボブはb
を相手に公開していないので、安全に共通鍵を生成できる。
この楕円曲線を使ったDH鍵共有をbitcoin-rubyを使って書くと↓のようになる。
実際の鍵共有はffiでOpenSSLの機能を使っており、dh_compute_key
の中身はOpenSSLのC実装になる。
楕円曲線の加算
Bitcoinの取引の量を秘匿するConfidential Transactionや、Pay-to-Contractプロトコルなど楕円曲線の加法特性を利用した暗号トリックを使うケースが増えており、そんな楕円曲線の加算を行うRubyのコードを書いてみる。
アリスのBitcoinの公開鍵と秘密鍵に対して、ランダムに選択した値r
を別々に加算する。公開鍵にr
加算してできた公開鍵と、秘密鍵にr
を加算してできた秘密鍵から生成した公開鍵が同じ値になることが確認できる↓
こちらの楕円曲線の加算の実装もOpenSSLを利用。
ECDHも加算も楕円曲線の演算は全てOpenSSL側で実装されているので、Rubyはあくまでラッパーかな。Secp256k1を使った実装もあるけど、そっちも実装はlibsecp256k1なので、いずれにせよPure Rubyの実装があるわけではない。