go/cm/enc/chapoly/dem.go | 89 ++++++++++++++++++++++++++++++++--------------------- go/cm/go.mod | 1 + go/cm/go.sum | 2 ++ diff --git a/go/cm/enc/chapoly/dem.go b/go/cm/enc/chapoly/dem.go index 568895e49401f09ab253c9e2a608ce2826a175d87626db35ae09c6849fb7e554..0f1672930df314f588c21587fecc70c55a9c0c3163da2f92ecdee869a907d7ef 100644 --- a/go/cm/enc/chapoly/dem.go +++ b/go/cm/enc/chapoly/dem.go @@ -17,27 +17,30 @@ package chapoly import ( "bytes" - "crypto/cipher" "crypto/hkdf" "crypto/subtle" "errors" "hash" "io" + "github.com/aead/chacha20" "go.cypherpunks.su/keks" "golang.org/x/crypto/blake2b" "golang.org/x/crypto/chacha20poly1305" + "golang.org/x/crypto/poly1305" ) const ( - ChunkLen = 128 * 1024 - CommitmentLen = 32 - CEKLen = blake2b.Size - DEMAlgo = "xchapoly-krkc" + ChunkLen = 128 * 1024 + CommitmentLen = 32 + CEKLen = blake2b.Size + DEMAlgo = "xchapoly-krkc" + Poly1305KeyLen = 32 ) type keymat struct { key []byte + mac [Poly1305KeyLen]byte iv []byte } @@ -72,34 +75,43 @@ keymats := make(chan keymat, procs) go func() { ck := cek var key []byte + var mac []byte var iv []byte var errHKDF error for { + ck, errHKDF = hkdf.Extract(blake2bHash, nil, ck) + if errHKDF != nil { + panic(errHKDF) + } + ck, errHKDF = hkdf.Expand( + blake2bHash, ck, "cm/encrypted/xchapoly-krkc/kr", CEKLen) + if errHKDF != nil { + panic(errHKDF) + } key, errHKDF = hkdf.Expand( blake2bHash, ck, "cm/encrypted/xchapoly-krkc/key", chacha20poly1305.KeySize) if errHKDF != nil { panic(errHKDF) } + mac, errHKDF = hkdf.Expand( + blake2bHash, ck, "cm/encrypted/xchapoly-krkc/mac", + Poly1305KeyLen) + if errHKDF != nil { + panic(errHKDF) + } iv, errHKDF = hkdf.Expand( blake2bHash, ck, "cm/encrypted/xchapoly-krkc/iv", chacha20poly1305.NonceSizeX) if errHKDF != nil { panic(errHKDF) } - keymats <- keymat{key: key, iv: iv} - ck, errHKDF = hkdf.Extract(blake2bHash, nil, ck) - if errHKDF != nil { - panic(errHKDF) - } - ck, errHKDF = hkdf.Expand( - blake2bHash, ck, "cm/encrypted/xchapoly-krkc/kr", CEKLen) - if errHKDF != nil { - panic(errHKDF) - } + k := keymat{key: key, iv: iv} + copy(k.mac[:], mac) + keymats <- k } }() - blobChunkLen := ChunkLen + chacha20poly1305.Overhead + CommitmentLen + blobChunkLen := ChunkLen + +CommitmentLen var blobDecoder *keks.BlobDecoder if seal { if blob { @@ -122,47 +134,54 @@ processed: make(chan error), } ready <- &j var errJob error - var ciph cipher.AEAD var com hash.Hash - var tag []byte + var tag [16]byte ourCom := make([]byte, CommitmentLen) for { <-j.bufReady - ciph, errJob = chacha20poly1305.NewX(j.keymat.key) - if errJob != nil { - panic(errJob) - } com, errJob = blake2b.New(CommitmentLen, nil) if errJob != nil { panic(errJob) } if seal { - ciph.Seal( - j.buf[:0], + chacha20.XORKeyStream( + j.buf[:len(j.buf)-CommitmentLen], + j.buf[:len(j.buf)-CommitmentLen], j.keymat.iv, - j.buf[:len(j.buf)-chacha20poly1305.Overhead-CommitmentLen], - nil, + j.keymat.key, ) - tag = j.buf[len(j.buf)-chacha20poly1305.Overhead-CommitmentLen:] - tag = tag[:chacha20poly1305.Overhead] + poly1305.Sum( + &tag, + j.buf[:len(j.buf)-CommitmentLen], + &j.keymat.mac, + ) com.Write(j.keymat.key) com.Write(j.keymat.iv) - com.Write(tag) + com.Write(j.keymat.mac[:]) + com.Write(tag[:]) com.Sum(j.buf[:len(j.buf)-CommitmentLen]) } else { - tag = j.buf[len(j.buf)-chacha20poly1305.Overhead-CommitmentLen:] - tag = tag[:chacha20poly1305.Overhead] + poly1305.Sum( + &tag, + j.buf[:len(j.buf)-CommitmentLen], + &j.keymat.mac, + ) com.Write(j.keymat.key) com.Write(j.keymat.iv) - com.Write(tag) + com.Write(j.keymat.mac[:]) + com.Write(tag[:]) ourCom = com.Sum(ourCom[:0]) if subtle.ConstantTimeCompare( ourCom, j.buf[len(j.buf)-CommitmentLen:], ) == 1 { - j.buf, errJob = ciph.Open( - j.buf[:0], j.keymat.iv, j.buf[:len(j.buf)-CommitmentLen], nil, + chacha20.XORKeyStream( + j.buf[:len(j.buf)-CommitmentLen], + j.buf[:len(j.buf)-CommitmentLen], + j.keymat.iv, + j.keymat.key, ) + j.buf = j.buf[:len(j.buf)-CommitmentLen] } else { errJob = errors.New("commitment differs") } @@ -242,7 +261,7 @@ } errR = nil eof = true if seal { - j.buf = j.buf[:n+chacha20poly1305.Overhead+CommitmentLen] + j.buf = j.buf[:n+CommitmentLen] } } if !seal && n == 0 { diff --git a/go/cm/go.mod b/go/cm/go.mod index d84456d38b6902ae11317995a03200bdd900c1a2ccef20871029611b250884cb..189fda0806329c1abd8cfbdb04e06fc73c7b6a834eaca2dc9eb66dd8fd9665bb 100644 --- a/go/cm/go.mod +++ b/go/cm/go.mod @@ -13,6 +13,7 @@ golang.org/x/term v0.28.0 ) require ( + github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect go.cypherpunks.su/tai64n/v4 v4.1.1 // indirect ) diff --git a/go/cm/go.sum b/go/cm/go.sum index e66f328fedd01e79a27e9cec39a914db1bbd75caaba3589f97e91352fbab0ce0..e1bf0f59deeb96897e2c9e4525237a37130447e9c1944cb09a2cdb37808b15ac 100644 --- a/go/cm/go.sum +++ b/go/cm/go.sum @@ -1,3 +1,5 @@ +github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY= +github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=