/* |-------------------------------------------------------------------------- | Manifest |-------------------------------------------------------------------------- | | Name: | - Hash | | Purpose: | - Generate and verify cryptographic hash values using standard or | salted hashing methods. | | Guideline: | - Use for deterministic hashing workflows. | - Use for salted hashing workflows requiring verification support. | - Use for integrity verification and fingerprint generation. | - Accept exactly two primary parameters: type and config. | | Example: | - ObrimHash("calculate", config) | - ObrimHash("compare", config) | |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | Credit |-------------------------------------------------------------------------- | | Contributor: | - Rajon Ahmed | - Scionite | |-------------------------------------------------------------------------- */ package hash import ( "crypto/rand" "crypto/sha256" "crypto/sha512" "encoding/hex" "strings" "go/module/essential/visible/service/helper/log" "go/module/essential/visible/service/helper/status" ) // ObrimHash processes hash generation and verification requests. func ObrimHash( hashType string, config map[string]any, ) map[string]any { status.ObrimStatus("INFO", "Hash utility execution started.") log.ObrimLog("INIT", "Hash utility execution started.") if !obrimHashValidateType(hashType) { status.ObrimStatus("ERROR", "Invalid hash type.") log.ObrimLog("ERROR", "Invalid hash type.") return obrimHashBuildErrorPayload("FAILED_INVALID_TYPE") } if !obrimHashValidateConfig(hashType, config) { status.ObrimStatus("ERROR", "Invalid configuration.") log.ObrimLog("ERROR", "Invalid configuration.") return obrimHashBuildErrorPayload("FAILED_INVALID_CONFIG") } mode := config["mode"].(string) if !obrimHashValidateMode(mode) { status.ObrimStatus("ERROR", "Invalid mode.") log.ObrimLog("ERROR", "Invalid mode.") return obrimHashBuildErrorPayload("FAILED_INVALID_MODE") } algorithm := config["algorithm"].(string) if !obrimHashValidateAlgorithm(mode, algorithm) { status.ObrimStatus("ERROR", "Invalid algorithm.") log.ObrimLog("ERROR", "Invalid algorithm.") return obrimHashBuildErrorPayload("FAILED_INVALID_ALGORITHM") } switch hashType { case "calculate": return obrimHashCalculate(config) case "compare": return obrimHashCompare(config) default: return obrimHashBuildErrorPayload("FAILED_INVALID_TYPE") } } // obrimHashValidateType validates operation type. func obrimHashValidateType(hashType string) bool { switch hashType { case "calculate", "compare": return true default: return false } } // obrimHashValidateMode validates hashing mode. func obrimHashValidateMode(mode string) bool { switch mode { case "standard", "salted": return true default: return false } } // obrimHashValidateConfig validates configuration keys and values. func obrimHashValidateConfig( hashType string, config map[string]any, ) bool { if config == nil { return false } // Mutable variable holding supported keys. supportedKeys := map[string]bool{ "mode": true, "algorithm": true, "value": true, "hash": true, "salt": true, } for key := range config { if !supportedKeys[key] { return false } } modeValue, modeExists := config["mode"] algorithmValue, algorithmExists := config["algorithm"] valueValue, valueExists := config["value"] if !modeExists || !algorithmExists || !valueExists { return false } mode, modeOK := modeValue.(string) algorithm, algorithmOK := algorithmValue.(string) value, valueOK := valueValue.(string) if !modeOK || !algorithmOK || !valueOK { return false } if mode == "" || algorithm == "" || value == "" { return false } if hashType == "calculate" { if mode == "standard" { if _, exists := config["salt"]; exists { return false } } return true } if hashType == "compare" { hashValue, hashExists := config["hash"] if !hashExists { return false } hashString, hashOK := hashValue.(string) if !hashOK || hashString == "" { return false } if mode == "standard" { if _, exists := config["salt"]; exists { return false } } if mode == "salted" { saltValue, saltExists := config["salt"] if !saltExists { return false } saltString, saltOK := saltValue.(string) if !saltOK || saltString == "" { return false } } return true } return false } // obrimHashValidateAlgorithm validates hashing algorithm selection. func obrimHashValidateAlgorithm( mode string, algorithm string, ) bool { if mode == "standard" { switch algorithm { case "sha256", "sha512": return true } } if mode == "salted" { switch algorithm { case "salted_sha256", "salted_sha512": return true } } return false } // obrimHashGenerateHash executes the selected hashing algorithm. func obrimHashGenerateHash( algorithm string, value string, salt string, ) (string, bool) { switch algorithm { case "sha256": sum := sha256.Sum256([]byte(value)) return hex.EncodeToString(sum[:]), true case "sha512": sum := sha512.Sum512([]byte(value)) return hex.EncodeToString(sum[:]), true case "salted_sha256": sum := sha256.Sum256([]byte(value + salt)) return hex.EncodeToString(sum[:]), true case "salted_sha512": sum := sha512.Sum512([]byte(value + salt)) return hex.EncodeToString(sum[:]), true default: return "", false } } // obrimHashBuildSuccessPayload constructs success response payloads. func obrimHashBuildSuccessPayload( code string, payload map[string]any, ) map[string]any { return map[string]any{ "status": true, "code": code, "payload": payload, } } // obrimHashBuildErrorPayload constructs error response payloads. func obrimHashBuildErrorPayload(code string) map[string]any { return map[string]any{ "status": false, "code": code, "payload": nil, } } // obrimHashCalculate processes hash generation requests. func obrimHashCalculate( config map[string]any, ) map[string]any { mode := config["mode"].(string) switch mode { case "standard": return obrimHashCalculateStandard(config) case "salted": return obrimHashCalculateSalted(config) default: return obrimHashBuildErrorPayload("FAILED_INVALID_MODE") } } // obrimHashCalculateStandard generates a deterministic hash. func obrimHashCalculateStandard( config map[string]any, ) map[string]any { algorithm := config["algorithm"].(string) value := config["value"].(string) hashValue, success := obrimHashGenerateHash( algorithm, value, "", ) if !success { return obrimHashBuildErrorPayload("FAILED_HASH_GENERATION") } payload := map[string]any{ "algorithm": algorithm, "hash": hashValue, } status.ObrimStatus("SUCCESS", "Hash generated.") log.ObrimLog("SUCCESS", "Standard hash generated.") return obrimHashBuildSuccessPayload( "SUCCESS_CALCULATE_STANDARD", payload, ) } // obrimHashCalculateSalted generates a salted hash and salt pair. func obrimHashCalculateSalted( config map[string]any, ) map[string]any { algorithm := config["algorithm"].(string) value := config["value"].(string) // Mutable variable holding salt value. saltValue := "" if suppliedSalt, exists := config["salt"]; exists { saltString, ok := suppliedSalt.(string) if !ok || saltString == "" { return obrimHashBuildErrorPayload("FAILED_INVALID_SALT") } saltValue = saltString } else { generatedSalt, success := obrimHashGenerateSalt() if !success { return obrimHashBuildErrorPayload("FAILED_SALT_GENERATION") } saltValue = generatedSalt } hashValue, success := obrimHashGenerateHash( algorithm, value, saltValue, ) if !success { return obrimHashBuildErrorPayload("FAILED_HASH_GENERATION") } payload := map[string]any{ "algorithm": algorithm, "hash": hashValue, "salt": saltValue, } status.ObrimStatus("SUCCESS", "Salted hash generated.") log.ObrimLog("SUCCESS", "Salted hash generated.") return obrimHashBuildSuccessPayload( "SUCCESS_CALCULATE_SALTED", payload, ) } // obrimHashGenerateSalt generates a cryptographically secure salt. func obrimHashGenerateSalt() (string, bool) { // Mutable variable holding salt bytes. saltBytes := make([]byte, 32) _, err := rand.Read(saltBytes) if err != nil { return "", false } return hex.EncodeToString(saltBytes), true } // obrimHashCompare processes hash verification requests. func obrimHashCompare( config map[string]any, ) map[string]any { mode := config["mode"].(string) switch mode { case "standard": return obrimHashCompareStandard(config) case "salted": return obrimHashCompareSalted(config) default: return obrimHashBuildErrorPayload("FAILED_INVALID_MODE") } } // obrimHashCompareStandard regenerates a standard hash for verification. func obrimHashCompareStandard( config map[string]any, ) map[string]any { algorithm := config["algorithm"].(string) value := config["value"].(string) hashValue := config["hash"].(string) regeneratedHash, success := obrimHashGenerateHash( algorithm, value, "", ) if !success { return obrimHashBuildErrorPayload("FAILED_HASH_GENERATION") } matched := obrimHashVerify( regeneratedHash, hashValue, ) payload := map[string]any{ "algorithm": algorithm, "matched": matched, "hash": hashValue, } return obrimHashBuildSuccessPayload( "SUCCESS_COMPARE_STANDARD", payload, ) } // obrimHashCompareSalted regenerates a salted hash for verification. func obrimHashCompareSalted( config map[string]any, ) map[string]any { algorithm := config["algorithm"].(string) value := config["value"].(string) hashValue := config["hash"].(string) saltValue := config["salt"].(string) regeneratedHash, success := obrimHashGenerateHash( algorithm, value, saltValue, ) if !success { return obrimHashBuildErrorPayload("FAILED_HASH_GENERATION") } matched := obrimHashVerify( regeneratedHash, hashValue, ) payload := map[string]any{ "algorithm": algorithm, "matched": matched, "hash": hashValue, "salt": saltValue, } return obrimHashBuildSuccessPayload( "SUCCESS_COMPARE_SALTED", payload, ) } // obrimHashVerify compares regenerated and supplied hash values. func obrimHashVerify( regeneratedHash string, suppliedHash string, ) bool { return strings.Compare( regeneratedHash, suppliedHash, ) == 0 }