sonr/crypto/subtle/hkdf.go
Prad Nukala 807b2e86ec
feature/1220 origin handle exists method (#1241)
* feat: add docs and CI workflow for publishing to onsonr.dev

* (refactor): Move hway,motr executables to their own repos

* feat: simplify devnet and testnet configurations

* refactor: update import path for didcrypto package

* docs(networks): Add README with project overview, architecture, and community links

* refactor: Move network configurations to deploy directory

* build: update golang version to 1.23

* refactor: move logger interface to appropriate package

* refactor: Move devnet configuration to networks/devnet

* chore: improve release process with date variable

* (chore): Move Crypto Library

* refactor: improve code structure and readability in DID module

* feat: integrate Trunk CI checks

* ci: optimize CI workflow by removing redundant build jobs

---------

Co-authored-by: Darp Alakun <i@prad.nu>
2025-01-06 17:06:10 +00:00

56 lines
1.3 KiB
Go

package subtle
import (
"errors"
"fmt"
"io"
"golang.org/x/crypto/hkdf"
)
const (
// Minimum tag size in bytes. This provides minimum 80-bit security strength.
minTagSizeInBytes = uint32(10)
)
var errHKDFInvalidInput = errors.New("HKDF: invalid input")
// validateHKDFParams validates parameters of HKDF constructor.
func validateHKDFParams(hash string, _ uint32, tagSize uint32) error {
// validate tag size
digestSize, err := GetHashDigestSize(hash)
if err != nil {
return err
}
if tagSize > 255*digestSize {
return fmt.Errorf("tag size too big")
}
if tagSize < minTagSizeInBytes {
return fmt.Errorf("tag size too small")
}
return nil
}
// ComputeHKDF extracts a pseudorandom key.
func ComputeHKDF(hashAlg string, key []byte, salt []byte, info []byte, tagSize uint32) ([]byte, error) {
keySize := uint32(len(key))
if err := validateHKDFParams(hashAlg, keySize, tagSize); err != nil {
return nil, fmt.Errorf("hkdf: %s", err)
}
hashFunc := GetHashFunc(hashAlg)
if hashFunc == nil {
return nil, fmt.Errorf("hkdf: invalid hash algorithm")
}
if len(salt) == 0 {
salt = make([]byte, hashFunc().Size())
}
result := make([]byte, tagSize)
kdf := hkdf.New(hashFunc, key, salt, info)
n, err := io.ReadFull(kdf, result)
if n != len(result) || err != nil {
return nil, fmt.Errorf("compute of hkdf failed")
}
return result, nil
}