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 }