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