github.com/gcash/bchutil@v0.0.0-20210113190856-6ea28dff4000/bech32/bech32.go (about)

     1  // Copyright (c) 2017 The btcsuite developers
     2  // Use of this source code is governed by an ISC
     3  // license that can be found in the LICENSE file.
     4  
     5  package bech32
     6  
     7  import (
     8  	"fmt"
     9  	"strings"
    10  )
    11  
    12  const charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
    13  
    14  var gen = []int{0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3}
    15  
    16  // Decode decodes a bech32 encoded string, returning the human-readable
    17  // part and the data part excluding the checksum.
    18  func Decode(bech string) (string, []byte, error) {
    19  	// The maximum allowed length for a bech32 string is 90. It must also
    20  	// be at least 8 characters, since it needs a non-empty HRP, a
    21  	// separator, and a 6 character checksum.
    22  	if len(bech) < 8 || len(bech) > 90 {
    23  		return "", nil, fmt.Errorf("invalid bech32 string length %d",
    24  			len(bech))
    25  	}
    26  	// Only	ASCII characters between 33 and 126 are allowed.
    27  	for i := 0; i < len(bech); i++ {
    28  		if bech[i] < 33 || bech[i] > 126 {
    29  			return "", nil, fmt.Errorf("invalid character in "+
    30  				"string: '%c'", bech[i])
    31  		}
    32  	}
    33  
    34  	// The characters must be either all lowercase or all uppercase.
    35  	lower := strings.ToLower(bech)
    36  	upper := strings.ToUpper(bech)
    37  	if bech != lower && bech != upper {
    38  		return "", nil, fmt.Errorf("string not all lowercase or all " +
    39  			"uppercase")
    40  	}
    41  
    42  	// We'll work with the lowercase string from now on.
    43  	bech = lower
    44  
    45  	// The string is invalid if the last '1' is non-existent, it is the
    46  	// first character of the string (no human-readable part) or one of the
    47  	// last 6 characters of the string (since checksum cannot contain '1'),
    48  	// or if the string is more than 90 characters in total.
    49  	one := strings.LastIndexByte(bech, '1')
    50  	if one < 1 || one+7 > len(bech) {
    51  		return "", nil, fmt.Errorf("invalid index of 1")
    52  	}
    53  
    54  	// The human-readable part is everything before the last '1'.
    55  	hrp := bech[:one]
    56  	data := bech[one+1:]
    57  
    58  	// Each character corresponds to the byte with value of the index in
    59  	// 'charset'.
    60  	decoded, err := toBytes(data)
    61  	if err != nil {
    62  		return "", nil, fmt.Errorf("failed converting data to bytes: "+
    63  			"%v", err)
    64  	}
    65  
    66  	if !bech32VerifyChecksum(hrp, decoded) {
    67  		moreInfo := ""
    68  		checksum := bech[len(bech)-6:]
    69  		expected, err := toChars(bech32Checksum(hrp,
    70  			decoded[:len(decoded)-6]))
    71  		if err == nil {
    72  			moreInfo = fmt.Sprintf("Expected %v, got %v.",
    73  				expected, checksum)
    74  		}
    75  		return "", nil, fmt.Errorf("checksum failed. " + moreInfo)
    76  	}
    77  
    78  	// We exclude the last 6 bytes, which is the checksum.
    79  	return hrp, decoded[:len(decoded)-6], nil
    80  }
    81  
    82  // Encode encodes a byte slice into a bech32 string with the
    83  // human-readable part hrb. Note that the bytes must each encode 5 bits
    84  // (base32).
    85  func Encode(hrp string, data []byte) (string, error) {
    86  	// Calculate the checksum of the data and append it at the end.
    87  	checksum := bech32Checksum(hrp, data)
    88  	combined := append(data, checksum...)
    89  
    90  	// The resulting bech32 string is the concatenation of the hrp, the
    91  	// separator 1, data and checksum. Everything after the separator is
    92  	// represented using the specified charset.
    93  	dataChars, err := toChars(combined)
    94  	if err != nil {
    95  		return "", fmt.Errorf("unable to convert data bytes to chars: "+
    96  			"%v", err)
    97  	}
    98  	return hrp + "1" + dataChars, nil
    99  }
   100  
   101  // toBytes converts each character in the string 'chars' to the value of the
   102  // index of the correspoding character in 'charset'.
   103  func toBytes(chars string) ([]byte, error) {
   104  	decoded := make([]byte, 0, len(chars))
   105  	for i := 0; i < len(chars); i++ {
   106  		index := strings.IndexByte(charset, chars[i])
   107  		if index < 0 {
   108  			return nil, fmt.Errorf("invalid character not part of "+
   109  				"charset: %v", chars[i])
   110  		}
   111  		decoded = append(decoded, byte(index))
   112  	}
   113  	return decoded, nil
   114  }
   115  
   116  // toChars converts the byte slice 'data' to a string where each byte in 'data'
   117  // encodes the index of a character in 'charset'.
   118  func toChars(data []byte) (string, error) {
   119  	result := make([]byte, 0, len(data))
   120  	for _, b := range data {
   121  		if int(b) >= len(charset) {
   122  			return "", fmt.Errorf("invalid data byte: %v", b)
   123  		}
   124  		result = append(result, charset[b])
   125  	}
   126  	return string(result), nil
   127  }
   128  
   129  // ConvertBits converts a byte slice where each byte is encoding fromBits bits,
   130  // to a byte slice where each byte is encoding toBits bits.
   131  func ConvertBits(data []byte, fromBits, toBits uint8, pad bool) ([]byte, error) {
   132  	if fromBits < 1 || fromBits > 8 || toBits < 1 || toBits > 8 {
   133  		return nil, fmt.Errorf("only bit groups between 1 and 8 allowed")
   134  	}
   135  
   136  	// The final bytes, each byte encoding toBits bits.
   137  	var regrouped []byte
   138  
   139  	// Keep track of the next byte we create and how many bits we have
   140  	// added to it out of the toBits goal.
   141  	nextByte := byte(0)
   142  	filledBits := uint8(0)
   143  
   144  	for _, b := range data {
   145  
   146  		// Discard unused bits.
   147  		b = b << (8 - fromBits)
   148  
   149  		// How many bits remaining to extract from the input data.
   150  		remFromBits := fromBits
   151  		for remFromBits > 0 {
   152  			// How many bits remaining to be added to the next byte.
   153  			remToBits := toBits - filledBits
   154  
   155  			// The number of bytes to next extract is the minimum of
   156  			// remFromBits and remToBits.
   157  			toExtract := remFromBits
   158  			if remToBits < toExtract {
   159  				toExtract = remToBits
   160  			}
   161  
   162  			// Add the next bits to nextByte, shifting the already
   163  			// added bits to the left.
   164  			nextByte = (nextByte << toExtract) | (b >> (8 - toExtract))
   165  
   166  			// Discard the bits we just extracted and get ready for
   167  			// next iteration.
   168  			b = b << toExtract
   169  			remFromBits -= toExtract
   170  			filledBits += toExtract
   171  
   172  			// If the nextByte is completely filled, we add it to
   173  			// our regrouped bytes and start on the next byte.
   174  			if filledBits == toBits {
   175  				regrouped = append(regrouped, nextByte)
   176  				filledBits = 0
   177  				nextByte = 0
   178  			}
   179  		}
   180  	}
   181  
   182  	// We pad any unfinished group if specified.
   183  	if pad && filledBits > 0 {
   184  		nextByte = nextByte << (toBits - filledBits)
   185  		regrouped = append(regrouped, nextByte)
   186  		filledBits = 0
   187  		nextByte = 0
   188  	}
   189  
   190  	// Any incomplete group must be <= 4 bits, and all zeroes.
   191  	if filledBits > 0 && (filledBits > 4 || nextByte != 0) {
   192  		return nil, fmt.Errorf("invalid incomplete group")
   193  	}
   194  
   195  	return regrouped, nil
   196  }
   197  
   198  // For more details on the checksum calculation, please refer to BIP 173.
   199  func bech32Checksum(hrp string, data []byte) []byte {
   200  	// Convert the bytes to list of integers, as this is needed for the
   201  	// checksum calculation.
   202  	integers := make([]int, len(data))
   203  	for i, b := range data {
   204  		integers[i] = int(b)
   205  	}
   206  	values := append(bech32HrpExpand(hrp), integers...)
   207  	values = append(values, []int{0, 0, 0, 0, 0, 0}...)
   208  	polymod := bech32Polymod(values) ^ 1
   209  	var res []byte
   210  	for i := 0; i < 6; i++ {
   211  		res = append(res, byte((polymod>>uint(5*(5-i)))&31))
   212  	}
   213  	return res
   214  }
   215  
   216  // For more details on the polymod calculation, please refer to BIP 173.
   217  func bech32Polymod(values []int) int {
   218  	chk := 1
   219  	for _, v := range values {
   220  		b := chk >> 25
   221  		chk = (chk&0x1ffffff)<<5 ^ v
   222  		for i := 0; i < 5; i++ {
   223  			if (b>>uint(i))&1 == 1 {
   224  				chk ^= gen[i]
   225  			}
   226  		}
   227  	}
   228  	return chk
   229  }
   230  
   231  // For more details on HRP expansion, please refer to BIP 173.
   232  func bech32HrpExpand(hrp string) []int {
   233  	v := make([]int, 0, len(hrp)*2+1)
   234  	for i := 0; i < len(hrp); i++ {
   235  		v = append(v, int(hrp[i]>>5))
   236  	}
   237  	v = append(v, 0)
   238  	for i := 0; i < len(hrp); i++ {
   239  		v = append(v, int(hrp[i]&31))
   240  	}
   241  	return v
   242  }
   243  
   244  // For more details on the checksum verification, please refer to BIP 173.
   245  func bech32VerifyChecksum(hrp string, data []byte) bool {
   246  	integers := make([]int, len(data))
   247  	for i, b := range data {
   248  		integers[i] = int(b)
   249  	}
   250  	concat := append(bech32HrpExpand(hrp), integers...)
   251  	return bech32Polymod(concat) == 1
   252  }