- Fix remaining 187 pkg/ files referencing core/cli → core/go - Move SDK library code from internal/cmd/sdk/ → pkg/sdk/ (new package) - Create pkg/rag/helpers.go with convenience functions from internal/cmd/rag/ - Fix pkg/mcp/tools_rag.go to use pkg/rag instead of internal/cmd/rag - Fix pkg/build/buildcmd/cmd_sdk.go and pkg/release/sdk.go to use pkg/sdk - Remove all non-library content: main.go, internal/, cmd/, docker/, scripts/, tasks/, tools/, .core/, .forgejo/, .woodpecker/, Taskfile.yml - Run go mod tidy to trim unused dependencies core/go is now a pure Go package suite (library only). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Claude <developers@lethean.io> Reviewed-on: #3
60 lines
1.9 KiB
Go
60 lines
1.9 KiB
Go
// Package crypt provides cryptographic utilities including encryption,
|
|
// hashing, key derivation, HMAC, and checksum functions.
|
|
package crypt
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/sha256"
|
|
"io"
|
|
|
|
core "forge.lthn.ai/core/go/pkg/framework/core"
|
|
"golang.org/x/crypto/argon2"
|
|
"golang.org/x/crypto/hkdf"
|
|
"golang.org/x/crypto/scrypt"
|
|
)
|
|
|
|
// Argon2id default parameters.
|
|
const (
|
|
argon2Memory = 64 * 1024 // 64 MB
|
|
argon2Time = 3
|
|
argon2Parallelism = 4
|
|
argon2KeyLen = 32
|
|
argon2SaltLen = 16
|
|
)
|
|
|
|
// DeriveKey derives a key from a passphrase using Argon2id with default parameters.
|
|
// The salt must be argon2SaltLen bytes. keyLen specifies the desired key length.
|
|
func DeriveKey(passphrase, salt []byte, keyLen uint32) []byte {
|
|
return argon2.IDKey(passphrase, salt, argon2Time, argon2Memory, argon2Parallelism, keyLen)
|
|
}
|
|
|
|
// DeriveKeyScrypt derives a key from a passphrase using scrypt.
|
|
// Uses recommended parameters: N=32768, r=8, p=1.
|
|
func DeriveKeyScrypt(passphrase, salt []byte, keyLen int) ([]byte, error) {
|
|
key, err := scrypt.Key(passphrase, salt, 32768, 8, 1, keyLen)
|
|
if err != nil {
|
|
return nil, core.E("crypt.DeriveKeyScrypt", "failed to derive key", err)
|
|
}
|
|
return key, nil
|
|
}
|
|
|
|
// HKDF derives a key using HKDF-SHA256.
|
|
// secret is the input keying material, salt is optional (can be nil),
|
|
// info is optional context, and keyLen is the desired output length.
|
|
func HKDF(secret, salt, info []byte, keyLen int) ([]byte, error) {
|
|
reader := hkdf.New(sha256.New, secret, salt, info)
|
|
key := make([]byte, keyLen)
|
|
if _, err := io.ReadFull(reader, key); err != nil {
|
|
return nil, core.E("crypt.HKDF", "failed to derive key", err)
|
|
}
|
|
return key, nil
|
|
}
|
|
|
|
// generateSalt creates a random salt of the given length.
|
|
func generateSalt(length int) ([]byte, error) {
|
|
salt := make([]byte, length)
|
|
if _, err := rand.Read(salt); err != nil {
|
|
return nil, core.E("crypt.generateSalt", "failed to generate random salt", err)
|
|
}
|
|
return salt, nil
|
|
}
|