github.com/slspeek/camlistore_namedsearch@v0.0.0-20140519202248-ed6f70f7721a/third_party/code.google.com/p/rsc/gf256/gf256.go (about) 1 // Copyright 2010 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package gf256 implements arithmetic over the Galois Field GF(256). 6 package gf256 7 8 import "strconv" 9 10 // A Field represents an instance of GF(256) defined by a specific polynomial. 11 type Field struct { 12 log [256]byte // log[0] is unused 13 exp [510]byte 14 } 15 16 // NewField returns a new field corresponding to the polynomial poly 17 // and generator α. The Reed-Solomon encoding in QR codes uses 18 // polynomial 0x11d with generator 2. 19 // 20 // The choice of generator α only affects the Exp and Log operations. 21 func NewField(poly, α int) *Field { 22 if poly < 0x100 || poly >= 0x200 || reducible(poly) { 23 panic("gf256: invalid polynomial: " + strconv.Itoa(poly)) 24 } 25 26 var f Field 27 x := 1 28 for i := 0; i < 255; i++ { 29 if x == 1 && i != 0 { 30 panic("gf256: invalid generator " + strconv.Itoa(α) + 31 " for polynomial " + strconv.Itoa(poly)) 32 } 33 f.exp[i] = byte(x) 34 f.exp[i+255] = byte(x) 35 f.log[x] = byte(i) 36 x = mul(x, α, poly) 37 } 38 f.log[0] = 255 39 for i := 0; i < 255; i++ { 40 if f.log[f.exp[i]] != byte(i) { 41 panic("bad log") 42 } 43 if f.log[f.exp[i+255]] != byte(i) { 44 panic("bad log") 45 } 46 } 47 for i := 1; i < 256; i++ { 48 if f.exp[f.log[i]] != byte(i) { 49 panic("bad log") 50 } 51 } 52 53 return &f 54 } 55 56 // nbit returns the number of significant in p. 57 func nbit(p int) uint { 58 n := uint(0) 59 for ; p > 0; p >>= 1 { 60 n++ 61 } 62 return n 63 } 64 65 // polyDiv divides the polynomial p by q and returns the remainder. 66 func polyDiv(p, q int) int { 67 np := nbit(p) 68 nq := nbit(q) 69 for ; np >= nq; np-- { 70 if p&(1<<(np-1)) != 0 { 71 p ^= q << (np - nq) 72 } 73 } 74 return p 75 } 76 77 // mul returns the product x*y mod poly, a GF(256) multiplication. 78 func mul(x, y, poly int) int { 79 z := 0 80 for x > 0 { 81 if x&1 != 0 { 82 z ^= y 83 } 84 x >>= 1 85 y <<= 1 86 if y&0x100 != 0 { 87 y ^= poly 88 } 89 } 90 return z 91 } 92 93 // reducible reports whether p is reducible. 94 func reducible(p int) bool { 95 // Multiplying n-bit * n-bit produces (2n-1)-bit, 96 // so if p is reducible, one of its factors must be 97 // of np/2+1 bits or fewer. 98 np := nbit(p) 99 for q := 2; q < 1<<(np/2+1); q++ { 100 if polyDiv(p, q) == 0 { 101 return true 102 } 103 } 104 return false 105 } 106 107 // Add returns the sum of x and y in the field. 108 func (f *Field) Add(x, y byte) byte { 109 return x ^ y 110 } 111 112 // Exp returns the the base-α exponential of e in the field. 113 // If e < 0, Exp returns 0. 114 func (f *Field) Exp(e int) byte { 115 if e < 0 { 116 return 0 117 } 118 return f.exp[e%255] 119 } 120 121 // Log returns the base-α logarithm of x in the field. 122 // If x == 0, Log returns -1. 123 func (f *Field) Log(x byte) int { 124 if x == 0 { 125 return -1 126 } 127 return int(f.log[x]) 128 } 129 130 // Inv returns the multiplicative inverse of x in the field. 131 // If x == 0, Inv returns 0. 132 func (f *Field) Inv(x byte) byte { 133 if x == 0 { 134 return 0 135 } 136 return f.exp[255-f.log[x]] 137 } 138 139 // Mul returns the product of x and y in the field. 140 func (f *Field) Mul(x, y byte) byte { 141 if x == 0 || y == 0 { 142 return 0 143 } 144 return f.exp[int(f.log[x])+int(f.log[y])] 145 } 146 147 // An RSEncoder implements Reed-Solomon encoding 148 // over a given field using a given number of error correction bytes. 149 type RSEncoder struct { 150 f *Field 151 c int 152 gen []byte 153 lgen []byte 154 p []byte 155 } 156 157 func (f *Field) gen(e int) (gen, lgen []byte) { 158 // p = 1 159 p := make([]byte, e+1) 160 p[e] = 1 161 162 for i := 0; i < e; i++ { 163 // p *= (x + Exp(i)) 164 // p[j] = p[j]*Exp(i) + p[j+1]. 165 c := f.Exp(i) 166 for j := 0; j < e; j++ { 167 p[j] = f.Mul(p[j], c) ^ p[j+1] 168 } 169 p[e] = f.Mul(p[e], c) 170 } 171 172 // lp = log p. 173 lp := make([]byte, e+1) 174 for i, c := range p { 175 if c == 0 { 176 lp[i] = 255 177 } else { 178 lp[i] = byte(f.Log(c)) 179 } 180 } 181 182 return p, lp 183 } 184 185 // NewRSEncoder returns a new Reed-Solomon encoder 186 // over the given field and number of error correction bytes. 187 func NewRSEncoder(f *Field, c int) *RSEncoder { 188 gen, lgen := f.gen(c) 189 return &RSEncoder{f: f, c: c, gen: gen, lgen: lgen} 190 } 191 192 // ECC writes to check the error correcting code bytes 193 // for data using the given Reed-Solomon parameters. 194 func (rs *RSEncoder) ECC(data []byte, check []byte) { 195 if len(check) < rs.c { 196 panic("gf256: invalid check byte length") 197 } 198 if rs.c == 0 { 199 return 200 } 201 202 // The check bytes are the remainder after dividing 203 // data padded with c zeros by the generator polynomial. 204 205 // p = data padded with c zeros. 206 var p []byte 207 n := len(data) + rs.c 208 if len(rs.p) >= n { 209 p = rs.p 210 } else { 211 p = make([]byte, n) 212 } 213 copy(p, data) 214 for i := len(data); i < len(p); i++ { 215 p[i] = 0 216 } 217 218 // Divide p by gen, leaving the remainder in p[len(data):]. 219 // p[0] is the most significant term in p, and 220 // gen[0] is the most significant term in the generator, 221 // which is always 1. 222 // To avoid repeated work, we store various values as 223 // lv, not v, where lv = log[v]. 224 f := rs.f 225 lgen := rs.lgen[1:] 226 for i := 0; i < len(data); i++ { 227 c := p[i] 228 if c == 0 { 229 continue 230 } 231 q := p[i+1:] 232 exp := f.exp[f.log[c]:] 233 for j, lg := range lgen { 234 if lg != 255 { // lgen uses 255 for log 0 235 q[j] ^= exp[lg] 236 } 237 } 238 } 239 copy(check, p[len(data):]) 240 rs.p = p 241 }