mirror of
https://github.com/golang/go
synced 2024-09-29 22:34:33 -06:00
crypto/ed25519: outline NewKeyFromSeed and Sign
This allows the returned key/signature to be stack-allocated where possible.
name old time/op new time/op delta
NewKeyFromSeed-4 61.8µs ± 8% 57.2µs ±11% ~ (p=0.056 n=5+5)
Signing-4 56.6µs ± 3% 67.8µs ±38% ~ (p=1.000 n=5+5)
name old alloc/op new alloc/op delta
NewKeyFromSeed-4 64.0B ± 0% 0.0B -100.00% (p=0.008 n=5+5)
Signing-4 512B ± 0% 448B ± 0% -12.50% (p=0.008 n=5+5)
name old allocs/op new allocs/op delta
NewKeyFromSeed-4 1.00 ± 0% 0.00 -100.00% (p=0.008 n=5+5)
Signing-4 6.00 ± 0% 5.00 ± 0% -16.67% (p=0.008 n=5+5)
Change-Id: I7dc6a1b8a483c4b213f380ac7c30cefc5caca0f9
GitHub-Last-Rev: 0dd2e0f93e
GitHub-Pull-Request: golang/go#34357
Reviewed-on: https://go-review.googlesource.com/c/go/+/195980
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
39ab8db914
commit
2dfff3633b
@ -96,6 +96,13 @@ func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
|
||||
// with RFC 8032. RFC 8032's private keys correspond to seeds in this
|
||||
// package.
|
||||
func NewKeyFromSeed(seed []byte) PrivateKey {
|
||||
// Outline the function body so that the returned key can be stack-allocated.
|
||||
privateKey := make([]byte, PrivateKeySize)
|
||||
newKeyFromSeed(privateKey, seed)
|
||||
return privateKey
|
||||
}
|
||||
|
||||
func newKeyFromSeed(privateKey, seed []byte) {
|
||||
if l := len(seed); l != SeedSize {
|
||||
panic("ed25519: bad seed length: " + strconv.Itoa(l))
|
||||
}
|
||||
@ -112,16 +119,21 @@ func NewKeyFromSeed(seed []byte) PrivateKey {
|
||||
var publicKeyBytes [32]byte
|
||||
A.ToBytes(&publicKeyBytes)
|
||||
|
||||
privateKey := make([]byte, PrivateKeySize)
|
||||
copy(privateKey, seed)
|
||||
copy(privateKey[32:], publicKeyBytes[:])
|
||||
|
||||
return privateKey
|
||||
}
|
||||
|
||||
// Sign signs the message with privateKey and returns a signature. It will
|
||||
// panic if len(privateKey) is not PrivateKeySize.
|
||||
func Sign(privateKey PrivateKey, message []byte) []byte {
|
||||
// Outline the function body so that the returned signature can be
|
||||
// stack-allocated.
|
||||
signature := make([]byte, SignatureSize)
|
||||
sign(signature, privateKey, message)
|
||||
return signature
|
||||
}
|
||||
|
||||
func sign(signature, privateKey, message []byte) {
|
||||
if l := len(privateKey); l != PrivateKeySize {
|
||||
panic("ed25519: bad private key length: " + strconv.Itoa(l))
|
||||
}
|
||||
@ -161,11 +173,8 @@ func Sign(privateKey PrivateKey, message []byte) []byte {
|
||||
var s [32]byte
|
||||
edwards25519.ScMulAdd(&s, &hramDigestReduced, &expandedSecretKey, &messageDigestReduced)
|
||||
|
||||
signature := make([]byte, SignatureSize)
|
||||
copy(signature[:], encodedR[:])
|
||||
copy(signature[32:], s[:])
|
||||
|
||||
return signature
|
||||
}
|
||||
|
||||
// Verify reports whether sig is a valid signature of message by publicKey. It
|
||||
|
@ -191,6 +191,14 @@ func BenchmarkKeyGeneration(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkNewKeyFromSeed(b *testing.B) {
|
||||
seed := make([]byte, SeedSize)
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = NewKeyFromSeed(seed)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSigning(b *testing.B) {
|
||||
var zero zeroReader
|
||||
_, priv, err := GenerateKey(zero)
|
||||
@ -198,6 +206,7 @@ func BenchmarkSigning(b *testing.B) {
|
||||
b.Fatal(err)
|
||||
}
|
||||
message := []byte("Hello, world!")
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
Sign(priv, message)
|
||||
|
Loading…
Reference in New Issue
Block a user