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 }