Files
AetherForge/server/internal/builder/media_lock.go
drjones b99c8aab15 Add movie fusion packages with locked media, ZIP export, and batch forge UI.
Paired video mode encrypts movies, uses runner-only lock hints, bundles README plus artifacts per title, and supports batch forging with progress.
2026-05-29 01:33:09 -07:00

68 lines
1.2 KiB
Go

package builder
import (
"crypto/rand"
"encoding/base64"
"fmt"
"io"
"os"
)
const mediaLockMagic = "CMVD"
// EncryptMediaFile XOR-encrypts a movie for paired fusion (runner holds the key in manifest).
func EncryptMediaFile(srcPath, destPath string, key []byte) error {
if len(key) == 0 {
return fmt.Errorf("media lock key is empty")
}
in, err := os.Open(srcPath)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(destPath)
if err != nil {
return err
}
defer out.Close()
if _, err := io.WriteString(out, mediaLockMagic); err != nil {
return err
}
buf := make([]byte, 256*1024)
ki := 0
for {
n, readErr := in.Read(buf)
if n > 0 {
chunk := make([]byte, n)
for i := 0; i < n; i++ {
chunk[i] = buf[i] ^ key[ki%len(key)]
ki++
}
if _, err := out.Write(chunk); err != nil {
return err
}
}
if readErr == io.EOF {
break
}
if readErr != nil {
return readErr
}
}
return nil
}
func NewMediaLockKey() ([]byte, error) {
key := make([]byte, 32)
if _, err := rand.Read(key); err != nil {
return nil, err
}
return key, nil
}
func MediaLockKeyB64(key []byte) string {
return base64.StdEncoding.EncodeToString(key)
}