4. Division
For polynomials, the efficient algorithm of synthetic division is mainly used. Before talking about synthetic division, review the long division:
例:f(x) = x3 - x2 - x - 1
Expand f(x) to Taylor's expression based on offset a : c 0 + c 1 (xa) + c 2 (xa) 2 + c 3 (xa) 3
Suppose the offset value a=2
Expansion of f(x) above = 1 + 7(x-2) + 5(x-2) 2 + (xa) 3
i.e. c 0 = 1, c 1 = 7, c 2 = 5, c 3 = 1
We can calculate c 0, c 1, c 2, c 3 separately by long division
Get the remainder 1 , which is c 0 , and repeat the calculation twice (x2 + x + 1) / (x-2) = (x + 3) … 7, (x + 3) / (x-2) = 1 … 5
All coefficients c 0 to c 3 are all counted up
The same result can also be obtained by synthetic division, but the calculation method is much simpler than the above
Still taking the above f(x) as an example, obtain c 0, c 1, c 2, c 3 by comprehensive division
The first step is to extract the coefficients of x 3 , -x 2 , -x, -1 , multiply -a of xa by -1 and put it on the far right
The calculation steps are as follows:
- The first number in row 1 remains unchanged and moves down to row 2
- Add the 1st number in the 2nd row 1 * 2 and the 2nd number in the 1st row to get the 2nd number in the 2nd row ,
- Add the 2nd number 1 * 2 in the 2nd row and the 3rd number in the 1st row to get the 3rd number in the 2nd row ,
- Add the 3rd number in the 2nd row 1 * 2 and the 4th number in the 1st row to get the 4th number in the 2nd row
The last number in the second row is the remainder, and the remainder is not calculated as a parameter. The above are the steps of a comprehensive division, and the number in the third row is obtained by the second comprehensive division.
The following code is an extended implementation of the algorithm for the GF(2^p) polynomial:
def gf_poly_div(dividend, divisor): '''Applies to fast polynomial division in GF(2^p) field.''' msg_out = list(dividend) # Copy the dividend (suffix ecc bytes at the end, padded with 0) #normalizer = divisor[0] # precomputing for performance for i in range(0, len(dividend) - (len(divisor)-1)): #msg_out[i] /= normalizer coef = msg_out[i] if coef != 0: # Avoid log(0) undefined errors. for j in range(1, len(divisor)): # Since the first position of the polynomial is 1, (1^1==0) it can be skipped if divisor[j] != 0: # log(0) is undefined msg_out[i + j] ^= gf_mul(divisor[j], coef) # Equivalent to mathematical expression: msg_out[i + j] += -divisor[j] * coef , but XOR operation is efficient # msg_out contains the quotient and remainder, the highest power of the remainder ( == length-1) is the same as the divisor, and the breakpoint is calculated below. separator = -(len(divisor)-1) return msg_out[:separator], msg_out[separator:] # Return quotient, remainder