diff --git a/base58/alphabet.go b/base58/alphabet.go deleted file mode 100644 index 11e7c18..0000000 --- a/base58/alphabet.go +++ /dev/null @@ -1,30 +0,0 @@ -package base58 - -import "errors" - -// Alphabet is a a b58 alphabet. -type Alphabet struct { - decode [128]int8 - encode [58]byte -} - -// NewAlphabet creates a new alphabet from the passed string. -// -// It returns an error if the passed string is not 58 bytes long or isn't valid ASCII. -func NewAlphabet(s string) (*Alphabet, error) { - if len(s) != 58 { - return nil, errors.New("base58 alphabets must be 58 bytes long") - } - ret := new(Alphabet) - copy(ret.encode[:], s) - for i := range ret.decode { - ret.decode[i] = -1 - } - for i, b := range ret.encode { - ret.decode[b] = int8(i) - } - return ret, nil -} - -// base alphabet -var ab = ("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") diff --git a/base58/base58.go b/base58/base58.go deleted file mode 100644 index b408d5a..0000000 --- a/base58/base58.go +++ /dev/null @@ -1,180 +0,0 @@ -// Package base58 implementation ported from : https://github.com/mr-tron/base58 -package base58 - -import ( - "fmt" - "math/big" -) - -var ( - bn0 = big.NewInt(0) - bn58 = big.NewInt(58) -) - -// Encode encodes the passed bytes into a base58 encoded string. -func Encode(bin []byte) (string, error) { - return Encoding(bin) -} - -// EncodeAlphabet encodes the passed bytes into a base58 encoded string with the -// passed alphabet. -func EncodeAlphabet(bin []byte, alphabet *Alphabet) string { - return EncodingAlphabet(bin, alphabet) -} - -// Encoding encodes the passed bytes into a base58 encoded string. -func Encoding(bin []byte) (string, error) { - - BTCAlphabet, err := NewAlphabet(ab) - if err != nil { - return "", nil - } - return EncodingAlphabet(bin, BTCAlphabet), nil -} - -// EncodingAlphabet encodes the passed bytes into a base58 encoded -// string with the passed alphabet. -func EncodingAlphabet(bin []byte, alphabet *Alphabet) string { - zero := alphabet.encode[0] - - binsz := len(bin) - var i, j, zcount, high int - var carry uint32 - - for zcount < binsz && bin[zcount] == 0 { - zcount++ - } - - size := (binsz-zcount)*138/100 + 1 - var buf = make([]byte, size) - - high = size - 1 - for i = zcount; i < binsz; i++ { - j = size - 1 - for carry = uint32(bin[i]); j > high || carry != 0; j-- { - carry = carry + 256*uint32(buf[j]) - buf[j] = byte(carry % 58) - carry /= 58 - } - high = j - } - - for j = 0; j < size && buf[j] == 0; j++ { - } - - var b58 = make([]byte, size-j+zcount) - - if zcount != 0 { - for i = 0; i < zcount; i++ { - b58[i] = zero - } - } - - for i = zcount; j < size; i++ { - b58[i] = alphabet.encode[buf[j]] - j++ - } - - return string(b58) -} - -// Decode decodes the base58 encoded bytes. -func Decode(str string) ([]byte, error) { - return Decoding(str) -} - -// DecodeAlphabet decodes the base58 encoded bytes using the given b58 alphabet. -func DecodeAlphabet(str string, alphabet *Alphabet) ([]byte, error) { - return DecodingAlphabet(str, alphabet) -} - -// Decoding decodes the base58 encoded bytes. -func Decoding(str string) ([]byte, error) { - - BTCAlphabet, err := NewAlphabet(ab) - if err != nil { - return nil, err - } - return DecodingAlphabet(str, BTCAlphabet) -} - -// DecodingAlphabet decodes the base58 encoded bytes using the given -// b58 alphabet. -func DecodingAlphabet(str string, alphabet *Alphabet) ([]byte, error) { - if len(str) == 0 { - return nil, fmt.Errorf("zero length string") - } - - var ( - t uint64 - zmask, c uint32 - zcount int - - b58u = []rune(str) - b58sz = len(b58u) - - outisz = (b58sz + 3) / 4 // check to see if we need to change this buffer size to optimize - binu = make([]byte, (b58sz+3)*3) - bytesleft = b58sz % 4 - - zero = rune(alphabet.encode[0]) - ) - - if bytesleft > 0 { - zmask = (0xffffffff << uint32(bytesleft*8)) - } else { - bytesleft = 4 - } - - var outi = make([]uint32, outisz) - - for i := 0; i < b58sz && b58u[i] == zero; i++ { - zcount++ - } - - for _, r := range b58u { - if r > 127 { - return nil, fmt.Errorf("High-bit set on invalid digit") - } - if alphabet.decode[r] == -1 { - return nil, fmt.Errorf("Invalid base58 digit (%q)", r) - } - - c = uint32(alphabet.decode[r]) - - for j := (outisz - 1); j >= 0; j-- { - t = uint64(outi[j])*58 + uint64(c) - c = uint32(t>>32) & 0x3f - outi[j] = uint32(t & 0xffffffff) - } - - if c > 0 { - return nil, fmt.Errorf("Output number too big (carry to the next int32)") - } - - if outi[0]&zmask != 0 { - return nil, fmt.Errorf("Output number too big (last int32 filled too far)") - } - } - - var j, cnt int - for j, cnt = 0, 0; j < outisz; j++ { - for mask := byte(bytesleft-1) * 8; mask <= 0x18; mask, cnt = mask-8, cnt+1 { - binu[cnt] = byte(outi[j] >> mask) - } - if j == 0 { - bytesleft = 4 // because it could be less than 4 the first time through - } - } - - for n, v := range binu { - if v > 0 { - start := n - zcount - if start < 0 { - start = 0 - } - return binu[start:cnt], nil - } - } - return binu[:cnt], nil -} diff --git a/base58/base58_test.go b/base58/base58_test.go deleted file mode 100644 index 4118934..0000000 --- a/base58/base58_test.go +++ /dev/null @@ -1,122 +0,0 @@ -package base58 - -// Note:testing takes around 15seconds. -import ( - "crypto/rand" - "encoding/hex" - "testing" - - "github.com/stretchr/testify/assert" -) - -type testValues struct { - dec []byte - enc string -} - -var n = 500 -var testPairs = make([]testValues, 0, n) - -func initTestPairs() { - if len(testPairs) > 0 { - return - } - // pre-make the test pairs, so it doesn't take up benchmark time... - data := make([]byte, 32) - for i := 0; i < n; i++ { - rand.Read(data) - encodedData, _ := Encoding(data) - testPairs = append(testPairs, testValues{dec: data, enc: encodedData}) - } -} - -func randAlphabet() *Alphabet { - // Permutes [0, 127] and returns the first 58 elements. - // Like (math/rand).Perm but using crypto/rand. - var randomness [128]byte - rand.Read(randomness[:]) - - var bts [128]byte - for i, r := range randomness { - j := int(r) % (i + 1) - bts[i] = bts[j] - bts[j] = byte(i) - } - alphabet, err := NewAlphabet(string(bts[:58])) - if err != nil { - return nil - } - return alphabet -} - -func TestEncodingAndDecoding(t *testing.T) { - for k := 0; k < 10; k++ { - testEncDecLoop(t, randAlphabet()) - } - BTCAlphabet, err := NewAlphabet(ab) - if err != nil { - t.Fail() - } - testEncDecLoop(t, BTCAlphabet) -} - -func testEncDecLoop(t *testing.T, alph *Alphabet) { - for j := 1; j < 20; j++ { - var b = make([]byte, j) - for i := 0; i < 10; i++ { - rand.Read(b) - fe := EncodingAlphabet(b, alph) - - fd, ferr := DecodingAlphabet(fe, alph) - if ferr != nil { - t.Errorf(" error: %v", ferr) - } - - if hex.EncodeToString(b) != hex.EncodeToString(fd) { - t.Errorf("decoding err: %s != %s", hex.EncodeToString(b), hex.EncodeToString(fd)) - } - } - } -} - -func TestBase58WithBitcoinAddresses(t *testing.T) { - - testAddr := []string{ - "1QCaxc8hutpdZ62iKZsn1TCG3nh7uPZojq", - "1DhRmSGnhPjUaVPAj48zgPV9e2oRhAQFUb", - "17LN2oPYRYsXS9TdYdXCCDvF2FegshLDU2", - "14h2bDLZSuvRFhUL45VjPHJcW667mmRAAn", - } - - for ii, vv := range testAddr { - // num := Base58Decode([]byte(vv)) - // chk := Base58Encode(num) - num, err := Decoding(vv) - if err != nil { - t.Errorf("Test %d, expected success, got error %s\n", ii, err) - } - chk, err := Encoding(num) - assert.Equal(t, nil, err) - if vv != string(chk) { - t.Errorf("Test %d, expected=%s got=%s Address did base58 encode/decode correctly.", ii, vv, chk) - } - } -} - -func BenchmarkEncoding(b *testing.B) { - initTestPairs() - b.ResetTimer() - - for i := 0; i < b.N; i++ { - Encoding(testPairs[i%n].dec) - } -} - -func BenchmarkDecoding(b *testing.B) { - initTestPairs() - b.ResetTimer() - - for i := 0; i < b.N; i++ { - Decoding(testPairs[i%n].enc) - } -}