gf256_test.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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. package gf256
  5. import (
  6. "bytes"
  7. "fmt"
  8. "testing"
  9. )
  10. var f = NewField(0x11d, 2) // x^8 + x^4 + x^3 + x^2 + 1
  11. func TestBasic(t *testing.T) {
  12. if f.Exp(0) != 1 || f.Exp(1) != 2 || f.Exp(255) != 1 {
  13. panic("bad Exp")
  14. }
  15. }
  16. func TestECC(t *testing.T) {
  17. data := []byte{0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11}
  18. check := []byte{0xa5, 0x24, 0xd4, 0xc1, 0xed, 0x36, 0xc7, 0x87, 0x2c, 0x55}
  19. out := make([]byte, len(check))
  20. rs := NewRSEncoder(f, len(check))
  21. rs.ECC(data, out)
  22. if !bytes.Equal(out, check) {
  23. t.Errorf("have %x want %x", out, check)
  24. }
  25. }
  26. func TestLinear(t *testing.T) {
  27. d1 := []byte{0x00, 0x00}
  28. c1 := []byte{0x00, 0x00}
  29. out := make([]byte, len(c1))
  30. rs := NewRSEncoder(f, len(c1))
  31. if rs.ECC(d1, out); !bytes.Equal(out, c1) {
  32. t.Errorf("ECBytes(%x, %d) = %x, want 0", d1, len(c1), out)
  33. }
  34. d2 := []byte{0x00, 0x01}
  35. c2 := make([]byte, 2)
  36. rs.ECC(d2, c2)
  37. d3 := []byte{0x00, 0x02}
  38. c3 := make([]byte, 2)
  39. rs.ECC(d3, c3)
  40. cx := make([]byte, 2)
  41. for i := range cx {
  42. cx[i] = c2[i] ^ c3[i]
  43. }
  44. d4 := []byte{0x00, 0x03}
  45. c4 := make([]byte, 2)
  46. rs.ECC(d4, c4)
  47. if !bytes.Equal(cx, c4) {
  48. t.Errorf("ECBytes(%x, 2) = %x\nECBytes(%x, 2) = %x\nxor = %x\nECBytes(%x, 2) = %x",
  49. d2, c2, d3, c3, cx, d4, c4)
  50. }
  51. }
  52. func TestGaussJordan(t *testing.T) {
  53. rs := NewRSEncoder(f, 2)
  54. m := make([][]byte, 16)
  55. for i := range m {
  56. m[i] = make([]byte, 4)
  57. m[i][i/8] = 1 << uint(i%8)
  58. rs.ECC(m[i][:2], m[i][2:])
  59. }
  60. if false {
  61. fmt.Printf("---\n")
  62. for _, row := range m {
  63. fmt.Printf("%x\n", row)
  64. }
  65. }
  66. b := []uint{0, 1, 2, 3, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27}
  67. for i := 0; i < 16; i++ {
  68. bi := b[i]
  69. if m[i][bi/8]&(1<<(7-bi%8)) == 0 {
  70. for j := i + 1; ; j++ {
  71. if j >= len(m) {
  72. t.Errorf("lost track for %d", bi)
  73. break
  74. }
  75. if m[j][bi/8]&(1<<(7-bi%8)) != 0 {
  76. m[i], m[j] = m[j], m[i]
  77. break
  78. }
  79. }
  80. }
  81. for j := i + 1; j < len(m); j++ {
  82. if m[j][bi/8]&(1<<(7-bi%8)) != 0 {
  83. for k := range m[j] {
  84. m[j][k] ^= m[i][k]
  85. }
  86. }
  87. }
  88. }
  89. if false {
  90. fmt.Printf("---\n")
  91. for _, row := range m {
  92. fmt.Printf("%x\n", row)
  93. }
  94. }
  95. for i := 15; i >= 0; i-- {
  96. bi := b[i]
  97. for j := i - 1; j >= 0; j-- {
  98. if m[j][bi/8]&(1<<(7-bi%8)) != 0 {
  99. for k := range m[j] {
  100. m[j][k] ^= m[i][k]
  101. }
  102. }
  103. }
  104. }
  105. if false {
  106. fmt.Printf("---\n")
  107. for _, row := range m {
  108. fmt.Printf("%x", row)
  109. out := make([]byte, 2)
  110. if rs.ECC(row[:2], out); !bytes.Equal(out, row[2:]) {
  111. fmt.Printf(" - want %x", out)
  112. }
  113. fmt.Printf("\n")
  114. }
  115. }
  116. }
  117. func BenchmarkECC(b *testing.B) {
  118. data := []byte{0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11}
  119. check := []byte{0x29, 0x41, 0xb3, 0x93, 0x8, 0xe8, 0xa3, 0xe7, 0x63, 0x8f}
  120. out := make([]byte, len(check))
  121. rs := NewRSEncoder(f, len(check))
  122. for i := 0; i < b.N; i++ {
  123. rs.ECC(data, out)
  124. }
  125. b.SetBytes(int64(len(data)))
  126. if !bytes.Equal(out, check) {
  127. fmt.Printf("have %#v want %#v\n", out, check)
  128. }
  129. }
  130. func TestGen(t *testing.T) {
  131. for i := 0; i < 256; i++ {
  132. _, lg := f.gen(i)
  133. if lg[0] != 0 {
  134. t.Errorf("#%d: %x", i, lg)
  135. }
  136. }
  137. }
  138. func TestReducible(t *testing.T) {
  139. var count = []int{1, 2, 3, 6, 9, 18, 30, 56, 99, 186} // oeis.org/A1037
  140. for i, want := range count {
  141. n := 0
  142. for p := 1 << uint(i+2); p < 1<<uint(i+3); p++ {
  143. if !reducible(p) {
  144. n++
  145. }
  146. }
  147. if n != want {
  148. t.Errorf("#reducible(%d-bit) = %d, want %d", i+2, n, want)
  149. }
  150. }
  151. }
  152. func TestExhaustive(t *testing.T) {
  153. for poly := 0x100; poly < 0x200; poly++ {
  154. if reducible(poly) {
  155. continue
  156. }
  157. α := 2
  158. for !generates(α, poly) {
  159. α++
  160. }
  161. f := NewField(poly, α)
  162. for p := 0; p < 256; p++ {
  163. for q := 0; q < 256; q++ {
  164. fm := int(f.Mul(byte(p), byte(q)))
  165. pm := mul(p, q, poly)
  166. if fm != pm {
  167. t.Errorf("NewField(%#x).Mul(%#x, %#x) = %#x, want %#x", poly, p, q, fm, pm)
  168. }
  169. }
  170. }
  171. }
  172. }
  173. func generates(α, poly int) bool {
  174. x := α
  175. for i := 0; i < 254; i++ {
  176. if x == 1 {
  177. return false
  178. }
  179. x = mul(x, α, poly)
  180. }
  181. return true
  182. }