diff --git a/x/logic/predicate/crypto.go b/x/logic/predicate/crypto.go index cb6b834b..15c8a591 100644 --- a/x/logic/predicate/crypto.go +++ b/x/logic/predicate/crypto.go @@ -72,6 +72,7 @@ func SHAHash(vm *engine.VM, data, hash engine.Term, cont engine.Cont, env *engin // For Alg, the supported algorithms are: // // - sha256 (default): The SHA-256 algorithm. +// - sha512: The SHA-512 algorithm. // // Note: Due to the principles of the hash algorithm (pre-image resistance), this predicate can only compute the hash // value from input data, and cannot compute the original input data from the hash value. @@ -93,29 +94,28 @@ func CryptoDataHash( algorithmOpt := engine.NewAtom("algorithm") return engine.Delay(func(ctx context.Context) *engine.Promise { - algorithm, err := getOptionAsAtomWithDefault(algorithmOpt, options, engine.NewAtom("sha256"), env, functor) + algorithmAtom, err := getOptionAsAtomWithDefault(algorithmOpt, options, engine.NewAtom("sha256"), env, functor) if err != nil { return engine.Error(err) } + algorithm, err := util.ParseHashAlg(algorithmAtom.String()) + if err != nil { + return engine.Error(fmt.Errorf("%s: invalid algorithm: %s. Possible values: %s", + functor, + algorithmAtom.String(), + util.HashAlgNames())) + } decodedData, err := TermToBytes(data, options, AtomUtf8, env) if err != nil { return engine.Error(fmt.Errorf("%s: failed to decode data: %w", functor, err)) } - switch algorithm.String() { - case util.HashAlgSha256.String(): - result, err := util.Hash(util.HashAlgSha256, decodedData) - if err != nil { - engine.Error(fmt.Errorf("sha_hash/2: failed to hash data: %w", err)) - } - - return engine.Unify(vm, hash, BytesToList(result), cont, env) - default: - return engine.Error(fmt.Errorf("%s: invalid algorithm: %s. Possible values: %s", - functor, - algorithm.String(), - util.HashAlgNames())) + result, err := util.Hash(algorithm, decodedData) + if err != nil { + engine.Error(fmt.Errorf("sha_hash/2: failed to hash data: %w", err)) } + + return engine.Unify(vm, hash, BytesToList(result), cont, env) }) } diff --git a/x/logic/util/crypto.go b/x/logic/util/crypto.go index 154cfe7a..3ad96fdb 100644 --- a/x/logic/util/crypto.go +++ b/x/logic/util/crypto.go @@ -6,6 +6,7 @@ import ( "crypto/ed25519" "crypto/elliptic" "crypto/sha256" + "crypto/sha512" "fmt" "github.com/dustinxie/ecc" @@ -26,7 +27,7 @@ func (a KeyAlg) String() string { } // HashAlg is the type of hash algorithm supported by the crypto util functions. -// ENUM(sha256) +// ENUM(sha256,sha512) type HashAlg int // VerifySignature verifies the signature of the given message with the given public key using the given algorithm. @@ -56,6 +57,10 @@ func Hash(alg HashAlg, bytes []byte) ([]byte, error) { hasher := sha256.New() hasher.Write(bytes) return hasher.Sum(nil), nil + case HashAlgSha512: + hasher := sha512.New() + hasher.Write(bytes) + return hasher.Sum(nil), nil default: return nil, fmt.Errorf("algo %s not supported", alg) } diff --git a/x/logic/util/crypto_enum.go b/x/logic/util/crypto_enum.go index fd8d7a1b..0b020fef 100644 --- a/x/logic/util/crypto_enum.go +++ b/x/logic/util/crypto_enum.go @@ -14,14 +14,17 @@ import ( const ( // HashAlgSha256 is a HashAlg of type Sha256. HashAlgSha256 HashAlg = iota + // HashAlgSha512 is a HashAlg of type Sha512. + HashAlgSha512 ) var ErrInvalidHashAlg = fmt.Errorf("not a valid HashAlg, try [%s]", strings.Join(_HashAlgNames, ", ")) -const _HashAlgName = "sha256" +const _HashAlgName = "sha256sha512" var _HashAlgNames = []string{ _HashAlgName[0:6], + _HashAlgName[6:12], } // HashAlgNames returns a list of possible string values of HashAlg. @@ -33,6 +36,7 @@ func HashAlgNames() []string { var _HashAlgMap = map[HashAlg]string{ HashAlgSha256: _HashAlgName[0:6], + HashAlgSha512: _HashAlgName[6:12], } // String implements the Stringer interface. @@ -51,7 +55,8 @@ func (x HashAlg) IsValid() bool { } var _HashAlgValue = map[string]HashAlg{ - _HashAlgName[0:6]: HashAlgSha256, + _HashAlgName[0:6]: HashAlgSha256, + _HashAlgName[6:12]: HashAlgSha512, } // ParseHashAlg attempts to convert a string to a HashAlg.