Initial commit, imported from https://git.gammaspectra.live/P2Pool/moneroutil commit 7b24ed2d11ce3f88ca88247778296d60a6129319
This commit is contained in:
commit
3e013d432d
8
LICENSE
Normal file
8
LICENSE
Normal 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
27
LICENSE-BSD
Normal 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
25
LICENSE-MIT
Normal 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
133
base58.go
Normal 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
16
base58_test.go
Normal 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()
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue