Skip to content

Commit f7d2c56

Browse files
committed
docs: rewrite README with usage guide
- expand README with rationale (“Why pwdhash?”), installation steps, and a fuller Quick Start example - document configuration options, custom hasher integration, and PHC string layout for clarity - describe testing/lint workflow plus contributor expectations and license reminder
1 parent 03588fc commit f7d2c56

1 file changed

Lines changed: 112 additions & 19 deletions

File tree

README.md

Lines changed: 112 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,125 @@
11
# pwdhash
22

3-
`pwdhash` is a modern, extensible password hashing library for Go.
3+
`pwdhash` is a Go library for producing PHC-compatible password hashes with sensible Argon2id defaults, explicit configuration, and deterministic rehash guidance.
44

5-
Inspired by:
6-
- PHC string format
7-
- argon2id best practices
8-
- pwdlib (Python)
5+
## Why pwdhash?
96

10-
## Features
7+
- **Modern defaults** – ships with Argon2id tuned to `64MiB` memory, `3` iterations, `4` lanes, `16` byte salts, and `32` byte keys.
8+
- **PHC compliance** – encodes outputs as `$argon2id$v=19$...` strings so you can interoperate with other runtimes.
9+
- **Extensible registry** – swap or add hashers through options without touching call sites.
10+
- **Clear lifecycle**`Hash`, `Verify`, and `NeedsRehash` expose the minimal API you need for password management.
11+
- **Constant-time verification** – comparisons run through `crypto/subtle` helpers to avoid timing leaks.
1112

12-
- Argon2id (default)
13-
- PHC-compliant encoding
14-
- Rehash detection
15-
- Constant-time verification
16-
- Extensible hasher registry
13+
## Installation
1714

18-
## Example
15+
```bash
16+
go get github.com/allisson/go-pwdhash
17+
```
18+
19+
The module targets Go 1.24 and depends only on `golang.org/x/crypto` plus `testify` for tests.
20+
21+
## Quick Start
1922

2023
```go
21-
hasher, _ := pwdhash.New()
24+
package main
2225

23-
hash, _ := hasher.Hash([]byte("secret"))
26+
import (
27+
"fmt"
2428

25-
ok, _ := hasher.Verify([]byte("secret"), hash)
29+
"github.com/allisson/go-pwdhash"
30+
)
2631

27-
if ok {
28-
needs, _ := hasher.NeedsRehash(hash)
29-
if needs {
30-
hash, _ = hasher.Hash([]byte("secret"))
32+
func main() {
33+
hasher, err := pwdhash.New()
34+
if err != nil {
35+
panic(err)
3136
}
37+
38+
encoded, err := hasher.Hash([]byte("s3cret"))
39+
if err != nil {
40+
panic(err)
41+
}
42+
43+
ok, err := hasher.Verify([]byte("s3cret"), encoded)
44+
if err != nil {
45+
panic(err)
46+
}
47+
fmt.Println("password matches?", ok)
48+
49+
needsRehash, err := hasher.NeedsRehash(encoded)
50+
if err != nil {
51+
panic(err)
52+
}
53+
fmt.Println("should upgrade hash?", needsRehash)
54+
}
55+
```
56+
57+
## Configuration
58+
59+
`pwdhash.New` accepts functional options. By default it registers a single Argon2id hasher returned by `argon2.Default()`. To customize parameters, call the constructor directly and inject it:
60+
61+
```go
62+
import "github.com/allisson/go-pwdhash/argon2"
63+
64+
func tunedHasher() (*pwdhash.PasswordHasher, error) {
65+
argon2id := &argon2.Argon2idHasher{
66+
Memory: 128 * 1024,
67+
Iterations: 4,
68+
Parallelism: 2,
69+
SaltLength: 16,
70+
KeyLength: 32,
71+
}
72+
73+
return pwdhash.New(pwdhash.WithHasher(argon2id))
74+
}
75+
```
76+
77+
You can also author alternate algorithms by satisfying the `pwdhash.Hasher` interface:
78+
79+
```go
80+
type Hasher interface {
81+
ID() string
82+
Hash(password []byte) (string, error)
83+
Verify(password []byte, encoded string) (bool, error)
84+
NeedsRehash(encoded string) (bool, error)
3285
}
86+
```
87+
88+
Registering a hasher via `WithHasher` places it in the internal registry keyed by `ID()`. `Verify` and `NeedsRehash` parse the PHC string, look up the algorithm by its identifier, and dispatch to the correct implementation.
89+
90+
## PHC Encoding Basics
91+
92+
Internally the library parses/produces `encoding.EncodedHash` structures:
93+
94+
```
95+
$argon2id$v=19$m=65536,t=3,p=4$<base64(salt)>$<base64(hash)>
96+
```
97+
98+
- Algorithm identifiers map to registered hashers.
99+
- Parameters are stored verbatim; `NeedsRehash` compares them to the current configuration to decide when to upgrade.
100+
101+
## Testing & Tooling
102+
103+
Run the full suite:
104+
105+
```bash
106+
go test ./...
107+
```
108+
109+
CI-style workflows use the Makefile helpers:
110+
111+
```bash
112+
make lint # golangci-lint run -v --fix
113+
make test # go test -covermode=count -coverprofile=count.out -v ./...
114+
```
115+
116+
## Contributing
117+
118+
1. Fork and clone the repo.
119+
2. Run `go test ./...` (and `make lint`) before submitting patches.
120+
3. Keep exports documented, follow Go formatting (`gofmt`, `goimports`), and prefer table-driven tests.
121+
4. Discuss larger API changes via issues or draft PRs to ensure alignment with the Argon2 focus of the project.
122+
123+
## License
124+
125+
This project is licensed under the MIT License. See `LICENSE` for details.

0 commit comments

Comments
 (0)