Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
xinshuhao committed Jun 14, 2019
1 parent c3c5636 commit 35dc1e7
Show file tree
Hide file tree
Showing 12 changed files with 777 additions and 0 deletions.
44 changes: 44 additions & 0 deletions commons/base58/alphabet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Package base58 provides ...
package base58

const (
// alphabet is the modified base58 alphabet used by Bitcoin.
alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

alphabetIdx0 = '1'
)

var b58 = [256]byte{
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 0, 1, 2, 3, 4, 5, 6,
7, 8, 255, 255, 255, 255, 255, 255,
255, 9, 10, 11, 12, 13, 14, 15,
16, 255, 17, 18, 19, 20, 21, 255,
22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 255, 255, 255, 255, 255,
255, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 255, 44, 45, 46,
47, 48, 49, 50, 51, 52, 53, 54,
55, 56, 57, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
}
69 changes: 69 additions & 0 deletions commons/base58/base58.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Package base58 provides ...
// https://github.com/btcsuite/btcutil/blob/master/base58/base58.go
package base58

import "math/big"

var bigRadix = big.NewInt(58)
var bigZero = big.NewInt(0)

// Decode decodes a modified base58 string to a byte slice.
func Decode(b string) []byte {
answer := big.NewInt(0)
j := big.NewInt(1)

scratch := new(big.Int)
for i := len(b) - 1; i >= 0; i-- {
tmp := b58[b[i]]
if tmp == 255 {
return []byte("")
}
scratch.SetInt64(int64(tmp))
scratch.Mul(j, scratch)
answer.Add(answer, scratch)
j.Mul(j, bigRadix)
}

tmpval := answer.Bytes()

var numZeros int
for numZeros = 0; numZeros < len(b); numZeros++ {
if b[numZeros] != alphabetIdx0 {
break
}
}
flen := numZeros + len(tmpval)
val := make([]byte, flen)
copy(val[numZeros:], tmpval)

return val
}

// Encode encodes a byte slice to a modified base58 string.
func Encode(b []byte) string {
x := new(big.Int)
x.SetBytes(b)

answer := make([]byte, 0, len(b)*136/100)
for x.Cmp(bigZero) > 0 {
mod := new(big.Int)
x.DivMod(x, bigRadix, mod)
answer = append(answer, alphabet[mod.Int64()])
}

// leading zero bytes
for _, i := range b {
if i != 0 {
break
}
answer = append(answer, alphabetIdx0)
}

// reverse
alen := len(answer)
for i := 0; i < alen/2; i++ {
answer[i], answer[alen-1-i] = answer[alen-1-i], answer[i]
}

return string(answer)
}
23 changes: 23 additions & 0 deletions commons/base58/base58check.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Package basen provides ...
package base58

import (
"crypto/sha256"
)

func checksum(input []byte) (cksum [4]byte) {
h := sha256.Sum256(input)
h2 := sha256.Sum256(h[:])
copy(cksum[:], h2[:4])
return
}

func CheckEncode(input []byte) string {
b := make([]byte, 0, len(input)+4)
b = append(b, input[:]...)
cksum := checksum(input)
b = append(b, cksum[:]...)
// return base582.Encode(b)
return Encode(b)

}
77 changes: 77 additions & 0 deletions commons/bip32path.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Package bip32 provides ...
package commons

import (
"errors"
"strconv"
"strings"
)

var ErrKeyPathFormat = errors.New("Wallet Path Error")
var ErrParentKey = errors.New("Key must master")

var mapKey = make(map[string]*ExtendedKey)

// DerivePath return key by path : m/0'/1/2' etc...
func (key *ExtendedKey) DerivePath(pathStr string) (*ExtendedKey, error) {
//fmt.Println("###########", len(mapKey))
if key.childNum > 0 {
return nil, ErrParentKey
}
keyTmp := mapKey[pathStr]
path := strings.Split(pathStr, "/")
err := vaildPath(path)
if err != nil {
return nil, err
}
tmpPath := []string{}
var tmpPathStr string
var tmpParentKey *ExtendedKey
for _, childNumStr := range path {
tmpPath = append(tmpPath, childNumStr)
tmpPathStr = strings.Join(tmpPath, "/")
keyTmp = mapKey[tmpPathStr]
if tmpPathStr == "m" {
keyTmp = key
} else {
isHardenedChild := false
if strings.HasSuffix(childNumStr, "'") {
childNumStr = strings.Replace(childNumStr, "'", "", -1)
isHardenedChild = true
}
childNum, _ := strconv.Atoi(childNumStr)
var err error
if isHardenedChild {
keyTmp, err = tmpParentKey.HardenedChild(uint32(childNum))
} else {
keyTmp, err = tmpParentKey.Child(uint32(childNum))
}
if err != nil {
return nil, err
}
}
mapKey[tmpPathStr] = keyTmp
tmpParentKey = keyTmp
}
return keyTmp, nil
}

