RubyのOpenSSLバインディングのOpenSSL::PKey::EC::Point#mulまわりがひどい(?)

Rubyは素晴らしい言語です(以下、自分でRubyに貢献もせずに好き放題言う上での事前の言い訳)

先日から、Bitcoinで遊んでいて、その関係でOpenSSLの楕円曲線(EC)暗号まわりをいじっていたが、RubyでOpenSSLのECDSAを使おうという人があまりいないのか、わりとひどい。

OpenSSLのECで、秘密鍵から公開鍵を生成するには一般にはEC_POINT_mulが用いられる(Satoshi Nakamotoのコードでもこれを用いて秘密鍵から公開鍵を生成している)が、Rubyには長らくmulすら存在していなかった。

EC_POINT_mul(ecdsa->group, new_public_key, private_key, NULL, NULL, ctx);

でも実際に過去にRubyBitcoinクライアントを書いている人はいて、じゃあどうしているかというと鍵の再生成の時だけFFIで自前でOpenSSLのAPIを叩いていて、なんというworkaround…(そんなきたない事してないで後の人のためにRuby本体にコミットしてよ!!!)

で、2.0.0ぐらいで追加されたmulを使おうとするも、mulのコードを読んでも、どうやれば上のごく簡単なCコードと同等の記述ができるのかわからない(というかbn2だけ渡してbn1をNULLにする、ってことができない時点でAPIの引数のマップの仕方がおかしい気がする)。というか全体的にバインディングのコードが怪しい。

で、挙句の果てにかなり基本的なコードでセグフォすることを発見してしまった!

require 'openssl'
OpenSSL::PKey::EC::Point.new(OpenSSL::PKey::EC.new('secp256k1').group).mul([], [], OpenSSL::BN.new("00", 16))

Bitcoinの本質からは大脱線なので、「Bitcoinのしくみ」が書き終わってからバグレポートなりパッチなりをアレするなりしようと思いますが、かなりぐぬぬ…ってなりましたし、えっ、RubyでECDSAで電子署名したくなる、って現代においてそんなマイナーな行為なんですか…?