package ssss import ( "crypto/rand" "io" "math/big" "xdx.jelly/xgcl/gerrors" ) /* coefficients of some irreducible polynomials over GF(2) */ // var irred_coeff = [...]byte{ // 4, 3, 1, 5, 3, 1, 4, 3, 1, 7, 3, 2, 5, 4, 3, 5, 3, 2, 7, 4, 2, 4, 3, 1, 10, 9, 3, 9, 4, 2, 7, 6, 2, 10, 9, // 6, 4, 3, 1, 5, 4, 3, 4, 3, 1, 7, 2, 1, 5, 3, 2, 7, 4, 2, 6, 3, 2, 5, 3, 2, 15, 3, 2, 11, 3, 2, 9, 8, 7, 7, // 2, 1, 5, 3, 2, 9, 3, 1, 7, 3, 1, 9, 8, 3, 9, 4, 2, 8, 5, 3, 15, 14, 10, 10, 5, 2, 9, 6, 2, 9, 3, 2, 9, 5, // 2, 11, 10, 1, 7, 3, 2, 11, 2, 1, 9, 7, 4, 4, 3, 1, 8, 3, 1, 7, 4, 1, 7, 2, 1, 13, 11, 6, 5, 3, 2, 7, 3, 2, // 8, 7, 5, 12, 3, 2, 13, 10, 6, 5, 3, 2, 5, 3, 2, 9, 5, 2, 9, 7, 2, 13, 4, 3, 4, 3, 1, 11, 6, 4, 18, 9, 6, // 19, 18, 13, 11, 3, 2, 15, 9, 6, 4, 3, 1, 16, 5, 2, 15, 14, 6, 8, 5, 2, 15, 11, 2, 11, 6, 2, 7, 5, 3, 8, // 3, 1, 19, 16, 9, 11, 9, 6, 15, 7, 6, 13, 4, 3, 14, 13, 3, 13, 6, 3, 9, 5, 2, 19, 13, 6, 19, 10, 3, 11, // 6, 5, 9, 2, 1, 14, 3, 2, 13, 3, 1, 7, 5, 4, 11, 9, 8, 11, 6, 5, 23, 16, 9, 19, 14, 6, 23, 10, 2, 8, 3, // 2, 5, 4, 3, 9, 6, 4, 4, 3, 2, 13, 8, 6, 13, 11, 1, 13, 10, 3, 11, 6, 5, 19, 17, 4, 15, 14, 7, 13, 9, 6, // 9, 7, 3, 9, 7, 1, 14, 3, 2, 11, 8, 2, 11, 6, 4, 13, 5, 2, 11, 5, 1, 11, 4, 1, 19, 10, 3, 21, 10, 6, 13, // 3, 1, 15, 7, 5, 19, 18, 10, 7, 5, 3, 12, 7, 2, 7, 5, 1, 14, 9, 6, 10, 3, 2, 15, 13, 12, 12, 11, 9, 16, // 9, 7, 12, 9, 3, 9, 5, 2, 17, 10, 6, 24, 9, 3, 17, 15, 13, 5, 4, 3, 19, 17, 8, 15, 6, 3, 19, 6, 1} // irreducible polynomials of GF(2) var irred_coeff = [...][3]byte{ {4, 3, 1}, // x^8 + x^4 + x^3 + x + 1 {5, 3, 1}, // x^16 + x^5 + x^3 + x + 1 {4, 3, 1}, // x^24 + x^4 + x^3 + x + 1 {7, 3, 2}, // x^32 + x^7 + x^3 + x^2 + 1 {5, 4, 3}, // x^40 + x^5 + x^4 + x^3 + 1 {5, 3, 2}, // x^48 + x^5 + x^3 + x^2 + 1 {7, 4, 2}, // x^56 + x^7 + x^4 + x^2 + 1 {4, 3, 1}, // x^64 + x^4 + x^3 + x + 1 {10, 9, 3}, // x^72 + x^10 + x^9 + x^3 + 1 {9, 4, 2}, // x^80 + x^9 + x^4 + x^2 + 1 {7, 6, 2}, // x^88 + x^7 + x^6 + x^2 + 1 {10, 9, 6}, // x^96 + x^10 + x^9 + x^6 + 1 {4, 3, 1}, // x^104 + x^4 + x^3 + x + 1 {5, 4, 3}, // x^112 + x^5 + x^4 + x^3 + 1 {4, 3, 1}, // x^120 + x^4 + x^3 + x + 1 {7, 2, 1}, // x^128 + x^7 + x^2 + x + 1 {5, 3, 2}, // x^136 + x^5 + x^3 + x^2 + 1 {7, 4, 2}, // x^144 + x^7 + x^4 + x^2 + 1 {6, 3, 2}, // x^152 + x^6 + x^3 + x^2 + 1 {5, 3, 2}, // x^160 + x^5 + x^3 + x^2 + 1 {15, 3, 2}, // x^168 + x^15 + x^3 + x^2 + 1 {11, 3, 2}, // x^176 + x^11 + x^3 + x^2 + 1 {9, 8, 7}, // x^184 + x^9 + x^8 + x^7 + 1 {7, 2, 1}, // x^192 + x^7 + x^2 + x + 1 {5, 3, 2}, // x^200 + x^5 + x^3 + x^2 + 1 {9, 3, 1}, // x^208 + x^9 + x^3 + x + 1 {7, 3, 1}, // x^216 + x^7 + x^3 + x + 1 {9, 8, 3}, // x^224 + x^9 + x^8 + x^3 + 1 {9, 4, 2}, // x^232 + x^9 + x^4 + x^2 + 1 {8, 5, 3}, // x^240 + x^8 + x^5 + x^3 + 1 {15, 14, 10}, // x^248 + x^15 + x^14 + x^10 + 1 {10, 5, 2}, // x^256 + x^10 + x^5 + x^2 + 1 {9, 6, 2}, // x^264 + x^9 + x^6 + x^2 + 1 {9, 3, 2}, // x^272 + x^9 + x^3 + x^2 + 1 {9, 5, 2}, // x^280 + x^9 + x^5 + x^2 + 1 {11, 10, 1}, // x^288 + x^11 + x^10 + x + 1 {7, 3, 2}, // x^296 + x^7 + x^3 + x^2 + 1 {11, 2, 1}, // x^304 + x^11 + x^2 + x + 1 {9, 7, 4}, // x^312 + x^9 + x^7 + x^4 + 1 {4, 3, 1}, // x^320 + x^4 + x^3 + x + 1 {8, 3, 1}, // x^328 + x^8 + x^3 + x + 1 {7, 4, 1}, // x^336 + x^7 + x^4 + x + 1 {7, 2, 1}, // x^344 + x^7 + x^2 + x + 1 {13, 11, 6}, // x^352 + x^13 + x^11 + x^6 + 1 {5, 3, 2}, // x^360 + x^5 + x^3 + x^2 + 1 {7, 3, 2}, // x^368 + x^7 + x^3 + x^2 + 1 {8, 7, 5}, // x^376 + x^8 + x^7 + x^5 + 1 {12, 3, 2}, // x^384 + x^12 + x^3 + x^2 + 1 {13, 10, 6}, // x^392 + x^13 + x^10 + x^6 + 1 {5, 3, 2}, // x^400 + x^5 + x^3 + x^2 + 1 {5, 3, 2}, // x^408 + x^5 + x^3 + x^2 + 1 {9, 5, 2}, // x^416 + x^9 + x^5 + x^2 + 1 {9, 7, 2}, // x^424 + x^9 + x^7 + x^2 + 1 {13, 4, 3}, // x^432 + x^13 + x^4 + x^3 + 1 {4, 3, 1}, // x^440 + x^4 + x^3 + x + 1 {11, 6, 4}, // x^448 + x^11 + x^6 + x^4 + 1 {18, 9, 6}, // x^456 + x^18 + x^9 + x^6 + 1 {19, 18, 13}, // x^464 + x^19 + x^18 + x^13 + 1 {11, 3, 2}, // x^472 + x^11 + x^3 + x^2 + 1 {15, 9, 6}, // x^480 + x^15 + x^9 + x^6 + 1 {4, 3, 1}, // x^488 + x^4 + x^3 + x + 1 {16, 5, 2}, // x^496 + x^16 + x^5 + x^2 + 1 {15, 14, 6}, // x^504 + x^15 + x^14 + x^6 + 1 {8, 5, 2}, // x^512 + x^8 + x^5 + x^2 + 1 {15, 11, 2}, // x^520 + x^15 + x^11 + x^2 + 1 {11, 6, 2}, // x^528 + x^11 + x^6 + x^2 + 1 {7, 5, 3}, // x^536 + x^7 + x^5 + x^3 + 1 {8, 3, 1}, // x^544 + x^8 + x^3 + x + 1 {19, 16, 9}, // x^552 + x^19 + x^16 + x^9 + 1 {11, 9, 6}, // x^560 + x^11 + x^9 + x^6 + 1 {15, 7, 6}, // x^568 + x^15 + x^7 + x^6 + 1 {13, 4, 3}, // x^576 + x^13 + x^4 + x^3 + 1 {14, 13, 3}, // x^584 + x^14 + x^13 + x^3 + 1 {13, 6, 3}, // x^592 + x^13 + x^6 + x^3 + 1 {9, 5, 2}, // x^600 + x^9 + x^5 + x^2 + 1 {19, 13, 6}, // x^608 + x^19 + x^13 + x^6 + 1 {19, 10, 3}, // x^616 + x^19 + x^10 + x^3 + 1 {11, 6, 5}, // x^624 + x^11 + x^6 + x^5 + 1 {9, 2, 1}, // x^632 + x^9 + x^2 + x + 1 {14, 3, 2}, // x^640 + x^14 + x^3 + x^2 + 1 {13, 3, 1}, // x^648 + x^13 + x^3 + x + 1 {7, 5, 4}, // x^656 + x^7 + x^5 + x^4 + 1 {11, 9, 8}, // x^664 + x^11 + x^9 + x^8 + 1 {11, 6, 5}, // x^672 + x^11 + x^6 + x^5 + 1 {23, 16, 9}, // x^680 + x^23 + x^16 + x^9 + 1 {19, 14, 6}, // x^688 + x^19 + x^14 + x^6 + 1 {23, 10, 2}, // x^696 + x^23 + x^10 + x^2 + 1 {8, 3, 2}, // x^704 + x^8 + x^3 + x^2 + 1 {5, 4, 3}, // x^712 + x^5 + x^4 + x^3 + 1 {9, 6, 4}, // x^720 + x^9 + x^6 + x^4 + 1 {4, 3, 2}, // x^728 + x^4 + x^3 + x^2 + 1 {13, 8, 6}, // x^736 + x^13 + x^8 + x^6 + 1 {13, 11, 1}, // x^744 + x^13 + x^11 + x + 1 {13, 10, 3}, // x^752 + x^13 + x^10 + x^3 + 1 {11, 6, 5}, // x^760 + x^11 + x^6 + x^5 + 1 {19, 17, 4}, // x^768 + x^19 + x^17 + x^4 + 1 {15, 14, 7}, // x^776 + x^15 + x^14 + x^7 + 1 {13, 9, 6}, // x^784 + x^13 + x^9 + x^6 + 1 {9, 7, 3}, // x^792 + x^9 + x^7 + x^3 + 1 {9, 7, 1}, // x^800 + x^9 + x^7 + x + 1 {14, 3, 2}, // x^808 + x^14 + x^3 + x^2 + 1 {11, 8, 2}, // x^816 + x^11 + x^8 + x^2 + 1 {11, 6, 4}, // x^824 + x^11 + x^6 + x^4 + 1 {13, 5, 2}, // x^832 + x^13 + x^5 + x^2 + 1 {11, 5, 1}, // x^840 + x^11 + x^5 + x + 1 {11, 4, 1}, // x^848 + x^11 + x^4 + x + 1 {19, 10, 3}, // x^856 + x^19 + x^10 + x^3 + 1 {21, 10, 6}, // x^864 + x^21 + x^10 + x^6 + 1 {13, 3, 1}, // x^872 + x^13 + x^3 + x + 1 {15, 7, 5}, // x^880 + x^15 + x^7 + x^5 + 1 {19, 18, 10}, // x^888 + x^19 + x^18 + x^10 + 1 {7, 5, 3}, // x^896 + x^7 + x^5 + x^3 + 1 {12, 7, 2}, // x^904 + x^12 + x^7 + x^2 + 1 {7, 5, 1}, // x^912 + x^7 + x^5 + x + 1 {14, 9, 6}, // x^920 + x^14 + x^9 + x^6 + 1 {10, 3, 2}, // x^928 + x^10 + x^3 + x^2 + 1 {15, 13, 12}, // x^936 + x^15 + x^13 + x^12 + 1 {12, 11, 9}, // x^944 + x^12 + x^11 + x^9 + 1 {16, 9, 7}, // x^952 + x^16 + x^9 + x^7 + 1 {12, 9, 3}, // x^960 + x^12 + x^9 + x^3 + 1 {9, 5, 2}, // x^968 + x^9 + x^5 + x^2 + 1 {17, 10, 6}, // x^976 + x^17 + x^10 + x^6 + 1 {24, 9, 3}, // x^984 + x^24 + x^9 + x^3 + 1 {17, 15, 13}, // x^992 + x^17 + x^15 + x^13 + 1 {5, 4, 3}, // x^1000 + x^5 + x^4 + x^3 + 1 {19, 17, 8}, // x^1008 + x^19 + x^17 + x^8 + 1 {15, 6, 3}, // x^1016 + x^15 + x^6 + x^3 + 1 {19, 6, 1}, // x^1024 + x^19 + x^6 + x + 1 } // f2m, the extention filed over GF(2) of degree m type gf2x struct { poly *big.Int degree int intPool []*big.Int } func init() { } // newGF2x return the irred. polynomial of degree deg, where deg must divided by 8. func newGF2x(deg int) *gf2x { poly := big.NewInt(1) poly.SetBit(poly, deg, 1) // poly.SetBit(poly, int(irred_coeff[3*(deg/8-1)+0]), 1) // poly.SetBit(poly, int(irred_coeff[3*(deg/8-1)+1]), 1) // poly.SetBit(poly, int(irred_coeff[3*(deg/8-1)+2]), 1) poly.SetBit(poly, int(irred_coeff[deg/8-1][0]), 1) poly.SetBit(poly, int(irred_coeff[deg/8-1][1]), 1) poly.SetBit(poly, int(irred_coeff[deg/8-1][2]), 1) return &gf2x{ poly: poly, degree: deg, } } func (g *gf2x) getInt() (r *big.Int) { if len(g.intPool) > 0 { r = g.intPool[len(g.intPool)-1] r.SetInt64(0) g.intPool = g.intPool[:len(g.intPool)-1] return } return new(big.Int) } func (g *gf2x) putInt(r *big.Int) { g.intPool = append(g.intPool, r) } func (g *gf2x) rand(r io.Reader) (*big.Int, error) { for { x, err := rand.Int(r, g.poly) x.SetBit(x, g.degree, 0) if err == nil && x.Sign() != 0 { return x, nil } if err != nil { return nil, gerrors.WithStack(err) } } } func (g *gf2x) add(z, x, y *big.Int) { z.Xor(x, y) } // z can't be y, z could be x func (g *gf2x) mul(z, x, y *big.Int) { var yy *big.Int if z == y { yy = g.getInt().Set(y) defer g.putInt(yy) } else { yy = y } b := g.getInt() defer g.putInt(b) // note that z may be x, so make b a copy of x b.Set(x) if yy.Bit(0) == 1 { // y = 1 + y1*X + y2*X^2 + ... z.Set(b) } else { z.SetInt64(0) } for i := 1; i < g.degree; i++ { b.Lsh(b, 1) if b.Bit(g.degree) == 1 { b.Xor(b, g.poly) } if yy.Bit(i) == 1 { z.Xor(z, b) } } } var one = new(big.Int).SetInt64(1) // extend eudlic algorithm func (f *gf2x) invert(z, x *big.Int) error { u := f.getInt() v := f.getInt() g := f.getInt() h := f.getInt() t := f.getInt() defer func() { f.putInt(u) f.putInt(v) f.putInt(g) f.putInt(h) f.putInt(t) }() if x.Sign() == 0 { return gerrors.WithAnnotating(ErrDivideZero, "input x is zero") } u.Set(x) v.Set(f.poly) g.SetInt64(0) h.SetInt64(1) // x*h = u mod poly // x*g = v mod poly for u.Cmp(one) != 0 { i := u.BitLen() - v.BitLen() if i < 0 { u, v, h, g = v, u, g, h i = -i } t.Lsh(v, uint(i)) u.Xor(u, t) t.Lsh(g, uint(i)) h.Xor(h, t) } z.Set(h) return nil }