github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/btcec/precompute.go (about)

     1  // Copyright 2015 The btcsuite developers
     2  // Copyright (c) 2016 The Dash developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package btcec
     7  
     8  import (
     9  	"compress/zlib"
    10  	"encoding/base64"
    11  	"encoding/binary"
    12  	"io/ioutil"
    13  	"strings"
    14  )
    15  
    16  //go:generate go run -tags gensecp256k1 genprecomps.go
    17  
    18  // loadS256BytePoints decompresses and deserializes the pre-computed byte points
    19  // used to accelerate scalar base multiplication for the secp256k1 curve.  This
    20  // approach is used since it allows the compile to use significantly less ram
    21  // and be performed much faster than it is with hard-coding the final in-memory
    22  // data structure.  At the same time, it is quite fast to generate the in-memory
    23  // data structure at init time with this approach versus computing the table.
    24  func loadS256BytePoints() error {
    25  	// There will be no byte points to load when generating them.
    26  	bp := secp256k1BytePoints
    27  	if len(bp) == 0 {
    28  		return nil
    29  	}
    30  
    31  	// Decompress the pre-computed table used to accelerate scalar base
    32  	// multiplication.
    33  	decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(bp))
    34  	r, err := zlib.NewReader(decoder)
    35  	if err != nil {
    36  		return err
    37  	}
    38  	serialized, err := ioutil.ReadAll(r)
    39  	if err != nil {
    40  		return err
    41  	}
    42  
    43  	// Deserialize the precomputed byte points and set the curve to them.
    44  	offset := 0
    45  	var bytePoints [32][256][3]fieldVal
    46  	for byteNum := 0; byteNum < 32; byteNum++ {
    47  		// All points in this window.
    48  		for i := 0; i < 256; i++ {
    49  			px := &bytePoints[byteNum][i][0]
    50  			py := &bytePoints[byteNum][i][1]
    51  			pz := &bytePoints[byteNum][i][2]
    52  			for i := 0; i < 10; i++ {
    53  				px.n[i] = binary.LittleEndian.Uint32(serialized[offset:])
    54  				offset += 4
    55  			}
    56  			for i := 0; i < 10; i++ {
    57  				py.n[i] = binary.LittleEndian.Uint32(serialized[offset:])
    58  				offset += 4
    59  			}
    60  			for i := 0; i < 10; i++ {
    61  				pz.n[i] = binary.LittleEndian.Uint32(serialized[offset:])
    62  				offset += 4
    63  			}
    64  		}
    65  	}
    66  	secp256k1.bytePoints = &bytePoints
    67  	return nil
    68  }