From 6d169425d1609a564c6c1f2fb8f4e8d59e896e50 Mon Sep 17 00:00:00 2001 From: Jack Robison Date: Mon, 27 Nov 2017 10:24:10 -0500 Subject: [PATCH] split b58 checksum validation from address validation --- address/base58/character.go | 5 ++--- address/base58/checksum.go | 20 ++++++++++++++++++++ address/base58/decode.go | 7 +++++-- address/base58/encode.go | 4 ++-- address/decode.go | 1 + address/validate.go | 19 ++++--------------- 6 files changed, 34 insertions(+), 22 deletions(-) create mode 100644 address/base58/checksum.go diff --git a/address/base58/character.go b/address/base58/character.go index 82adb0d..cc9a78c 100644 --- a/address/base58/character.go +++ b/address/base58/character.go @@ -1,17 +1,16 @@ package base58 import ( - "math/big" "errors" + "math/big" ) -var b58_characters = [58]byte {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, +var b58_characters = [58]byte{0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a} - func CharacterIndex(character byte) (*big.Int, error) { for i := 0; i < 58; i++ { if b58_characters[i] == character { diff --git a/address/base58/checksum.go b/address/base58/checksum.go new file mode 100644 index 0000000..de115c1 --- /dev/null +++ b/address/base58/checksum.go @@ -0,0 +1,20 @@ +package base58 + +import "crypto/sha256" + +const checksum_length = 4 + +func VerifyBase58Checksum(v []byte) bool { + checksum := [checksum_length]byte{} + for i := range checksum { + checksum[i] = v[len(v)-checksum_length+i] + } + real_checksum := sha256.Sum256(v[:len(v)-checksum_length]) + real_checksum = sha256.Sum256(real_checksum[:]) + for i, c := range checksum { + if c != real_checksum[i] { + return false + } + } + return true +} diff --git a/address/base58/decode.go b/address/base58/decode.go index 46dd65f..d0854f1 100644 --- a/address/base58/decode.go +++ b/address/base58/decode.go @@ -1,8 +1,8 @@ package base58 import ( - "math/big" "errors" + "math/big" ) func DecodeBase58(value string, size int64) ([]byte, error) { @@ -12,7 +12,7 @@ func DecodeBase58(value string, size int64) ([]byte, error) { for i := int64(len(buf) - 1); i >= 0; i-- { to_add := big.NewInt(0) to_add = to_add.Exp(big.NewInt(58), big.NewInt(i), to_add) - c, err := CharacterIndex(buf[int64(len(buf)) - i - 1]) + c, err := CharacterIndex(buf[int64(len(buf))-i-1]) if err != nil { return result, err } @@ -32,5 +32,8 @@ func DecodeBase58(value string, size int64) ([]byte, error) { if long_value.Int64() != 0 { return result, errors.New("cannot decode to the given size") } + if size != int64(len(result)) { + return result, errors.New("length mismatch") + } return result, nil } diff --git a/address/base58/encode.go b/address/base58/encode.go index 12eeafa..a0f86b6 100644 --- a/address/base58/encode.go +++ b/address/base58/encode.go @@ -4,13 +4,13 @@ import ( "math/big" ) -func EncodeBase58(data []byte) (string) { +func EncodeBase58(data []byte) string { long_value := big.NewInt(0) result := "" for i := 0; i < len(data); i++ { to_add := big.NewInt(0) to_add = to_add.Exp(big.NewInt(256), big.NewInt(int64(i)), to_add) - to_add = to_add.Mul(big.NewInt(int64(data[24 - i])), to_add) + to_add = to_add.Mul(big.NewInt(int64(data[24-i])), to_add) long_value = long_value.Add(to_add, long_value) } i := 0 diff --git a/address/decode.go b/address/decode.go index 6d244fa..73789e1 100644 --- a/address/decode.go +++ b/address/decode.go @@ -14,5 +14,6 @@ func DecodeAddress(address string, blockchainName string) ([address_length]byte, for i, b := range decoded { buf[i] = b } + return ValidateAddress(buf, blockchainName) } diff --git a/address/validate.go b/address/validate.go index 5b5a893..992e3f4 100644 --- a/address/validate.go +++ b/address/validate.go @@ -1,7 +1,7 @@ package address import ( - "crypto/sha256" + "./base58" "errors" ) @@ -48,19 +48,8 @@ func PubKeyIsValid(address [address_length]byte) bool { return true } -func ChecksumIsValid(address [address_length]byte) bool { - checksum := [checksum_length]byte{} - for i := range checksum { - checksum[i] = address[prefix_length+pubkey_length+i] - } - real_checksum := sha256.Sum256(address[:prefix_length+pubkey_length]) - real_checksum = sha256.Sum256(real_checksum[:]) - for i, c := range checksum { - if c != real_checksum[i] { - return false - } - } - return true +func AddressChecksumIsValid(address [address_length]byte) bool { + return base58.VerifyBase58Checksum(address[:]) } func ValidateAddress(address [address_length]byte, blockchainName string) ([address_length]byte, error) { @@ -73,7 +62,7 @@ func ValidateAddress(address [address_length]byte, blockchainName string) ([addr if !PubKeyIsValid(address) { return address, errors.New("invalid pubkey") } - if !ChecksumIsValid(address) { + if !AddressChecksumIsValid(address) { return address, errors.New("invalid address checksum") } return address, nil