Skip to content
This repository was archived by the owner on Sep 10, 2024. It is now read-only.

Conversation

@mvayngrib
Copy link

@mvayngrib mvayngrib commented Sep 20, 2023

todo: verify correctness 😛

@mvayngrib mvayngrib changed the base branch from master to exodus September 20, 2023 20:23
@mvayngrib mvayngrib marked this pull request as draft September 20, 2023 20:23
@alexandrius
Copy link

alexandrius commented Dec 5, 2023

All tests are successful.

Test Results
yarn test
yarn run v1.19.1
$ standard && mocha


  hdkey
    + fromMasterSeed
      ✓ should properly derive the chain path: m
      ✓ should properly derive the chain path: m/0'
      ✓ should properly derive the chain path: m/0'/1
      ✓ should properly derive the chain path: m/0'/1/2'
      ✓ should properly derive the chain path: m/0'/1/2'/2
      ✓ should properly derive the chain path: m/0'/1/2'/2/1000000000
      ✓ should properly derive the chain path: m
      ✓ should properly derive the chain path: m/0
      ✓ should properly derive the chain path: m/0/2147483647'
      ✓ should properly derive the chain path: m/0/2147483647'/1
      ✓ should properly derive the chain path: m/0/2147483647'/1/2147483646'
      ✓ should properly derive the chain path: m/0/2147483647'/1/2147483646'/2
      > m toJSON() / fromJSON()
        ✓ should return an object read for JSON serialization
      > m/0' toJSON() / fromJSON()
        ✓ should return an object read for JSON serialization
      > m/0'/1 toJSON() / fromJSON()
        ✓ should return an object read for JSON serialization
      > m/0'/1/2' toJSON() / fromJSON()
        ✓ should return an object read for JSON serialization
      > m/0'/1/2'/2 toJSON() / fromJSON()
        ✓ should return an object read for JSON serialization
      > m/0'/1/2'/2/1000000000 toJSON() / fromJSON()
        ✓ should return an object read for JSON serialization
      > m toJSON() / fromJSON()
        ✓ should return an object read for JSON serialization
      > m/0 toJSON() / fromJSON()
        ✓ should return an object read for JSON serialization
      > m/0/2147483647' toJSON() / fromJSON()
        ✓ should return an object read for JSON serialization
      > m/0/2147483647'/1 toJSON() / fromJSON()
        ✓ should return an object read for JSON serialization
      > m/0/2147483647'/1/2147483646' toJSON() / fromJSON()
        ✓ should return an object read for JSON serialization
      > m/0/2147483647'/1/2147483646'/2 toJSON() / fromJSON()
        ✓ should return an object read for JSON serialization
    - privateKey
      ✓ should throw an error if incorrect key size
    - publicKey
      ✓ should throw an error if incorrect key size
      ✓ should not throw if key is 33 bytes (compressed)
      ✓ should not throw if key is 65 bytes (not compressed)
    + fromExtendedKey()
      > when private
        ✓ should parse it
      > when public
        ✓ should parse it
        ✓ should parse it without verification
    > when signing
      ✓ should work
    > when deriving public key
      ✓ should work
    > when private key integer is less than 32 bytes
      ✓ should work
    HARDENED_OFFSET
      ✓ should be set
    > when private key has leading zeros
      ✓ will include leading zeros when hashing to derive child
    > when private key is null
      ✓ privateExtendedKey should return null and not throw
     - when the path given to derive contains only the master extended key
      ✓ should return the same hdkey instance
     - when the path given to derive does not begin with master extended key
      ✓ should throw an error
    - after wipePrivateData()
      ✓ should not have private data
      ✓ should have correct data
      ✓ should be able to verify signatures
      ✓ should not throw if called on hdkey without private data
    Deriving a child key does not mutate the internal state
      ✓ should not mutate it when deriving with a private key
      ✓ should not mutate it when deriving without a private key


  45 passing (107ms)

✨  Done in 1.05s.

@mvayngrib Do you think we need to add more test cases?

@alexandrius
Copy link

alexandrius commented Dec 5, 2023

The change assumes correctness of @bitcoinerlab/secp256k1, HDKey's API is tested public and private keys. We can add some tests there.

I'd add create separate tests for @exodus/secp256k1 vs @bitcoinerlab/secp256k1.

publicKeyVerify ~> isPoint
publicKeyConvert ~> pointCompress
privateKeyTweakAdd ~> privateAdd
publicKeyTweakAdd ~> pointAddScalar
ecdsaSign ~> sign
ecdsaVerify ~> verify
privateKeyVerify ~> isPrivate
publicKeyCreate ~> pointFromScalar

Will update more later.

cc @andrejborstnik

@RyanZim Can you also chime in here?

@RyanZim
Copy link

RyanZim commented Dec 6, 2023

In reviewing the tests here, one thing that sticks out is the publicKey API. It would be great to have actual data correctness checks added here, to verify that the resulting public key is properly compressed/left compressed:

