Skip to content

Commit

Permalink
Reuse buffer when possible for salsa20 cipher.
Browse files Browse the repository at this point in the history
  • Loading branch information
cyfdecyf committed Apr 26, 2015
1 parent c045c82 commit 67ddbe4
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 12 deletions.
35 changes: 25 additions & 10 deletions shadowsocks/encrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ package shadowsocks

import (
"bytes"
"golang.org/x/crypto/blowfish"
"golang.org/x/crypto/cast5"
"golang.org/x/crypto/salsa20/salsa"
"crypto/aes"
"crypto/cipher"
"crypto/des"
Expand All @@ -13,6 +10,9 @@ import (
"crypto/rc4"
"encoding/binary"
"errors"
"golang.org/x/crypto/blowfish"
"golang.org/x/crypto/cast5"
"golang.org/x/crypto/salsa20/salsa"
"io"
)

Expand Down Expand Up @@ -139,20 +139,35 @@ func newRC4MD5Stream(key, iv []byte, _ DecOrEnc) (cipher.Stream, error) {
}

type salsaStreamCipher struct {
nonce [8]byte
key [32]byte
nonce [8]byte
key [32]byte
counter int
}

func (c *salsaStreamCipher) XORKeyStream(dst, src []byte) {
var buf []byte
padLen := c.counter % 64
dataSize := len(src) + padLen
if cap(dst) >= dataSize {
buf = dst[:dataSize]
} else if leakyBufSize >= dataSize {
buf = leakyBuf.Get()
defer leakyBuf.Put(buf)
buf = buf[:dataSize]
} else {
buf = make([]byte, dataSize)
}

var subNonce [16]byte
padlen := c.counter % 64
buf := make([]byte, padlen+len(src))
copy(buf[padlen:], src[:])
copy(subNonce[:], c.nonce[:])
binary.LittleEndian.PutUint64(subNonce[len(c.nonce):], uint64(c.counter / 64))
binary.LittleEndian.PutUint64(subNonce[len(c.nonce):], uint64(c.counter/64))

// It's difficult to avoid data copy here. src or dst maybe slice from
// Conn.Read/Write, which can't have padding.
copy(buf[padLen:], src[:])
salsa.XORKeyStream(buf, buf, &subNonce, &c.key)
copy(dst, buf[padlen:])
copy(dst, buf[padLen:])

c.counter += len(src)
}

Expand Down
4 changes: 2 additions & 2 deletions shadowsocks/leakybuf.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ type LeakyBuf struct {
freeList chan []byte
}

const bufSize = 4096
const leakyBufSize = 4096
const maxNBuf = 2048

var leakyBuf = NewLeakyBuf(maxNBuf, bufSize)
var leakyBuf = NewLeakyBuf(maxNBuf, leakyBufSize)

// NewLeakyBuf creates a leaky buffer which can hold at most n buffer, each
// with bufSize bytes.
Expand Down

0 comments on commit 67ddbe4

Please sign in to comment.