From 1a01f0814290eb55a62a70d64ae6919aeeaad257 Mon Sep 17 00:00:00 2001 From: Yusef Napora Date: Fri, 15 Nov 2019 13:31:26 -0500 Subject: [PATCH] use buffer pool for envelope signatures --- crypto/envelope.go | 49 +++++++++++++++++++++++++++++++++++----------- go.mod | 1 + 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/crypto/envelope.go b/crypto/envelope.go index 5474ee2a..359cf18b 100644 --- a/crypto/envelope.go +++ b/crypto/envelope.go @@ -5,6 +5,7 @@ import ( "encoding/binary" "errors" "github.com/golang/protobuf/proto" + "github.com/libp2p/go-buffer-pool" pb "github.com/libp2p/go-libp2p-core/crypto/pb" ) @@ -42,7 +43,10 @@ func MakeEnvelope(privateKey PrivKey, domain string, payloadType []byte, payload if len(domain) == 0 { return nil, errEmptyDomain } - toSign := makeSigBuffer(domain, payloadType, payload) + toSign, err := makeSigBuffer(domain, payloadType, payload) + if err != nil { + return nil, err + } sig, err := privateKey.Sign(toSign) if err != nil { return nil, err @@ -129,7 +133,10 @@ func (e *SignedEnvelope) Equals(other *SignedEnvelope) bool { // validate returns true if the envelope signature is valid for the given 'domain', // or false if it is invalid. May return an error if signature validation fails. func (e *SignedEnvelope) validate(domain string) error { - toVerify := makeSigBuffer(domain, e.payloadType, e.payload) + toVerify, err := makeSigBuffer(domain, e.payloadType, e.payload) + if err != nil { + return err + } valid, err := e.publicKey.Verify(toVerify, e.signature) if err != nil { return err @@ -141,16 +148,36 @@ func (e *SignedEnvelope) validate(domain string) error { } // makeSigBuffer is a helper function that prepares a buffer to sign or verify. -func makeSigBuffer(domain string, typeHint []byte, content []byte) []byte { - b := bytes.Buffer{} +func makeSigBuffer(domain string, payloadType []byte, payload []byte) ([]byte, error) { domainBytes := []byte(domain) - b.Write(encodedSize(domainBytes)) - b.Write(domainBytes) - b.Write(encodedSize(typeHint)) - b.Write(typeHint) - b.Write(encodedSize(content)) - b.Write(content) - return b.Bytes() + fields := [][]byte{domainBytes, payloadType, payload} + + const lengthPrefixSize = 8 + size := 0 + for _, f := range fields { + size += len(f) + lengthPrefixSize + } + + b := pool.NewBuffer(nil) + b.Grow(size) + + for _, f := range fields { + err := writeField(b, f) + if err != nil { + return nil, err + } + } + + return b.Bytes(), nil +} + +func writeField(b *pool.Buffer, f []byte) error { + _, err := b.Write(encodedSize(f)) + if err != nil { + return err + } + _, err = b.Write(f) + return err } func encodedSize(content []byte) []byte { diff --git a/go.mod b/go.mod index d9cadea8..b04fbe6d 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/golang/protobuf v1.3.1 github.com/ipfs/go-cid v0.0.3 github.com/jbenet/goprocess v0.1.3 + github.com/libp2p/go-buffer-pool v0.0.1 github.com/libp2p/go-flow-metrics v0.0.2 github.com/libp2p/go-msgio v0.0.4 github.com/libp2p/go-openssl v0.0.3