Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

secp256k1: Optimize precomp value storage. #2885

Merged
merged 2 commits into from
Mar 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions dcrec/secp256k1/compressedbytepoints.go

Large diffs are not rendered by default.

11 changes: 9 additions & 2 deletions dcrec/secp256k1/genprecomps.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright 2015 The btcsuite developers
// Copyright (c) 2015-2021 The Decred developers
// Copyright (c) 2015-2022 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

Expand Down Expand Up @@ -44,7 +44,7 @@ func main() {
base64.StdEncoding.Encode(encoded, compressed.Bytes())

fmt.Fprintln(fi, "// Copyright (c) 2015 The btcsuite developers")
fmt.Fprintln(fi, "// Copyright (c) 2015-2021 The Decred developers")
fmt.Fprintln(fi, "// Copyright (c) 2015-2022 The Decred developers")
fmt.Fprintln(fi, "// Use of this source code is governed by an ISC")
fmt.Fprintln(fi, "// license that can be found in the LICENSE file.")
fmt.Fprintln(fi)
Expand All @@ -54,6 +54,13 @@ func main() {
fmt.Fprintln(fi, "// DO NOT EDIT")
fmt.Fprintln(fi)
fmt.Fprintf(fi, "var compressedBytePoints = %q\n", string(encoded))
fmt.Fprintln(fi)
fmt.Fprintln(fi, "// Set accessor to a real function.")
fmt.Fprintln(fi, "func init() {")
fmt.Fprintln(fi, " compressedBytePointsFn = func() string {")
fmt.Fprintln(fi, " return compressedBytePoints")
fmt.Fprintln(fi, " }")
fmt.Fprintln(fi, "}")

a1, b1, a2, b2 := secp256k1.EndomorphismVectors()
fmt.Println("The following values are the computed linearly " +
Expand Down
21 changes: 6 additions & 15 deletions dcrec/secp256k1/genstatics.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2014-2015 The btcsuite developers
// Copyright (c) 2015-2021 The Decred developers
// Copyright (c) 2015-2022 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

Expand All @@ -14,14 +14,9 @@ package secp256k1
// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone)

import (
"encoding/binary"
"math/big"
)

// compressedBytePoints are dummy points used so the code which generates the
// real values can compile.
var compressedBytePoints = ""

// SerializedBytePoints returns a serialized byte slice which contains all of
// the possible points per 8-bit window. This is used to when generating
// compressedbytepoints.go.
Expand All @@ -39,7 +34,7 @@ func SerializedBytePoints() []byte {

// Separate the bits into byte-sized windows.
curveByteSize := curveParams.BitSize / 8
serialized := make([]byte, curveByteSize*256*2*10*4)
serialized := make([]byte, curveByteSize*256*2*32)
offset := 0
for byteNum := 0; byteNum < curveByteSize; byteNum++ {
// Grab the 8 bits that make up this byte from doubling points.
Expand All @@ -57,14 +52,10 @@ func SerializedBytePoints() []byte {
}
point.ToAffine()

for i := 0; i < len(point.X.n); i++ {
binary.LittleEndian.PutUint32(serialized[offset:], point.X.n[i])
offset += 4
}
for i := 0; i < len(point.Y.n); i++ {
binary.LittleEndian.PutUint32(serialized[offset:], point.Y.n[i])
offset += 4
}
point.X.PutBytesUnchecked(serialized[offset:])
offset += 32
point.Y.PutBytesUnchecked(serialized[offset:])
offset += 32
}
}

Expand Down
24 changes: 12 additions & 12 deletions dcrec/secp256k1/loadprecomputed.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright 2015 The btcsuite developers
// Copyright (c) 2015-2021 The Decred developers
// Copyright (c) 2015-2022 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

Expand All @@ -8,7 +8,6 @@ package secp256k1
import (
"compress/zlib"
"encoding/base64"
"encoding/binary"
"io"
"strings"
"sync"
Expand All @@ -20,6 +19,11 @@ import (
// accelerating scalar base multiplication.
type bytePointTable [32][256][2]FieldVal

// compressedBytePointsFn is set to a real function by the code generation to
// return the compressed pre-computed values for accelerating scalar base
// multiplication.
var compressedBytePointsFn func() string

// s256BytePoints houses pre-computed values used to accelerate scalar base
// multiplication such that they are only loaded on first use.
var s256BytePoints = func() func() *bytePointTable {
Expand All @@ -38,10 +42,10 @@ var s256BytePoints = func() func() *bytePointTable {
var data *bytePointTable
mustLoadBytePoints := func() {
// There will be no byte points to load when generating them.
bp := compressedBytePoints
if len(bp) == 0 {
if compressedBytePointsFn == nil {
return
}
bp := compressedBytePointsFn()

// Decompress the pre-computed table used to accelerate scalar base
// multiplication.
Expand All @@ -64,14 +68,10 @@ var s256BytePoints = func() func() *bytePointTable {
for i := 0; i < len(bytePoints[byteNum]); i++ {
px := &bytePoints[byteNum][i][0]
py := &bytePoints[byteNum][i][1]
for i := 0; i < len(px.n); i++ {
px.n[i] = binary.LittleEndian.Uint32(serialized[offset:])
offset += 4
}
for i := 0; i < len(py.n); i++ {
py.n[i] = binary.LittleEndian.Uint32(serialized[offset:])
offset += 4
}
px.SetByteSlice(serialized[offset:])
offset += 32
py.SetByteSlice(serialized[offset:])
offset += 32
}
}
data = &bytePoints
Expand Down