From e7886a26fb48c1a4755db902c83e878b113a568d Mon Sep 17 00:00:00 2001 From: The-Tysonator Date: Thu, 12 Oct 2023 11:11:16 +0100 Subject: [PATCH] Added the ARGON2 algorithm. --- README.md | 1 + algorithms/argon2/Algorithm.go | 22 +++++++++++++ algorithms/argon2/CheckHash.go | 58 ++++++++++++++++++++++++++++++++++ algorithms/argon2/Hash.go | 24 ++++++++++++++ 4 files changed, 105 insertions(+) create mode 100644 algorithms/argon2/Algorithm.go create mode 100644 algorithms/argon2/CheckHash.go create mode 100644 algorithms/argon2/Hash.go diff --git a/README.md b/README.md index fb6a1da..29f0d4b 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ GCL is a Go library designed to offer a robust collection of cryptographic algor GCL offers support for a diverse range of cryptographic algorithms, ensuring that your cryptographic requirements are comprehensively addressed. Our library includes: +- [X] ARGON2 - [X] BLAKE2 - [X] SHA256 - [X] SHA512 diff --git a/algorithms/argon2/Algorithm.go b/algorithms/argon2/Algorithm.go new file mode 100644 index 0000000..d1149c1 --- /dev/null +++ b/algorithms/argon2/Algorithm.go @@ -0,0 +1,22 @@ +package argon2 + +// Algorithm +type Algorithm struct { + keyLen uint32 + memory uint32 + saltLen uint32 + threads uint8 + time uint32 +} + +// New +func New(keyLen uint32, memory uint32, saltLen uint32, threads uint8, time uint32) Algorithm { + // Return Algorithm + return Algorithm{ + keyLen: keyLen, + memory: memory, + saltLen: saltLen, + threads: threads, + time: time, + } +} diff --git a/algorithms/argon2/CheckHash.go b/algorithms/argon2/CheckHash.go new file mode 100644 index 0000000..5920232 --- /dev/null +++ b/algorithms/argon2/CheckHash.go @@ -0,0 +1,58 @@ +package argon2 + +import ( + // Standard + "crypto/subtle" + "encoding/base64" + "errors" + "fmt" + "strings" + + // Standard Extended + "golang.org/x/crypto/argon2" +) + +// Check Hash +func (algorithm Algorithm) CheckHash(data []byte, hashToCheck string) (bool, error) { + // Hash Information + var version int + var memory uint32 + var threads uint8 + var time uint32 + // Hash Parts + hashParts := strings.Split(hashToCheck, "$") + // Validate Hash Parts + if len(hashParts) != 6 { + return false, errors.New("the hash is invalid") + } + // Get Version + _, err := fmt.Sscanf(hashParts[2], "v=%d", &version) + // Handle Error + if err != nil { + return false, err + } + // Validate Version + if version != argon2.Version { + return false, errors.New("incompatible version") + } + // Get Other Hash Information + _, err = fmt.Sscanf(hashParts[3], "m=%d,t=%d,p=%d", &memory, &time, &threads) + // Handle Error + if err != nil { + return false, err + } + // Salt + salt, err := base64.RawStdEncoding.Strict().DecodeString(hashParts[4]) + // Handle Error + if err != nil { + return false, err + } + // Hash + hash, err := base64.RawStdEncoding.Strict().DecodeString(hashParts[5]) + // Handle Error + if err != nil { + return false, err + } + // Return Match + return subtle.ConstantTimeCompare(argon2.IDKey(data, salt, time, memory, threads, uint32(len(hash))), hash) == 1, err +} diff --git a/algorithms/argon2/Hash.go b/algorithms/argon2/Hash.go new file mode 100644 index 0000000..d77f768 --- /dev/null +++ b/algorithms/argon2/Hash.go @@ -0,0 +1,24 @@ +package argon2 + +import ( + // Standard + "crypto/rand" + "encoding/base64" + "fmt" + + // Standard Extended + "golang.org/x/crypto/argon2" +) + +// Hash +func (algorithm Algorithm) Hash(data []byte) (string, error) { + // Generate Salt + salt := make([]byte, algorithm.saltLen) + _, err := rand.Read(salt) + // Handle Error + if err != nil { + return "", err + } + // Hash + return fmt.Sprintf("$argon2id$v=%d$m=%d,t=%d,p=%d$%s$%s", argon2.Version, algorithm.memory, algorithm.time, algorithm.threads, base64.RawStdEncoding.EncodeToString(salt), base64.RawStdEncoding.EncodeToString(argon2.IDKey(data, salt, algorithm.time, algorithm.memory, algorithm.threads, algorithm.keyLen))), err +}