package common import ( "crypto/ed25519" "crypto/hmac" "crypto/sha256" "encoding/base64" "encoding/hex" "errors" "golang.org/x/crypto/bcrypt" ) func GenerateHMACWithKey(key []byte, data string) string { h := hmac.New(sha256.New, key) h.Write([]byte(data)) return hex.EncodeToString(h.Sum(nil)) } func GenerateHMAC(data string) string { h := hmac.New(sha256.New, []byte(CryptoSecret)) h.Write([]byte(data)) return hex.EncodeToString(h.Sum(nil)) } func Password2Hash(password string) (string, error) { passwordBytes := []byte(password) hashedPassword, err := bcrypt.GenerateFromPassword(passwordBytes, bcrypt.DefaultCost) return string(hashedPassword), err } func ValidatePasswordAndHash(password string, hash string) bool { err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) return err == nil } // VerifyEd25519Signature validates a base64-encoded Ed25519 signature over // the given message bytes, using a base64-encoded 32-byte public key. // Returns nil if valid, otherwise an error describing what failed. // // Used by the device-signature middleware to authenticate per-request // signatures from device-bound Heicode clients. The client signs the // SHA-256 hash of a canonical request string; this helper just does the // raw Ed25519 verify and surface-level decode. func VerifyEd25519Signature(pubkeyB64 string, message []byte, signatureB64 string) error { if pubkeyB64 == "" { return errors.New("empty public key") } if signatureB64 == "" { return errors.New("empty signature") } pubkey, err := base64.StdEncoding.DecodeString(pubkeyB64) if err != nil { return errors.New("public key is not valid base64") } if len(pubkey) != ed25519.PublicKeySize { return errors.New("public key has wrong length") } sig, err := base64.StdEncoding.DecodeString(signatureB64) if err != nil { return errors.New("signature is not valid base64") } if len(sig) != ed25519.SignatureSize { return errors.New("signature has wrong length") } if !ed25519.Verify(ed25519.PublicKey(pubkey), message, sig) { return errors.New("signature did not verify") } return nil }