This function will compute what 6 5-bit values to XOR into the last 6 input values, in order to * make the checksum 0. These 6 values are packed together in a single 30-bit integer. The higher * bits correspond to earlier values. */
| 125 | * make the checksum 0. These 6 values are packed together in a single 30-bit integer. The higher |
| 126 | * bits correspond to earlier values. */ |
| 127 | uint32_t PolyMod(const data& v) |
| 128 | { |
| 129 | // The input is interpreted as a list of coefficients of a polynomial over F = GF(32), with an |
| 130 | // implicit 1 in front. If the input is [v0,v1,v2,v3,v4], that polynomial is v(x) = |
| 131 | // 1*x^5 + v0*x^4 + v1*x^3 + v2*x^2 + v3*x + v4. The implicit 1 guarantees that |
| 132 | // [v0,v1,v2,...] has a distinct checksum from [0,v0,v1,v2,...]. |
| 133 | |
| 134 | // The output is a 30-bit integer whose 5-bit groups are the coefficients of the remainder of |
| 135 | // v(x) mod g(x), where g(x) is the Bech32 generator, |
| 136 | // x^6 + {29}x^5 + {22}x^4 + {20}x^3 + {21}x^2 + {29}x + {18}. g(x) is chosen in such a way |
| 137 | // that the resulting code is a BCH code, guaranteeing detection of up to 3 errors within a |
| 138 | // window of 1023 characters. Among the various possible BCH codes, one was selected to in |
| 139 | // fact guarantee detection of up to 4 errors within a window of 89 characters. |
| 140 | |
| 141 | // Note that the coefficients are elements of GF(32), here represented as decimal numbers |
| 142 | // between {}. In this finite field, addition is just XOR of the corresponding numbers. For |
| 143 | // example, {27} + {13} = {27 ^ 13} = {22}. Multiplication is more complicated, and requires |
| 144 | // treating the bits of values themselves as coefficients of a polynomial over a smaller field, |
| 145 | // GF(2), and multiplying those polynomials mod a^5 + a^3 + 1. For example, {5} * {26} = |
| 146 | // (a^2 + 1) * (a^4 + a^3 + a) = (a^4 + a^3 + a) * a^2 + (a^4 + a^3 + a) = a^6 + a^5 + a^4 + a |
| 147 | // = a^3 + 1 (mod a^5 + a^3 + 1) = {9}. |
| 148 | |
| 149 | // During the course of the loop below, `c` contains the bitpacked coefficients of the |
| 150 | // polynomial constructed from just the values of v that were processed so far, mod g(x). In |
| 151 | // the above example, `c` initially corresponds to 1 mod g(x), and after processing 2 inputs of |
| 152 | // v, it corresponds to x^2 + v0*x + v1 mod g(x). As 1 mod g(x) = 1, that is the starting value |
| 153 | // for `c`. |
| 154 | |
| 155 | // The following Sage code constructs the generator used: |
| 156 | // |
| 157 | // B = GF(2) # Binary field |
| 158 | // BP.<b> = B[] # Polynomials over the binary field |
| 159 | // F_mod = b**5 + b**3 + 1 |
| 160 | // F.<f> = GF(32, modulus=F_mod, repr='int') # GF(32) definition |
| 161 | // FP.<x> = F[] # Polynomials over GF(32) |
| 162 | // E_mod = x**2 + F.fetch_int(9)*x + F.fetch_int(23) |
| 163 | // E.<e> = F.extension(E_mod) # GF(1024) extension field definition |
| 164 | // for p in divisors(E.order() - 1): # Verify e has order 1023. |
| 165 | // assert((e**p == 1) == (p % 1023 == 0)) |
| 166 | // G = lcm([(e**i).minpoly() for i in range(997,1000)]) |
| 167 | // print(G) # Print out the generator |
| 168 | // |
| 169 | // It demonstrates that g(x) is the least common multiple of the minimal polynomials |
| 170 | // of 3 consecutive powers (997,998,999) of a primitive element (e) of GF(1024). |
| 171 | // That guarantees it is, in fact, the generator of a primitive BCH code with cycle |
| 172 | // length 1023 and distance 4. See https://en.wikipedia.org/wiki/BCH_code for more details. |
| 173 | |
| 174 | uint32_t c = 1; |
| 175 | for (const auto v_i : v) { |
| 176 | // We want to update `c` to correspond to a polynomial with one extra term. If the initial |
| 177 | // value of `c` consists of the coefficients of c(x) = f(x) mod g(x), we modify it to |
| 178 | // correspond to c'(x) = (f(x) * x + v_i) mod g(x), where v_i is the next input to |
| 179 | // process. Simplifying: |
| 180 | // c'(x) = (f(x) * x + v_i) mod g(x) |
| 181 | // ((f(x) mod g(x)) * x + v_i) mod g(x) |
| 182 | // (c(x) * x + v_i) mod g(x) |
| 183 | // If c(x) = c0*x^5 + c1*x^4 + c2*x^3 + c3*x^2 + c4*x + c5, we want to compute |
| 184 | // c'(x) = (c0*x^5 + c1*x^4 + c2*x^3 + c3*x^2 + c4*x + c5) * x + v_i mod g(x) |
no outgoing calls
no test coverage detected