base58check.go raw

   1  package base58
   2  
   3  import (
   4  	"crypto/sha256"
   5  	"errors"
   6  )
   7  
   8  // ErrChecksum indicates that the checksum of a check-encoded string does not verify against the checksum.
   9  var ErrChecksum = errors.New("checksum error")
  10  
  11  // ErrInvalidFormat indicates that the check-encoded string has an invalid format.
  12  var ErrInvalidFormat = errors.New("invalid format: version and/or checksum bytes missing")
  13  
  14  // checksum: first four bytes of sha256^2
  15  func checksum(input []byte) (cksum [4]byte) {
  16  	h := sha256.Sum256(input)
  17  	h2 := sha256.Sum256(h[:])
  18  	copy(cksum[:], h2[:4])
  19  	return
  20  }
  21  
  22  // CheckEncode prepends a version byte and appends a four byte checksum.
  23  func CheckEncode(input []byte, version byte) string {
  24  	b := make([]byte, 0, 1+len(input)+4)
  25  	b = append(b, version)
  26  	b = append(b, input[:]...)
  27  	cksum := checksum(b)
  28  	b = append(b, cksum[:]...)
  29  	return Encode(b)
  30  }
  31  
  32  // CheckDecode decodes a string that was encoded with CheckEncode and verifies the checksum.
  33  func CheckDecode(input string) (result []byte, version byte, e error) {
  34  	decoded := Decode(input)
  35  	if len(decoded) < 5 {
  36  		return nil, 0, ErrInvalidFormat
  37  	}
  38  	version = decoded[0]
  39  	var cksum [4]byte
  40  	copy(cksum[:], decoded[len(decoded)-4:])
  41  	if checksum(decoded[:len(decoded)-4]) != cksum {
  42  		return nil, 0, ErrChecksum
  43  	}
  44  	payload := decoded[1 : len(decoded)-4]
  45  	result = append(result, payload...)
  46  	return
  47  }
  48