bitpay / bitauth

Authenticate with web services utilizing the same strategy as Bitcoin.
MIT License
497 stars 171 forks source link

using secp256k1-node v3.0.0 #60

Open fanatid opened 8 years ago

fanatid commented 8 years ago

Some optimizations with secp256k1-node v3.0.0 (hope will be available soon).

  1. I totally don't understand verifySignature and validateSin callback pattern. Why not just throw error or return boolean? All operations are synchronous.
  2. Why you don't use ECIES? With integrated encryption BitAuth can be used with HTTP.
fanatid commented 8 years ago

Updated!

braydonf commented 8 years ago

Interesting that bitauth-browserify.js and bitauth-node.js are now longer needed.

gabegattis commented 8 years ago

@fanatid I was looking at this last night in attempt to get bitauth updated to v3.2.2 of the bindings. Most of it looks pretty good, but there is one problem.

secp256k1-node now returns false when verifying signatures with high s values. This is a problem for us. The bitauth spec does not require the strict signature style found in BIP0062.

We have BitPay api clients in a number of different languages. I looked at a few, (C#, ruby, php), and they don't do any kind of s value checking. If we started verifying signatures with the new bindings, lots of api requests to bitpay.com would fail signature validation.

Is it possible to add an additional api to the bindings to do non-strict signature verification? I would prefer not to have to normalize all signatures in order to verify them.

As I understand it, we would also want to use secp256k1.signatureImportLax() instead of secp256k1.signatureImport() in order to handle non-DER signatures.

fanatid commented 8 years ago

@gabegattis it is possible add additional api method, but I do not want to do this, because bitcoin-core/secp256k1 doesn't have this and as result I will have to make something that did with ecdh.

So answer is no, we should use normalize and then verify :)

gabegattis commented 8 years ago

Ok. I will guess I will need to do some testing with normalization. Do you have any concept of the computational cost for normalizing/verifying a signature compared to just verifying an already-normalized sig? I will make some benchmarks at some point.

fanatid commented 8 years ago

@gabegattis normalize is very-very fast:

const bindings = require('./bindings')

const priv = Buffer.from('c26848a3a9b8c60ba6757d6e3c8baa0a0ded80887510b4eebc0980db74415684', 'hex')
const pub = bindings.publicKeyCreate(priv)
const msg = Buffer.from('3dc81fd01b4b8b23e1c92cb461b5752d76bad4d990b9f4d591ff7fc77d4b8419', 'hex')
const sig = bindings.sign(msg, priv).signature

console.time('verify')
for (let i = 0; i < 10000; ++i) { bindings.verify(msg, sig, pub) }
console.timeEnd('verify')

console.time('normialize')
for (let i = 0; i < 10000; ++i) { bindings.signatureNormalize(sig) }
console.timeEnd('normialize')

on my machine:

verify: 1936.436ms
normialize: 20.875ms

verify -- ~5000 ops/s normalize -- ~500000 ops/s

gabegattis commented 8 years ago

That is good news then. I just tried my own benchmark as well, but using a high s value sig. I got similar results. Normalizing is about 100 times faster than verifying.