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  }