1 // NNCP -- Node to Node copy, utilities for store-and-forward data exchange
2 // Copyright (C) 2016-2024 Sergey Matveev <stargrave@stargrave.org>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, version 3 of the License.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 xdr "github.com/davecgh/go-xdr/xdr2"
24 "go.cypherpunks.ru/balloon"
25 "golang.org/x/crypto/blake2b"
26 "golang.org/x/crypto/chacha20poly1305"
30 DefaultS = 1 << 20 / 32
44 func blake256() hash.Hash {
45 h, err := blake2b.New256(nil)
52 // Create an encrypted blob. sCost -- memory space requirements, number
53 // of hash-output sized (32 bytes) blocks. tCost -- time requirements,
54 // number of rounds. pCost -- number of parallel jobs.
55 func NewEBlob(sCost, tCost, pCost int, password, data []byte) ([]byte, error) {
58 if _, err = rand.Read(salt[:]); err != nil {
62 Magic: MagicNNCPBv3.B,
69 var eblobBuf bytes.Buffer
70 if _, err = xdr.Marshal(&eblobBuf, &eblob); err != nil {
73 key := balloon.H(blake256, password, salt[:], sCost, tCost, pCost)
74 aead, err := chacha20poly1305.New(key)
78 buf := make([]byte, 0, len(data)+aead.Overhead())
79 buf = aead.Seal(buf, make([]byte, aead.NonceSize()), data, eblobBuf.Bytes())
82 if _, err = xdr.Marshal(&eblobBuf, &eblob); err != nil {
85 return eblobBuf.Bytes(), nil
88 func DeEBlob(eblobRaw, password []byte) ([]byte, error) {
91 if _, err = xdr.Unmarshal(bytes.NewReader(eblobRaw), &eblob); err != nil {
96 err = MagicNNCPBv1.TooOld()
98 err = MagicNNCPBv1.TooOld()
114 aead, err := chacha20poly1305.New(key)
119 ciphertext := eblob.Blob
121 var eblobBuf bytes.Buffer
122 if _, err = xdr.Marshal(&eblobBuf, &eblob); err != nil {
125 data, err := aead.Open(
127 make([]byte, aead.NonceSize()),