Skip to content

Instantly share code, notes, and snippets.

@jonnadul
Last active January 21, 2024 07:43
Show Gist options
  • Save jonnadul/ad4eab0bac13cf44cb42e401045e1dac to your computer and use it in GitHub Desktop.
Save jonnadul/ad4eab0bac13cf44cb42e401045e1dac to your computer and use it in GitHub Desktop.
Simple go-lang app for brute forcing the dictionary phrase behind SHA1 seed values
package ecdsaseedbf
import (
"context"
"crypto/sha1"
"encoding/hex"
"fmt"
"strings"
"sync"
"time"
"unicode"
openai "github.com/sashabaranov/go-openai"
)
const maxOpenAICalls = 5
const maxPostPendLen = 3
const sleepDuration = 5 * time.Second
type FoundSeed struct {
seedName string
seed string
found bool
phrase string
}
var foundSeedsMutex sync.Mutex
var foundSeeds []FoundSeed
/*
* Each phrase from OpenAI is a numbered item, need to truncate that
* leading digit + '.' + ' ' to get the raw sentence back.
*/
func truncLeadingNumber(preTrunc string) string {
truncStr := preTrunc
done := false
for !done {
if len(truncStr) <= 0 {
done = true
} else {
if len(truncStr) > 0 &&
(unicode.IsDigit(rune(truncStr[0])) || truncStr[0] == '.' || truncStr[0] == ' ') {
truncStr = truncStr[1:]
} else {
done = true
}
}
}
return truncStr
}
func hexsha1(input string) string {
h := sha1.New()
h.Write([]byte(input))
return strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
}
func generatePerms(basePhrase string, index int, length int, current string) {
if index == length {
fullPhrases := []string{
basePhrase + current,
current + basePhrase,
current + basePhrase + current,
}
results := []string{
hexsha1(basePhrase + current),
hexsha1(current + basePhrase),
hexsha1(current + basePhrase + current),
}
for idx, result := range results {
foundSeedsMutex.Lock()
for _, foundSeed := range foundSeeds {
if (!foundSeed.found) && (foundSeed.seed == result) {
fmt.Printf("Found phase for %s! %s\n", foundSeed.seedName, fullPhrases[idx])
foundSeed.found = true
foundSeed.phrase = fullPhrases[idx]
}
}
foundSeedsMutex.Unlock()
}
return
}
for i := 0; i < 256; i++ {
generatePerms(basePhrase, index+1, length, current+string(rune(i)))
}
}
func main() {
foundSeeds = []FoundSeed{
{
seedName: "p_192",
seed: "3045AE6FC8422F64ED579528D38120EAE12196D5",
found: false,
phrase: "",
},
{
seedName: "p_224",
seed: "BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5",
found: false,
phrase: "",
},
{
seedName: "p_256",
seed: "C49D360886E704936A6678E1139D26B7819F7E90",
found: false,
phrase: "",
},
{
seedName: "p_384",
seed: "A335926AA319A27A1D00896A6773A4827ACDAC73",
found: false,
phrase: "",
},
{
seedName: "p_521",
seed: "D09E8800291CB85396CC6717393284AAA0DA64BA",
found: false,
phrase: "",
},
}
client := openai.NewClient("<OpenAI Token>")
messages := []openai.ChatCompletionMessage{
{
Role: openai.ChatMessageRoleSystem,
Content: "Return a list of 100 similar phrases.",
},
{
Role: openai.ChatMessageRoleUser,
Content: "Jerry and Bob need raises",
},
}
var wg sync.WaitGroup
for k := 0; k < maxOpenAICalls; k++ {
fmt.Println("Calling OpenAI for list of 100 phrases.")
resp, err := client.CreateChatCompletion(
context.Background(),
openai.ChatCompletionRequest{
Model: openai.GPT3Dot5Turbo,
Messages: messages,
},
)
if err != nil {
fmt.Println("Error encountered in call to OpenAI")
break
}
listOfPhrases := strings.Split(resp.Choices[0].Message.Content, "\n")
for _, phrase := range listOfPhrases {
basePhrase := strings.Trim(truncLeadingNumber(phrase), ".")
for ppLen := 0; ppLen <= maxPostPendLen; ppLen++ {
fmt.Printf("Starting for phrase %s and postpend length %d\n", basePhrase, ppLen)
wg.Add(1)
go func(bP string, pL int) {
generatePerms(bP, 0, pL, "")
fmt.Printf("Complete for phrase %s and postpend length %d\n", bP, pL)
wg.Done()
}(basePhrase, ppLen)
}
time.Sleep(sleepDuration)
}
messages = append(messages, openai.ChatCompletionMessage{
Role: openai.ChatMessageRoleAssistant,
Content: resp.Choices[0].Message.Content,
})
messages = append(messages, openai.ChatCompletionMessage{
Role: openai.ChatMessageRoleUser,
Content: "Can you share the next 100?",
})
}
fmt.Println("Waiting...")
wg.Wait()
foundSeedsMutex.Lock()
for _, foundSeed := range foundSeeds {
fmt.Printf("seedName = %s, seed = %s, found = %b, phrase = %s\n",
foundSeed.seedName,
foundSeed.seed,
foundSeed.found,
foundSeed.phrase)
}
foundSeedsMutex.Unlock()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment