-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from 01node/feat/ecsda
Add ecsda encryption and Berachain
- Loading branch information
Showing
13 changed files
with
711 additions
and
166 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
./vanity-forge | ||
dist/ | ||
vanity-forge |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package main | ||
|
||
type Encryption int64 | ||
|
||
const ( | ||
Undefined Encryption = iota | ||
Secp256k1 | ||
Ethsecp256k1 | ||
ECSDA | ||
) | ||
|
||
type chain struct { | ||
Name string | ||
Prefix string | ||
PrefixFull string | ||
Encryption | ||
} | ||
|
||
type settings struct { | ||
SelectedChain chain // chain selector string or nil | ||
MatcherMode string // starts-with, ends-with, contains | ||
SearchString string // search string | ||
NumAccounts string // number of accounts to generate | ||
RequiredLetters int // number of letters to generate | ||
RequiredDigits int // number of digits to generate | ||
} | ||
|
||
type walletgenerator struct { | ||
GenerateWallet func() wallet | ||
} | ||
|
||
type matcher struct { | ||
Mode string | ||
SearchString string | ||
Chain chain | ||
RequiredLetters int | ||
RequiredDigits int | ||
} | ||
|
||
var ( | ||
AvailableChains = []chain{ | ||
{ | ||
Name: "celestia", | ||
Prefix: "celestia", | ||
PrefixFull: "celestia1", | ||
Encryption: Secp256k1, | ||
}, | ||
{ | ||
Name: "cosmos", | ||
Prefix: "cosmos", | ||
PrefixFull: "cosmos1", | ||
Encryption: Secp256k1, | ||
}, | ||
{ | ||
Name: "dydx", | ||
Prefix: "dydx", | ||
PrefixFull: "dydx1", | ||
Encryption: Secp256k1, | ||
}, | ||
{ | ||
Name: "berachain", | ||
Prefix: "0x", | ||
PrefixFull: "0x", | ||
Encryption: ECSDA, | ||
}, | ||
} | ||
MatcherModes = []string{"contains", "starts-with", "ends-with", "regex"} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package main | ||
|
||
import ( | ||
"crypto/ecdsa" | ||
"log" | ||
"strings" | ||
|
||
"github.com/ethereum/go-ethereum/crypto" | ||
) | ||
|
||
type ecsdaWallet struct { | ||
Chain chain | ||
} | ||
|
||
// On Ethereum and other networks compatible with the Ethereum Virtual Machine (EVM), public addresses all share the same format: they begin with 0x, and are followed by 40 alphanumeric characters (numerals and letters), adding up to 42 characters in total. They're also not case sensitive. | ||
|
||
// This address is a number, even though it also includes alphabetical characters. This is because the hexadecimal (base 16) system used to generate the address doesn't just use numerals, like our ten-digit decimal system. Instead, the hexadecimal system uses the numerals 0-9 and the letters A-F. This means it has 16 characters at its disposal, hence the name base 16. In computer science and many programming languages, the 0x prefix is used at the start of all hex numbers, as they are known, to differentiate them from decimal values. | ||
|
||
// bech16digits is a constant string representing the valid characters in a Bech16 encoding. | ||
const bech16digits = "0123456789" | ||
|
||
// bech16letters represents the valid characters for a Bech16 encoding. | ||
const bech16letters = "abcdefABCDEF" | ||
|
||
// bech16chars is a constant string that represents the characters used in the bech16 encoding scheme, which includes both digits and letters. | ||
const bech16chars = bech16digits + bech16letters | ||
|
||
// bech16Only checks if the given string contains only characters from the bech16 character set. | ||
func (w ecsdaWallet) bech16Only(s string) bool { | ||
return w.countUnionChars(s, bech16chars) == len(s) | ||
} | ||
|
||
// countUnionChars counts the number of characters in the input string 's' that are present in the 'letterSet'. | ||
// It returns the count of such characters. | ||
func (w ecsdaWallet) countUnionChars(s string, letterSet string) int { | ||
count := 0 | ||
for _, char := range s { | ||
if strings.Contains(letterSet, string(char)) { | ||
count++ | ||
} | ||
} | ||
return count | ||
} | ||
|
||
// CheckRequiredDigits checks if the given candidate string has the required number of digits. | ||
// It counts the number of union characters between the candidate string and the bech16digits string. | ||
// If the count is less than the required number, it returns false; otherwise, it returns true. | ||
func (w ecsdaWallet) CheckRequiredDigits(candidate string, required int) bool { | ||
if w.countUnionChars(candidate, bech16digits) < required { | ||
return false | ||
} | ||
|
||
return true | ||
} | ||
|
||
// CheckRequiredLetters checks if a candidate string contains the required number of union characters. | ||
// It returns true if the candidate string meets the requirement, otherwise false. | ||
func (w ecsdaWallet) CheckRequiredLetters(candidate string, required int) bool { | ||
if w.countUnionChars(candidate, bech16letters) < required { | ||
return false | ||
} | ||
|
||
return true | ||
} | ||
|
||
// ValidateInput validates the input string based on the specified criteria. | ||
// It checks if the input string contains bech16 incompatible characters, | ||
// if it exceeds the maximum length of 40 characters, | ||
// and if the required number of letters and digits are non-negative and do not exceed 40. | ||
// It returns a slice of error messages indicating the validation errors, if any. | ||
func (w ecsdaWallet) ValidateInput(SearchString string, RequiredLetters int, RequiredDigits int) []string { | ||
var errs []string | ||
if !w.bech16Only(SearchString) { | ||
errs = append(errs, "ERROR: "+SearchString+" contains bech16 incompatible characters") | ||
} | ||
if len(SearchString) > 40 { | ||
errs = append(errs, "ERROR: "+SearchString+" is too long. Must be max 40 characters.") | ||
} | ||
if RequiredDigits < 0 || RequiredLetters < 0 { | ||
errs = append(errs, "ERROR: Can't require negative amount of characters.") | ||
} | ||
if RequiredDigits+RequiredLetters > 40 { | ||
errs = append(errs, "ERROR: Can't require more than 40 characters.") | ||
} | ||
return errs | ||
} | ||
|
||
// GenerateWallet generates a new wallet by generating a private key and deriving the corresponding public key and address. | ||
// It returns a wallet struct containing the address, public key, and private key bytes. | ||
func (w ecsdaWallet) GenerateWallet() wallet { | ||
privateKey, err := crypto.GenerateKey() | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
privateKeyBytes := crypto.FromECDSA(privateKey) | ||
|
||
publicKey := privateKey.Public() | ||
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) | ||
if !ok { | ||
log.Fatal("cannot assert type: publicKey is not of type *ecdsa.PublicKey") | ||
} | ||
|
||
publicKeyBytes := crypto.FromECDSAPub(publicKeyECDSA) | ||
|
||
address := crypto.PubkeyToAddress(*publicKeyECDSA).Hex() | ||
|
||
return wallet{address, publicKeyBytes, privateKeyBytes} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
package main | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestEcsdaWallet_GenerateWallet(t *testing.T) { | ||
wallet := ecsdaWallet{} | ||
w := wallet.GenerateWallet() | ||
assert.NotEmpty(t, w.Address) | ||
assert.NotNil(t, w.PublicKey) | ||
assert.NotNil(t, w.PrivateKey) | ||
} | ||
func TestEcsdaWallet_CountUnionChars(t *testing.T) { | ||
wallet := ecsdaWallet{} | ||
|
||
// Test case 1: Counting union characters in a string with valid letter set | ||
s1 := "abcdef123456" | ||
letterSet1 := "abc123" | ||
expectedCount1 := 6 | ||
assert.Equal(t, expectedCount1, wallet.countUnionChars(s1, letterSet1), "Expected count of 6 for valid letter set") | ||
|
||
// Test case 2: Counting union characters in a string with empty letter set | ||
s2 := "abcdef123456" | ||
letterSet2 := "" | ||
expectedCount2 := 0 | ||
assert.Equal(t, expectedCount2, wallet.countUnionChars(s2, letterSet2), "Expected count of 0 for empty letter set") | ||
|
||
// Test case 3: Counting union characters in an empty string with valid letter set | ||
s3 := "" | ||
letterSet3 := "abc123" | ||
expectedCount3 := 0 | ||
assert.Equal(t, expectedCount3, wallet.countUnionChars(s3, letterSet3), "Expected count of 0 for empty string") | ||
|
||
// Test case 4: Counting union characters in a string with invalid letter set | ||
s4 := "abcdef123456" | ||
letterSet4 := "!@#$%" | ||
expectedCount4 := 0 | ||
assert.Equal(t, expectedCount4, wallet.countUnionChars(s4, letterSet4), "Expected count of 0 for invalid letter set") | ||
} | ||
func TestEcsdaWallet_Bech16Only(t *testing.T) { | ||
wallet := ecsdaWallet{} | ||
|
||
// Test case 1: All characters are valid bech16 characters | ||
s1 := "abcdef123456" | ||
assert.True(t, wallet.bech16Only(s1), "Expected true for valid bech16 characters") | ||
|
||
// Test case 2: Some characters are not valid bech16 characters | ||
s2 := "abcde!@#$%" | ||
assert.False(t, wallet.bech16Only(s2), "Expected false for invalid bech16 characters") | ||
|
||
// Test case 3: Empty string | ||
s3 := "" | ||
assert.True(t, wallet.bech16Only(s3), "Expected true for empty string") | ||
|
||
// Test case 4: String with valid bech16 characters and additional characters | ||
s4 := "abcdef123456!" | ||
assert.False(t, wallet.bech16Only(s4), "Expected false for string with additional characters") | ||
} | ||
func TestEcsdaWallet_CheckRequiredDigits(t *testing.T) { | ||
wallet := ecsdaWallet{} | ||
|
||
// Test case 1: Candidate string has less required digits | ||
candidate1 := "abcdef123456" | ||
required1 := 7 | ||
assert.False(t, wallet.CheckRequiredDigits(candidate1, required1), "Expected false for candidate string with less required digits") | ||
|
||
// Test case 2: Candidate string has exact required digits | ||
candidate2 := "abcdef123456" | ||
required2 := 6 | ||
assert.True(t, wallet.CheckRequiredDigits(candidate2, required2), "Expected true for candidate string with exact required digits") | ||
|
||
// Test case 3: Candidate string has more than required digits | ||
candidate3 := "abcdef123456" | ||
required3 := 5 | ||
assert.True(t, wallet.CheckRequiredDigits(candidate3, required3), "Expected true for candidate string with more than required digits") | ||
|
||
// Test case 4: Empty candidate string | ||
candidate4 := "" | ||
required4 := 3 | ||
assert.False(t, wallet.CheckRequiredDigits(candidate4, required4), "Expected false for empty candidate string") | ||
} | ||
func TestEcsdaWallet_CheckRequiredLetters(t *testing.T) { | ||
wallet := ecsdaWallet{} | ||
|
||
// Test case 1: Candidate string has enough required letters | ||
candidate1 := "abcdef123" | ||
required1 := 5 | ||
assert.True(t, wallet.CheckRequiredLetters(candidate1, required1), "Expected true for candidate string with enough required letters") | ||
|
||
// Test case 2: Candidate string does not have enough required letters | ||
candidate2 := "abc123" | ||
required2 := 10 | ||
assert.False(t, wallet.CheckRequiredLetters(candidate2, required2), "Expected false for candidate string without enough required letters") | ||
|
||
// Test case 3: Candidate string is empty | ||
candidate3 := "" | ||
required3 := 5 | ||
assert.False(t, wallet.CheckRequiredLetters(candidate3, required3), "Expected false for empty candidate string") | ||
|
||
// Test case 4: Required letters is 0 | ||
candidate4 := "abc123" | ||
required4 := 0 | ||
assert.True(t, wallet.CheckRequiredLetters(candidate4, required4), "Expected true for required letters equal to 0") | ||
} | ||
|
||
func TestEcsdaWallet_ValidateInput(t *testing.T) { | ||
wallet := ecsdaWallet{} | ||
|
||
// Test case 1: Valid input | ||
searchString1 := "abcdef123456" | ||
requiredLetters1 := 6 | ||
requiredDigits1 := 6 | ||
expectedErrs1 := []string(nil) | ||
assert.Equal(t, expectedErrs1, wallet.ValidateInput(searchString1, requiredLetters1, requiredDigits1), "Expected no errors for valid input") | ||
|
||
// Test case 2: Invalid bech16 characters | ||
searchString2 := "abcde!@#$%" | ||
requiredLetters2 := 6 | ||
requiredDigits2 := 6 | ||
expectedErrs2 := []string{"ERROR: abcde!@#$% contains bech16 incompatible characters"} | ||
assert.Equal(t, expectedErrs2, wallet.ValidateInput(searchString2, requiredLetters2, requiredDigits2), "Expected error for invalid bech16 characters") | ||
|
||
// Test case 3: String too long | ||
searchString3 := "abcdef123456abcdef123456abcdef123456abcdef1234567" | ||
requiredLetters3 := 6 | ||
requiredDigits3 := 6 | ||
expectedErrs3 := []string{"ERROR: abcdef123456abcdef123456abcdef123456abcdef1234567 is too long. Must be max 40 characters."} | ||
assert.Equal(t, expectedErrs3, wallet.ValidateInput(searchString3, requiredLetters3, requiredDigits3), "Expected error for string too long") | ||
|
||
// Test case 4: Negative required characters | ||
searchString4 := "abcdef123456" | ||
requiredLetters4 := -1 | ||
requiredDigits4 := 6 | ||
expectedErrs4 := []string{"ERROR: Can't require negative amount of characters."} | ||
assert.Equal(t, expectedErrs4, wallet.ValidateInput(searchString4, requiredLetters4, requiredDigits4), "Expected error for negative required characters") | ||
|
||
// Test case 5: Required characters exceed string length | ||
searchString5 := "abcdef123456abcdef123456abcdef123456abcdef123456abcdef123456abcdef123456" | ||
requiredLetters5 := 10 | ||
requiredDigits5 := 10 | ||
expectedErrs5 := []string{"ERROR: abcdef123456abcdef123456abcdef123456abcdef123456abcdef123456abcdef123456 is too long. Must be max 40 characters."} | ||
assert.Equal(t, expectedErrs5, wallet.ValidateInput(searchString5, requiredLetters5, requiredDigits5), "Expected error for required characters exceeding string length") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.