Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix isPoint inconsistency with native library #28

Merged
merged 6 commits into from
Nov 30, 2018
Merged

fix isPoint inconsistency with native library #28

merged 6 commits into from
Nov 30, 2018

Conversation

dcousens
Copy link
Contributor

@dcousens dcousens commented Nov 20, 2018

Two things:

  • We need more tests (adding in this PR)
  • We need to be ensuring external modules run their unit tests in both a native and forced JS environment

The elliptic point that passes with isPoint, throws immediately in decodeFrom (and therefore isn't usable for any ECDSA operations).

@dcousens
Copy link
Contributor Author

(note: this is not a fix for #6)

@fanatid
Copy link
Member

fanatid commented Nov 20, 2018

@dcousens any idea why elliptic throws error? code in library looks valid, but this is not work... (y**0.5)**2 != y (?)

  var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b);
  var y = y2.redSqrt();
  if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
    throw new Error('invalid point');

@dcousens
Copy link
Contributor Author

dcousens commented Nov 20, 2018

@fanatid the tl;dr is we used to have curve.validate AND ECPoint.decodeFrom, but secp256k1 native doesn't have the two, it merges them.

elliptic does equivalent to curve.validate... in decodeFrom.
We weren't doing a curve.validate with our optimized isPoint.
That optimization is leading to this differentiation, for isPoint.

See https://github.com/bitcoinjs/bitcoinjs-lib/blob/f4caaf42e7b58332d74c1540f88bcda7e55b82e6/src/hdnode.js#L107-L112

@fanatid
Copy link
Member

fanatid commented Nov 20, 2018

Just realized that sqrt can give 2 numbers, so probably valid code should be:

  var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b);
  var y2c = y2.redSqrt().redSqr();
  if (y2c.redSub(y2).cmp(this.zero) !== 0 && y2c.redNeg().redSub(y2).cmp(this.zero) !== 0)
    throw new Error('invalid point');

@dcousens does this fix make sense? should we fix elliptic?

@dcousens
Copy link
Contributor Author

@fanatid elliptic throws invalid point because the point is not on the curve?

@fanatid
Copy link
Member

fanatid commented Nov 20, 2018

I have no idea currently what give to us check (y^0.5)^2 = y (which generate invalid point error) in current code...

@dcousens
Copy link
Contributor Author

dcousens commented Nov 20, 2018

Added two failing cases in 83ce5e4 - I intend to follow up with more tests, but this seems OK for patch?
@junderw @jprichardson

@dcousens
Copy link
Contributor Author

Any review?

Copy link
Member

@junderw junderw left a comment

Choose a reason for hiding this comment

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

LGTM

@junderw junderw merged commit 8c400b8 into master Nov 30, 2018
@dcousens dcousens deleted the fixme branch November 30, 2018 03:21
@dcousens dcousens mentioned this pull request Nov 30, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants