taken from stdin, then you have to have 2 GiB of disk space for that
temporary file and resulting encrypted packet. You can control where
temporary file will be stored using @env{TMPDIR} environment variable.
-Encryption is performed with
-@url{https://www.schneier.com/academic/twofish/, Twofish} algorithm, 256
-bit random key, zero IV, in
-@url{https://en.wikipedia.org/wiki/Counter_mode#Counter_.28CTR.29, CTR}
-mode.
+Encryption is performed with @url{https://cr.yp.to/chacha.html,
+ChaCha20} algorithm. Data is splitted on 128 KiB blocks. Each block is
+encrypted with increasing nonce counter.
If @option{-chunked} is specified, then source file will be split
@ref{Chunked, on chunks}. @option{INT} is the desired chunk size in
BLAKE2b-256 MAC of encrypted blob
@end multitable
-Blob's encryption is done using
-@url{https://www.schneier.com/academic/twofish/, Twofish} algorithm with
-256-bit key in
-@url{https://en.wikipedia.org/wiki/Counter_mode#Counter_.28CTR.29, CTR}
-mode of operation with zero initialization vector.
-@code{balloon(BLAKE2b-256, S, T, P, salt, password)} gives the main key,
-that is fed to @url{https://en.wikipedia.org/wiki/HKDF,
-HKDF}-BLAKE2b-256 KDF. Actual encryption key for Twofish and
-authentication key for MAC are derived from that KDF.
+Blob's encryption is done using @url{https://cr.yp.to/chacha.html,
+ChaCha20} algorithm. Data is splitted on 128 KiB blocks. Each block is
+encrypted with increasing nonce counter. @code{balloon(BLAKE2b-256, S,
+T, P, salt, password)} gives the main key, that is fed to
+@url{https://blake2.net/, BLAKE2Xb} XOF Actual encryption key for
+ChaCha20 and authentication key for MAC are derived from that XOF.
@node Новости
@section Новости
+@node Релиз 2.0
+@subsection Релиз 2.0
+@itemize
+@item
+@strong{Несовместимое} изменение формата зашифрованных и eblob пакетов.
+Работа со старыми версиями не поддерживается.
+@item
+Алгоритм шифрования Twofish заменён на ChaCha20. Он намного быстрее.
+Одним криптографическим примитивом меньше.
+@item
+HKDF-BLAKE2b-256 KDF алгоритм заменён на BLAKE2Xb XOF. Ещё одним
+криптографическим примитивом меньше (предполагая, что BLAKE2X
+практически идентичен BLAKE2).
+@end itemize
+
@node Релиз 1.0
@subsection Релиз 1.0
@itemize
See also this page @ref{Новости, on russian}.
+@node Release 2.0
+@section Release 2.0
+@itemize
+@item
+@strong{Incompatible} encrypted/eblob packet format changes. Older
+versions are not supported.
+@item
+Twofish encryption algorithm is replaced with ChaCha20. It is much more
+faster. One cryptographic primitive less.
+@item
+HKDF-BLAKE2b-256 KDF algorithm is replaced with BLAKE2Xb XOF. Yet
+another cryptographic primitive less (assuming that BLAKE2X is nearly
+identical to BLAKE2).
+@end itemize
+
@node Release 1.0
@section Release 1.0
@itemize
Signature is calculated over all previous fields.
-All following encryption is done using
-@url{https://www.schneier.com/academic/twofish/, Twofish} algorithm with
-256-bit key in
-@url{https://en.wikipedia.org/wiki/Counter_mode#Counter_.28CTR.29, CTR}
-mode of operation with zero initialization vector (because each
-encrypted packet has ephemeral exchange key). @url{https://blake2.net/,
+All following encryption is done using @url{https://cr.yp.to/chacha.html,
+ChaCha20} algorithm. Data is splitted on 128 KiB blocks. Each block is
+encrypted with increasing nonce counter. @url{https://blake2.net/,
BLAKE2b-256} MAC is appended to the ciphertext.
After the headers comes an encrypted payload size and MAC of that size.
@item takes remote node's exchange public key and performs
Diffie-Hellman computation on this remote static public key and
private ephemeral one
-@item derived ephemeral key is used as an input to
- @url{https://en.wikipedia.org/wiki/HKDF, HKDF}-BLAKE2b-256 KDF
-@item derives four session keys using
- @url{https://en.wikipedia.org/wiki/HKDF, HKDF}-BLAKE2b-256 KDF:
+@item derived ephemeral key is used as a key input to
+ @url{https://blake2.net/, BLAKE2Xb} XOF
+@item derives five session keys using output from the XOF above:
@enumerate
- @item "Size" encryption (for Twofish) key
+ @item "Size" encryption (for ChaCha20) key
@item "Size" authentication (for BLAKE2b-MAC) key
@item Payload encryption key
@item Payload authentication key
+ @item Optional pad generation key (for ChaCha20)
@end enumerate
@item encrypts size, appends its ciphertext to the header
@item appends MAC tag over that ciphertext
golang.org/x/crypto/chacha20poly1305
golang.org/x/crypto/curve25519
golang.org/x/crypto/ed25519
-golang.org/x/crypto/hkdf
golang.org/x/crypto/nacl
golang.org/x/crypto/poly1305
golang.org/x/crypto/salsa20
golang.org/x/crypto/ssh/terminal
-golang.org/x/crypto/twofish
golang.org/x/net/AUTHORS
golang.org/x/net/CONTRIBUTORS
golang.org/x/net/LICENSE
# $FreeBSD$
PORTNAME= nncp
-PORTVERSION= 1.0
+PORTVERSION= 2.0
CATEGORIES= net
MASTER_SITES= http://www.nncpgo.org/download/
--- /dev/null
+golang.org/x/crypto/chacha20poly1305/internal/chacha20
\ No newline at end of file
func CfgParse(data []byte) (*Ctx, error) {
var err error
- if bytes.Compare(data[:8], MagicNNCPBv1[:]) == 0 {
+ if bytes.Compare(data[:8], MagicNNCPBv2[:]) == 0 {
os.Stderr.WriteString("Passphrase:")
password, err := terminal.ReadPassword(0)
if err != nil {
ctx.LogD("nncp-bundle", sds, "Bad packet structure")
continue
}
- if pktEnc.Magic != nncp.MagicNNCPEv2 {
+ if pktEnc.Magic != nncp.MagicNNCPEv3 {
ctx.LogD("nncp-bundle", sds, "Bad packet magic number")
continue
}
if _, err := xdr.Unmarshal(bytes.NewReader(data), &eblob); err != nil {
log.Fatalln(err)
}
- if eblob.Magic != nncp.MagicNNCPBv1 {
+ if eblob.Magic != nncp.MagicNNCPBv2 {
log.Fatalln(errors.New("Unknown eblob type"))
}
fmt.Println("Strengthening function: Balloon with BLAKE2b-256")
}
var pktEnc nncp.PktEnc
_, err = xdr.Unmarshal(bytes.NewReader(beginning), &pktEnc)
- if err == nil && pktEnc.Magic == nncp.MagicNNCPEv2 {
+ if err == nil && pktEnc.Magic == nncp.MagicNNCPEv3 {
if *dump {
ctx, err := nncp.CtxFromCmdline(*cfgPath, "", "", false, false)
if err != nil {
}
var pktEnc nncp.PktEnc
_, err = xdr.Unmarshal(fd, &pktEnc)
- if err != nil || pktEnc.Magic != nncp.MagicNNCPEv2 {
+ if err != nil || pktEnc.Magic != nncp.MagicNNCPEv3 {
ctx.LogD("nncp-xfer", sds, "is not a packet")
fd.Close()
continue
import (
"bytes"
- "crypto/cipher"
"crypto/rand"
"crypto/subtle"
"errors"
+ "hash"
"io"
+ "chacha20"
"cypherpunks.ru/balloon"
"github.com/davecgh/go-xdr/xdr2"
"golang.org/x/crypto/blake2b"
- "golang.org/x/crypto/hkdf"
- "golang.org/x/crypto/twofish"
)
const (
)
var (
- MagicNNCPBv1 [8]byte = [8]byte{'N', 'N', 'C', 'P', 'B', 0, 0, 1}
+ MagicNNCPBv2 [8]byte = [8]byte{'N', 'N', 'C', 'P', 'B', 0, 0, 2}
)
type EBlob struct {
MAC *[blake2b.Size256]byte
}
+func blake256() hash.Hash {
+ h, err := blake2b.New256(nil)
+ if err != nil {
+ panic(err)
+ }
+ return h
+}
+
// Create an encrypted blob. sCost -- memory space requirements, number
// of hash-output sized (32 bytes) blocks. tCost -- time requirements,
// number of rounds. pCost -- number of parallel jobs.
return nil, err
}
key := balloon.H(blake256, password, salt[:], sCost, tCost, pCost)
- kdf := hkdf.New(blake256, key, nil, MagicNNCPBv1[:])
- keyEnc := make([]byte, 32)
- if _, err = io.ReadFull(kdf, keyEnc); err != nil {
+ kdf, err := blake2b.NewXOF(32+64, key)
+ if err != nil {
return nil, err
}
- keyAuth := make([]byte, 64)
- if _, err = io.ReadFull(kdf, keyAuth); err != nil {
+ if _, err = kdf.Write(MagicNNCPBv2[:]); err != nil {
return nil, err
}
- ciph, err := twofish.NewCipher(keyEnc)
- if err != nil {
+ keyEnc := new([32]byte)
+ if _, err = io.ReadFull(kdf, keyEnc[:]); err != nil {
+ return nil, err
+ }
+ keyAuth := make([]byte, 64)
+ if _, err = io.ReadFull(kdf, keyAuth); err != nil {
return nil, err
}
- ctr := cipher.NewCTR(ciph, make([]byte, twofish.BlockSize))
mac, err := blake2b.New256(keyAuth)
if err != nil {
return nil, err
}
- var blob bytes.Buffer
- mw := io.MultiWriter(&blob, mac)
- ae := &cipher.StreamWriter{S: ctr, W: mw}
- if _, err = ae.Write(data); err != nil {
+ chacha20.XORKeyStream(data, data, new([16]byte), keyEnc)
+ if _, err = mac.Write(data); err != nil {
return nil, err
}
macTag := new([blake2b.Size256]byte)
mac.Sum(macTag[:0])
eblob := EBlob{
- Magic: MagicNNCPBv1,
+ Magic: MagicNNCPBv2,
SCost: uint32(sCost),
TCost: uint32(tCost),
PCost: uint32(pCost),
Salt: salt,
- Blob: blob.Bytes(),
+ Blob: data,
MAC: macTag,
}
var eblobRaw bytes.Buffer
if _, err = xdr.Unmarshal(bytes.NewReader(eblobRaw), &eblob); err != nil {
return nil, err
}
- if eblob.Magic != MagicNNCPBv1 {
+ if eblob.Magic != MagicNNCPBv2 {
return nil, BadMagic
}
key := balloon.H(
int(eblob.TCost),
int(eblob.PCost),
)
- kdf := hkdf.New(blake256, key, nil, MagicNNCPBv1[:])
- keyEnc := make([]byte, 32)
- if _, err = io.ReadFull(kdf, keyEnc); err != nil {
+ kdf, err := blake2b.NewXOF(32+64, key)
+ if err != nil {
return nil, err
}
- keyAuth := make([]byte, 64)
- if _, err = io.ReadFull(kdf, keyAuth); err != nil {
+ if _, err = kdf.Write(MagicNNCPBv2[:]); err != nil {
return nil, err
}
- ciph, err := twofish.NewCipher(keyEnc)
- if err != nil {
+ keyEnc := new([32]byte)
+ if _, err = io.ReadFull(kdf, keyEnc[:]); err != nil {
+ return nil, err
+ }
+ keyAuth := make([]byte, 64)
+ if _, err = io.ReadFull(kdf, keyAuth); err != nil {
return nil, err
}
- ctr := cipher.NewCTR(ciph, make([]byte, twofish.BlockSize))
mac, err := blake2b.New256(keyAuth)
if err != nil {
return nil, err
}
- var blob bytes.Buffer
- tr := io.TeeReader(bytes.NewReader(eblob.Blob), mac)
- ae := &cipher.StreamReader{S: ctr, R: tr}
- if _, err = io.Copy(&blob, ae); err != nil {
+ if _, err = mac.Write(eblob.Blob); err != nil {
return nil, err
}
if subtle.ConstantTimeCompare(mac.Sum(nil), eblob.MAC[:]) != 1 {
return nil, errors.New("Unauthenticated blob")
}
- return blob.Bytes(), nil
+ chacha20.XORKeyStream(eblob.Blob, eblob.Blob, new([16]byte), keyEnc)
+ return eblob.Blob, nil
}
continue
}
var pktEnc PktEnc
- if _, err = xdr.Unmarshal(fd, &pktEnc); err != nil || pktEnc.Magic != MagicNNCPEv2 {
+ if _, err = xdr.Unmarshal(fd, &pktEnc); err != nil || pktEnc.Magic != MagicNNCPEv3 {
fd.Close()
continue
}
import (
"bytes"
- "crypto/cipher"
"crypto/rand"
"crypto/subtle"
+ "encoding/binary"
"errors"
- "hash"
"io"
+ "chacha20"
"github.com/davecgh/go-xdr/xdr2"
"golang.org/x/crypto/blake2b"
"golang.org/x/crypto/curve25519"
"golang.org/x/crypto/ed25519"
- "golang.org/x/crypto/hkdf"
"golang.org/x/crypto/nacl/box"
- "golang.org/x/crypto/twofish"
)
type PktType uint8
const (
+ EncBlkSize = 128 * (1 << 10)
+ KDFXOFSize = 2*(32+64) + 32
+
PktTypeFile PktType = iota
PktTypeFreq PktType = iota
PktTypeMail PktType = iota
var (
MagicNNCPPv1 [8]byte = [8]byte{'N', 'N', 'C', 'P', 'P', 0, 0, 1}
- MagicNNCPEv2 [8]byte = [8]byte{'N', 'N', 'C', 'P', 'E', 0, 0, 2}
+ MagicNNCPEv3 [8]byte = [8]byte{'N', 'N', 'C', 'P', 'E', 0, 0, 3}
BadMagic error = errors.New("Unknown magic number")
BadPktType error = errors.New("Unknown packet type")
panic(err)
}
pktEnc := PktEnc{
- Magic: MagicNNCPEv2,
+ Magic: MagicNNCPEv3,
Nice: 123,
Sender: dummyId,
Recipient: dummyId,
return &pkt, nil
}
-func blake256() hash.Hash {
- h, err := blake2b.New256(nil)
- if err != nil {
- panic(err)
- }
- return h
-}
-
type DevZero struct{}
func (d DevZero) Read(b []byte) (n int, err error) {
return
}
+func ae(keyEnc *[32]byte, r io.Reader, w io.Writer) (int, error) {
+ var blkCtr uint64
+ ciphNonce := new([16]byte)
+ ciphCtr := ciphNonce[8:]
+ buf := make([]byte, EncBlkSize)
+ var n int
+ var written int
+ var err error
+ for {
+ n, err = io.ReadFull(r, buf)
+ if err != nil {
+ if err == io.EOF {
+ break
+ }
+ if err != io.ErrUnexpectedEOF {
+ return written + n, err
+ }
+ }
+ written += n
+ blkCtr++
+ binary.BigEndian.PutUint64(ciphCtr, blkCtr)
+ chacha20.XORKeyStream(buf[:n], buf[:n], ciphNonce, keyEnc)
+ if _, err = w.Write(buf[:n]); err != nil {
+ return written, err
+ }
+ }
+ return written, nil
+}
+
func PktEncWrite(our *NodeOur, their *Node, pkt *Pkt, nice uint8, size, padSize int64, data io.Reader, out io.Writer) error {
pubEph, prvEph, err := box.GenerateKey(rand.Reader)
if err != nil {
return err
}
tbs := PktTbs{
- Magic: MagicNNCPEv2,
+ Magic: MagicNNCPEv3,
Nice: nice,
Sender: our.Id,
Recipient: their.Id,
signature := new([ed25519.SignatureSize]byte)
copy(signature[:], ed25519.Sign(our.SignPrv, tbsBuf.Bytes()))
pktEnc := PktEnc{
- Magic: MagicNNCPEv2,
+ Magic: MagicNNCPEv3,
Nice: nice,
Sender: our.Id,
Recipient: their.Id,
}
sharedKey := new([32]byte)
curve25519.ScalarMult(sharedKey, prvEph, their.ExchPub)
- kdf := hkdf.New(blake256, sharedKey[:], nil, MagicNNCPEv2[:])
-
- keyEnc := make([]byte, 32)
- if _, err = io.ReadFull(kdf, keyEnc); err != nil {
+ kdf, err := blake2b.NewXOF(KDFXOFSize, sharedKey[:])
+ if err != nil {
return err
}
- keyAuth := make([]byte, 64)
- if _, err = io.ReadFull(kdf, keyAuth); err != nil {
+ if _, err = kdf.Write(MagicNNCPEv3[:]); err != nil {
return err
}
- ciph, err := twofish.NewCipher(keyEnc)
- if err != nil {
+ keyEnc := new([32]byte)
+ if _, err = io.ReadFull(kdf, keyEnc[:]); err != nil {
+ return err
+ }
+ keyAuth := make([]byte, 64)
+ if _, err = io.ReadFull(kdf, keyAuth); err != nil {
return err
}
- ctr := cipher.NewCTR(ciph, make([]byte, twofish.BlockSize))
mac, err := blake2b.New256(keyAuth)
if err != nil {
return err
}
- mw := io.MultiWriter(out, mac)
- ae := &cipher.StreamWriter{S: ctr, W: mw}
- usize := uint64(size)
- if _, err = xdr.Marshal(ae, &usize); err != nil {
+ sizeBuf := make([]byte, 8)
+ binary.BigEndian.PutUint64(sizeBuf, uint64(size))
+ chacha20.XORKeyStream(sizeBuf, sizeBuf, new([16]byte), keyEnc)
+ if _, err = out.Write(sizeBuf); err != nil {
+ return err
+ }
+ if _, err = mac.Write(sizeBuf); err != nil {
+ return err
+ }
+ if _, err = out.Write(mac.Sum(nil)); err != nil {
return err
}
- ae.Close()
- out.Write(mac.Sum(nil))
- if _, err = io.ReadFull(kdf, keyEnc); err != nil {
+ if _, err = io.ReadFull(kdf, keyEnc[:]); err != nil {
return err
}
if _, err = io.ReadFull(kdf, keyAuth); err != nil {
return err
}
-
- ciph, err = twofish.NewCipher(keyEnc)
+ mac, err = blake2b.New256(keyAuth)
if err != nil {
return err
}
- ctr = cipher.NewCTR(ciph, make([]byte, twofish.BlockSize))
- mac, err = blake2b.New256(keyAuth)
+ lr := io.LimitedReader{data, size}
+ mr := io.MultiReader(&pktBuf, &lr)
+ mw := io.MultiWriter(out, mac)
+ fullSize := pktBuf.Len() + int(size)
+ written, err := ae(keyEnc, mr, mw)
if err != nil {
return err
}
-
- mw = io.MultiWriter(out, mac)
- ae = &cipher.StreamWriter{S: ctr, W: mw}
- ae.Write(pktBuf.Bytes())
- if _, err = io.CopyN(ae, data, size); err != nil {
+ if written != fullSize {
+ return io.ErrUnexpectedEOF
+ }
+ if _, err = out.Write(mac.Sum(nil)); err != nil {
return err
}
- ae.Close()
- out.Write(mac.Sum(nil))
-
if padSize > 0 {
- if _, err = io.ReadFull(kdf, keyEnc); err != nil {
+ if _, err = io.ReadFull(kdf, keyEnc[:]); err != nil {
return err
}
- ciph, err = twofish.NewCipher(keyEnc)
+ lr = io.LimitedReader{DevZero{}, padSize}
+ written, err = ae(keyEnc, &lr, out)
if err != nil {
return err
}
- ctr = cipher.NewCTR(ciph, make([]byte, twofish.BlockSize))
- ae = &cipher.StreamWriter{S: ctr, W: out}
- if _, err = io.CopyN(ae, DevZero{}, padSize); err != nil {
- return err
+ if written != int(padSize) {
+ return io.ErrUnexpectedEOF
}
- ae.Close()
}
return nil
}
func TbsVerify(our *NodeOur, their *Node, pktEnc *PktEnc) (bool, error) {
tbs := PktTbs{
- Magic: MagicNNCPEv2,
+ Magic: MagicNNCPEv3,
Nice: pktEnc.Nice,
Sender: their.Id,
Recipient: our.Id,
if err != nil {
return nil, 0, err
}
- if pktEnc.Magic != MagicNNCPEv2 {
+ if pktEnc.Magic != MagicNNCPEv3 {
return nil, 0, BadMagic
}
their, known := nodes[*pktEnc.Sender]
}
sharedKey := new([32]byte)
curve25519.ScalarMult(sharedKey, our.ExchPrv, pktEnc.ExchPub)
- kdf := hkdf.New(blake256, sharedKey[:], nil, MagicNNCPEv2[:])
-
- keyEnc := make([]byte, 32)
- if _, err = io.ReadFull(kdf, keyEnc); err != nil {
+ kdf, err := blake2b.NewXOF(KDFXOFSize, sharedKey[:])
+ if err != nil {
return their, 0, err
}
- keyAuth := make([]byte, 64)
- if _, err = io.ReadFull(kdf, keyAuth); err != nil {
+ if _, err = kdf.Write(MagicNNCPEv3[:]); err != nil {
return their, 0, err
}
- ciph, err := twofish.NewCipher(keyEnc)
- if err != nil {
+ keyEnc := new([32]byte)
+ if _, err = io.ReadFull(kdf, keyEnc[:]); err != nil {
+ return their, 0, err
+ }
+ keyAuth := make([]byte, 64)
+ if _, err = io.ReadFull(kdf, keyAuth); err != nil {
return their, 0, err
}
- ctr := cipher.NewCTR(ciph, make([]byte, twofish.BlockSize))
mac, err := blake2b.New256(keyAuth)
if err != nil {
return their, 0, err
}
- tr := io.TeeReader(data, mac)
- ae := &cipher.StreamReader{S: ctr, R: tr}
- var usize uint64
- if _, err = xdr.Unmarshal(ae, &usize); err != nil {
+ sizeBuf := make([]byte, 8)
+ if _, err = io.ReadFull(data, sizeBuf); err != nil {
+ return their, 0, err
+ }
+ if _, err = mac.Write(sizeBuf); err != nil {
return their, 0, err
}
tag := make([]byte, blake2b.Size256)
if subtle.ConstantTimeCompare(mac.Sum(nil), tag) != 1 {
return their, 0, errors.New("Unauthenticated size")
}
- size := int64(usize)
+ chacha20.XORKeyStream(sizeBuf, sizeBuf, new([16]byte), keyEnc)
+ size := int64(binary.BigEndian.Uint64(sizeBuf))
- if _, err = io.ReadFull(kdf, keyEnc); err != nil {
+ if _, err = io.ReadFull(kdf, keyEnc[:]); err != nil {
return their, size, err
}
if _, err = io.ReadFull(kdf, keyAuth); err != nil {
return their, size, err
}
-
- ciph, err = twofish.NewCipher(keyEnc)
- if err != nil {
- return their, size, err
- }
- ctr = cipher.NewCTR(ciph, make([]byte, twofish.BlockSize))
mac, err = blake2b.New256(keyAuth)
if err != nil {
- return their, size, err
+ return their, 0, err
}
- tr = io.TeeReader(data, mac)
- ae = &cipher.StreamReader{S: ctr, R: tr}
- if _, err = io.CopyN(out, ae, PktOverhead+size-8-blake2b.Size256-blake2b.Size256); err != nil {
- return their, size, err
+ fullSize := PktOverhead + size - 8 - 2*blake2b.Size256
+ lr := io.LimitedReader{data, fullSize}
+ tr := io.TeeReader(&lr, mac)
+ written, err := ae(keyEnc, tr, out)
+ if err != nil {
+ return their, int64(written), err
+ }
+ if written != int(fullSize) {
+ return their, int64(written), io.ErrUnexpectedEOF
}
if _, err = io.ReadFull(data, tag); err != nil {
return their, size, err
defer os.RemoveAll(spool)
nodeOur, err := NewNodeGenerate()
if err != nil {
- panic(err)
+ t.Error(err)
+ return false
}
ctx := Ctx{
Spool: spool,
}
our, err := NewNodeGenerate()
if err != nil {
- panic(err)
+ t.Error(err)
+ return false
}
privates[recipient] = our
ctx.Neigh[*our.Id] = our.Their()
[]byte{123},
1<<15,
); err != nil {
- panic(err)
+ t.Error(err)
+ return false
}
}
for _, recipient := range recipients {
defer os.RemoveAll(spool)
nodeOur, err := NewNodeGenerate()
if err != nil {
- panic(err)
+ t.Error(err)
+ return false
}
ctx := Ctx{
Spool: spool,
fileName,
1<<15,
); err != nil {
- panic(err)
+ t.Error(err)
+ return false
}
}
rxPath := filepath.Join(spool, ctx.Self.Id.String(), string(TRx))
defer os.RemoveAll(spool)
nodeOur, err := NewNodeGenerate()
if err != nil {
- panic(err)
+ t.Error(err)
+ return false
}
ctx := Ctx{
Spool: spool,
[]byte("doesnotmatter"),
os.FileMode(0600),
); err != nil {
- panic(err)
+ t.Error(err)
+ return false
}
incomingPath := filepath.Join(spool, "incoming")
for i := 0; i < files; i++ {
"samefile",
1<<15,
); err != nil {
- panic(err)
+ t.Error(err)
+ return false
}
}
rxPath := filepath.Join(spool, ctx.Self.Id.String(), string(TRx))
defer os.RemoveAll(spool)
nodeOur, err := NewNodeGenerate()
if err != nil {
- panic(err)
+ t.Error(err)
+ return false
}
ctx := Ctx{
Spool: spool,
fileName,
1<<15,
); err != nil {
- panic(err)
+ t.Error(err)
+ return false
}
}
rxPath := filepath.Join(spool, ctx.Self.Id.String(), string(TRx))
var buf bytes.Buffer
_, _, err := PktEncRead(ctx.Self, ctx.Neigh, job.Fd, &buf)
if err != nil {
- panic(err)
+ t.Error(err)
+ return false
}
var pkt Pkt
if _, err = xdr.Unmarshal(&buf, &pkt); err != nil {
- panic(err)
+ t.Error(err)
+ return false
}
dst := string(pkt.Path[:int(pkt.PathLen)])
if bytes.Compare(buf.Bytes(), files[dst]) != 0 {
defer os.RemoveAll(spool)
nodeOur, err := NewNodeGenerate()
if err != nil {
- panic(err)
+ t.Error(err)
+ return false
}
ctx := Ctx{
Spool: spool,
bytes.NewReader(data),
&dst,
); err != nil {
- panic(err)
+ t.Error(err)
+ return false
}
checksum := blake2b.Sum256(dst.Bytes())
if err := ioutil.WriteFile(
"bufio"
"bytes"
"compress/zlib"
- "crypto/cipher"
"crypto/rand"
"errors"
"hash"
"github.com/davecgh/go-xdr/xdr2"
"golang.org/x/crypto/blake2b"
- "golang.org/x/crypto/twofish"
)
func (ctx *Ctx) Tx(node *Node, pkt *Pkt, nice uint8, size, minSize int64, src io.Reader) (*Node, error) {
}
os.Remove(src.Name())
tmpW := bufio.NewWriter(src)
-
- tmpKey := make([]byte, 32)
- if _, err = rand.Read(tmpKey); err != nil {
- return nil, nil, 0, err
- }
- ciph, err := twofish.NewCipher(tmpKey)
- if err != nil {
+ tmpKey := new([32]byte)
+ if _, err = rand.Read(tmpKey[:]); err != nil {
return nil, nil, 0, err
}
- ctr := cipher.NewCTR(ciph, make([]byte, twofish.BlockSize))
- encrypter := &cipher.StreamWriter{S: ctr, W: tmpW}
- fileSize, err = io.Copy(encrypter, bufio.NewReader(os.Stdin))
+ written, err := ae(tmpKey, bufio.NewReader(os.Stdin), tmpW)
if err != nil {
return nil, nil, 0, err
}
+ fileSize = int64(written)
tmpW.Flush()
src.Seek(0, 0)
- ctr = cipher.NewCTR(ciph, make([]byte, twofish.BlockSize))
- reader = &cipher.StreamReader{S: ctr, R: bufio.NewReader(src)}
+ r, w := io.Pipe()
+ go ae(tmpKey, bufio.NewReader(src), w)
+ reader = r
} else {
src, err = os.Open(srcPath)
if err != nil {