// Sign creates a signature on the hash under the given secret key. func Sign(sk *eckey.SecretKey, hash []byte) (*Signature, error) { // Generate random nonce nonce: k, kG, err := eckey.GenerateKeyPair() if err != nil { return nil, err } // Try again if kG is nil (point at infinity) if kG == nil { goto nonce } // Clear nonce after completion defer k.Zero() // Compute non-interactive challenge e := util.Hash256d(append([]byte(hash), kG[:]...)) kInt := new(big.Int).SetBytes(k[:]) eInt := new(big.Int).SetBytes(e[:]) rInt := new(big.Int).SetBytes(sk[:]) // Compute s = k - er s := new(big.Int) s.Mul(eInt, rInt) s.Sub(kInt, s) s.Mod(s, eckey.S256.N) // Serialize signature sig := new(Signature) copy(sig[:SignatureSize/2], e[:]) util.PaddedCopy(sig[SignatureSize/2:], s.Bytes(), SignatureSize/2) return sig, nil }
func BenchmarkSign(b *testing.B) { for i := 0; i < b.N; i++ { msg := []byte("Super short message") sk, _, _ := eckey.GenerateKeyPair() b.StartTimer() Sign(sk, msg) b.StopTimer() } }