Replace big int with uint128 implementation

This commit is contained in:
DataHoarder 2022-10-07 16:03:23 +02:00
parent 29dc54bf40
commit a2daa2d5fc
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk
3 changed files with 55 additions and 38 deletions

View file

@ -1,8 +1,8 @@
package moneroutil
import (
"math/big"
"strings"
"bytes"
"lukechampine.com/uint128"
)
const BASE58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
@ -17,58 +17,78 @@ var base58Lookup = map[string]int{
"q": 48, "r": 49, "s": 50, "t": 51, "u": 52, "v": 53, "w": 54, "x": 55,
"y": 56, "z": 57,
}
var bigBase = big.NewInt(58)
func encodeChunk(raw []byte, padding int) (result string) {
remainder := new(big.Int)
remainder.SetBytes(raw)
bigZero := new(big.Int)
for remainder.Cmp(bigZero) > 0 {
current := new(big.Int)
remainder.DivMod(remainder, bigBase, current)
result = string(BASE58[current.Int64()]) + result
var base128 = uint128.From64(58)
func encodeChunk(raw []byte, padding int) (result []byte) {
remainder := uint128.FromBytes(append(bytes.Repeat([]byte{0}, 16-len(raw)), raw...)).ReverseBytes()
var current uint128.Uint128
for remainder.Cmp64(0) > 0 {
remainder, current = remainder.QuoRem(base128)
result = append([]byte{BASE58[current.Lo]}, result...)
}
if len(result) < padding {
result = strings.Repeat("1", (padding-len(result))) + result
result = append(bytes.Repeat([]byte{'1'}, padding-len(result)), result...)
}
return
}
func decodeChunk(encoded string) (result []byte) {
bigResult := big.NewInt(0)
currentMultiplier := big.NewInt(1)
tmp := new(big.Int)
var bigResult uint128.Uint128
currentMultiplier := uint128.From64(1)
for i := len(encoded) - 1; i >= 0; i-- {
tmp.SetInt64(int64(base58Lookup[string(encoded[i])]))
tmp.Mul(currentMultiplier, tmp)
bigResult.Add(bigResult, tmp)
currentMultiplier.Mul(currentMultiplier, bigBase)
bigResult = bigResult.Add(currentMultiplier.Mul64(uint64(base58Lookup[string(encoded[i])])))
currentMultiplier = currentMultiplier.Mul(base128)
}
result = bigResult.Bytes()
return
result = make([]byte, 16)
bigResult.ReverseBytes().PutBytes(result)
switch len(encoded) {
case 0:
return result[8+8:]
case 2:
return result[8+7:]
case 3:
return result[8+6:]
case 5:
return result[8+5:]
case 6:
return result[8+4:]
case 7:
return result[8+3:]
case 9:
return result[8+2:]
case 10:
return result[8+1:]
case 11:
return result[8:]
default:
}
return nil
}
func EncodeMoneroBase58(data ...[]byte) (result string) {
func EncodeMoneroBase58(data ...[]byte) string {
var combined []byte
for _, item := range data {
combined = append(combined, item...)
}
result := make([]byte, 0, len(data)*2)
length := len(combined)
rounds := length / 8
for i := 0; i < rounds; i++ {
result += encodeChunk(combined[i*8:(i+1)*8], 11)
result = append(result, encodeChunk(combined[i*8:(i+1)*8], 11)...)
}
if length%8 > 0 {
result += encodeChunk(combined[rounds*8:], 7)
result = append(result, encodeChunk(combined[rounds*8:], 7)...)
}
return
return string(result)
}
func DecodeMoneroBase58(data string) (result []byte) {
length := len(data)
rounds := length / 11
for i := 0; i < rounds; i++ {
result = append(result, decodeChunk(data[i*11:(i+1)*11])...)
result = append(result, decodeChunk(data[i*11:i*11+11])...)
}
if length%11 > 0 {
result = append(result, decodeChunk(data[rounds*11:])...)

7
go.mod
View file

@ -2,6 +2,9 @@ module git.gammaspectra.live/P2Pool/moneroutil
go 1.19
require golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b
require (
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b
lukechampine.com/uint128 v1.2.0
)
require golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec // indirect
require golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875 // indirect

14
go.sum
View file

@ -1,12 +1,6 @@
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b h1:huxqepDufQpLLIRXiVkTvnxrzJlpwmIWAObmcCcUFr0=
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875 h1:AzgQNqF+FKwyQ5LbVrVqOcuuFB67N47F9+htZYH0wFM=
golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=