Commit graph

71 commits

Author SHA1 Message Date
Jimmy Song
6c36218ef3 Optimize ScalarMult with NAF
Use Non-Adjacent Form (NAF) of large numbers to reduce ScalarMult computation times.

Preliminary results indicate around a 8-9% speed improvement according to BenchmarkScalarMult.

The algorithm used is 3.77 from Guide to Elliptical Curve Crytography by Hankerson, et al.

This closes #3
2015-02-05 08:28:51 -06:00
Jimmy Song
95b23c293c Optimize ScalarMult using endomorphism
This implements a speedup to ScalarMult using the endomorphism available to secp256k1.

Note the constants lambda, beta, a1, b1, a2 and b2 are from here:

https://bitcointalk.org/index.php?topic=3238.0

Preliminary tests indicate a speedup of between 17%-20% (BenchScalarMult).

More speedup can probably be achieved once splitK uses something more like what fieldVal uses. Unfortunately, the prime for this math is the order of G (N), not P.

Note the NAF optimization was specifically not done as that's the purview of another issue.

Changed both ScalarMult and ScalarBaseMult to take advantage of curve.N to reduce k.
This results in a 80% speedup to large values of k for ScalarBaseMult.
Note the new test BenchmarkScalarBaseMultLarge is how that speedup number can
be checked.

This closes #1
2015-02-03 14:14:21 -06:00
John C. Vernaleo
d4d2f622b5 Fix bug and inconsistant error msg seen by lint. 2015-02-03 10:02:44 -06:00
Dave Collins
46829e8ddc Update TravisCI to use latest cover paths. 2015-02-03 09:47:09 -06:00
Dave Collins
9535058a7b Rework the pre-computed table generation and load.
This commit reworks the way that the pre-computed table which is used to
accelerate scalar base multiple is generated and loaded to make use of the
go generate infrastructure and greatly reduce the memory needed to compile
as well as speed up the compile.

Previously, the table was being generated using the in-memory
representation directly written into the file.  Since the table has a very
large number of entries, the Go compiler was taking up to nearly 1GB to
compile.  It also took a comparatively long period of time to compile.

Instead, this commit modifies the generated table to be a serialized,
compressed, and base64-encoded byte slice.  At init time, this process is
reversed to create the in-memory representation.  This approach provides
fast compile times with much lower memory needed to compile (16MB versus
1GB).  In addition, the init time cost is extremely low, especially as
compared to computing the entire table.

Finally, the automatic generation wasn't really automatic.  It is now
fully automatic with 'go generate'.
2015-02-01 03:26:51 -06:00
David Evans
f9365fd542 Update btcec.go
Updated link to SEC 2: Recommended Elliptic Curve Domain Parameters standard (URL given no longer exists).
2015-01-20 20:44:43 -05:00
Dave Collins
b362c1e464 Update to new location in README.md too. 2015-01-16 23:21:48 -06:00
Dave Collins
45d21a254c Update btcec import paths to new location. 2015-01-16 18:02:57 -06:00
Dave Collins
41317e8712 Update btcwire import paths to new location. 2015-01-16 14:00:23 -06:00
Dave Collins
da74b98565 Fix a benign race detected by the race detector.
The addition of the pre-computed values for the ScalarBaseMult
optimizations added a benign race condition since a pointer to each
pre-computed Jacobian point was being used in the call to addJacobian
instead of a local stack copy.

This resulted in the code which normalizes the field values to check for
further optimization conditions such as equal Z values to race against the
IsZero checks when multiple goroutines were performing EC operations since
they were all operating on the same point in memory.

In practice this was benign since the value was being replaced with the
same thing and thus it was the same before and after the race, but it's
never a good idea to have races.
2015-01-15 14:22:01 -06:00
Jimmy Song
ae28fe6d97 Use btcec structs instead of ecdsa structs everywhere.
This change should make it so that only btcec relies on the crypto/ecdsa package for secp256k1 math.
2014-10-12 22:36:06 -05:00
Jimmy Song
d312d47298 RecoverCompact and SignCompact now use the btcec.PrivateKey and btcec.PublicKey types.
btcwallet/rpcserver.go needs a corresponding change or else that will break.

This closes #6
2014-09-27 13:37:27 -05:00
Jimmy Song
d69442834c Optimize ScalarBaseMult
Code uses a windowing/precomputing strategy to minimize ECC math.
Every 8-bit window of the 256 bits that compose a possible scalar multiple has a complete map that's pre-computed.
The precomputed data is in secp256k1.go and the generator for that file is in gensecp256k1.go

Also fixed a spelling error in a benchmark test.

