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