mirror of
https://github.com/golang/go
synced 2024-11-16 15:50:22 -07:00
crypto/elliptic: store P-256 precomputed basepoint table in source
Store the precomputed P-256 basepoint table in source rather than computing it at runtime, saving ~88kB from the heap. The flip side is that this increases binary sizes by ~77kB. Fixes #44992 Change-Id: Ia5421eae87b41522b0d8cecba051cba1d2ed73db Reviewed-on: https://go-review.googlesource.com/c/go/+/315189 Run-TryBot: Roland Shoemaker <roland@golang.org> Trust: Roland Shoemaker <roland@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Filippo Valsorda <filippo@golang.org>
This commit is contained in:
parent
87e4dcd446
commit
7b32830f58
@ -17,7 +17,6 @@ package elliptic
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type (
|
||||
@ -31,9 +30,7 @@ type (
|
||||
)
|
||||
|
||||
var (
|
||||
p256 p256Curve
|
||||
p256Precomputed *[43][32 * 8]uint64
|
||||
precomputeOnce sync.Once
|
||||
p256 p256Curve
|
||||
)
|
||||
|
||||
func initP256() {
|
||||
@ -412,53 +409,7 @@ func boothW6(in uint) (int, int) {
|
||||
return int(d), int(s & 1)
|
||||
}
|
||||
|
||||
func initTable() {
|
||||
p256Precomputed = new([43][32 * 8]uint64)
|
||||
|
||||
basePoint := []uint64{
|
||||
0x79e730d418a9143c, 0x75ba95fc5fedb601, 0x79fb732b77622510, 0x18905f76a53755c6,
|
||||
0xddf25357ce95560a, 0x8b4ab8e4ba19e45c, 0xd2e88688dd21f325, 0x8571ff1825885d85,
|
||||
0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe,
|
||||
}
|
||||
t1 := make([]uint64, 12)
|
||||
t2 := make([]uint64, 12)
|
||||
copy(t2, basePoint)
|
||||
|
||||
zInv := make([]uint64, 4)
|
||||
zInvSq := make([]uint64, 4)
|
||||
for j := 0; j < 32; j++ {
|
||||
copy(t1, t2)
|
||||
for i := 0; i < 43; i++ {
|
||||
// The window size is 6 so we need to double 6 times.
|
||||
if i != 0 {
|
||||
for k := 0; k < 6; k++ {
|
||||
p256PointDoubleAsm(t1, t1)
|
||||
}
|
||||
}
|
||||
// Convert the point to affine form. (Its values are
|
||||
// still in Montgomery form however.)
|
||||
p256Inverse(zInv, t1[8:12])
|
||||
p256Sqr(zInvSq, zInv, 1)
|
||||
p256Mul(zInv, zInv, zInvSq)
|
||||
|
||||
p256Mul(t1[:4], t1[:4], zInvSq)
|
||||
p256Mul(t1[4:8], t1[4:8], zInv)
|
||||
|
||||
copy(t1[8:12], basePoint[8:12])
|
||||
// Update the table entry
|
||||
copy(p256Precomputed[i][j*8:], t1[:8])
|
||||
}
|
||||
if j == 0 {
|
||||
p256PointDoubleAsm(t2, basePoint)
|
||||
} else {
|
||||
p256PointAddAsm(t2, t2, basePoint)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *p256Point) p256BaseMult(scalar []uint64) {
|
||||
precomputeOnce.Do(initTable)
|
||||
|
||||
wvalue := (scalar[0] << 1) & 0x7f
|
||||
sel, sign := boothW6(uint(wvalue))
|
||||
p256SelectBase(p.xyz[0:8], p256Precomputed[0][0:], sel)
|
||||
|
1473
src/crypto/elliptic/p256_asm_table.go
Normal file
1473
src/crypto/elliptic/p256_asm_table.go
Normal file
File diff suppressed because it is too large
Load Diff
59
src/crypto/elliptic/p256_asm_table_test.go
Normal file
59
src/crypto/elliptic/p256_asm_table_test.go
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build amd64 || arm64
|
||||
// +build amd64 arm64
|
||||
|
||||
package elliptic
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestP256PrecomputedTable(t *testing.T) {
|
||||
|
||||
basePoint := []uint64{
|
||||
0x79e730d418a9143c, 0x75ba95fc5fedb601, 0x79fb732b77622510, 0x18905f76a53755c6,
|
||||
0xddf25357ce95560a, 0x8b4ab8e4ba19e45c, 0xd2e88688dd21f325, 0x8571ff1825885d85,
|
||||
0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe,
|
||||
}
|
||||
t1 := make([]uint64, 12)
|
||||
t2 := make([]uint64, 12)
|
||||
copy(t2, basePoint)
|
||||
|
||||
zInv := make([]uint64, 4)
|
||||
zInvSq := make([]uint64, 4)
|
||||
for j := 0; j < 32; j++ {
|
||||
copy(t1, t2)
|
||||
for i := 0; i < 43; i++ {
|
||||
// The window size is 6 so we need to double 6 times.
|
||||
if i != 0 {
|
||||
for k := 0; k < 6; k++ {
|
||||
p256PointDoubleAsm(t1, t1)
|
||||
}
|
||||
}
|
||||
// Convert the point to affine form. (Its values are
|
||||
// still in Montgomery form however.)
|
||||
p256Inverse(zInv, t1[8:12])
|
||||
p256Sqr(zInvSq, zInv, 1)
|
||||
p256Mul(zInv, zInv, zInvSq)
|
||||
|
||||
p256Mul(t1[:4], t1[:4], zInvSq)
|
||||
p256Mul(t1[4:8], t1[4:8], zInv)
|
||||
|
||||
copy(t1[8:12], basePoint[8:12])
|
||||
|
||||
if got, want := p256Precomputed[i][j*8:(j*8)+8], t1[:8]; !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("Unexpected table entry at [%d][%d:%d]: got %v, want %v", i, j*8, (j*8)+8, got, want)
|
||||
}
|
||||
}
|
||||
if j == 0 {
|
||||
p256PointDoubleAsm(t2, basePoint)
|
||||
} else {
|
||||
p256PointAddAsm(t2, t2, basePoint)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user