1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
package scrypt
import (
"fmt"
"github.com/go-crypt/crypt/algorithm"
)
// Opt describes the functional option pattern for the scrypt.Hasher.
type Opt func(h *Hasher) (err error)
// WithVariant configures the scrypt.Variant of the resulting scrypt.Digest.
// Default is scrypt.VariantScrypt.
func WithVariant(variant Variant) Opt {
return func(h *Hasher) (err error) {
switch variant {
case VariantNone:
return nil
case VariantScrypt, VariantYescrypt:
h.variant = variant
return nil
default:
return fmt.Errorf(algorithm.ErrFmtHasherValidation, AlgName, fmt.Errorf("%w: variant '%d' is invalid", algorithm.ErrParameterInvalid, variant))
}
}
}
// WithVariantName uses the variant name or identifier to configure the scrypt.Variant of the resulting scrypt.Digest.
// Default is scrypt.VariantScrypt.
func WithVariantName(identifier string) Opt {
return func(h *Hasher) (err error) {
if identifier == "" {
return nil
}
variant := NewVariant(identifier)
if variant == VariantNone {
return fmt.Errorf(algorithm.ErrFmtHasherValidation, AlgName, fmt.Errorf("%w: variant identifier '%s' is invalid", algorithm.ErrParameterInvalid, identifier))
}
h.variant = variant
return nil
}
}
// WithK adjusts the key length of the resulting scrypt.Digest.
// Minimum is 1, Maximum is 137438953440. Default is 32.
func WithK(k int) Opt {
return func(h *Hasher) (err error) {
if k < KeyLengthMin || k > KeyLengthMax {
return fmt.Errorf(algorithm.ErrFmtHasherValidation, AlgName, fmt.Errorf(algorithm.ErrFmtInvalidIntParameter, algorithm.ErrParameterInvalid, "key length", KeyLengthMin, "", KeyLengthMax, k))
}
h.k = k
return nil
}
}
// WithKeyLength is an alias for WithK.
func WithKeyLength(k int) Opt {
return WithK(k)
}
// WithS adjusts the salt length of the resulting scrypt.Digest.
// Minimum is 8, Maximum is 1024. Default is 16.
func WithS(s int) Opt {
return func(h *Hasher) (err error) {
if s < SaltLengthMin || s > SaltLengthMax {
return fmt.Errorf(algorithm.ErrFmtHasherValidation, AlgName, fmt.Errorf(algorithm.ErrFmtInvalidIntParameter, algorithm.ErrParameterInvalid, "salt length", SaltLengthMin, "", SaltLengthMax, s))
}
h.bytesSalt = s
return nil
}
}
// WithSaltLength is an alias for WithS.
func WithSaltLength(s int) Opt {
return WithS(s)
}
// WithLN sets the ln parameter (logN) of the resulting scrypt.Digest.
// Minimum is 1, Maximum is 58. Default is 16.
func WithLN(ln int) Opt {
return func(h *Hasher) (err error) {
if ln < IterationsMin || ln > IterationsMax {
return fmt.Errorf(algorithm.ErrFmtHasherValidation, AlgName, fmt.Errorf(algorithm.ErrFmtInvalidIntParameter, algorithm.ErrParameterInvalid, "iterations", IterationsMin, "", IterationsMax, ln))
}
h.ln = ln
return nil
}
}
// WithR sets the r parameter (block size) of the resulting scrypt.Digest.
// Minimum is 1, Maximum is math.MaxInt / 256. Default is 8.
func WithR(r int) Opt {
return func(h *Hasher) (err error) {
if r < BlockSizeMin || r > BlockSizeMax {
return fmt.Errorf(algorithm.ErrFmtHasherValidation, AlgName, fmt.Errorf(algorithm.ErrFmtInvalidIntParameter, algorithm.ErrParameterInvalid, "block size", BlockSizeMin, "", BlockSizeMax, r))
}
h.r = r
return nil
}
}
// WithBlockSize is an alias for WithR.
func WithBlockSize(r int) Opt {
return WithS(r)
}
// WithP sets the p parameter (parallelism factor) of the resulting scrypt.Digest.
// Minimum is 1, Maximum is 1073741823. Default is 1.
func WithP(p int) Opt {
return func(h *Hasher) (err error) {
if p < ParallelismMin || p > ParallelismMax {
return fmt.Errorf(algorithm.ErrFmtHasherValidation, AlgName, fmt.Errorf(algorithm.ErrFmtInvalidIntParameter, algorithm.ErrParameterInvalid, "parallelism", ParallelismMin, "", ParallelismMax, p))
}
h.p = p
return nil
}
}
// WithParallelism is an alias for WithP.
func WithParallelism(p int) Opt {
return WithP(p)
}
|