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