diff --git a/pkg/crypto/base58/base58.go b/pkg/crypto/base58/base58.go index bfac3d4f0..5d57dc8c4 100755 --- a/pkg/crypto/base58/base58.go +++ b/pkg/crypto/base58/base58.go @@ -1,8 +1,11 @@ package base58 import ( + "bytes" "fmt" "math/big" + + "github.com/CityOfZion/neo-go/pkg/crypto/hash" ) const prefix rune = '1' @@ -76,3 +79,48 @@ func Encode(bytes []byte) string { return encoded } + +// CheckDecode decodes the given string. +func CheckDecode(s string) (b []byte, err error) { + b, err = Decode(s) + if err != nil { + return nil, err + } + + for i := 0; i < len(s); i++ { + if s[i] != '1' { + break + } + b = append([]byte{0x00}, b...) + } + + if len(b) < 5 { + return nil, fmt.Errorf("Invalid base-58 check string: missing checksum") + } + + hash, err := hash.DoubleSha256(b[:len(b)-4]) + + if err != nil { + return nil, fmt.Errorf("Could not double sha256 data") + } + + if bytes.Compare(hash[0:4], b[len(b)-4:]) != 0 { + return nil, fmt.Errorf("Invalid base-58 check string: invalid checksum") + } + + // Strip the 4 byte long hash. + b = b[:len(b)-4] + + return b, nil +} + +// CheckEncode encodes b into a base-58 check encoded string. +func CheckEncode(b []byte) (string, error) { + hash, err := hash.DoubleSha256(b) + if err != nil { + return "", fmt.Errorf("Could not double sha256 data") + } + b = append(b, hash[0:4]...) + + return Encode(b), nil +} diff --git a/pkg/wire/util/crypto/base58/base58.go b/pkg/wire/util/crypto/base58/base58.go deleted file mode 100644 index 0e9710009..000000000 --- a/pkg/wire/util/crypto/base58/base58.go +++ /dev/null @@ -1,126 +0,0 @@ -package base58 - -import ( - "bytes" - "fmt" - "math/big" - - "github.com/CityOfZion/neo-go/pkg/wire/util/crypto/hash" -) - -const prefix rune = '1' - -var decodeMap = map[rune]int64{ - '1': 0, '2': 1, '3': 2, '4': 3, '5': 4, - '6': 5, '7': 6, '8': 7, '9': 8, 'A': 9, - 'B': 10, 'C': 11, 'D': 12, 'E': 13, 'F': 14, - 'G': 15, 'H': 16, 'J': 17, 'K': 18, 'L': 19, - 'M': 20, 'N': 21, 'P': 22, 'Q': 23, 'R': 24, - 'S': 25, 'T': 26, 'U': 27, 'V': 28, 'W': 29, - 'X': 30, 'Y': 31, 'Z': 32, 'a': 33, 'b': 34, - 'c': 35, 'd': 36, 'e': 37, 'f': 38, 'g': 39, - 'h': 40, 'i': 41, 'j': 42, 'k': 43, 'm': 44, - 'n': 45, 'o': 46, 'p': 47, 'q': 48, 'r': 49, - 's': 50, 't': 51, 'u': 52, 'v': 53, 'w': 54, - 'x': 55, 'y': 56, 'z': 57, -} - -// Decode decodes the base58 encoded string. -func Decode(s string) ([]byte, error) { - var ( - startIndex = 0 - zero = 0 - ) - for i, c := range s { - if c == prefix { - zero++ - } else { - startIndex = i - break - } - } - - var ( - n = big.NewInt(0) - div = big.NewInt(58) - ) - for _, c := range s[startIndex:] { - charIndex, ok := decodeMap[c] - if !ok { - return nil, fmt.Errorf( - "invalid character '%c' when decoding this base58 string: '%s'", c, s, - ) - } - n.Add(n.Mul(n, div), big.NewInt(charIndex)) - } - - out := n.Bytes() - buf := make([]byte, (zero + len(out))) - copy(buf[zero:], out[:]) - - return buf, nil -} - -// Encode encodes a byte slice to be a base58 encoded string. -func Encode(bytes []byte) string { - var ( - lookupTable = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" - x = new(big.Int).SetBytes(bytes) - r = new(big.Int) - m = big.NewInt(58) - zero = big.NewInt(0) - encoded string - ) - - for x.Cmp(zero) > 0 { - x.QuoRem(x, m, r) - encoded = string(lookupTable[r.Int64()]) + encoded - } - - return encoded -} - -// CheckDecode decodes the given string. -func CheckDecode(s string) (b []byte, err error) { - b, err = Decode(s) - if err != nil { - return nil, err - } - - for i := 0; i < len(s); i++ { - if s[i] != '1' { - break - } - b = append([]byte{0x00}, b...) - } - - if len(b) < 5 { - return nil, fmt.Errorf("Invalid base-58 check string: missing checksum. -1") - } - - hash, err := hash.DoubleSha256(b[:len(b)-4]) - - if err != nil { - return nil, fmt.Errorf("Could not double sha256 data") - } - - if bytes.Compare(hash[0:4], b[len(b)-4:]) != 0 { - return nil, fmt.Errorf("Invalid base-58 check string: invalid checksum. -2") - } - - // Strip the 4 byte long hash. - b = b[:len(b)-4] - - return b, nil -} - -// CheckEncode encodes b into a base-58 check encoded string. -func CheckEncode(b []byte) (string, error) { - hash, err := hash.DoubleSha256(b) - if err != nil { - return "", fmt.Errorf("Could not double sha256 data") - } - b = append(b, hash[0:4]...) - - return Encode(b), nil -} diff --git a/pkg/wire/util/crypto/base58/base58_test.go b/pkg/wire/util/crypto/base58/base58_test.go deleted file mode 100644 index 524f0e55e..000000000 --- a/pkg/wire/util/crypto/base58/base58_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package base58 - -import ( - "encoding/hex" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestDecode(t *testing.T) { - input := "1F1tAaz5x1HUXrCNLbtMDqcw6o5GNn4xqX" - - data, err := Decode(input) - if err != nil { - t.Fatal(err) - } - - expected := "0099bc78ba577a95a11f1a344d4d2ae55f2f857b989ea5e5e2" - actual := hex.EncodeToString(data) - assert.Equal(t, expected, actual) -} -func TestEncode(t *testing.T) { - input := "0099bc78ba577a95a11f1a344d4d2ae55f2f857b989ea5e5e2" - - inputBytes, _ := hex.DecodeString(input) - - data := Encode(inputBytes) - - expected := "F1tAaz5x1HUXrCNLbtMDqcw6o5GNn4xqX" // Removed the 1 as it is not checkEncoding - actual := data - assert.Equal(t, expected, actual) -} diff --git a/pkg/wire/util/crypto/hash/hash.go b/pkg/wire/util/crypto/hash/hash.go deleted file mode 100644 index 018885984..000000000 --- a/pkg/wire/util/crypto/hash/hash.go +++ /dev/null @@ -1,83 +0,0 @@ -package hash - -import ( - "crypto/sha256" - "io" - - "github.com/CityOfZion/neo-go/pkg/wire/util" - "golang.org/x/crypto/ripemd160" -) - -// Sha256 hashes the byte slice using sha256 -func Sha256(data []byte) (util.Uint256, error) { - var hash util.Uint256 - hasher := sha256.New() - hasher.Reset() - _, err := hasher.Write(data) - - hash, err = util.Uint256DecodeBytes(hasher.Sum(nil)) - if err != nil { - return hash, err - } - return hash, nil -} - -// DoubleSha256 hashes the underlying data twice using sha256 -func DoubleSha256(data []byte) (util.Uint256, error) { - var hash util.Uint256 - - h1, err := Sha256(data) - if err != nil { - return hash, err - } - - hash, err = Sha256(h1.Bytes()) - if err != nil { - return hash, err - } - return hash, nil -} - -// RipeMD160 hashes the underlying data using ripemd160 -func RipeMD160(data []byte) (util.Uint160, error) { - var hash util.Uint160 - hasher := ripemd160.New() - hasher.Reset() - _, err := io.WriteString(hasher, string(data)) - - hash, err = util.Uint160DecodeBytes(hasher.Sum(nil)) - if err != nil { - return hash, err - } - return hash, nil -} - -//Hash160 hashes the underlying data using sha256 then ripemd160 -func Hash160(data []byte) (util.Uint160, error) { - var hash util.Uint160 - h1, err := Sha256(data) - - h2, err := RipeMD160(h1.Bytes()) - - hash, err = util.Uint160DecodeBytes(h2.Bytes()) - - if err != nil { - return hash, err - } - return hash, nil -} - -// Checksum calculates the checksum of the byte slice using sha256 -func Checksum(data []byte) ([]byte, error) { - hash, err := Sum(data) - if err != nil { - return nil, err - } - return hash[:4], nil -} - -// Sum calculates the Sum of the data by using double sha256 -func Sum(b []byte) (util.Uint256, error) { - hash, err := DoubleSha256((b)) - return hash, err -} diff --git a/pkg/wire/util/crypto/hash/hash_test.go b/pkg/wire/util/crypto/hash/hash_test.go deleted file mode 100644 index aa23718f6..000000000 --- a/pkg/wire/util/crypto/hash/hash_test.go +++ /dev/null @@ -1,62 +0,0 @@ -package hash - -import ( - "encoding/hex" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestSha256(t *testing.T) { - input := []byte("hello") - data, err := Sha256(input) - - if err != nil { - t.Fatal(err) - } - expected := "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824" - actual := hex.EncodeToString(data.Bytes()) // MARK: In the DecodeBytes function, there is a bytes reverse, not sure why? - - assert.Equal(t, expected, actual) -} - -func TestHashDoubleSha256(t *testing.T) { - input := []byte("hello") - data, err := DoubleSha256(input) - - if err != nil { - t.Fatal(err) - } - - firstSha, _ := Sha256(input) - doubleSha, _ := Sha256(firstSha.Bytes()) - expected := hex.EncodeToString(doubleSha.Bytes()) - - actual := hex.EncodeToString(data.Bytes()) - assert.Equal(t, expected, actual) -} - -func TestHashRipeMD160(t *testing.T) { - input := []byte("hello") - data, err := RipeMD160(input) - - if err != nil { - t.Fatal(err) - } - expected := "108f07b8382412612c048d07d13f814118445acd" - actual := hex.EncodeToString(data.Bytes()) - assert.Equal(t, expected, actual) -} - -func TestHash160(t *testing.T) { - input := "02cccafb41b220cab63fd77108d2d1ebcffa32be26da29a04dca4996afce5f75db" - publicKeyBytes, _ := hex.DecodeString(input) - data, err := Hash160(publicKeyBytes) - - if err != nil { - t.Fatal(err) - } - expected := "c8e2b685cc70ec96743b55beb9449782f8f775d8" - actual := hex.EncodeToString(data.Bytes()) - assert.Equal(t, expected, actual) -}