hashgraph / hedera-sdk-js

Hedera™ Hashgraph SDK for JavaScript/TypeScript
https://docs.hedera.com/guides/docs/sdks
Apache License 2.0
277 stars 146 forks source link

ECDSA PrivateKey sometime generates less than 32 bytes raw key #1220

Closed ar-conmit closed 2 years ago

ar-conmit commented 2 years ago

Description

There are cases when the generated ECDSA private keys are with different lengths.

The full private key(with DER header) is generated fine. The raw private key sometime is 31-bytes long.

Example:

It seems the raw key is not extracted successfully, the last 00 are missing. This behaviour is observed once in a while.

If the full key is provided to the SDK, the raw key is extracted successfully: PrivateKey.fromStringECDSA('3030020100300706052b8104000a04220420a5c09853a1628353f4bd0eb6acf5d89c3a90fc2a9dc2caf44c9aabdf96640b00').toStringRaw()

-> a5c09853a1628353f4bd0eb6acf5d89c3a90fc2a9dc2caf44c9aabdf96640b00

The issue occurs only in the generation process

Steps to reproduce

Once in n times the generated raw key will be 31 bytes long

(() => {
    let tries = 0;
    setInterval(() => {
        tries++;

        const pk = PrivateKey.generateECDSA();
        const raw = pk.toStringRaw();
        const der = pk.toStringDer();

        if (raw.length < 64) {
            console.log({ try: tries, raw, der, rawLength: raw.length, derLength: der.length });
            process.exit(0);
        }
    }, 300);
})();

after some time, the following response will be printed out

{
  try: 29,
  raw: 'c1069f71c4b9755df5ca95bda49c8fcec0eb1e51576f3d0d6bedcd469e9af8',
  der: '3030020100300706052b8104000a04220420c1069f71c4b9755df5ca95bda49c8fcec0eb1e51576f3d0d6bedcd469e9af800',
  rawLength: 62, <--- 31 bytes
  derLength: 100
}

Additional context

The following change seems to fix the issue

in cryptography/ECDSAPrivateKey.js file

toBytesRaw() {
    return this._keyPair.privateKey.slice(0, 32);
}

to be

toBytesRaw() {
    const bytes = new Uint8Array(32);
    bytes.set(this._keyPair.privateKey.slice(0, 32), 0)
    return bytes;
}

Hedera network

other

Version

2.17.0

Operating system

macOS

janaakhterov commented 2 years ago

@ar-conmit Thanks for such a well documented issue. I didn't even consider that we may be only returning 31 bytes instead of 32. Since you've already put in the work to figure out what the fix should be perhaps making a PR and getting credit for it would make sense? If no that's completely fine too.