Skip to content

Commit 291045d

Browse files
v1.1.1; 2025-03-20 (yescrypt)
1 parent 60efc73 commit 291045d

File tree

5 files changed

+85
-34
lines changed

5 files changed

+85
-34
lines changed

CHANGELOG.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
### v1.1.1; 2025-03-20
2+
```
3+
added mode: yescrypt (https://github.com/cyclone-github/yescrypt_crack)
4+
tweaked read/write buffers for per-CPU thread
5+
```
16
### v1.1.0; 2025-03-19
27
```
3-
added modes: base58, argon2id, bcrypt w/custom cost factor
8+
added modes: base58, bcrypt w/custom cost factor, argon2id (https://github.com/cyclone-github/argon_cracker)
49
```
510
### v1.0.0; 2024-12-10
611
```

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ To use hashgen, type your mode, wordlist input & hash output files with a simple
6666
| sha3-512| 17600 |
6767
| keccak-256| 17800 |
6868
| keccak-512| 18000 |
69+
| yescrypt | |
6970

7071
### Benchmarks:
7172
- https://github.com/cyclone-github/hashgen-testing/tree/main/benchmarks

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ go 1.24.1
44

55
require (
66
github.com/btcsuite/btcutil v1.0.2
7+
github.com/openwall/yescrypt-go v1.0.0
78
golang.org/x/crypto v0.36.0
89
)
910

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6
1919
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
2020
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
2121
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
22+
github.com/openwall/yescrypt-go v1.0.0 h1:jsGk48zkFvtUjGVOhYPGh+CS595JmTRcKnpggK2AON4=
23+
github.com/openwall/yescrypt-go v1.0.0/go.mod h1:e6CWtFizUEOUttaOjeVMiv1lJaJie3mfOtLJ9CCD6sA=
2224
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
2325
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
2426
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=

hashgen.go

+75-33
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"unicode/utf16"
2727

2828
"github.com/btcsuite/btcutil/base58"
29+
"github.com/openwall/yescrypt-go"
2930
"golang.org/x/crypto/argon2"
3031
"golang.org/x/crypto/bcrypt"
3132
"golang.org/x/crypto/md4"
@@ -65,11 +66,14 @@ v2024-11-04.1445-threaded;
6566
v1.0.0; 2024-12-10
6667
v1.0.0 release
6768
v1.1.0; 2025-03-19
68-
added modes: base58, argon2id, bcrypt w/custom cost factor
69+
added modes: base58, bcrypt w/custom cost factor, argon2id (https://github.com/cyclone-github/argon_cracker)
70+
v1.1.1; 2025-03-20
71+
added mode: yescrypt (https://github.com/cyclone-github/yescrypt_crack)
72+
tweaked read/write buffers for per-CPU thread
6973
*/
7074

7175
func versionFunc() {
72-
fmt.Fprintln(os.Stderr, "Cyclone hash generator v1.1.0; 2025-03-19")
76+
fmt.Fprintln(os.Stderr, "Cyclone hash generator v1.1.1; 2025-03-20")
7377
}
7478

7579
// help function
@@ -79,45 +83,46 @@ func helpFunc() {
7983
"\n./hashgen -m md5 -w wordlist.txt -o output.txt\n" +
8084
"./hashgen -m bcrypt -cost 8 -w wordlist.txt\n" +
8185
"cat wordlist | ./hashgen -m md5 -hashplain\n" +
82-
"\nSupported Options:\n-m {mode} -w {wordlist} -t {cpu threads} -o {output_file} -hashplain {generates hash:plain pairs} -cost {bcrypt}\n" +
86+
"\nSupported Options:\n-m {mode}\n-w {wordlist}\n-t {cpu threads}\n-o {output_file}\n-cost {bcrypt}\n-hashplain {generates hash:plain pairs}\n" +
8387
"\nIf -w is not specified, defaults to stdin\n" +
8488
"If -o is not specified, defaults to stdout\n" +
8589
"If -t is not specified, defaults to max available CPU threads\n" +
8690
"\nModes:\t\tHashcat Mode Equivalent:\n" +
87-
"\nargon2id \t(very slow!)\n" +
91+
"\nargon2id\t(slow algo)\n" +
8892
"base58encode\n" +
8993
"base58decode\n" +
9094
"base64encode\n" +
9195
"base64decode\n" +
92-
"bcrypt \t\t 3200 (very slow!)\n" +
96+
"bcrypt\t\t3200 (slow algo)\n" +
9397
//"blake2s-256\n" +
9498
//"blake2b-256\n" +
9599
//"blake2b-384\n" +
96-
//"blake2b-512 \t 600\n" +
97-
"morsecode\t (ITU-R M.1677-1)\n" +
100+
//"blake2b-512\t600\n" +
101+
"morsecode\t(ITU-R M.1677-1)\n" +
98102
"crc32\n" +
99-
"11500\t\t (hashcat compatible CRC32)\n" +
103+
"11500\t\t(hashcat compatible CRC32)\n" +
100104
"crc64\n" +
101-
"md4 \t\t 900\n" +
102-
"md5 \t\t 0\n" +
103-
"ntlm \t\t 1000\n" +
104-
"plaintext \t 99999 \t (can be used to dehex wordlist)\n" +
105-
"ripemd-160 \t 6000\n" +
106-
"sha1 \t\t 100\n" +
107-
"sha2-224 \t 1300\n" +
108-
"sha2-384 \t 10800\n" +
109-
"sha2-256 \t 1400\n" +
110-
"sha2-512 \t 1700\n" +
105+
"md4\t\t900\n" +
106+
"md5\t\t0\n" +
107+
"ntlm\t\t1000\n" +
108+
"plaintext\t99999\t(can be used to dehex wordlist)\n" +
109+
"ripemd-160\t6000\n" +
110+
"sha1 \t\t100\n" +
111+
"sha2-224\t1300\n" +
112+
"sha2-384\t10800\n" +
113+
"sha2-256\t1400\n" +
114+
"sha2-512\t1700\n" +
111115
"sha2-512-224\n" +
112116
"sha2-512-256\n" +
113-
"sha3-224 \t 17300\n" +
114-
"sha3-256 \t 17400\n" +
115-
"sha3-384 \t 17500\n" +
116-
"sha3-512 \t 17600\n" +
117-
//"keccak-224\t 17700\n" +
118-
"keccak-256\t 17800\n" +
119-
//"keccak-384\t 17900\n" +
120-
"keccak-512\t 18000\n"
117+
"sha3-224\t17300\n" +
118+
"sha3-256\t17400\n" +
119+
"sha3-384\t17500\n" +
120+
"sha3-512\t17600\n" +
121+
//"keccak-224\t17700\n" +
122+
"keccak-256\t17800\n" +
123+
//"keccak-384\t17900\n" +
124+
"keccak-512\t18000\n" +
125+
"yescrypt\t(slow algo)\n"
121126
fmt.Fprintln(os.Stderr, str)
122127
os.Exit(0)
123128
}
@@ -229,6 +234,40 @@ func encodeToMorseBytes(input []byte) []byte {
229234
// supported hash algos / modes
230235
func hashBytes(hashFunc string, data []byte, cost int) string {
231236
switch hashFunc {
237+
// yescrypt
238+
case "yescrypt":
239+
salt := make([]byte, 8) // random 8-byte salt
240+
if _, err := rand.Read(salt); err != nil {
241+
fmt.Fprintln(os.Stderr, "Error generating salt:", err)
242+
return ""
243+
}
244+
key, err := yescrypt.Key(data, salt, 32768, 8, 1, 32) // use default yescrypt parameters: N=32768, r=8, p=1, keyLen=32
245+
if err != nil {
246+
fmt.Fprintln(os.Stderr, "yescrypt error:", err)
247+
return ""
248+
}
249+
const itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // custom yescrypt base64 alphabet
250+
encode64 := func(src []byte) string {
251+
var dst []byte
252+
var value uint32
253+
bits := 0
254+
for i := 0; i < len(src); i++ {
255+
value |= uint32(src[i]) << bits
256+
bits += 8
257+
for bits >= 6 {
258+
dst = append(dst, itoa64[value&0x3f])
259+
value >>= 6
260+
bits -= 6
261+
}
262+
}
263+
if bits > 0 {
264+
dst = append(dst, itoa64[value&0x3f])
265+
}
266+
return string(dst)
267+
}
268+
encodedSalt := encode64(salt)
269+
encodedKey := encode64(key)
270+
return fmt.Sprintf("$y$jC5$%s$%s", encodedSalt, encodedKey)
232271
// argon2id
233272
case "argon2id", "argon2", "argon":
234273
salt := make([]byte, 16) // random 16-byte salt
@@ -420,17 +459,20 @@ func processChunk(chunk []byte, count *int64, hexErrorCount *int64, hashFunc str
420459

421460
// process logic
422461
func startProc(hashFunc string, inputFile string, outputPath string, hashPlainOutput bool, numGoroutines int, cost int) {
423-
var readBufferSize = 1024 * 1024 // read buffer
424-
var writeBufferSize = 2 * readBufferSize // write buffer (larger than read buffer)
462+
//var readBufferSize = 1024 * 1024 // read buffer
463+
var readBufferSize = numGoroutines + 16*32*1024 // variable read buffer
425464

426-
if hashFunc == "bcrypt" || hashFunc == "3200" { // lower read buffer for bcrypt
427-
readBufferSize = cost * 2
465+
// lower read buffer for bcrypt (varies with -cost)
466+
if hashFunc == "bcrypt" || hashFunc == "3200" {
467+
readBufferSize = numGoroutines/cost + 32*2
428468
}
429-
430-
if hashFunc == "argon2id" || hashFunc == "argon2" || hashFunc == "argon" { // lower read buffer for argon2id
431-
readBufferSize = 64
469+
// lower read buffer for argon2id, yescrypt
470+
if hashFunc == "argon2id" || hashFunc == "argon2" || hashFunc == "argon" || hashFunc == "yescrypt" {
471+
readBufferSize = numGoroutines + 8*2
432472
}
433473

474+
var writeBufferSize = 2 * readBufferSize // write buffer (larger than read buffer)
475+
434476
var linesHashed int64 = 0
435477
var procWg sync.WaitGroup
436478
var readWg sync.WaitGroup

0 commit comments

Comments
 (0)