OpenSSLで楕円曲線暗号を使った署名を試してみました。
OpenSSLで利用できる楕円曲線
ecparam -list_curves
で利用できる楕円曲線の一覧を表示できる。
openssl ecparam -list_curves
secp112r1 : SECG/WTLS curve over a 112 bit prime field
secp112r2 : SECG curve over a 112 bit prime field
secp128r1 : SECG curve over a 128 bit prime field
secp128r2 : SECG curve over a 128 bit prime field
...
sect113r1 : SECG curve over a 113 bit binary field
sect113r2 : SECG curve over a 113 bit binary field
sect131r1 : SECG/WTLS curve over a 131 bit binary field
sect131r2 : SECG curve over a 131 bit binary field
...
ECDSAで署名の生成・検証をする
echo abcde > plain.txt
# 公開鍵・秘密鍵を生成する
openssl ecparam -genkey -name secp112r1 -out key-pair.pem
openssl ec -in key-pair.pem -outform PEM -pubout -out public.pem
openssl ec -in key-pair.pem -outform PEM -out private.pem
# 署名を生成する
openssl dgst -sha1 -sign private.pem plain.txt > signature.dat
# 生成した署名を検証する
openssl dgst -sha1 -verify public.pem -signature signature.dat plain.txt
署名のサイズ
# 署名の構造を表示する
openssl asn1parse -inform DER -in signature.dat
ここで、この112bitのECDSA署名のサイズは実行する度に34~36 byteで変化する。これは署名がDER形式でエンコードされているためである。
署名の構成要素である2つの112 bit (= 14 byte) の数値 $r$、$s$ は2の補数表現でエンコードされるため、$8^{13}-1$ より大きい場合は符号ビットを確保するために 15 byte が必要になる。
sが15byteになる場合の署名データ構造
30 21 # Sequence (0x30) が以後33バイト (0x21) 続く
02 0e # Integer (0x02) が以後14バイト (0x0e) 続く
(rのバイト列 14バイト)
02 0f # Integer (0x02) が以後15バイト (0x0f) 続く
00 (sのバイト列 14バイト) # 先頭に符号バイトが足されている