func vaildPath(path []string) error {
if path[0] != "m" {
return ErrKeyPathFormat
}
for i := 1; i < len(path); i++ {
childNumStr := path[i]
if strings.HasSuffix(childNumStr, "'") {
childNumStr = strings.Replace(childNumStr, "'", "", -1)
}
childNum, err := strconv.Atoi(childNumStr)
if err != nil {
return ErrKeyPathFormat
}
if uint32(childNum) >= HardenedKeyStart || childNum < 0 {
return ErrKeyPathFormat
}
}
return nil
}
35 changes: 35 additions & 0 deletions commons/bytes/bytes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Package bytes provides ...
package bytes

import (
"errors"
"math/big"
)

// PaddedAppend append src to dst, if less than size padding 0 at start
func PaddedAppend(dst []byte, srcPaddedSize int, src []byte) []byte {
return append(dst, PaddedBytes(srcPaddedSize, src)...)
}

// PaddedBytes padding byte array to size length
func PaddedBytes(size int, src []byte) []byte {
offset := size - len(src)
tmp := src
if offset > 0 {
tmp = make([]byte, size)
copy(tmp[offset:], src)
}
return tmp
}

// BytesFromHexStrFixZeroPrefix return fix Zero start strings
// like 00010203040506
func BytesFromHexStrFixZeroPrefix(str string) ([]byte, error) {
strNum, ok := new(big.Int).SetString(str, 16)
if !ok {
return nil, errors.New("string error")
}
bytes := strNum.Bytes()
bytes = PaddedBytes(len(str)/2, bytes)
return bytes, nil
}
47 changes: 47 additions & 0 deletions commons/ec/address.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Package address provides ...
package ec

import (
"errors"

"golang.org/x/crypto/ripemd160"
"github.com/WaykiChain/wicc-wallet-utils-go/commons/base58"
)

// AddressPubKeyHash pay-to-pubkey-hash (P2PKH)
type AddressPubKeyHash struct {
hash [ripemd160.Size]byte
version byte
}

func NewAddressPubKeyHash(pkHash []byte, version byte) (*AddressPubKeyHash, error) {
return newAddressPubKeyHash(pkHash, version)
}

func newAddressPubKeyHash(pkHash []byte, version byte) (*AddressPubKeyHash, error) {
if len(pkHash) != ripemd160.Size {
return nil, errors.New("pkHash must be 20 bytes")
}
addr := &AddressPubKeyHash{}
addr.version = version
copy(addr.hash[:], pkHash)
return addr, nil
}

// EncodeAddress return P2PKH address
func (a *AddressPubKeyHash) EncodeAddress() string {
return encodeAddress(a.hash[:], a.version)
}

// P2PKH P2SH address encoding
func encodeAddress(hash160 []byte, version byte) string {
input := make([]byte, 21)
input[0] = version
copy(input[1:], hash160)
return base58.CheckEncode(input)
}

// Hash160 return hash160
func (a *AddressPubKeyHash) Hash160() []byte {
return a.hash[:]
}
30 changes: 30 additions & 0 deletions commons/ec/privkey.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Package ec provides ...
package ec

import (
"math/big"
"github.com/WaykiChain/wicc-wallet-utils-go/commons/bytes"
)

const PrivKeyBytesLen = 32

type PrivateKey struct {
PubKey PublicKey
D *big.Int
}

func PrivKeyFromBytes(bytes []byte) (*PrivateKey, *PublicKey) {
x, y := secp256k1.ScalarBaseMult(bytes)
privKey := &PrivateKey{
PubKey: PublicKey{
X: x,
Y: y,
},
D: new(big.Int).SetBytes(bytes),
}
return privKey, &privKey.PubKey
}

func (privKey *PrivateKey) Serialize() []byte {
return bytes.PaddedBytes(32, privKey.D.Bytes())
}
Loading

0 comments on commit 35dc1e7

Please sign in to comment.