feat: initial release

This commit is contained in:
2026-01-16 02:39:40 +01:00
parent 15af32d382
commit 2af23db0ad
21 changed files with 1163 additions and 0 deletions
+70
View File
@@ -0,0 +1,70 @@
package crypto
import (
"crypto/aes"
"crypto/cipher"
"crypto/sha256"
"encoding/base64"
"encoding/binary"
"io"
)
const (
GCMChunkSize = 64 * 1024
NonceSize = 12
)
func DeriveKey(r io.Reader) ([]byte, error) {
h := sha256.New()
if _, err := io.Copy(h, r); err != nil {
return nil, err
}
return h.Sum(nil)[:16], nil
}
func GetID(key []byte, ext string) string {
h := sha256.New()
h.Write(key)
h.Write([]byte(ext))
return base64.RawURLEncoding.EncodeToString(h.Sum(nil)[:9])
}
type GCMStreamer struct {
AEAD cipher.AEAD
}
func NewGCMStreamer(key []byte) (*GCMStreamer, error) {
b, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
g, err := cipher.NewGCM(b)
if err != nil {
return nil, err
}
return &GCMStreamer{AEAD: g}, nil
}
func (g *GCMStreamer) EncryptStream(dst io.Writer, src io.Reader) error {
buf := make([]byte, GCMChunkSize)
var chunkIdx uint64 = 0
for {
n, err := io.ReadFull(src, buf)
if n > 0 {
nonce := make([]byte, NonceSize)
binary.BigEndian.PutUint64(nonce[4:], chunkIdx)
ciphertext := g.AEAD.Seal(nil, nonce, buf[:n], nil)
if _, werr := dst.Write(ciphertext); werr != nil {
return werr
}
chunkIdx++
}
if err == io.EOF || err == io.ErrUnexpectedEOF {
break
}
if err != nil {
return err
}
}
return nil
}