yescrypt

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 19, 2024 License: BSD-3-Clause Imports: 7 Imported by: 4

README

Go implementation of scrypt and yescrypt key derivation and password hashing
functions, which have their homepages at:
https://www.tarsnap.com/scrypt.html
https://www.openwall.com/yescrypt/

This Go implementation of scrypt was created in 2012 by Dmitry Chestnykh, who
has since contributed it to the official Go x/crypto repository where it's now
maintained by the Go authors.  This tree is based on Dmitry's with all x/crypto
changes as of mid-2024 added.  The implementation of yescrypt was added in 2024
by Solar Designer, sponsored by Sandfly Security https://sandflysecurity.com -
Agentless Security for Linux.

INSTALLATION

    $ go get github.com/openwall/yescrypt-go

PACKAGE
    import "github.com/openwall/yescrypt-go"

    Package yescrypt implements the scrypt key derivation function as defined
    in Colin Percival's paper "Stronger Key Derivation via Sequential
    Memory-Hard Functions", as well as Solar Designer's yescrypt.

FUNCTIONS

func ScryptKey(password, salt []byte, N, r, p, keyLen int) ([]byte, error)

    ScryptKey implements classic scrypt (not yescrypt).  It is compatible with
    the x/crypto scrypt module's Key.

    It derives a key from the password, salt and cost parameters, returning a
    byte slice of length keyLen that can be used as cryptographic key.

    N is a CPU/memory cost parameter, must be a power of two greater than 1.
    r and p must satisfy r * p < 2³⁰. If the parameters do not satisfy the
    limits, the function returns a nil byte slice and an error.

    For example, you can get a derived key for e.g. AES-256 (which needs a
    32-byte key) by doing:

	dk, err := yescrypt.ScryptKey([]byte("some password"), salt, 32768, 8, 1, 32)

The recommended parameters for interactive logins as of 2017 are N=32768, r=8
and p=1. The parameters N, r, and p should be increased as memory latency and
CPU parallelism increases; consider setting N to the highest power of 2 you
can derive within 100 milliseconds. Remember to get a good random salt.

func Key(password, salt []byte, N, r, p, keyLen int) ([]byte, error)

    Key is similar to ScryptKey, but computes native yescrypt assuming
    reference yescrypt's current default flags (as of yescrypt 1.1.0), p=1
    (which it currently requires), t=0, and no ROM.  Example usage:

	dk, err := yescrypt.Key([]byte("some password"), salt, 32768, 8, 1, 32)

    The set of parameters accepted by Key will likely change in future versions
    of this Go module to support more yescrypt functionality.

func Hash(password, setting []byte) ([]byte, error)

    Computes yescrypt hash encoding given the password and existing yescrypt
    setting or full hash encoding.  The salt and other parameters are decoded
    from setting.  Currently supports (only a little more than) the subset of
    yescrypt parameters that libxcrypt can generate (as of libxcrypt 4.4.36).

KEYWORDS

    go, golang, scrypt, yescrypt, kdf, hash, password

Documentation

Overview

Example
package main

import (
	"encoding/base64"
	"fmt"
	"log"

	"github.com/openwall/yescrypt-go"
)

func main() {
	// DO NOT use this salt value; generate your own random salt. 8 bytes is
	// a good length.
	salt := []byte{0xc8, 0x28, 0xf2, 0x58, 0xa7, 0x6a, 0xad, 0x7b}

	dk, err := yescrypt.ScryptKey([]byte("some password"), salt, 1<<15, 8, 1, 32)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(base64.StdEncoding.EncodeToString(dk))
	hash, err := yescrypt.Hash([]byte("openwall"), []byte("$y$j9T$AAt9R641xPvCI9nXw1HHW/"))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(hash))
	hash, err = yescrypt.Hash([]byte("pleaseletmein"), []byte("$y$j9T$e8R9q85ZuzUkArEUurdtS.$esON.7y6H.u3UCPVCpbRFueRpAut2n2cMf1EhpjbuiC"))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(hash))
}
Output:
lGnMz8io0AUkfzn6Pls1qX20Vs7PGN6sbYQ2TQgY12M=
$y$j9T$AAt9R641xPvCI9nXw1HHW/$cuQRBMN3N/f8IcmVN.4YrZ1bHMOiLOoz9/XQMKV/v0A
$y$j9T$e8R9q85ZuzUkArEUurdtS.$esON.7y6H.u3UCPVCpbRFueRpAut2n2cMf1EhpjbuiC

Index

Examples

Constants

View Source
const (
	PWXsimple = 2
	PWXgather = 4
	PWXrounds = 6
	Swidth    = 8
)

These were tunable at design time, but they must meet certain constraints

View Source
const (
	PWXbytes = PWXgather * PWXsimple * 8
	PWXwords = PWXbytes / 8
	Sbytes   = 3 * (1 << Swidth) * PWXsimple * 8
	Swords   = Sbytes / 8
	Smask    = (((1 << Swidth) - 1) * PWXsimple * 8)
)

Derived values. These were never tunable on their own.

Variables

This section is empty.

Functions

func Hash

func Hash(password, setting []byte) ([]byte, error)

Computes yescrypt hash encoding given the password and existing yescrypt setting or full hash encoding. The salt and other parameters are decoded from setting. Currently supports (only a little more than) the subset of yescrypt parameters that libxcrypt can generate (as of libxcrypt 4.4.36).

func Key

func Key(password, salt []byte, N, r, p, keyLen int) ([]byte, error)

Native yescrypt

Key is similar to ScryptKey, but computes native yescrypt assuming reference yescrypt's current default flags (as of yescrypt 1.1.0), p=1 (which it currently requires), t=0, and no ROM. Example usage:

dk, err := yescrypt.Key([]byte("some password"), salt, 32768, 8, 1, 32)

The set of parameters accepted by Key will likely change in future versions of this Go module to support more yescrypt functionality.

func ScryptKey

func ScryptKey(password, salt []byte, N, r, p, keyLen int) ([]byte, error)

Classic scrypt

ScryptKey implements classic scrypt (not yescrypt). It is compatible with the x/crypto scrypt module's Key.

It derives a key from the password, salt and cost parameters, returning a byte slice of length keyLen that can be used as cryptographic key.

N is a CPU/memory cost parameter, which must be a power of two greater than 1. r and p must satisfy r * p < 2³⁰. If the parameters do not satisfy the limits, the function returns a nil byte slice and an error.

For example, you can get a derived key for e.g. AES-256 (which needs a 32-byte key) by doing:

dk, err := yescrypt.ScryptKey([]byte("some password"), salt, 32768, 8, 1, 32)

The recommended parameters for interactive logins as of 2017 are N=32768, r=8 and p=1. The parameters N, r, and p should be increased as memory latency and CPU parallelism increases; consider setting N to the highest power of 2 you can derive within 100 milliseconds. Remember to get a good random salt.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL