// 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))
}
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))
}
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
}
}
+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)
b.Fatal(err)
}
message := []byte("Hello, world!")
+ b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
Sign(priv, message)