標数が 0 じゃないとか言われると身震いして漏らしちゃうんだけど

ECC を OpenSSL 1.0.0d で試した。

パラメータの処理は ecparam でおこなう。パラメータ (曲線) を選ぶ必要があるが、選択肢は以下で表示。

$ openssl ecparam -list_curves | head -n 10
  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
  secp160k1 : SECG curve over a 160 bit prime field
  secp160r1 : SECG curve over a 160 bit prime field
  secp160r2 : SECG/WTLS curve over a 160 bit prime field
  secp192k1 : SECG curve over a 192 bit prime field
  secp224k1 : SECG curve over a 224 bit prime field
  secp224r1 : NIST/SECG curve over a 224 bit prime field

パラメータを作るのは

$ openssl ecparam -name secp160k1 | tee param.pem
-----BEGIN EC PARAMETERS-----
BgUrgQQACQ==
-----END EC PARAMETERS-----

パラメータを使って秘密鍵作るのは

$ openssl ecparam -noout -genkey < param.pem | tee private.pem
-----BEGIN EC PRIVATE KEY-----
MFACAQEEFMy8sXl7dXe0akXPJdVBF7MbwoAJoAcGBSuBBAAJoSwDKgAE73OY1iML
wUgxwFl6SiTHFLSxcsDLxptKGEEjGGvCbexyeMhIMeh1Gw==
-----END EC PRIVATE KEY-----

だけど、一辺に作ってもいい

$ openssl ecparam -name secp160k1 -genkey
-----BEGIN EC PARAMETERS-----
BgUrgQQACQ==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MFACAQEEFJZPSZiYj12XrLmsHtRslPcda7JfoAcGBSuBBAAJoSwDKgAEzG0UU2fs
0qh/9g5wUzDZ2GghN2esmI/0RCd5I92ooc+453pqWZ9N+A==
-----END EC PRIVATE KEY-----

公開鍵は ec で作れる

$ openssl ec -pubout < private.pem | tee public.pem
read EC key
writing EC key
-----BEGIN PUBLIC KEY-----
MD4wEAYHKoZIzj0CAQYFK4EEAAkDKgAE73OY1iMLwUgxwFl6SiTHFLSxcsDLxptK
GEEjGGvCbexyeMhIMeh1Gw==
-----END PUBLIC KEY-----

公開鍵を使うのに pkeyutl というのがあり、楕円の場合 sign/verify と derive (鍵共有) が用意されてる。平文を作る。

$ cat > plain.txt
This is a plain text.
$

これを署名するとデータができる。

$ openssl pkeyutl -sign -in plain.txt -inkey private.pem -out signature.dat -pkeyopt digest:sha256
$ od -t x1 signature.dat
0000000 30 2c 02 14 65 52 51 50 2e 29 9e dd 31 bb fb 8c
0000020 8f b5 1e f8 2b 89 7f a1 02 14 7b 84 4a b4 af 54
0000040 19 fa b0 7c 23 34 63 a9 c1 2c 1b c0 c8 65
0000056

検証も pkeyutl で

$ openssl pkeyutl -verify -in plain.txt -sigfile signature.dat -pubin -inkey public.pem
Signature Verified Successfully

改竄されてたら失敗する

$ cat > plein.txt
This is a plein text.
$ openssl pkeyutl -verify -in plein.txt -sigfile signature.dat -pubin -inkey public.pem
Signature Verification Failure

鍵共有は -derive で。まずはもう一つ鍵を作る。

$ openssl ecparam -name secp160k1 -genkey > newkey.pem

で、さっきの公開鍵が相手の公開鍵だと思うことにして、

$ openssl pkeyutl -derive -inkey newkey.pem -peerkey public.pem | od -t x1
0000000 97 de 38 c0 2a 0e 17 89 f3 45 3a 7c 7c b6 b6 2c
0000020 b7 1f ca c6
0000024

と、160 bits = 20 bytes の列が生成される。これでいい、のかな?