Pay attention how to get @ref{Sources, development source code}.
@table @asis
-@item Nonce and identity encryption
- @url{http://www.cix.co.uk/~klockstone/xtea.pdf, XTEA}.
+@item Nonce and identity obfuscation
+ @url{https://blake2.net/, BLAKE2b-MAC}.
@item Data encryption
@url{http://cr.yp.to/snuffle.html, Salsa20}.
@item Message authentication
@url{http://theory.lcs.mit.edu/~cis/pubs/rivest/fusion.ps,
All-Or-Nothing-Transformed} (based on
@url{http://cseweb.ucsd.edu/~mihir/papers/oaep.html, OAEP} using
- Salsa20 with @url{https://blake2.net/, BLAKE2b-256} based
+ Salsa20 with BLAKE2b-256 based
@url{http://crypto.stanford.edu/~dabo/abstracts/saep.html, SAEP+}
checksums) data with 128-bits of feeded random.
@item Packet overhead
In this mode each outgoing packet became larger on 4128 bytes and
@ref{Noise, noise} is forcefully enabled. So this is resource hungry mode!
-@strong{Beware}: by default packet serial numbers are still processed
-through the XTEA encryption. It is not required for confidentiality and
-security, but for randomizing some parts of the traffic to make it
-indistinguishable from the noise, for making it more DPI-proof. It
-safely can be disabled, turned off or maybe its keys even can be
-revealed without security and forward secrecy loss.
-
See @code{govpn/cnw} and @code{govpn/aont} packages for details of AONT
and chaffing operations.
@verbatiminclude handshake.utxt
-Each handshake message ends with so called @code{IDtag}: it is an XTEA
-encrypted first 64 bits of each message with client's @ref{Identity} as
-a key. It is used to transmit identity and to mark packet as handshake
-message.
+Each handshake message ends with so called @code{IDtag}: it is
+BLAKE2b-MAC of the first 64 bits of the handshake message, with client's
+@ref{Identity} used as a key. It is used to transmit identity and to
+mark packet as handshake message.
If @ref{Noise, noise} is enabled, then data is padded to fill up packet
to MTU's size.
@item Опциональная возможность использовать syslog для журналирования,
с @url{https://tools.ietf.org/html/rfc5424, RFC 5424}-похожими
структурированными записями.
+@item XTEA алгоритм больше не используется для обфускации nonce. Вместо
+него BLAKE2b-MAC. Теперь нешифрованный режим действительно не зависит
+от алгоритмов шифрования.
@end itemize
@node Релиз 5.7
@item Optional ability to use syslog for logging, with
@url{https://tools.ietf.org/html/rfc5424, RFC 5424}-like
structured records.
+@item XTEA algorithm is not used anymore for nonce obfuscation.
+BLAKE2-MAC is used instead. Encryptionless mode now really does not
+depend on encryption functions.
@end itemize
@node Release 5.7
| |
| +--< DATA || PAD [|| ZEROS]
|
- +--< PRP(PRP_KEY, SERIAL)
+ +--< MAC(MAC_KEY, SERIAL)
@end verbatim
@code{SERIAL} is message's serial number. Odds are reserved for
client (to server) messages, evens for server (to client) messages.
-@code{PRP} is XTEA block cipher algorithm used here as PRP (pseudo
-random permutation function) to obfuscate @code{SERIAL}. Plaintext
-@code{SERIAL} state is kept in peers internal state, but encrypted
-before transmission.
-
-XTEA's encryption key @code{PRP_KEY} is the first 128-bit of Salsa20's
-output with established common key and zero nonce (message nonces start
-from 1).
+@code{MAC} is BLAKE2b-MAC used to obfuscate @code{SERIAL}. MAC's key
+@code{MAC_KEY} is the first 256-bit of Salsa20's output with established
+common key and zero nonce (message nonces start from 1).
@verbatim
-PRP_KEY = 128bit(ENCRYPT(KEY, 0))
+MAC_KEY = 256bit(ENCRYPT(KEY, 0))
@end verbatim
@code{ENCRYPT} is Salsa20 stream cipher, with established session
@verbatim
PACKET = ENCODED || NONCE
ENCODED = ENCLESS(DATA || PAD || ZEROS)
- NONCE = PRP(PRP_KEY, SERIAL)
+ NONCE = MAC(MAC_KEY, SERIAL)
@end verbatim
@code{ENCLESS} is AONT and chaffing function. There is no need in
timeout int
firstUpCall bool = true
knownPeers govpn.KnownPeers
- idsCache *govpn.CipherCache
+ idsCache *govpn.MACCache
)
func main() {
Verifier: verifier,
DSAPriv: priv,
}
- idsCache = govpn.NewCipherCache()
+ idsCache = govpn.NewMACCache()
confs := map[govpn.PeerId]*govpn.PeerConf{*verifier.Id: conf}
idsCache.Update(&confs)
log.Println(govpn.VersionGet())
return
}
- nonceExpectation := make([]byte, govpn.NonceSize)
- peer.NonceExpectation(nonceExpectation)
prev = 0
var i int
TransportCycle:
if prev < govpn.MinPktLength {
continue
}
- i = bytes.Index(buf[:prev], nonceExpectation)
+ i = bytes.Index(buf[:prev], peer.NonceExpect)
if i == -1 {
continue
}
rehandshaking <- struct{}{}
break TransportCycle
}
- peer.NonceExpectation(nonceExpectation)
copy(buf, buf[i+govpn.NonceSize:prev])
prev = prev - i - govpn.NonceSize
goto CheckMore
var (
confs map[govpn.PeerId]*govpn.PeerConf
- idsCache *govpn.CipherCache
+ idsCache *govpn.MACCache
)
func confRead() (*map[govpn.PeerId]*govpn.PeerConf, error) {
}
func confInit() {
- idsCache = govpn.NewCipherCache()
+ idsCache = govpn.NewMACCache()
if err := confRefresh(); err != nil {
log.Fatalln(err)
}
return
}
- nonceExpectation := make([]byte, govpn.NonceSize)
- peer.NonceExpectation(nonceExpectation)
prev = 0
var i int
for {
if prev < govpn.MinPktLength {
continue
}
- i = bytes.Index(buf[:prev], nonceExpectation)
+ i = bytes.Index(buf[:prev], peer.NonceExpect)
if i == -1 {
continue
}
)
break
}
- peer.NonceExpectation(nonceExpectation)
copy(buf, buf[i+govpn.NonceSize:prev])
prev = prev - i - govpn.NonceSize
goto CheckMore
"github.com/dchest/blake2b"
"golang.org/x/crypto/curve25519"
"golang.org/x/crypto/salsa20"
- "golang.org/x/crypto/xtea"
)
const (
// Generate ID tag from client identification and data.
func idTag(id *PeerId, timeSync int, data []byte) []byte {
- ciph, err := xtea.NewCipher(id[:])
- if err != nil {
- panic(err)
- }
- enc := make([]byte, xtea.BlockSize)
+ enc := make([]byte, 8)
copy(enc, data)
AddTimeSync(timeSync, enc)
- ciph.Encrypt(enc, enc)
+ mac := blake2b.NewMAC(8, id[:])
+ mac.Write(enc)
+ mac.Sum(enc[:0])
return enc
}
}
var enc []byte
if conf.Noise {
- enc = make([]byte, conf.MTU-xtea.BlockSize-RSize)
+ enc = make([]byte, conf.MTU-8-RSize)
} else {
enc = make([]byte, 32)
}
out, err := EnclessDecode(
h.dsaPubH,
h.rNonce[:],
- data[RSize:len(data)-xtea.BlockSize],
+ data[RSize:len(data)-8],
)
if err != nil {
log.Println("Unable to decode packet from", h.addr, err)
}
copy(cDHRepr[:], out)
} else {
- salsa20.XORKeyStream(
- cDHRepr[:],
- data[RSize:RSize+32],
- h.rNonce[:],
- h.dsaPubH,
- )
+ salsa20.XORKeyStream(cDHRepr[:], data[RSize:RSize+32], h.rNonce[:], h.dsaPubH)
}
// Generate DH keypair
}
var encRs []byte
if h.Conf.Noise && !h.Conf.Encless {
- encRs = make([]byte, h.Conf.MTU-len(encPub)-xtea.BlockSize)
+ encRs = make([]byte, h.Conf.MTU-len(encPub)-8)
} else if h.Conf.Encless {
- encRs = make([]byte, h.Conf.MTU-xtea.BlockSize)
+ encRs = make([]byte, h.Conf.MTU-8)
} else {
encRs = make([]byte, RSize+SSize)
}
dec, err = EnclessDecode(
h.key,
h.rNonceNext(1),
- data[:len(data)-xtea.BlockSize],
+ data[:len(data)-8],
)
if err != nil {
log.Println("Unable to decode packet from", h.addr, err)
// Send final answer to client
var enc []byte
if h.Conf.Noise {
- enc = make([]byte, h.Conf.MTU-xtea.BlockSize)
+ enc = make([]byte, h.Conf.MTU-8)
} else {
enc = make([]byte, RSize)
}
}
copy(sDHRepr[:], tmp[:32])
} else {
- salsa20.XORKeyStream(
- sDHRepr[:],
- data[:32],
- h.rNonceNext(1),
- h.dsaPubH,
- )
+ salsa20.XORKeyStream(sDHRepr[:], data[:32], h.rNonceNext(1), h.dsaPubH)
}
// Compute shared key
tmp, err = EnclessDecode(
h.key,
h.rNonce[:],
- data[len(data)/2:len(data)-xtea.BlockSize],
+ data[len(data)/2:len(data)-8],
)
if err != nil {
log.Println("Unable to decode packet from", h.addr, err)
copy(h.sServer[:], tmp[RSize:RSize+SSize])
} else {
decRs := make([]byte, RSize+SSize)
- salsa20.XORKeyStream(
- decRs,
- data[SSize:SSize+RSize+SSize],
- h.rNonce[:],
- h.key,
- )
+ salsa20.XORKeyStream(decRs, data[SSize:SSize+RSize+SSize], h.rNonce[:], h.key)
copy(h.rServer[:], decRs[:RSize])
copy(h.sServer[:], decRs[RSize:])
}
var enc []byte
if h.Conf.Noise {
- enc = make([]byte, h.Conf.MTU-xtea.BlockSize)
+ enc = make([]byte, h.Conf.MTU-8)
} else {
enc = make([]byte, RSize+RSize+SSize+ed25519.SignatureSize)
}
// Decrypt rClient
var dec []byte
if h.Conf.Encless {
- dec, err = EnclessDecode(
- h.key,
- h.rNonceNext(2),
- data[:len(data)-xtea.BlockSize],
- )
+ dec, err = EnclessDecode(h.key, h.rNonceNext(2), data[:len(data)-8])
if err != nil {
log.Println("Unable to decode packet from", h.addr, err)
return nil
"crypto/subtle"
"encoding/base64"
"encoding/binary"
+ "hash"
"log"
"sync"
"time"
- "golang.org/x/crypto/xtea"
+ "github.com/dchest/blake2b"
)
const (
return []byte(`"` + id.String() + `"`), nil
}
-type CipherAndTimeSync struct {
- c *xtea.Cipher
- t int
+type MACAndTimeSync struct {
+ mac hash.Hash
+ ts int
+ l sync.Mutex
}
-type CipherCache struct {
- c map[PeerId]*CipherAndTimeSync
- l sync.RWMutex
+type MACCache struct {
+ cache map[PeerId]*MACAndTimeSync
+ l sync.RWMutex
}
-func NewCipherCache() *CipherCache {
- return &CipherCache{c: make(map[PeerId]*CipherAndTimeSync)}
+func NewMACCache() *MACCache {
+ return &MACCache{cache: make(map[PeerId]*MACAndTimeSync)}
}
-// Remove disappeared keys, add missing ones with initialized ciphers.
-func (cc *CipherCache) Update(peers *map[PeerId]*PeerConf) {
- cc.l.Lock()
- for pid, _ := range cc.c {
+// Remove disappeared keys, add missing ones with initialized MACs.
+func (mc *MACCache) Update(peers *map[PeerId]*PeerConf) {
+ mc.l.Lock()
+ for pid, _ := range mc.cache {
if _, exists := (*peers)[pid]; !exists {
log.Println("Cleaning key:", pid)
- delete(cc.c, pid)
+ delete(mc.cache, pid)
}
}
for pid, pc := range *peers {
- if _, exists := cc.c[pid]; exists {
- cc.c[pid].t = pc.TimeSync
+ if _, exists := mc.cache[pid]; exists {
+ mc.cache[pid].ts = pc.TimeSync
} else {
log.Println("Adding key", pid)
- cipher, err := xtea.NewCipher(pid[:])
- if err != nil {
- panic(err)
+ mc.cache[pid] = &MACAndTimeSync{
+ mac: blake2b.NewMAC(8, pid[:]),
+ ts: pc.TimeSync,
}
- cc.c[pid] = &CipherAndTimeSync{cipher, pc.TimeSync}
}
}
- cc.l.Unlock()
+ mc.l.Unlock()
}
// If timeSync > 0, then XOR timestamp with the data.
}
}
-// Try to find peer's identity (that equals to an encryption key)
+// Try to find peer's identity (that equals to MAC)
// by taking first blocksize sized bytes from data at the beginning
// as plaintext and last bytes as cyphertext.
-func (cc *CipherCache) Find(data []byte) *PeerId {
- if len(data) < xtea.BlockSize*2 {
+func (mc *MACCache) Find(data []byte) *PeerId {
+ if len(data) < 8*2 {
return nil
}
- buf := make([]byte, xtea.BlockSize)
- cc.l.RLock()
- for pid, ct := range cc.c {
- ct.c.Decrypt(buf, data[len(data)-xtea.BlockSize:])
- AddTimeSync(ct.t, buf)
- if subtle.ConstantTimeCompare(buf, data[:xtea.BlockSize]) == 1 {
+ buf := make([]byte, 8)
+ mc.l.RLock()
+ for pid, mt := range mc.cache {
+ copy(buf, data)
+ AddTimeSync(mt.ts, buf)
+ mt.l.Lock()
+ mt.mac.Reset()
+ mt.mac.Write(buf)
+ mt.mac.Sum(buf[:0])
+ mt.l.Unlock()
+ if subtle.ConstantTimeCompare(buf, data[len(data)-8:]) == 1 {
ppid := PeerId(pid)
- cc.l.RUnlock()
+ mc.l.RUnlock()
return &ppid
}
}
- cc.l.RUnlock()
+ mc.l.RUnlock()
return nil
}
import (
"bytes"
+ "crypto/subtle"
"encoding/binary"
"io"
"log"
"sync/atomic"
"time"
+ "github.com/dchest/blake2b"
"golang.org/x/crypto/poly1305"
"golang.org/x/crypto/salsa20"
- "golang.org/x/crypto/xtea"
)
const (
NonceSize = 8
- NonceBucketSize = 128
+ NonceBucketSize = 256
TagSize = poly1305.TagSize
// S20BS is Salsa20's internal blocksize in bytes
S20BS = 64
PadByte = byte(0x80)
)
-func newNonceCipher(key *[32]byte) *xtea.Cipher {
- nonceKey := make([]byte, 16)
- salsa20.XORKeyStream(
- nonceKey,
- make([]byte, 32),
- make([]byte, xtea.BlockSize),
- key,
- )
- ciph, err := xtea.NewCipher(nonceKey)
- if err != nil {
- panic(err)
- }
- return ciph
+func newNonces(key *[32]byte, i uint64) chan *[NonceSize]byte {
+ macKey := make([]byte, 32)
+ salsa20.XORKeyStream(macKey, make([]byte, 32), make([]byte, 8), key)
+ mac := blake2b.NewMAC(NonceSize, macKey)
+ nonces := make(chan *[NonceSize]byte, NonceBucketSize*3)
+ go func() {
+ for {
+ buf := new([NonceSize]byte)
+ binary.BigEndian.PutUint64(buf[:], i)
+ mac.Write(buf[:])
+ mac.Sum(buf[:0])
+ nonces <- buf
+ mac.Reset()
+ i += 2
+ }
+ }()
+ return nonces
}
type Peer struct {
Encless bool
MTU int
- // Cryptography related
- Key *[SSize]byte `json:"-"`
- NonceCipher *xtea.Cipher `json:"-"`
- nonceRecv uint64
- nonceLatest uint64
- nonceOur uint64
- NonceExpect uint64 `json:"-"`
- nonceBucket0 map[uint64]struct{}
- nonceBucket1 map[uint64]struct{}
- nonceFound0 bool
- nonceFound1 bool
- nonceBucketN int32
+ key *[SSize]byte `json:"-"`
// Timers
Timeout time.Duration `json:"-"`
keyAuthR *[SSize]byte
pktSizeR int
+ // UDP-related
+ noncesR chan *[NonceSize]byte
+ nonceRecv [NonceSize]byte
+ nonceBucketL map[[NonceSize]byte]struct{}
+ nonceBucketM map[[NonceSize]byte]struct{}
+ nonceBucketH map[[NonceSize]byte]struct{}
+
+ // TCP-related
+ NonceExpect []byte `json:"-"`
+ noncesExpect chan *[NonceSize]byte
+
// Transmitter
BusyT sync.Mutex `json:"-"`
bufT []byte
tagT *[TagSize]byte
keyAuthT *[SSize]byte
frameT []byte
+ noncesT chan *[NonceSize]byte
}
func (p *Peer) String() string {
func (p *Peer) Zero() {
p.BusyT.Lock()
p.BusyR.Lock()
- SliceZero(p.Key[:])
+ SliceZero(p.key[:])
SliceZero(p.bufR)
SliceZero(p.bufT)
SliceZero(p.keyAuthR[:])
p.BusyR.Unlock()
}
-func (p *Peer) NonceExpectation(buf []byte) {
- binary.BigEndian.PutUint64(buf, p.NonceExpect)
- p.NonceCipher.Encrypt(buf, buf)
-}
-
func cprCycleCalculate(conf *PeerConf) time.Duration {
if conf.CPR == 0 {
return time.Duration(0)
bufSize += EnclessEnlargeSize
noiseEnable = true
}
+
peer := Peer{
Addr: addr,
Id: conf.Id,
Encless: conf.Encless,
MTU: conf.MTU,
- Key: key,
- NonceCipher: newNonceCipher(key),
- nonceBucket0: make(map[uint64]struct{}, NonceBucketSize),
- nonceBucket1: make(map[uint64]struct{}, NonceBucketSize),
+ key: key,
Timeout: timeout,
Established: now,
keyAuthR: new([SSize]byte),
keyAuthT: new([SSize]byte),
}
+
if isClient {
- peer.nonceOur = 1
- peer.NonceExpect = 0 + 2
+ peer.noncesT = newNonces(peer.key, 1 + 2)
+ peer.noncesR = newNonces(peer.key, 0 + 2)
+ peer.noncesExpect = newNonces(peer.key, 0 + 2)
} else {
- peer.nonceOur = 0
- peer.NonceExpect = 1 + 2
+ peer.noncesT = newNonces(peer.key, 0 + 2)
+ peer.noncesR = newNonces(peer.key, 1 + 2)
+ peer.noncesExpect = newNonces(peer.key, 1 + 2)
}
- return &peer
+ peer.NonceExpect = make([]byte, NonceSize)
+ nonce := <-peer.noncesExpect
+ copy(peer.NonceExpect, nonce[:])
+
+ var i int
+ peer.nonceBucketL = make(map[[NonceSize]byte]struct{}, NonceBucketSize)
+ for i = 0; i < NonceBucketSize; i++ {
+ nonce = <-peer.noncesR
+ peer.nonceBucketL[*nonce] = struct{}{}
+ }
+ peer.nonceBucketM = make(map[[NonceSize]byte]struct{}, NonceBucketSize)
+ for i = 0; i < NonceBucketSize; i++ {
+ nonce = <-peer.noncesR
+ peer.nonceBucketM[*nonce] = struct{}{}
+ }
+ peer.nonceBucketH = make(map[[NonceSize]byte]struct{}, NonceBucketSize)
+ for i = 0; i < NonceBucketSize; i++ {
+ nonce = <-peer.noncesR
+ peer.nonceBucketH[*nonce] = struct{}{}
+ }
+
+ return &peer
}
// Process incoming Ethernet packet.
} else {
p.frameT = p.bufT[S20BS : S20BS+len(data)+1+NonceSize]
}
- p.nonceOur += 2
- binary.BigEndian.PutUint64(p.frameT[len(p.frameT)-NonceSize:], p.nonceOur)
- p.NonceCipher.Encrypt(
- p.frameT[len(p.frameT)-NonceSize:],
- p.frameT[len(p.frameT)-NonceSize:],
- )
+ copy(p.frameT[len(p.frameT)-NonceSize:], (<-p.noncesT)[:])
var out []byte
if p.Encless {
var err error
out, err = EnclessEncode(
- p.Key,
+ p.key,
p.frameT[len(p.frameT)-NonceSize:],
p.frameT[:len(p.frameT)-NonceSize],
)
p.bufT[:S20BS+len(p.frameT)-NonceSize],
p.bufT[:S20BS+len(p.frameT)-NonceSize],
p.frameT[len(p.frameT)-NonceSize:],
- p.Key,
+ p.key,
)
copy(p.keyAuthT[:], p.bufT[:SSize])
poly1305.Sum(p.tagT, p.frameT, p.keyAuthT)
if p.Encless {
var err error
out, err = EnclessDecode(
- p.Key,
+ p.key,
data[len(data)-NonceSize:],
data[:len(data)-NonceSize],
)
p.bufR[:S20BS+len(data)-TagSize-NonceSize],
p.bufR[:S20BS+len(data)-TagSize-NonceSize],
data[len(data)-NonceSize:],
- p.Key,
+ p.key,
)
copy(p.keyAuthR[:], p.bufR[:SSize])
copy(p.tagR[:], data[:TagSize])
out = p.bufR[S20BS : S20BS+len(data)-TagSize-NonceSize]
}
- // Check if received nonce is known to us in either of two buckets.
- // If yes, then this is ignored duplicate.
- // Check from the oldest bucket, as in most cases this will result
- // in constant time check.
- // If Bucket0 is filled, then it becomes Bucket1.
- p.NonceCipher.Decrypt(
- data[len(data)-NonceSize:],
- data[len(data)-NonceSize:],
- )
- p.nonceRecv = binary.BigEndian.Uint64(data[len(data)-NonceSize:])
if reorderable {
- _, p.nonceFound0 = p.nonceBucket0[p.nonceRecv]
- _, p.nonceFound1 = p.nonceBucket1[p.nonceRecv]
- if p.nonceFound0 || p.nonceFound1 || p.nonceRecv+2*NonceBucketSize < p.nonceLatest {
+ copy(p.nonceRecv[:], data[len(data)-NonceSize:])
+ _, foundL := p.nonceBucketL[p.nonceRecv]
+ _, foundM := p.nonceBucketM[p.nonceRecv]
+ _, foundH := p.nonceBucketH[p.nonceRecv]
+ // If found is none of buckets: either it is too old,
+ // or too new (many packets were lost)
+ if !(foundL || foundM || foundH) {
p.FramesDup++
p.BusyR.Unlock()
return false
}
- p.nonceBucket0[p.nonceRecv] = struct{}{}
- p.nonceBucketN++
- if p.nonceBucketN == NonceBucketSize {
- p.nonceBucket1 = p.nonceBucket0
- p.nonceBucket0 = make(map[uint64]struct{}, NonceBucketSize)
- p.nonceBucketN = 0
+ // Delete seen nonce
+ if foundL {
+ delete(p.nonceBucketL, p.nonceRecv)
+ }
+ if foundM {
+ delete(p.nonceBucketM, p.nonceRecv)
+ }
+ if foundH {
+ delete(p.nonceBucketH, p.nonceRecv)
+ }
+ // If we are dealing with the latest bucket, create the new one
+ if foundH {
+ p.nonceBucketL, p.nonceBucketM = p.nonceBucketM, p.nonceBucketH
+ p.nonceBucketH = make(map[[NonceSize]byte]struct{})
+ var nonce *[NonceSize]byte
+ for i := 0; i < NonceBucketSize; i++ {
+ nonce = <-p.noncesR
+ p.nonceBucketH[*nonce] = struct{}{}
+ }
}
} else {
- if p.nonceRecv != p.NonceExpect {
+ if subtle.ConstantTimeCompare(data[len(data)-NonceSize:], p.NonceExpect) != 1 {
p.FramesDup++
p.BusyR.Unlock()
return false
}
- p.NonceExpect += 2
- }
- if p.nonceRecv > p.nonceLatest {
- p.nonceLatest = p.nonceRecv
+ copy(p.NonceExpect, (<-p.noncesExpect)[:])
}
p.FramesIn++
MTU: MTUDefault,
Timeout: time.Second * time.Duration(TimeoutDefault),
}
- testPeer = newPeer(true, "foo", Dummy{&testCt}, testConf, new([SSize]byte))
testPt = make([]byte, 789)
}
+func testPeerNew() {
+ testPeer = newPeer(true, "foo", Dummy{&testCt}, testConf, new([SSize]byte))
+}
+
func TestTransportSymmetric(t *testing.T) {
- peerd := newPeer(true, "foo", Dummy{nil}, testConf, new([SSize]byte))
+ testPeerNew()
+ peerd := newPeer(false, "foo", Dummy{nil}, testConf, new([SSize]byte))
f := func(payload []byte) bool {
if len(payload) == 0 {
return true
}
func TestTransportSymmetricNoise(t *testing.T) {
- peerd := newPeer(true, "foo", Dummy{nil}, testConf, new([SSize]byte))
+ testPeerNew()
+ peerd := newPeer(false, "foo", Dummy{nil}, testConf, new([SSize]byte))
testPeer.NoiseEnable = true
peerd.NoiseEnable = true
f := func(payload []byte) bool {
}
func TestTransportSymmetricEncless(t *testing.T) {
- peerd := newPeer(true, "foo", Dummy{nil}, testConf, new([SSize]byte))
+ testPeerNew()
+ peerd := newPeer(false, "foo", Dummy{nil}, testConf, new([SSize]byte))
testPeer.Encless = true
testPeer.NoiseEnable = true
peerd.Encless = true
testPeer = newPeer(true, "foo", Dummy{nil}, testConf, new([SSize]byte))
orig := make([]byte, len(testCt))
copy(orig, testCt)
+ nonce := new([NonceSize]byte)
+ copy(nonce[:], testCt[len(testCt)-NonceSize:])
b.ResetTimer()
for i := 0; i < b.N; i++ {
- testPeer.nonceBucket0 = make(map[uint64]struct{}, 1)
- testPeer.nonceBucket1 = make(map[uint64]struct{}, 1)
+ testPeer.nonceBucketL = make(map[[NonceSize]byte]struct{}, 1)
+ testPeer.nonceBucketM = make(map[[NonceSize]byte]struct{}, 1)
+ testPeer.nonceBucketH = make(map[[NonceSize]byte]struct{}, 1)
+ testPeer.nonceBucketL[*nonce] = struct{}{}
copy(testCt, orig)
if !testPeer.PktProcess(testCt, Dummy{nil}, true) {
b.Fail()