diff --git a/crypto/legacy_address.go b/crypto/legacy_address.go new file mode 100644 index 0000000..440d700 --- /dev/null +++ b/crypto/legacy_address.go @@ -0,0 +1,53 @@ +// This file is part of Ark Go Crypto. +// +// (c) Ark Ecosystem +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +package crypto + +import ( + "encoding/hex" + + "github.com/btcsuite/btcutil/base58" + "golang.org/x/crypto/ripemd160" +) + +func LegacyAddressFromPassphrase(passphrase string, pubKeyHash byte) (string, error) { + privateKey, err := PrivateKeyFromPassphrase(passphrase) + if err != nil { + return "", err + } + return LegacyAddressFromPrivateKey(privateKey, pubKeyHash) +} + +func LegacyAddressFromPublicKey(publicKey string, pubKeyHash byte) (string, error) { + publicKeyBytes, err := hex.DecodeString(publicKey) + if err != nil { + return "", err + } + + hasher := ripemd160.New() + hasher.Write(publicKeyBytes) + hash := hasher.Sum(nil) + + return base58.CheckEncode(hash, pubKeyHash), nil +} + +func LegacyAddressFromPrivateKey(privateKey *PrivateKey, pubKeyHash byte) (string, error) { + return LegacyAddressFromPublicKey(privateKey.PublicKey.ToHex(), pubKeyHash) +} + +func ValidateLegacyAddress(address string, pubKeyHash byte) bool { + decoded, version, err := base58.CheckDecode(address) + if err != nil { + return false + } + + if len(decoded) != ripemd160.Size { + return false + } + + return version == pubKeyHash +} diff --git a/crypto/legacy_address_test.go b/crypto/legacy_address_test.go new file mode 100644 index 0000000..d4571ae --- /dev/null +++ b/crypto/legacy_address_test.go @@ -0,0 +1,72 @@ +// This file is part of Ark Go Crypto. +// +// (c) Ark Ecosystem +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +package crypto + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +const ( + legacyPubKeyHash byte = 30 + legacyPassphrase string = "enact busy minimum fantasy endless shoot reduce few inject ostrich snow promote" + legacyPublicKey string = "02a7c5ca78f6abbced169cb883aec3ffc0a0950affc0de575fb211873b5846e668" + legacyPrivateKey string = "c7a0df6e1c42268946af49af28c49c6da64419f0203fa970b6e9be9f85a44875" + legacyAddress string = "D6WFwqYDRiFkSf4ezzWRt3jCsUp2sRmDMi" +) + +func TestLegacyAddressFromPassphrase(t *testing.T) { + address, err := LegacyAddressFromPassphrase(legacyPassphrase, legacyPubKeyHash) + + assert := assert.New(t) + assert.NoError(err) + assert.Equal(legacyAddress, address) +} + +func TestLegacyAddressFromPublicKey(t *testing.T) { + address, err := LegacyAddressFromPublicKey(legacyPublicKey, legacyPubKeyHash) + + assert := assert.New(t) + assert.NoError(err) + assert.Equal(legacyAddress, address) +} + +func TestLegacyAddressFromPrivateKey(t *testing.T) { + privateKey, _ := PrivateKeyFromHex(legacyPrivateKey) + + address, err := LegacyAddressFromPrivateKey(privateKey, legacyPubKeyHash) + + assert := assert.New(t) + assert.NoError(err) + assert.Equal(legacyAddress, address) +} + +func TestValidateLegacyAddress(t *testing.T) { + assert := assert.New(t) + + assert.True(ValidateLegacyAddress(legacyAddress, legacyPubKeyHash)) +} + +func TestValidateLegacyAddressFailsWithIncorrectPubKeyHash(t *testing.T) { + assert := assert.New(t) + + assert.False(ValidateLegacyAddress(legacyAddress, 32)) +} + +func TestValidateLegacyAddressFailsWithInvalidAddress(t *testing.T) { + assert := assert.New(t) + + assert.False(ValidateLegacyAddress("D2WFnqYDRiFkSf4ezzWRt3jCsUp2sRmDMifwd", legacyPubKeyHash)) +} + +func TestValidateLegacyAddressFailsWithDecodingError(t *testing.T) { + assert := assert.New(t) + + assert.False(ValidateLegacyAddress("invalid", legacyPubKeyHash)) +}