bech32.go
1 package zpay32 2 3 import ( 4 "fmt" 5 "strings" 6 ) 7 8 const charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l" 9 10 var gen = []int{0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3} 11 12 // NOTE: This method it a slight modification of the method bech32.Decode found 13 // btcutil, allowing strings to be more than 90 characters. 14 15 // decodeBech32 decodes a bech32 encoded string, returning the human-readable 16 // part and the data part excluding the checksum. 17 // Note: the data will be base32 encoded, that is each element of the returned 18 // byte array will encode 5 bits of data. Use the ConvertBits method to convert 19 // this to 8-bit representation. 20 func decodeBech32(bech string) (string, []byte, error) { 21 // The maximum allowed length for a bech32 string is 90. It must also 22 // be at least 8 characters, since it needs a non-empty HRP, a 23 // separator, and a 6 character checksum. 24 // NB: The 90 character check specified in BIP173 is skipped here, to 25 // allow strings longer than 90 characters. 26 if len(bech) < 8 { 27 return "", nil, fmt.Errorf("invalid bech32 string length %d", 28 len(bech)) 29 } 30 // Only ASCII characters between 33 and 126 are allowed. 31 for i := 0; i < len(bech); i++ { 32 if bech[i] < 33 || bech[i] > 126 { 33 return "", nil, fmt.Errorf("invalid character in "+ 34 "string: '%c'", bech[i]) 35 } 36 } 37 38 // The characters must be either all lowercase or all uppercase. 39 lower := strings.ToLower(bech) 40 upper := strings.ToUpper(bech) 41 if bech != lower && bech != upper { 42 return "", nil, fmt.Errorf("string not all lowercase or all " + 43 "uppercase") 44 } 45 46 // We'll work with the lowercase string from now on. 47 bech = lower 48 49 // The string is invalid if the last '1' is non-existent, it is the 50 // first character of the string (no human-readable part) or one of the 51 // last 6 characters of the string (since checksum cannot contain '1'), 52 // or if the string is more than 90 characters in total. 53 one := strings.LastIndexByte(bech, '1') 54 if one < 1 || one+7 > len(bech) { 55 return "", nil, fmt.Errorf("invalid index of 1") 56 } 57 58 // The human-readable part is everything before the last '1'. 59 hrp := bech[:one] 60 data := bech[one+1:] 61 62 // Each character corresponds to the byte with value of the index in 63 // 'charset'. 64 decoded, err := toBytes(data) 65 if err != nil { 66 return "", nil, fmt.Errorf("failed converting data to bytes: "+ 67 "%v", err) 68 } 69 70 if !bech32VerifyChecksum(hrp, decoded) { 71 moreInfo := "" 72 checksum := bech[len(bech)-6:] 73 expected, err := toChars(bech32Checksum(hrp, 74 decoded[:len(decoded)-6])) 75 if err == nil { 76 moreInfo = fmt.Sprintf("Expected %v, got %v.", 77 expected, checksum) 78 } 79 80 return "", nil, fmt.Errorf("checksum failed. %s", moreInfo) 81 } 82 83 // We exclude the last 6 bytes, which is the checksum. 84 return hrp, decoded[:len(decoded)-6], nil 85 } 86 87 // toBytes converts each character in the string 'chars' to the value of the 88 // index of the corresponding character in 'charset'. 89 func toBytes(chars string) ([]byte, error) { 90 decoded := make([]byte, 0, len(chars)) 91 for i := 0; i < len(chars); i++ { 92 index := strings.IndexByte(charset, chars[i]) 93 if index < 0 { 94 return nil, fmt.Errorf("invalid character not part of "+ 95 "charset: %v", chars[i]) 96 } 97 decoded = append(decoded, byte(index)) 98 } 99 return decoded, nil 100 } 101 102 // toChars converts the byte slice 'data' to a string where each byte in 'data' 103 // encodes the index of a character in 'charset'. 104 func toChars(data []byte) (string, error) { 105 result := make([]byte, 0, len(data)) 106 for _, b := range data { 107 if int(b) >= len(charset) { 108 return "", fmt.Errorf("invalid data byte: %v", b) 109 } 110 result = append(result, charset[b]) 111 } 112 return string(result), nil 113 } 114 115 // For more details on the checksum calculation, please refer to BIP 173. 116 func bech32Checksum(hrp string, data []byte) []byte { 117 // Convert the bytes to list of integers, as this is needed for the 118 // checksum calculation. 119 integers := make([]int, len(data)) 120 for i, b := range data { 121 integers[i] = int(b) 122 } 123 values := append(bech32HrpExpand(hrp), integers...) 124 values = append(values, []int{0, 0, 0, 0, 0, 0}...) 125 polymod := bech32Polymod(values) ^ 1 126 var res []byte 127 for i := 0; i < 6; i++ { 128 res = append(res, byte((polymod>>uint(5*(5-i)))&31)) 129 } 130 return res 131 } 132 133 // For more details on the polymod calculation, please refer to BIP 173. 134 func bech32Polymod(values []int) int { 135 chk := 1 136 for _, v := range values { 137 b := chk >> 25 138 chk = (chk&0x1ffffff)<<5 ^ v 139 for i := 0; i < 5; i++ { 140 if (b>>uint(i))&1 == 1 { 141 chk ^= gen[i] 142 } 143 } 144 } 145 return chk 146 } 147 148 // For more details on HRP expansion, please refer to BIP 173. 149 func bech32HrpExpand(hrp string) []int { 150 v := make([]int, 0, len(hrp)*2+1) 151 for i := 0; i < len(hrp); i++ { 152 v = append(v, int(hrp[i]>>5)) 153 } 154 v = append(v, 0) 155 for i := 0; i < len(hrp); i++ { 156 v = append(v, int(hrp[i]&31)) 157 } 158 return v 159 } 160 161 // For more details on the checksum verification, please refer to BIP 173. 162 func bech32VerifyChecksum(hrp string, data []byte) bool { 163 integers := make([]int, len(data)) 164 for i, b := range data { 165 integers[i] = int(b) 166 } 167 concat := append(bech32HrpExpand(hrp), integers...) 168 return bech32Polymod(concat) == 1 169 }