Results so far seem to indicate the time taken is about 35% of what it was before.

Closes #2
2014-09-24 19:07:58 -05:00
Dave Collins
4ca0daacc1 Add test for private key serialization.
Also move private key tests to their own file while here.
2014-08-10 16:46:46 -05:00
Dave Collins
ff095cfa8e Correct verify signature example doco link. 2014-08-10 15:16:14 -05:00
Dave Collins
c949e04246 Use testable examples and update doc.go README.md.
This commit adds an example test file so it integrates nicely with Go's
example tooling.

This allows the example output to be tested as a part of running the
normal Go tests to help ensure it doesn't get out of date with the code.
It is also nice to have the examples in one place rather than repeating it
in doc.go and README.md.

Links and information about the examples have been included in README.md in
place of the examples and doc.go has been updated accordingly.
2014-08-10 15:14:36 -05:00
Dave Collins
c4fa69d490 Use a more specific license adjective. 2014-08-10 15:12:28 -05:00
Dave Collins
a51b5f98bf Remove test coverage report refs from README.md.
This is no longer needed since the repository is now configured to work
with coveralls.io for test coverage reporting.
2014-08-10 15:10:55 -05:00
Dave Collins
cf69fbec0a Move test coverage badge to top of README.md. 2014-08-10 14:07:45 -05:00
Dave Collins
d043cea490 Add test coverage badge to README.md. 2014-08-10 14:06:28 -05:00
Dave Collins
cdc91dd9ba Setup TravisCI to report cov stats to coveralls.io. 2014-08-10 14:02:54 -05:00
Dave Collins
e6011eaa49 Add godoc reference badge to README.md. 2014-08-10 13:58:10 -05:00
Yurii Rashkovskii
b19d0a0232 Enforce low S values, by negating the value (modulo the order) if above order/2.
Reference implementation: b7bba43a14/src/key.cpp (L235-L238)

ht @oleganza
2014-07-31 22:04:14 +02:00
Dave Collins
22014931d4 goimports -w . 2014-07-02 19:39:37 -05:00
Josh Rickmar
cea5e44f2d Add Serialize method to PrivateKey.
ok @davecgh
2014-05-21 17:04:28 -05:00
Dave Collins
77c02f36ee Cleanup new code introduced by Pull Request #4.
- Keep comments to 80 cols for consistency with the rest of the code base
- Made verify a method off of Signature instead of PublicKey since one
  verifies a signature with a public key as opposed to the other way
  around
- Return new signature from Sign function directly rather than creating a
  local temporary variable
- Modify a couple of comments as recommended by @owainga
- Update sample usage in doc.go for both signing messages and verifying
  signatures

ok @owainga
2014-05-20 10:36:15 -05:00
Geert-Johan Riemer
af82a73fe4 Add tests for sign and verify. 2014-05-20 10:01:40 -05:00
Geert-Johan Riemer
ac7a367950 Add type PrivateKey, (*PrivateKey).Sign() and (*PublicKey).Verify(). 2014-05-20 09:59:29 -05:00
Josh Rickmar
1dbf389ceb Optimize public key serialization.
This change removes the internal pad function in favor a more opimized
paddedAppend function.  Unlike pad, which would always alloate a new
slice of the desired size and copy the bytes into it, paddedAppend
only appends the leading padding when necesary, and uses the builtin
append to copy the remaining source bytes.  pad was also used in
combination with another call to the builtin copy func to copy into a
zeroed byte slice.  As the slice is now created using make with an
initial length of zero, this copy can also be removed.

As confirmed by poking the bytes with the unsafe package, gc does not
zero array elements between the len and cap when allocating slices
with make().  In combination with the paddedAppend func, this results
in only a single copy of each byte, with no unnecssary zeroing, when
creating the serialized pubkeys.  This has not been tested with other
Go compilers (namely, gccgo and llgo), but the new behavior is still
functionally correct regardless of compiler optimizations.

The TestPad function has been removed as the pad func it tested has
likewise been removed.

ok @davecgh
2014-05-19 23:13:48 -05:00
Owain G. Ainsworth
e841a2e999 Make ParsePubkey reutrn a *btcec.PublicKey
Provide a fucntion on public key to get the ecdsa type without knowing
internals.
2014-04-09 19:27:56 +01:00
Owain G. Ainsworth
d0a4086e29 Add an api to get a pubkey and privkey from a privkey byte string.
ok and some tweaks from @jrick.
2014-03-25 15:10:58 +00:00
Owain G. Ainsworth
de670bd5b2 check for 0 length strings in pubkey parser.
We check length later, but we assumed it was always 1 bytes long. Not
always the case. I'm a little depressed that this bug was there.
2014-03-17 18:07:43 +00:00
Owain G. Ainsworth
ff3fac426d Add code to produce and verify compact signatures.
The format used is identical to that used in bitcoind.
2014-02-13 18:47:10 +00:00
Dave Collins
218906a91e Make the race detect happy.
Since the Z values are normalized (which ordinarily mutates them as
needed) before checking for equality, the race detector gets confused when
using a global value for the field representation of the value 1 and
passing it into the various internal arithmetic routines and reports a
false positive.

Even though the race was a false positive and had no adverse effects, this
commit silences the race detector by creating new variables at the top
level and passing them instead of the global fieldOne variable.  The
global is still used for comparison operations since those have no
potential to mutate the value and hence don't trigger the race detector.
2014-02-13 10:59:14 -06:00
Dave Collins
7427e82664 Add bench for adding Jacobian points where Z!=1. 2014-02-12 13:53:17 -06:00
David Hill
d991c18d16 gofmt 2014-02-04 16:17:45 -05:00
Dave Collins
58cab817f0 Add 2014 to copyright dates. 2014-01-08 23:51:37 -06:00
Dave Collins
2d875b39f9 Bring README.md up-to-date with the current status. 2013-12-28 15:30:33 -06:00
Dave Collins
cc712827da Add tests for pad function.
This brings the overall test coverage up to 99.88%.
2013-12-28 15:30:10 -06:00
Dave Collins
8f8eeae962 Add benchmark for adding two Jacobian points. 2013-12-26 21:52:26 -06:00
Dave Collins
e3c2b87536 Fix a comment typo. 2013-12-26 18:52:30 -06:00
Dave Collins
ab14c30fe1 Add benchmark for signature verifies. 2013-12-23 17:24:01 -06:00
Dave Collins
cd9694e9ad Add benchmarks for ScalarBaseMult and ScalarMult. 2013-12-23 16:59:47 -06:00
Dave Collins
627aeb5e9c Add support for TravisCI.
Also add TravisCI build status badge to README.md.
2013-12-23 11:43:10 -06:00
Dave Collins
bb6b277706 Add tests for new Signature.Serialize function.
This is part of the resolution for issue btcscript/#3.
2013-12-23 11:31:26 -06:00
Dave Collins
2067215193 Expose a new Serialize function on Signature type.
This commit exposes a new function named Serialize on the Signature type
which can be used to obtain a DER encoded signature.  Previously this
function was named sigDer and was part of btcscript, but as @donovanhide
pointed out in issue btcscript/#3, it really should have been part of this
package.

ok @owainga
2013-12-23 11:31:08 -06:00
Dave Collins
85ac6b06f7 Make NewFieldVal only avilable to the test package.
Since the function was only exported for use by the test package (and was
commented as such), just move it into the internal_test.go file so it is
only available when the tests run.
2013-12-20 19:19:02 -06:00
Dave Collins
ac7e4de201 Add field and point addition/multiplicaiton tests.
This commit adds 100% test coverage for the new code.  This brings the
overall btcec coverage up to 99.76%.
2013-12-20 15:09:58 -06:00
Dave Collins
9be5c5cbd9 Significantly optimize signature verification.
This commit essentially rewrites all of the primitives needed to perform
the arithmetic for ECDSA signature verification of secp256k1 signatures to
significantly speed it up.  Benchmarking has shown signature verification
is roughly 10 times faster with this commit over the previous.

In particular, it introduces a new field value which is used to perform the
modular field arithmetic using fixed-precision operations specifically
tailored for the secp256k1 prime.  The field also takes advantage of
special properties of the prime for significantly faster modular reduction
than is available through generic methods.

In addition, the curve point addition and doubling have been optimized
minimize the number of field multiplications in favor field squarings
since they are quite a bit faster.  They routines also now look for
certain assumptions such as z values of 1 or equivalent z values which
can be used to further reduce the number of multiplicaitons needed when
possible.

Note there are still quite a few more optimizations that could be done
such as using precomputation for ScalarBaseMult, making use of the
secp256k1 endomorphism, and using windowed NAF, however this work already
offers significant performance improvements.

For example, testing 10000 random signature verifications resulted in:
New btcec took 15.9821565s
Old btcec took 2m34.1016716s

Closes conformal/btcd#26.
2013-12-20 15:07:15 -06:00
Owain G. Ainsworth
95b3c063e3 remove lazy computation of QPlus1Div4 and do at init time.
Should shut up the race detector (thought this should be harmless)
2013-11-21 18:59:15 +00:00