ethereumjs / ethereumjs-util

Project is in active development and has been moved to the EthereumJS monorepo.
https://github.com/ethereumjs/ethereumjs-monorepo
Mozilla Public License 2.0
604 stars 274 forks source link

Error: Expected private key to be an Uint8Array #268

Closed shrpne closed 4 years ago

shrpne commented 4 years ago

With such code:

import {privateToPublic} from 'ethereumjs-util/dist/account.js';
const PRIVATE_KEY = Buffer.from('5fa3a8b186f6cc2d748ee2d8c0eb7a905a7b73de0f2c34c5e7857c3b46f187da', 'hex');
const publicKey = privateToPublic(PRIVATE_KEY);

I've got an error

Error: Expected private key to be an Uint8Array
    at assert (/node_modules/secp256k1/lib/index.js:18:20)
    at isUint8Array (/node_modules/secp256k1/lib/index.js:22:3)
    at publicKeyCreate (/node_modules/secp256k1/lib/index.js:113:7)
    at exports.privateToPublic (/node_modules/ethereumjs-util/src/account.ts:182:22)

privateToPublic want Buffer argument. And it uses publicKeyCreate which wants Uint8Array. So I can't use either Buffer or Uint8Array

My setup macOS - 10.15.6 Node - 12.16.1 ethereumjs-util - 7.0.3 secp256k1 - 4.0.2

BTW I tried to clone ethereumjs-util and run its test and everything work fine, I don't understand why.

ryanio commented 4 years ago

@shrpne do you have a script or repo to reproduce? using your code snippet works for me and I don't run into the error, it returns the publicKey fine for me.

shrpne commented 4 years ago

You can try it on my project. Try to run this test directly https://github.com/MinterTeam/minterjs-util/blob/ethereum-7/test/public.test.js#L13 or run npm run jest

If it is not suitable, then I can try to make a minimal test case later.

But I still don't understand, how such code can run without problems:

const privateToPublic = function(privateKey: Buffer): Buffer {
  assertIsBuffer(privateKey)
  publicKeyCreate(privateKey, false)
}

function publicKeyCreate (seckey, compressed = true, output) {
   isUint8Array('private key', seckey, 32)
    /* ... */
},

Because privateKey can't be a Buffer and a Uint8Array at the same time.

holgerd77 commented 4 years ago

@shrpne a Node.js Buffer is a special type of Uint8Array and actually inherits from the Uint8Array class, see e.g. this explanation.

You can test this e.g. with the following code snippet in ts-node:

> let t = Buffer.alloc(0)
undefined
> t
<Buffer >
> Buffer.isBuffer(t)
true
> t instanceof Uint8Array
true

This is also the code executed in the assertions from the function calls in your example above.

shrpne commented 4 years ago

Thank you for clarification

Looks like it is an issue with jest-environment-jsdom@26, which is a part of the latest jest https://github.com/facebook/jest/issues/7780#issuecomment-669828353

holgerd77 commented 4 years ago

Ok, will close here.

kumavis commented 3 years ago

@holgerd77 could this be Buffer.isBuffer(buf) instead of an instanceof check, for duck typing?

kumavis commented 3 years ago

i worked around this by adding jest-environment-jsdom@25 as a dev dep

holgerd77 commented 3 years ago

@kumavis did a bit of a first read on duck typing - e.g. https://realpython.com/lessons/duck-typing/ - but have no great experience with the concept. Please just open a new issue if you think this is worth a change to make (everyone else of course as well).