btcec: Optimize pre-computed table load.

This commit modifies the pre-computed table used to optimize the secp256k1
scalar multiplication to a string instead of a byte slice.  This change
makes the compile more efficient since the Go compiler internally
represents bytes slices inefficiently.

This reduces the memory needed to compile btcec to 3MB versus the previous
40MB before this change.

In addition, it modifies the code which loads the pre-computed table to
deserialize directly into the table instead of into locals that are then
copied.

Fixes #297.
This commit is contained in:
Dave Collins 2015-02-11 23:10:53 -06:00
parent 15aa91514a
commit f6a437d4c9
4 changed files with 10 additions and 14 deletions

View file

@ -50,7 +50,7 @@ func main() {
fmt.Fprintln(fi, "// Auto-generated file (see genprecomps.go)")
fmt.Fprintln(fi, "// DO NOT EDIT")
fmt.Fprintln(fi)
fmt.Fprintf(fi, "var secp256k1BytePoints = []byte(%q)\n", encoded)
fmt.Fprintf(fi, "var secp256k1BytePoints = %q\n", string(encoded))
a1, b1, a2, b2 := btcec.S256().EndomorphismVectors()
fmt.Println("The following values are the computed linearly " +

View file

@ -18,7 +18,7 @@ import (
// secp256k1BytePoints are dummy points used so the code which generates the
// real values can compile.
var secp256k1BytePoints = []byte{}
var secp256k1BytePoints = ""
// getDoublingPoints returns all the possible G^(2^i) for i in
// 0..n-1 where n is the curve's bit size (256 in the case of secp256k1)

View file

@ -5,11 +5,11 @@
package btcec
import (
"bytes"
"compress/zlib"
"encoding/base64"
"encoding/binary"
"io/ioutil"
"strings"
)
//go:generate go run -tags gensecp256k1 genprecomps.go
@ -23,17 +23,14 @@ import (
func loadS256BytePoints() error {
// There will be no byte points to load when generating them.
bp := secp256k1BytePoints
if len(secp256k1BytePoints) == 0 {
if len(bp) == 0 {
return nil
}
// Decompress the pre-computed table used to accelerate scalar base
// multiplication.
decoded := make([]byte, base64.StdEncoding.DecodedLen(len(bp)))
if _, err := base64.StdEncoding.Decode(decoded, bp); err != nil {
return err
}
r, err := zlib.NewReader(bytes.NewReader(decoded))
decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(bp))
r, err := zlib.NewReader(decoder)
if err != nil {
return err
}
@ -48,7 +45,9 @@ func loadS256BytePoints() error {
for byteNum := 0; byteNum < 32; byteNum++ {
// All points in this window.
for i := 0; i < 256; i++ {
px, py, pz := new(fieldVal), new(fieldVal), new(fieldVal)
px := &bytePoints[byteNum][i][0]
py := &bytePoints[byteNum][i][1]
pz := &bytePoints[byteNum][i][2]
for i := 0; i < 10; i++ {
px.n[i] = binary.LittleEndian.Uint32(serialized[offset:])
offset += 4
@ -61,9 +60,6 @@ func loadS256BytePoints() error {
pz.n[i] = binary.LittleEndian.Uint32(serialized[offset:])
offset += 4
}
bytePoints[byteNum][i][0] = *px
bytePoints[byteNum][i][1] = *py
bytePoints[byteNum][i][2] = *pz
}
}
secp256k1.bytePoints = &bytePoints

File diff suppressed because one or more lines are too long