hdkey/test/hdkey.test.js

Lines 61 to 76 in 472ee65

it('should not throw if key is 33 bytes (compressed)', function () {
var priv = secureRandom.randomBuffer(32)
var pub = curve.G.multiply(BigInteger.fromBuffer(priv)).getEncoded(true)
assert.equal(pub.length, 33)
var hdkey = new HDKey()
hdkey.publicKey = pub
})
it('should not throw if key is 65 bytes (not compressed)', function () {
var priv = secureRandom.randomBuffer(32)
var pub = curve.G.multiply(BigInteger.fromBuffer(priv)).getEncoded(false)
assert.equal(pub.length, 65)
var hdkey = new HDKey()
hdkey.publicKey = pub
})
})

These test additions ideally should be contributed to upstream and backported here.

@alexandrius
Copy link

Added more fixtures, point compression test.

@mvayngrib Should I mark "Ready for review"?
Also could you update the head?

Copy link

@headfire94 headfire94 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK, i rely on unit tests here)

@mvayngrib mvayngrib marked this pull request as ready for review January 10, 2024 18:04
@mvayngrib
Copy link
Author

Also could you update the head?

@alexandrius is this PR behind the exodus branch?

@alexandrius
Copy link

@mvayngrib sorry I meant PR description

package.json Outdated
{
"name": "@exodus/hdkey",
"version": "2.1.0-exodus.0",
"version": "2.1.1-exodus.1",
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's not bundle this in with these changes, reverted e1b5ed9

"private": "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j"
},
{
"seed": "69afbf0608755b3480ca7314c145695c64f973c988790eabb165d19809c7991acecfe4518b1456f274e171d496ddd044942278577b6efcdb69a6374d5341ea0a",
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexandrius what did u use to generate these?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted from:
src/_local_modules/keys/derive.js createKeyAccess

Copy link

@RyanZim RyanZim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick utACK; did not verify correctness.

Can we get these new tests contributed to upstream?

@mvayngrib
Copy link
Author

mvayngrib commented Jan 10, 2024

I'd add create separate tests for @exodus/secp256k1 vs @bitcoinerlab/secp256k1.

publicKeyVerify ~> isPoint
publicKeyConvert ~> pointCompress
privateKeyTweakAdd ~> privateAdd
publicKeyTweakAdd ~> pointAddScalar
ecdsaSign ~> sign
ecdsaVerify ~> verify
privateKeyVerify ~> isPrivate
publicKeyCreate ~> pointFromScalar

comparing the two libs, they all look correct to me (the "tweak" methods are in-place vs immutable, but the way we use them it doesn't matter). @alexandrius did u still want to add unit tests for these?

@alexandrius
Copy link

@mvayngrib I don't think we need anything else, it was quick initial thought

@alexandrius
Copy link

@RyanZim will do

@mvayngrib
Copy link
Author

@mvayngrib I don't think we need anything else, it was quick initial thought

for something this core/sensitive, i think u had the right idea when u said to add them 😅

@alexandrius
Copy link

for something this core/sensitive, i think u had the right idea when u said to add them 😅

I can backport tests to previous version. I did on my end was successful

@alexandrius
Copy link

Should we go ahead with merge and publish?

@alexandrius
Copy link

@RyanZim BTW created pull request to upstream
cryptocoinjs#60

@mvayngrib
Copy link
Author

I can backport tests to previous version. I did on my end was successful

sorry, not following. I mean can we add some unit tests for the underlying functions u listed here #1 (comment)

@alexandrius
Copy link

@mvayngrib I can but I don't think we should do that since we also have this: ExodusMovement/secp256k1-node#1

@mvayngrib
Copy link
Author

ah, so the unit tests there will make sure those methods match correctly? sgtm

@mvayngrib
Copy link
Author

@alexandrius sorry, maybe i'm getting confused. With that PR, why do we even need this one?

@alexandrius
Copy link

@mvayngrib when this PR was created I think we thought only this PR would be enough to match perf. Another point is to incrementally jump on noble

@mvayngrib
Copy link
Author

could u walk me through the plan, is it this?

  1. finish unit tests in that PR to make us comfortable with this PR
  2. merge + release + use this
  3. sometime later, revert this and use that PR instead?

@alexandrius
Copy link

alexandrius commented Jan 15, 2024

@mvayngrib basically yes. Except swap 1st and 2nd steps. We have all tests to check hdkey correctness comparing the methods above do not belong in here

@mvayngrib
Copy link
Author

as long as we don't ship this to users before we have that unit test suite, i'm okay with it

@alexandrius
Copy link

@mvayngrib without that PR we won't be able to ship to users anyway.
However I would argue testing those methods do not belong here anyway since we have hdkey correctness checks

@alexandrius alexandrius merged commit a9882d7 into exodus Jan 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants