@@ -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;
6566v1.0.0; 2024-12-10
6667 v1.0.0 release
6768v1.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
7175func 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- "\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 " +
8387 "\n If -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 "\n Modes:\t \t Hashcat Mode Equivalent:\n " +
87- "\n argon2id \t (very slow! )\n " +
91+ "\n argon2id\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 \t 3200 ( 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 \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 " +
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\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 "
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
230235func 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
422461func 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