status-im / status-keycard

Our Javacard Implementation for making secure transactions within Status and Ethereum
Apache License 2.0
215 stars 65 forks source link

keycard returns a different signature each time #84

Closed gballet closed 2 years ago

gballet commented 2 years ago

I modified the message-signing test script to sign the same message twice:

# select the keycard applet
keycard-select
# set the secrets we had from the initialization
keycard-set-secrets 299324 894466013569 Cg3qEnS5M3XbKm7U

# pairing is usually done once per device
keycard-pair
keycard-open-secure-channel
keycard-verify-pin {{ session_pin }}
# sign a message
keycard-sign-message hello
keycard-sign-message hello
# we unpair the current device so that we don't use one of the 5 available slots.
keycard-unpair {{ session_pairing_index }}

I would expect the signature to be the same, that is not so:

> ./keycard-cli shell < _shell-commands-examples/07-sign-message.sh
Installed: true
Initialized: true
Key Initialized: true
InstanceUID: 1904a9c90cabe26ff0ed1c47119f1577
SecureChannelPublicKey: 04ee304a4cbdaa22efb5d929f0383533f40e1c60f6a12ddf000993c7ffe2ed7438222660e693aa7d121517310195fd306f2753280cc1c52d4ce7b6820b5c1fed27
Version: 0300
AvailableSlots: 04
KeyUID: 919f0926656ed6d04afd7a51b7714674457398af35644838111f2a80dabcc502
Capabilities:
  Secure channel:true
  Key management:true
  Credentials Management:true
  NDEF:true

PAIRING KEY: a90a37011fe45c5c7d1fce7e49738d7fadebae0dce169a20ff1f1c60191777ca
PAIRING INDEX: 1

SIGNATURE R: 2d1e16f733f8ca4cb79076d3589de2e0b553d0d8f0a0112e46d92e3c9b348f3b
SIGNATURE S: 19c1ae1935105a27ae036c3da0a32a5d8f58f73f45fdd4630b47bd57be5d94e8
SIGNATURE V: 0
ETH SIGNATURE: 0x2d1e16f733f8ca4cb79076d3589de2e0b553d0d8f0a0112e46d92e3c9b348f3b19c1ae1935105a27ae036c3da0a32a5d8f58f73f45fdd4630b47bd57be5d94e81b
PUBLIC KEY: 0x041dce5162349b08be9a5f5241b8b6f4857069c65d0aff9512a9e37d4c7261093152d050092e5d04fb73cddfba83add8ce84a2e80367e953be346144ed0f91b0a7
ADDRESS: 0x8D20965121Cb5d0C24728e32e755B9D7516F3458

SIGNATURE R: 060e980b43cf2afb6f5262cb1e4a6a1b393ca43a6b07ff6f7f76ecb1180c97ed
SIGNATURE S: 1b5fcb08e7fff949012b22c799443d43d9c87c3fc355da0132951cb6fb21a3be
SIGNATURE V: 1
ETH SIGNATURE: 0x060e980b43cf2afb6f5262cb1e4a6a1b393ca43a6b07ff6f7f76ecb1180c97ed1b5fcb08e7fff949012b22c799443d43d9c87c3fc355da0132951cb6fb21a3be1c
PUBLIC KEY: 0x041dce5162349b08be9a5f5241b8b6f4857069c65d0aff9512a9e37d4c7261093152d050092e5d04fb73cddfba83add8ce84a2e80367e953be346144ed0f91b0a7
ADDRESS: 0x8D20965121Cb5d0C24728e32e755B9D7516F3458

UNPAIRED

I'm wondering how that can be? Is it that it will derive a new key each time that sign is called? I haven't touched the codebase in over 2 years so I could very possibly have forgotten some details. In any case, the signature should be the same each time, though, if the signed message is the same.

I have observed the same behavior in geth with p1=0 and p2=0, so I believe the issue is in the keycard applet, or at least in the way both geth and keycard-cli understand the protocol.

willianpaixao commented 2 years ago

Hi @bitgamma could you comment on that?

bitgamma commented 2 years ago

the ECDSA algorithm is not inherenthly deterministic, since there is a value (called k) which can be generated randomly. Generating different, yet valid, signature it completely normal and expected.

Since some dApps came to rely on the fact that most implementation of ECDSA generate k in a deterministic way instead of random, we are working on a deterministic version of ECDSA as well.