signing of datablock as hash in erlang not working. Key derivation based on ec

343 views Asked by At

Erlang version: 9.2

I am trying to sign one datablock with generated keys on ecdh-base.

Here is my workflow:

86> {PublicKey, PrivKeyOut} = crypto:generate_key(ecdh, crypto:ec_curve(secp521r1)).
{<<4,0,196,6,85,178,189,234,231,13,82,152,96,162,92,163,
   133,81,42,147,168,146,138,226,15,80,127,228,...>>,
 <<1,33,215,135,89,40,35,40,104,14,217,153,78,62,53,83,
   198,165,84,30,135,159,218,82,47,102,204,...>>}
87> Mesage = "testmessage".
"testmessage"
88> Hash = crypto:hash(sha512, Mesage).
<<1,216,98,78,245,111,176,233,114,224,249,27,118,114,49,
  189,40,144,90,249,175,108,79,235,186,247,247,40,131,...>>
89> Signature = crypto:sign(ecdsa, sha512, Hash, PrivKeyOut).
** exception error: bad argument
     in function  crypto:pkey_sign_nif/5
        called as crypto:pkey_sign_nif(ecdsa,sha512,
                                       <<1,216,98,78,245,111,176,233,114,224,
                                         249,27,118,114,49,189,40,144,90,249,
                                         175,108,79,235,186,247,...>>,
                                       <<1,33,215,135,89,40,35,40,104,14,217,
                                         153,78,62,53,83,198,165,84,30,135,159,
                                         218,82,47,...>>,
                                       [])
     in call from crypto:sign/5 (crypto.erl, line 433)

What am I doing wrong?

2

There are 2 answers

1
Dániel Szoboszlay On BEST ANSWER

There are two problems with your code:

  • The 4th argument of crypto:sign/4 is called Key, but if you check the type spec, it in fact takes an [ecdh_private(), ecdh_params()] list (in case of using the ecdsa algorithm at least).
  • If you calculate the Hash yourself, the third argument shall be {digest, Hash}. Otherwise you will sign the hash of the message hash. You can also pass the plain message to the function, but in that case it has to be a binary, not a string.

This is how to fix these problems:

EcdhParams = crypto:ec_curve(secp521r1),
{PublicKey, PrivKeyOut} = crypto:generate_key(ecdh, EcdhParams),
Message = <<"testmessage">>,
crypto:sign(ecdsa, sha512, Message, [PrivKeyOut, EcdhParams]).

Or, in case you need the Hash later and/or you get Message as a string, this would also work:

EcdhParams = crypto:ec_curve(secp521r1),
{PublicKey, PrivKeyOut} = crypto:generate_key(ecdh, EcdhParams),
Message = "testmessage",
Hash = crypto:hash(sha512, Message),
crypto:sign(ecdsa, sha512, {digest, Hash}, [PrivKeyOut, EcdhParams]).
0
david On

I found old erlang bugs, these show that elliptic curve cipher suites are no completely implemented. Here URLs:

http://erlang.2086793.n4.nabble.com/Incomplete-Elliptic-Curve-Cipher-Suites-in-R16B01-and-R16B02-td4692857.html http://erlang-bugs.erlang.narkive.com/YNWGZ1F2/incomplete-elliptic-curve-cipher-suites-in-r16b01-and-r16b02

I would use the libsodium library for my tests:

https://github.com/jlouis/enacl

Thx