@@ -26,6 +26,7 @@ import (
26
26
"unicode/utf16"
27
27
28
28
"github.com/btcsuite/btcutil/base58"
29
+ "github.com/openwall/yescrypt-go"
29
30
"golang.org/x/crypto/argon2"
30
31
"golang.org/x/crypto/bcrypt"
31
32
"golang.org/x/crypto/md4"
@@ -65,11 +66,14 @@ v2024-11-04.1445-threaded;
65
66
v1.0.0; 2024-12-10
66
67
v1.0.0 release
67
68
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
69
73
*/
70
74
71
75
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 " )
73
77
}
74
78
75
79
// help function
@@ -79,45 +83,46 @@ func helpFunc() {
79
83
"\n ./hashgen -m md5 -w wordlist.txt -o output.txt\n " +
80
84
"./hashgen -m bcrypt -cost 8 -w wordlist.txt\n " +
81
85
"cat wordlist | ./hashgen -m md5 -hashplain\n " +
82
- "\n Supported Options:\n -m {mode} -w {wordlist} -t {cpu threads} -o {output_file} -hashplain {generates hash:plain pairs} -cost {bcrypt }\n " +
86
+ "\n Supported 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 " +
83
87
"\n If -w is not specified, defaults to stdin\n " +
84
88
"If -o is not specified, defaults to stdout\n " +
85
89
"If -t is not specified, defaults to max available CPU threads\n " +
86
90
"\n Modes:\t \t Hashcat Mode Equivalent:\n " +
87
- "\n argon2id \t (very slow! )\n " +
91
+ "\n argon2id\t (slow algo )\n " +
88
92
"base58encode\n " +
89
93
"base58decode\n " +
90
94
"base64encode\n " +
91
95
"base64decode\n " +
92
- "bcrypt \t \t 3200 (very slow! )\n " +
96
+ "bcrypt\t \t 3200 ( slow algo )\n " +
93
97
//"blake2s-256\n" +
94
98
//"blake2b-256\n" +
95
99
//"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 " +
98
102
"crc32\n " +
99
- "11500\t \t (hashcat compatible CRC32)\n " +
103
+ "11500\t \t (hashcat compatible CRC32)\n " +
100
104
"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 \t 900 \n " +
106
+ "md5\t \t 0 \n " +
107
+ "ntlm\t \t 1000 \n " +
108
+ "plaintext\t 99999 \t (can be used to dehex wordlist)\n " +
109
+ "ripemd-160\t 6000 \n " +
110
+ "sha1 \t \t 100 \n " +
111
+ "sha2-224\t 1300 \n " +
112
+ "sha2-384\t 10800 \n " +
113
+ "sha2-256\t 1400 \n " +
114
+ "sha2-512\t 1700 \n " +
111
115
"sha2-512-224\n " +
112
116
"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\t 17300\n " +
118
+ "sha3-256\t 17400\n " +
119
+ "sha3-384\t 17500\n " +
120
+ "sha3-512\t 17600\n " +
121
+ //"keccak-224\t17700\n" +
122
+ "keccak-256\t 17800\n " +
123
+ //"keccak-384\t17900\n" +
124
+ "keccak-512\t 18000\n " +
125
+ "yescrypt\t (slow algo)\n "
121
126
fmt .Fprintln (os .Stderr , str )
122
127
os .Exit (0 )
123
128
}
@@ -229,6 +234,40 @@ func encodeToMorseBytes(input []byte) []byte {
229
234
// supported hash algos / modes
230
235
func hashBytes (hashFunc string , data []byte , cost int ) string {
231
236
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 )
232
271
// argon2id
233
272
case "argon2id" , "argon2" , "argon" :
234
273
salt := make ([]byte , 16 ) // random 16-byte salt
@@ -420,17 +459,20 @@ func processChunk(chunk []byte, count *int64, hexErrorCount *int64, hashFunc str
420
459
421
460
// process logic
422
461
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
425
464
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
428
468
}
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
432
472
}
433
473
474
+ var writeBufferSize = 2 * readBufferSize // write buffer (larger than read buffer)
475
+
434
476
var linesHashed int64 = 0
435
477
var procWg sync.WaitGroup
436
478
var readWg sync.WaitGroup
0 commit comments