OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / btcec / precompute.go
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 btcec
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 }