Initial commit, imported from https://git.gammaspectra.live/P2Pool/moneroutil commit 7b24ed2d11ce3f88ca88247778296d60a6129319

This commit is contained in:
DataHoarder 2023-05-27 17:37:14 +02:00
commit 3e013d432d
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk
6 changed files with 212 additions and 0 deletions

8
LICENSE Normal file
View file

@ -0,0 +1,8 @@
Monero Utilities
Copyright (c) 2013 Go Authors
Copyright (c) 2017 Paxos
Portion of the code is Go Author's property, licensed under the BSD-3 license
Portion of the code is Paxos's property, licensed under the MIT license
const.go and edwards25519.go are licensed under BSD-3 (see LICENSE-BSD), all other files are licensed under MIT (see LICENSE-MIT).

27
LICENSE-BSD Normal file
View file

@ -0,0 +1,27 @@
Copyright (c) 2009 The Go Authors. All rights reserved
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

25
LICENSE-MIT Normal file
View file

@ -0,0 +1,25 @@
Monero Utilities
Copyright (c) 2017, Paxos <jimmy.song@paxos.com>
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

133
base58.go Normal file
View file

@ -0,0 +1,133 @@
package base58
import (
"encoding/binary"
)
const base58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
const reverseBase58 =
// 0 1 2 3 4 5 6 7 8 9 a b c d e f */
/* 00 */ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
/* 10 */ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
/* 20 */ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
/* 30 */ "\xff\x00\x01\x02\x03\x04\x05\x06\x07\x08\xff\xff\xff\xff\xff\xff" +
/* 40 */ "\xff\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\xff\x11\x12\x13\x14\x15\xff" +
/* 50 */ "\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\xff\xff\xff\xff\xff" +
/* 60 */ "\xff\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\xff\x2c\x2d\x2e" +
/* 70 */ "\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\xff\xff\xff\xff\xff" +
/* 80 */ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
/* 90 */ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
/* a0 */ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
/* b0 */ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
/* c0 */ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
/* d0 */ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
/* e0 */ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
/* f0 */ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
func encodeChunk(raw []byte, buf []byte) []byte {
intToDecode := binary.BigEndian.Uint64(raw[:])
for intToDecode > 0 {
buf = append(buf, base58[intToDecode%58])
intToDecode /= 58
}
for len(buf) < 11 {
buf = append(buf, '1')
}
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 encodeChunkTail(raw []byte, buf []byte) []byte {
var data [8]byte
copy(data[8-len(raw):], raw)
intToDecode := binary.BigEndian.Uint64(data[:])
for intToDecode > 0 {
buf = append(buf, base58[intToDecode%58])
intToDecode /= 58
}
for len(buf) < 7 {
buf = append(buf, '1')
}
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(buf []byte, encoded string) []byte {
var intResult uint64
currentMultiplier := uint64(1)
for i := len(encoded) - 1; i >= 0; i-- {
intResult += currentMultiplier * uint64(reverseBase58[encoded[i]])
// this can overflow, but only on the last iteration when i == 0 when all data is valid
currentMultiplier *= 58
}
var result [8]byte
binary.BigEndian.PutUint64(result[:], intResult)
switch len(encoded) {
case 0:
return append(buf, result[8:]...)
case 2:
return append(buf, result[7:]...)
case 3:
return append(buf, result[6:]...)
case 5:
return append(buf, result[5:]...)
case 6:
return append(buf, result[4:]...)
case 7:
return append(buf, result[3:]...)
case 9:
return append(buf, result[2:]...)
case 10:
return append(buf, result[1:]...)
case 11:
return append(buf, result[:]...)
default:
}
return nil
}
func Encode(data ...[]byte) string {
//preallocate common case
combined := make([]byte, 0, 96)
for _, item := range data {
combined = append(combined, item...)
}
result := make([]byte, 0, len(combined)*2)
buf := make([]byte, 0, len(combined)*2)
length := len(combined)
rounds := length / 8
for i := 0; i < rounds; i++ {
result = append(result, encodeChunk(combined[i*8:(i+1)*8], buf[:0])...)
}
if length%8 > 0 {
result = append(result, encodeChunkTail(combined[rounds*8:], buf[:0])...)
}
return string(result)
}
func Decode(data string) (result []byte) {
//common case
return DecodePreAllocated(make([]byte, 0, 69), data)
}
func DecodePreAllocated(buf []byte, data string) (result []byte) {
result = buf
length := len(data)
rounds := length / 11
for i := 0; i < rounds; i++ {
result = decodeChunk(result, data[i*11:i*11+11])
}
if length%11 > 0 {
result = decodeChunk(result, data[rounds*11:])
}
return
}

16
base58_test.go Normal file
View file

@ -0,0 +1,16 @@
package base58
import (
"bytes"
"testing"
)
func TestEncodeDecodeMoneroBase58Bounds(t *testing.T) {
data := make([]byte, 2048)
for i := range data {
data[i] = 0xff
}
if bytes.Compare(Decode(Encode(data)), data) != 0 {
t.Fatal()
}
}

3
go.mod Normal file
View file

@ -0,0 +1,3 @@
module git.gammaspectra.live/P2Pool/monero-base58
go 1.20