Update dependencies, reduce allocations in Base58 encoding
This commit is contained in:
parent
a2daa2d5fc
commit
d4bc15a433
|
@ -63,28 +63,32 @@ func TestAddress(t *testing.T) {
|
||||||
address: "9xYZvCDf6aFdLd7Qawg5XHZitWLKoeFvcLHfe5GxsGCFLbXSWeQNKciXX9YN4T7nPPLcpqYLUdrFiY77nQYeH9RuK9bogZJ",
|
address: "9xYZvCDf6aFdLd7Qawg5XHZitWLKoeFvcLHfe5GxsGCFLbXSWeQNKciXX9YN4T7nPPLcpqYLUdrFiY77nQYeH9RuK9bogZJ",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
var base58 string
|
|
||||||
var spendingKey, viewingKey []byte
|
for i := 0; i < 50000; i++ {
|
||||||
for _, test := range tests {
|
|
||||||
spendingKey, _ = hex.DecodeString(test.spendingKeyHex)
|
var base58 string
|
||||||
viewingKey, _ = hex.DecodeString(test.viewingKeyHex)
|
var spendingKey, viewingKey []byte
|
||||||
address, _ := NewAddress(test.address)
|
for _, test := range tests {
|
||||||
if address.network != test.network {
|
spendingKey, _ = hex.DecodeString(test.spendingKeyHex)
|
||||||
t.Errorf("%s: want: %d, got: %d", test.name, test.network, address.network)
|
viewingKey, _ = hex.DecodeString(test.viewingKeyHex)
|
||||||
continue
|
address, _ := NewAddress(test.address)
|
||||||
}
|
if address.network != test.network {
|
||||||
if bytes.Compare(address.spendingKey, spendingKey) != 0 {
|
t.Errorf("%s: want: %d, got: %d", test.name, test.network, address.network)
|
||||||
t.Errorf("%s: want: %x, got: %x", test.name, spendingKey, address.spendingKey)
|
continue
|
||||||
continue
|
}
|
||||||
}
|
if bytes.Compare(address.spendingKey, spendingKey) != 0 {
|
||||||
if bytes.Compare(address.viewingKey, viewingKey) != 0 {
|
t.Errorf("%s: want: %x, got: %x", test.name, spendingKey, address.spendingKey)
|
||||||
t.Errorf("%s: want: %x, got: %x", test.name, viewingKey, address.viewingKey)
|
continue
|
||||||
continue
|
}
|
||||||
}
|
if bytes.Compare(address.viewingKey, viewingKey) != 0 {
|
||||||
base58 = address.Base58()
|
t.Errorf("%s: want: %x, got: %x", test.name, viewingKey, address.viewingKey)
|
||||||
if base58 != test.address {
|
continue
|
||||||
t.Errorf("%s: want: %s, got: %s", test.name, test.address, base58)
|
}
|
||||||
continue
|
base58 = address.Base58()
|
||||||
|
if base58 != test.address {
|
||||||
|
t.Errorf("%s: want: %s, got: %s", test.name, test.address, base58)
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
28
base58.go
28
base58.go
|
@ -1,7 +1,6 @@
|
||||||
package moneroutil
|
package moneroutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"lukechampine.com/uint128"
|
"lukechampine.com/uint128"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,17 +19,22 @@ var base58Lookup = map[string]int{
|
||||||
|
|
||||||
var base128 = uint128.From64(58)
|
var base128 = uint128.From64(58)
|
||||||
|
|
||||||
func encodeChunk(raw []byte, padding int) (result []byte) {
|
func encodeChunk(raw []byte, padding int, buf []byte) []byte {
|
||||||
remainder := uint128.FromBytes(append(bytes.Repeat([]byte{0}, 16-len(raw)), raw...)).ReverseBytes()
|
var data [16]byte
|
||||||
|
copy(data[16-len(raw):], raw)
|
||||||
|
remainder := uint128.FromBytesBE(data[:])
|
||||||
var current uint128.Uint128
|
var current uint128.Uint128
|
||||||
for remainder.Cmp64(0) > 0 {
|
for remainder.Cmp64(0) > 0 {
|
||||||
remainder, current = remainder.QuoRem(base128)
|
remainder, current = remainder.QuoRem(base128)
|
||||||
result = append([]byte{BASE58[current.Lo]}, result...)
|
buf = append(buf, BASE58[current.Lo])
|
||||||
}
|
}
|
||||||
if len(result) < padding {
|
for len(buf) < padding {
|
||||||
result = append(bytes.Repeat([]byte{'1'}, padding-len(result)), result...)
|
buf = append(buf, '1')
|
||||||
}
|
}
|
||||||
return
|
for i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 {
|
||||||
|
buf[i], buf[j] = buf[j], buf[i]
|
||||||
|
}
|
||||||
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeChunk(encoded string) (result []byte) {
|
func decodeChunk(encoded string) (result []byte) {
|
||||||
|
@ -67,19 +71,21 @@ func decodeChunk(encoded string) (result []byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func EncodeMoneroBase58(data ...[]byte) string {
|
func EncodeMoneroBase58(data ...[]byte) string {
|
||||||
var combined []byte
|
//preallocate common case
|
||||||
|
combined := make([]byte, 0, 96)
|
||||||
for _, item := range data {
|
for _, item := range data {
|
||||||
combined = append(combined, item...)
|
combined = append(combined, item...)
|
||||||
}
|
}
|
||||||
|
|
||||||
result := make([]byte, 0, len(data)*2)
|
result := make([]byte, 0, len(combined)*2)
|
||||||
|
buf := make([]byte, 0, len(combined)*2)
|
||||||
length := len(combined)
|
length := len(combined)
|
||||||
rounds := length / 8
|
rounds := length / 8
|
||||||
for i := 0; i < rounds; i++ {
|
for i := 0; i < rounds; i++ {
|
||||||
result = append(result, encodeChunk(combined[i*8:(i+1)*8], 11)...)
|
result = append(result, encodeChunk(combined[i*8:(i+1)*8], 11, buf[:0])...)
|
||||||
}
|
}
|
||||||
if length%8 > 0 {
|
if length%8 > 0 {
|
||||||
result = append(result, encodeChunk(combined[rounds*8:], 7)...)
|
result = append(result, encodeChunk(combined[rounds*8:], 7, buf[:0])...)
|
||||||
}
|
}
|
||||||
return string(result)
|
return string(result)
|
||||||
}
|
}
|
||||||
|
|
6
go.mod
6
go.mod
|
@ -3,8 +3,8 @@ module git.gammaspectra.live/P2Pool/moneroutil
|
||||||
go 1.19
|
go 1.19
|
||||||
|
|
||||||
require (
|
require (
|
||||||
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b
|
golang.org/x/crypto v0.9.0
|
||||||
lukechampine.com/uint128 v1.2.0
|
lukechampine.com/uint128 v1.3.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875 // indirect
|
require golang.org/x/sys v0.8.0 // indirect
|
||||||
|
|
12
go.sum
12
go.sum
|
@ -1,6 +1,6 @@
|
||||||
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b h1:huxqepDufQpLLIRXiVkTvnxrzJlpwmIWAObmcCcUFr0=
|
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
||||||
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||||
golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875 h1:AzgQNqF+FKwyQ5LbVrVqOcuuFB67N47F9+htZYH0wFM=
|
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||||
golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
|
lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo=
|
||||||
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||||
|
|
Reference in a new issue