github.com/mavryk-network/mvgo@v1.19.9/base58/base58check.go (about)

     1  // Copyright (c) 2020-2021 Blockwatch Data Inc.
     2  // Copyright (c) 2013-2014 The btcsuite developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package base58
     7  
     8  import (
     9  	"crypto/sha256"
    10  	"errors"
    11  	"sync"
    12  )
    13  
    14  var bufPool = &sync.Pool{
    15  	New: func() interface{} { return make([]byte, 0, 96) },
    16  }
    17  
    18  // ErrChecksum indicates that the checksum of a check-encoded string does not verify against
    19  // the checksum.
    20  var ErrChecksum = errors.New("checksum error")
    21  
    22  // ErrInvalidFormat indicates that the check-encoded string has an invalid format.
    23  var ErrInvalidFormat = errors.New("invalid format: version and/or checksum bytes missing")
    24  
    25  // checksum: first four bytes of sha256^2
    26  func checksum(input []byte) (cksum [4]byte) {
    27  	h := sha256.Sum256(input)
    28  	h2 := sha256.Sum256(h[:])
    29  	copy(cksum[:], h2[:4])
    30  	return
    31  }
    32  
    33  // CheckEncode prepends a version byte and appends a four byte checksum.
    34  func CheckEncode(input []byte, version []byte) string {
    35  	bi := bufPool.Get()
    36  	b := bi.([]byte)[:0]
    37  	b = append(b, version...)
    38  	b = append(b, input...)
    39  	cksum := checksum(b)
    40  	b = append(b, cksum[:]...)
    41  	res := Encode(b)
    42  	bufPool.Put(bi)
    43  	return res
    44  }
    45  
    46  // CheckDecode decodes a string that was encoded with CheckEncode and verifies the checksum.
    47  // adapted to support multi-length version strings
    48  func CheckDecode(input string, vlen int, buf []byte) ([]byte, []byte, error) {
    49  	decoded := Decode(input, buf)
    50  	if len(decoded) < 4+vlen {
    51  		return nil, nil, ErrInvalidFormat
    52  	}
    53  	version := decoded[0:vlen]
    54  	var cksum [4]byte
    55  	copy(cksum[:], decoded[len(decoded)-4:])
    56  	if checksum(decoded[:len(decoded)-4]) != cksum {
    57  		return nil, nil, ErrChecksum
    58  	}
    59  	payload := decoded[vlen : len(decoded)-4]
    60  	return payload, version, nil
    61  }