@cryptotaxi247 / kubo / commits / 7aa1ab536

Remove whyrusleeping/chunker from godeps

License: MIT Signed-off-by: Hector Sanjuan <hector@protocol.ai>

Hector Sanjuan committed Feb 5, 2018 at 21:25 UTC 7aa1ab5368f1aff33f3e60090e510664c7ad2d18
9 files changed -1457
Godeps/Godeps.json
-4
@@ -56,10 +56,6 @@
56 {
57 "ImportPath": "github.com/texttheater/golang-levenshtein/levenshtein",
58 "Rev": "dfd657628c58d3eeaa26391097853b2473c8b94e"
59 - },
60 - {
61 - "ImportPath": "github.com/whyrusleeping/chunker",
62 - "Rev": "537e901819164627ca4bb5ce4e3faa8ce7956564"
59 }
60 ]
61 }
Godeps/_workspace/src/github.com/whyrusleeping/chunker/.travis.yml deleted
-10
@@ -1,10 +0,0 @@
1 -language: go
2 -sudo: false
3 -
4 -go:
5 - - 1.3.3
6 - - 1.4.2
7 -
8 -os:
9 - - linux
10 - - osx
Godeps/_workspace/src/github.com/whyrusleeping/chunker/LICENSE deleted
-23
@@ -1,23 +0,0 @@
1 -Copyright (c) 2014, Alexander Neumann <alexander@bumpern.de>
2 -All rights reserved.
3 -
4 -Redistribution and use in source and binary forms, with or without
5 -modification, are permitted provided that the following conditions are met:
6 -
7 -1. Redistributions of source code must retain the above copyright notice, this
8 - list of conditions and the following disclaimer.
9 -
10 -2. Redistributions in binary form must reproduce the above copyright notice,
11 - this list of conditions and the following disclaimer in the documentation
12 - and/or other materials provided with the distribution.
13 -
14 -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15 -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18 -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Godeps/_workspace/src/github.com/whyrusleeping/chunker/README.md deleted
-7
@@ -1,7 +0,0 @@
1 -[![Build Status](https://travis-ci.org/restic/chunker.svg?branch=master)](https://travis-ci.org/restic/chunker)
2 -
3 -Content Defined Chunking (CDC) based on a rolling Rabin Checksum.
4 -
5 -Part of https://github.com/restic/restic.
6 -
7 -Better README will follow soon.
Godeps/_workspace/src/github.com/whyrusleeping/chunker/chunker.go deleted
-370
@@ -1,370 +0,0 @@
1 -package chunker
2 -
3 -import (
4 - "errors"
5 - "hash"
6 - "io"
7 - "math"
8 - "sync"
9 -)
10 -
11 -const (
12 - KiB = 1024
13 - MiB = 1024 * KiB
14 -
15 - // WindowSize is the size of the sliding window.
16 - windowSize = 16
17 -
18 - chunkerBufSize = 512 * KiB
19 -)
20 -
21 -var bufPool = sync.Pool{
22 - New: func() interface{} { return make([]byte, chunkerBufSize) },
23 -}
24 -
25 -type tables struct {
26 - out [256]Pol
27 - mod [256]Pol
28 -}
29 -
30 -// cache precomputed tables, these are read-only anyway
31 -var cache struct {
32 - entries map[Pol]*tables
33 - sync.Mutex
34 -}
35 -
36 -func init() {
37 - cache.entries = make(map[Pol]*tables)
38 -}
39 -
40 -// Chunk is one content-dependent chunk of bytes whose end was cut when the
41 -// Rabin Fingerprint had the value stored in Cut.
42 -type Chunk struct {
43 - Start uint64
44 - Length uint64
45 - Cut uint64
46 - Digest []byte
47 - Data []byte
48 -}
49 -
50 -func (c Chunk) Reader(r io.ReaderAt) io.Reader {
51 - return io.NewSectionReader(r, int64(c.Start), int64(c.Length))
52 -}
53 -
54 -// Chunker splits content with Rabin Fingerprints.
55 -type Chunker struct {
56 - pol Pol
57 - polShift uint64
58 - tables *tables
59 -
60 - rd io.Reader
61 - closed bool
62 -
63 - chunkbuf []byte
64 -
65 - window [windowSize]byte
66 - wpos int
67 -
68 - buf []byte
69 - bpos uint64
70 - bmax uint64
71 -
72 - start uint64
73 - count uint64
74 - pos uint64
75 -
76 - pre uint64 // wait for this many bytes before start calculating an new chunk
77 -
78 - digest uint64
79 - h hash.Hash
80 -
81 - sizeMask uint64
82 -
83 - // minimal and maximal size of the outputted blocks
84 - MinSize uint64
85 - MaxSize uint64
86 -}
87 -
88 -// New returns a new Chunker based on polynomial p that reads from rd
89 -// with bufsize and pass all data to hash along the way.
90 -func New(rd io.Reader, pol Pol, h hash.Hash, avSize, min, max uint64) *Chunker {
91 -
92 - sizepow := uint(math.Log2(float64(avSize)))
93 -
94 - c := &Chunker{
95 - buf: bufPool.Get().([]byte),
96 - h: h,
97 - pol: pol,
98 - rd: rd,
99 - chunkbuf: make([]byte, 0, max),
100 - sizeMask: (1 << sizepow) - 1,
101 -
102 - MinSize: min,
103 - MaxSize: max,
104 - }
105 -
106 - c.reset()
107 -
108 - return c
109 -}
110 -
111 -func (c *Chunker) reset() {
112 - c.polShift = uint64(c.pol.Deg() - 8)
113 - c.fillTables()
114 -
115 - for i := 0; i < windowSize; i++ {
116 - c.window[i] = 0
117 - }
118 -
119 - c.closed = false
120 - c.digest = 0
121 - c.wpos = 0
122 - c.count = 0
123 - c.slide(1)
124 - c.start = c.pos
125 -
126 - if c.h != nil {
127 - c.h.Reset()
128 - }
129 -
130 - // do not start a new chunk unless at least MinSize bytes have been read
131 - c.pre = c.MinSize - windowSize
132 -}
133 -
134 -// Calculate out_table and mod_table for optimization. Must be called only
135 -// once. This implementation uses a cache in the global variable cache.
136 -func (c *Chunker) fillTables() {
137 - // if polynomial hasn't been specified, do not compute anything for now
138 - if c.pol == 0 {
139 - return
140 - }
141 -
142 - // test if the tables are cached for this polynomial
143 - cache.Lock()
144 - defer cache.Unlock()
145 - if t, ok := cache.entries[c.pol]; ok {
146 - c.tables = t
147 - return
148 - }
149 -
150 - // else create a new entry
151 - c.tables = &tables{}
152 - cache.entries[c.pol] = c.tables
153 -
154 - // calculate table for sliding out bytes. The byte to slide out is used as
155 - // the index for the table, the value contains the following:
156 - // out_table[b] = Hash(b || 0 || ... || 0)
157 - // \ windowsize-1 zero bytes /
158 - // To slide out byte b_0 for window size w with known hash
159 - // H := H(b_0 || ... || b_w), it is sufficient to add out_table[b_0]:
160 - // H(b_0 || ... || b_w) + H(b_0 || 0 || ... || 0)
161 - // = H(b_0 + b_0 || b_1 + 0 || ... || b_w + 0)
162 - // = H( 0 || b_1 || ... || b_w)
163 - //
164 - // Afterwards a new byte can be shifted in.
165 - for b := 0; b < 256; b++ {
166 - var h Pol
167 -
168 - h = appendByte(h, byte(b), c.pol)
169 - for i := 0; i < windowSize-1; i++ {
170 - h = appendByte(h, 0, c.pol)
171 - }
172 - c.tables.out[b] = h
173 - }
174 -
175 - // calculate table for reduction mod Polynomial
176 - k := c.pol.Deg()
177 - for b := 0; b < 256; b++ {
178 - // mod_table[b] = A | B, where A = (b(x) * x^k mod pol) and B = b(x) * x^k
179 - //
180 - // The 8 bits above deg(Polynomial) determine what happens next and so
181 - // these bits are used as a lookup to this table. The value is split in
182 - // two parts: Part A contains the result of the modulus operation, part
183 - // B is used to cancel out the 8 top bits so that one XOR operation is
184 - // enough to reduce modulo Polynomial
185 - c.tables.mod[b] = Pol(uint64(b)<<uint64(k)).Mod(c.pol) | (Pol(b) << uint64(k))
186 - }
187 -}
188 -
189 -func (c *Chunker) nextBytes() []byte {
190 - data := dupBytes(c.chunkbuf[:c.count])
191 - n := copy(c.chunkbuf, c.chunkbuf[c.count:])
192 - c.chunkbuf = c.chunkbuf[:n]
193 -
194 - return data
195 -}
196 -
197 -// Next returns the position and length of the next chunk of data. If an error
198 -// occurs while reading, the error is returned with a nil chunk. The state of
199 -// the current chunk is undefined. When the last chunk has been returned, all
200 -// subsequent calls yield a nil chunk and an io.EOF error.
201 -func (c *Chunker) Next() (*Chunk, error) {
202 - if c.tables == nil {
203 - return nil, errors.New("polynomial is not set")
204 - }
205 -
206 - for {
207 - if c.bpos >= c.bmax {
208 - n, err := io.ReadFull(c.rd, c.buf[:])
209 - c.chunkbuf = append(c.chunkbuf, c.buf[:n]...)
210 -
211 - if err == io.ErrUnexpectedEOF {
212 - err = nil
213 - }
214 -
215 - // io.ReadFull only returns io.EOF when no bytes could be read. If
216 - // this is the case and we're in this branch, there are no more
217 - // bytes to buffer, so this was the last chunk. If a different
218 - // error has occurred, return that error and abandon the current
219 - // chunk.
220 - if err == io.EOF && !c.closed {
221 - c.closed = true
222 -
223 - // return the buffer to the pool
224 - bufPool.Put(c.buf)
225 -
226 - data := c.nextBytes()
227 -
228 - // return current chunk, if any bytes have been processed
229 - if c.count > 0 {
230 - return &Chunk{
231 - Start: c.start,
232 - Length: c.count,
233 - Cut: c.digest,
234 - Digest: c.hashDigest(),
235 - Data: data,
236 - }, nil
237 - }
238 - }
239 -
240 - if err != nil {
241 - return nil, err
242 - }
243 -
244 - c.bpos = 0
245 - c.bmax = uint64(n)
246 - }
247 -
248 - // check if bytes have to be dismissed before starting a new chunk
249 - if c.pre > 0 {
250 - n := c.bmax - c.bpos
251 - if c.pre > uint64(n) {
252 - c.pre -= uint64(n)
253 - c.updateHash(c.buf[c.bpos:c.bmax])
254 -
255 - c.count += uint64(n)
256 - c.pos += uint64(n)
257 - c.bpos = c.bmax
258 -
259 - continue
260 - }
261 -
262 - c.updateHash(c.buf[c.bpos : c.bpos+c.pre])
263 -
264 - c.bpos += c.pre
265 - c.count += c.pre
266 - c.pos += c.pre
267 - c.pre = 0
268 - }
269 -
270 - add := c.count
271 - for _, b := range c.buf[c.bpos:c.bmax] {
272 - // inline c.slide(b) and append(b) to increase performance
273 - out := c.window[c.wpos]
274 - c.window[c.wpos] = b
275 - c.digest ^= uint64(c.tables.out[out])
276 - c.wpos = (c.wpos + 1) % windowSize
277 -
278 - // c.append(b)
279 - index := c.digest >> c.polShift
280 - c.digest <<= 8
281 - c.digest |= uint64(b)
282 -
283 - c.digest ^= uint64(c.tables.mod[index])
284 - // end inline
285 -
286 - add++
287 - if add < c.MinSize {
288 - continue
289 - }
290 -
291 - if (c.digest&c.sizeMask) == 0 || add >= c.MaxSize {
292 - i := add - c.count - 1
293 - c.updateHash(c.buf[c.bpos : c.bpos+uint64(i)+1])
294 - c.count = add
295 - c.pos += uint64(i) + 1
296 - c.bpos += uint64(i) + 1
297 -
298 - data := c.nextBytes()
299 -
300 - chunk := &Chunk{
301 - Start: c.start,
302 - Length: c.count,
303 - Cut: c.digest,
304 - Digest: c.hashDigest(),
305 - Data: data,
306 - }
307 -
308 - c.reset()
309 -
310 - return chunk, nil
311 - }
312 - }
313 -
314 - steps := c.bmax - c.bpos
315 - if steps > 0 {
316 - c.updateHash(c.buf[c.bpos : c.bpos+steps])
317 - }
318 - c.count += steps
319 - c.pos += steps
320 - c.bpos = c.bmax
321 - }
322 -}
323 -
324 -func dupBytes(b []byte) []byte {
325 - out := make([]byte, len(b))
326 - copy(out, b)
327 - return out
328 -}
329 -
330 -func (c *Chunker) updateHash(data []byte) {
331 - if c.h != nil {
332 - // the hashes from crypto/sha* do not return an error
333 - _, err := c.h.Write(data)
334 - if err != nil {
335 - panic(err)
336 - }
337 - }
338 -}
339 -
340 -func (c *Chunker) hashDigest() []byte {
341 - if c.h == nil {
342 - return nil
343 - }
344 -
345 - return c.h.Sum(nil)
346 -}
347 -
348 -func (c *Chunker) append(b byte) {
349 - index := c.digest >> c.polShift
350 - c.digest <<= 8
351 - c.digest |= uint64(b)
352 -
353 - c.digest ^= uint64(c.tables.mod[index])
354 -}
355 -
356 -func (c *Chunker) slide(b byte) {
357 - out := c.window[c.wpos]
358 - c.window[c.wpos] = b
359 - c.digest ^= uint64(c.tables.out[out])
360 - c.wpos = (c.wpos + 1) % windowSize
361 -
362 - c.append(b)
363 -}
364 -
365 -func appendByte(hash Pol, b byte, pol Pol) Pol {
366 - hash <<= 8
367 - hash |= Pol(b)
368 -
369 - return hash.Mod(pol)
370 -}
Godeps/_workspace/src/github.com/whyrusleeping/chunker/chunker_test.go deleted
-298
@@ -1,298 +0,0 @@
1 -package chunker_test
2 -
3 -import (
4 - "bytes"
5 - "crypto/md5"
6 - "crypto/sha256"
7 - "encoding/hex"
8 - "hash"
9 - "io"
10 - "io/ioutil"
11 - "math/rand"
12 - "testing"
13 - "time"
14 -
15 - "github.com/restic/chunker"
16 - . "github.com/restic/restic/test"
17 -)
18 -
19 -func parseDigest(s string) []byte {
20 - d, err := hex.DecodeString(s)
21 - if err != nil {
22 - panic(err)
23 - }
24 -
25 - return d
26 -}
27 -
28 -type chunk struct {
29 - Length uint
30 - CutFP uint64
31 - Digest []byte
32 -}
33 -
34 -// polynomial used for all the tests below
35 -const testPol = chunker.Pol(0x3DA3358B4DC173)
36 -
37 -// created for 32MB of random data out of math/rand's Uint32() seeded by
38 -// constant 23
39 -//
40 -// chunking configuration:
41 -// window size 64, avg chunksize 1<<20, min chunksize 1<<19, max chunksize 1<<23
42 -// polynom 0x3DA3358B4DC173
43 -var chunks1 = []chunk{
44 - chunk{2163460, 0x000b98d4cdf00000, parseDigest("4b94cb2cf293855ea43bf766731c74969b91aa6bf3c078719aabdd19860d590d")},
45 - chunk{643703, 0x000d4e8364d00000, parseDigest("5727a63c0964f365ab8ed2ccf604912f2ea7be29759a2b53ede4d6841e397407")},
46 - chunk{1528956, 0x0015a25c2ef00000, parseDigest("a73759636a1e7a2758767791c69e81b69fb49236c6929e5d1b654e06e37674ba")},
47 - chunk{1955808, 0x00102a8242e00000, parseDigest("c955fb059409b25f07e5ae09defbbc2aadf117c97a3724e06ad4abd2787e6824")},
48 - chunk{2222372, 0x00045da878000000, parseDigest("6ba5e9f7e1b310722be3627716cf469be941f7f3e39a4c3bcefea492ec31ee56")},
49 - chunk{2538687, 0x00198a8179900000, parseDigest("8687937412f654b5cfe4a82b08f28393a0c040f77c6f95e26742c2fc4254bfde")},
50 - chunk{609606, 0x001d4e8d17100000, parseDigest("5da820742ff5feb3369112938d3095785487456f65a8efc4b96dac4be7ebb259")},
51 - chunk{1205738, 0x000a7204dd600000, parseDigest("cc70d8fad5472beb031b1aca356bcab86c7368f40faa24fe5f8922c6c268c299")},
52 - chunk{959742, 0x00183e71e1400000, parseDigest("4065bdd778f95676c92b38ac265d361f81bff17d76e5d9452cf985a2ea5a4e39")},
53 - chunk{4036109, 0x001fec043c700000, parseDigest("b9cf166e75200eb4993fc9b6e22300a6790c75e6b0fc8f3f29b68a752d42f275")},
54 - chunk{1525894, 0x000b1574b1500000, parseDigest("2f238180e4ca1f7520a05f3d6059233926341090f9236ce677690c1823eccab3")},
55 - chunk{1352720, 0x00018965f2e00000, parseDigest("afd12f13286a3901430de816e62b85cc62468c059295ce5888b76b3af9028d84")},
56 - chunk{811884, 0x00155628aa100000, parseDigest("42d0cdb1ee7c48e552705d18e061abb70ae7957027db8ae8db37ec756472a70a")},
57 - chunk{1282314, 0x001909a0a1400000, parseDigest("819721c2457426eb4f4c7565050c44c32076a56fa9b4515a1c7796441730eb58")},
58 - chunk{1318021, 0x001cceb980000000, parseDigest("842eb53543db55bacac5e25cb91e43cc2e310fe5f9acc1aee86bdf5e91389374")},
59 - chunk{948640, 0x0011f7a470a00000, parseDigest("b8e36bf7019bb96ac3fb7867659d2167d9d3b3148c09fe0de45850b8fe577185")},
60 - chunk{645464, 0x00030ce2d9400000, parseDigest("5584bd27982191c3329f01ed846bfd266e96548dfa87018f745c33cfc240211d")},
61 - chunk{533758, 0x0004435c53c00000, parseDigest("4da778a25b72a9a0d53529eccfe2e5865a789116cb1800f470d8df685a8ab05d")},
62 - chunk{1128303, 0x0000c48517800000, parseDigest("08c6b0b38095b348d80300f0be4c5184d2744a17147c2cba5cc4315abf4c048f")},
63 - chunk{800374, 0x000968473f900000, parseDigest("820284d2c8fd243429674c996d8eb8d3450cbc32421f43113e980f516282c7bf")},
64 - chunk{2453512, 0x001e197c92600000, parseDigest("5fa870ed107c67704258e5e50abe67509fb73562caf77caa843b5f243425d853")},
65 - chunk{2651975, 0x000ae6c868000000, parseDigest("181347d2bbec32bef77ad5e9001e6af80f6abcf3576549384d334ee00c1988d8")},
66 - chunk{237392, 0x0000000000000001, parseDigest("fcd567f5d866357a8e299fd5b2359bb2c8157c30395229c4e9b0a353944a7978")},
67 -}
68 -
69 -// test if nullbytes are correctly split, even if length is a multiple of MinSize.
70 -var chunks2 = []chunk{
71 - chunk{chunker.MinSize, 0, parseDigest("07854d2fef297a06ba81685e660c332de36d5d18d546927d30daad6d7fda1541")},
72 - chunk{chunker.MinSize, 0, parseDigest("07854d2fef297a06ba81685e660c332de36d5d18d546927d30daad6d7fda1541")},
73 - chunk{chunker.MinSize, 0, parseDigest("07854d2fef297a06ba81685e660c332de36d5d18d546927d30daad6d7fda1541")},
74 - chunk{chunker.MinSize, 0, parseDigest("07854d2fef297a06ba81685e660c332de36d5d18d546927d30daad6d7fda1541")},
75 -}
76 -
77 -func testWithData(t *testing.T, chnker *chunker.Chunker, testChunks []chunk) []*chunker.Chunk {
78 - chunks := []*chunker.Chunk{}
79 -
80 - pos := uint(0)
81 - for i, chunk := range testChunks {
82 - c, err := chnker.Next()
83 -
84 - if err != nil {
85 - t.Fatalf("Error returned with chunk %d: %v", i, err)
86 - }
87 -
88 - if c == nil {
89 - t.Fatalf("Nil chunk returned")
90 - }
91 -
92 - if c != nil {
93 - if c.Start != pos {
94 - t.Fatalf("Start for chunk %d does not match: expected %d, got %d",
95 - i, pos, c.Start)
96 - }
97 -
98 - if c.Length != chunk.Length {
99 - t.Fatalf("Length for chunk %d does not match: expected %d, got %d",
100 - i, chunk.Length, c.Length)
101 - }
102 -
103 - if c.Cut != chunk.CutFP {
104 - t.Fatalf("Cut fingerprint for chunk %d/%d does not match: expected %016x, got %016x",
105 - i, len(chunks)-1, chunk.CutFP, c.Cut)
106 - }
107 -
108 - if c.Digest != nil && !bytes.Equal(c.Digest, chunk.Digest) {
109 - t.Fatalf("Digest fingerprint for chunk %d/%d does not match: expected %02x, got %02x",
110 - i, len(chunks)-1, chunk.Digest, c.Digest)
111 - }
112 -
113 - pos += c.Length
114 - chunks = append(chunks, c)
115 - }
116 - }
117 -
118 - c, err := chnker.Next()
119 -
120 - if c != nil {
121 - t.Fatal("additional non-nil chunk returned")
122 - }
123 -
124 - if err != io.EOF {
125 - t.Fatal("wrong error returned after last chunk")
126 - }
127 -
128 - return chunks
129 -}
130 -
131 -func getRandom(seed, count int) []byte {
132 - buf := make([]byte, count)
133 -
134 - rnd := rand.New(rand.NewSource(23))
135 - for i := 0; i < count; i += 4 {
136 - r := rnd.Uint32()
137 - buf[i] = byte(r)
138 - buf[i+1] = byte(r >> 8)
139 - buf[i+2] = byte(r >> 16)
140 - buf[i+3] = byte(r >> 24)
141 - }
142 -
143 - return buf
144 -}
145 -
146 -func TestChunker(t *testing.T) {
147 - // setup data source
148 - buf := getRandom(23, 32*1024*1024)
149 - ch := chunker.New(bytes.NewReader(buf), testPol, sha256.New())
150 - chunks := testWithData(t, ch, chunks1)
151 -
152 - // test reader
153 - for i, c := range chunks {
154 - rd := c.Reader(bytes.NewReader(buf))
155 -
156 - h := sha256.New()
157 - n, err := io.Copy(h, rd)
158 - if err != nil {
159 - t.Fatalf("io.Copy(): %v", err)
160 - }
161 -
162 - if uint(n) != chunks1[i].Length {
163 - t.Fatalf("reader returned wrong number of bytes: expected %d, got %d",
164 - chunks1[i].Length, n)
165 - }
166 -
167 - d := h.Sum(nil)
168 - if !bytes.Equal(d, chunks1[i].Digest) {
169 - t.Fatalf("wrong hash returned: expected %02x, got %02x",
170 - chunks1[i].Digest, d)
171 - }
172 - }
173 -
174 - // setup nullbyte data source
175 - buf = bytes.Repeat([]byte{0}, len(chunks2)*chunker.MinSize)
176 - ch = chunker.New(bytes.NewReader(buf), testPol, sha256.New())
177 -
178 - testWithData(t, ch, chunks2)
179 -}
180 -
181 -func TestChunkerWithRandomPolynomial(t *testing.T) {
182 - // setup data source
183 - buf := getRandom(23, 32*1024*1024)
184 -
185 - // generate a new random polynomial
186 - start := time.Now()
187 - p, err := chunker.RandomPolynomial()
188 - OK(t, err)
189 - t.Logf("generating random polynomial took %v", time.Since(start))
190 -
191 - start = time.Now()
192 - ch := chunker.New(bytes.NewReader(buf), p, sha256.New())
193 - t.Logf("creating chunker took %v", time.Since(start))
194 -
195 - // make sure that first chunk is different
196 - c, err := ch.Next()
197 -
198 - Assert(t, c.Cut != chunks1[0].CutFP,
199 - "Cut point is the same")
200 - Assert(t, c.Length != chunks1[0].Length,
201 - "Length is the same")
202 - Assert(t, !bytes.Equal(c.Digest, chunks1[0].Digest),
203 - "Digest is the same")
204 -}
205 -
206 -func TestChunkerWithoutHash(t *testing.T) {
207 - // setup data source
208 - buf := getRandom(23, 32*1024*1024)
209 -
210 - ch := chunker.New(bytes.NewReader(buf), testPol, nil)
211 - chunks := testWithData(t, ch, chunks1)
212 -
213 - // test reader
214 - for i, c := range chunks {
215 - rd := c.Reader(bytes.NewReader(buf))
216 -
217 - buf2, err := ioutil.ReadAll(rd)
218 - if err != nil {
219 - t.Fatalf("io.Copy(): %v", err)
220 - }
221 -
222 - if uint(len(buf2)) != chunks1[i].Length {
223 - t.Fatalf("reader returned wrong number of bytes: expected %d, got %d",
224 - chunks1[i].Length, uint(len(buf2)))
225 - }
226 -
227 - if uint(len(buf2)) != chunks1[i].Length {
228 - t.Fatalf("wrong number of bytes returned: expected %02x, got %02x",
229 - chunks[i].Length, len(buf2))
230 - }
231 -
232 - if !bytes.Equal(buf[c.Start:c.Start+c.Length], buf2) {
233 - t.Fatalf("invalid data for chunk returned: expected %02x, got %02x",
234 - buf[c.Start:c.Start+c.Length], buf2)
235 - }
236 - }
237 -
238 - // setup nullbyte data source
239 - buf = bytes.Repeat([]byte{0}, len(chunks2)*chunker.MinSize)
240 - ch = chunker.New(bytes.NewReader(buf), testPol, sha256.New())
241 -
242 - testWithData(t, ch, chunks2)
243 -}
244 -
245 -func benchmarkChunker(b *testing.B, hash hash.Hash) {
246 - size := 10 * 1024 * 1024
247 - rd := bytes.NewReader(getRandom(23, size))
248 -
249 - b.ResetTimer()
250 - b.SetBytes(int64(size))
251 -
252 - var chunks int
253 - for i := 0; i < b.N; i++ {
254 - chunks = 0
255 -
256 - rd.Seek(0, 0)
257 - ch := chunker.New(rd, testPol, hash)
258 -
259 - for {
260 - _, err := ch.Next()
261 -
262 - if err == io.EOF {
263 - break
264 - }
265 -
266 - if err != nil {
267 - b.Fatalf("Unexpected error occurred: %v", err)
268 - }
269 -
270 - chunks++
271 - }
272 - }
273 -
274 - b.Logf("%d chunks, average chunk size: %d bytes", chunks, size/chunks)
275 -}
276 -
277 -func BenchmarkChunkerWithSHA256(b *testing.B) {
278 - benchmarkChunker(b, sha256.New())
279 -}
280 -
281 -func BenchmarkChunkerWithMD5(b *testing.B) {
282 - benchmarkChunker(b, md5.New())
283 -}
284 -
285 -func BenchmarkChunker(b *testing.B) {
286 - benchmarkChunker(b, nil)
287 -}
288 -
289 -func BenchmarkNewChunker(b *testing.B) {
290 - p, err := chunker.RandomPolynomial()
291 - OK(b, err)
292 -
293 - b.ResetTimer()
294 -
295 - for i := 0; i < b.N; i++ {
296 - chunker.New(bytes.NewBuffer(nil), p, nil)
297 - }
298 -}
Godeps/_workspace/src/github.com/whyrusleeping/chunker/doc.go deleted
-82
@@ -1,82 +0,0 @@
1 -// Copyright 2014 Alexander Neumann. 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 -/*
6 -Package chunker implements Content Defined Chunking (CDC) based on a rolling
7 -Rabin Checksum.
8 -
9 -Choosing a Random Irreducible Polynomial
10 -
11 -The function RandomPolynomial() returns a new random polynomial of degree 53
12 -for use with the chunker. The degree 53 is chosen because it is the largest
13 -prime below 64-8 = 56, so that the top 8 bits of an uint64 can be used for
14 -optimising calculations in the chunker.
15 -
16 -A random polynomial is chosen selecting 64 random bits, masking away bits
17 -64..54 and setting bit 53 to one (otherwise the polynomial is not of the
18 -desired degree) and bit 0 to one (otherwise the polynomial is trivially
19 -reducible), so that 51 bits are chosen at random.
20 -
21 -This process is repeated until Irreducible() returns true, then this
22 -polynomials is returned. If this doesn't happen after 1 million tries, the
23 -function returns an error. The probability for selecting an irreducible
24 -polynomial at random is about 7.5% ( (2^53-2)/53 / 2^51), so the probability
25 -that no irreducible polynomial has been found after 100 tries is lower than
26 -0.04%.
27 -
28 -Verifying Irreducible Polynomials
29 -
30 -During development the results have been verified using the computational
31 -discrete algebra system GAP, which can be obtained from the website at
32 -http://www.gap-system.org/.
33 -
34 -For filtering a given list of polynomials in hexadecimal coefficient notation,
35 -the following script can be used:
36 -
37 - # create x over F_2 = GF(2)
38 - x := Indeterminate(GF(2), "x");
39 -
40 - # test if polynomial is irreducible, i.e. the number of factors is one
41 - IrredPoly := function (poly)
42 - return (Length(Factors(poly)) = 1);
43 - end;;
44 -
45 - # create a polynomial in x from the hexadecimal representation of the
46 - # coefficients
47 - Hex2Poly := function (s)
48 - return ValuePol(CoefficientsQadic(IntHexString(s), 2), x);
49 - end;;
50 -
51 - # list of candidates, in hex
52 - candidates := [ "3DA3358B4DC173" ];
53 -
54 - # create real polynomials
55 - L := List(candidates, Hex2Poly);
56 -
57 - # filter and display the list of irreducible polynomials contained in L
58 - Display(Filtered(L, x -> (IrredPoly(x))));
59 -
60 -All irreducible polynomials from the list are written to the output.
61 -
62 -Background Literature
63 -
64 -An introduction to Rabin Fingerprints/Checksums can be found in the following articles:
65 -
66 -Michael O. Rabin (1981): "Fingerprinting by Random Polynomials"
67 -http://www.xmailserver.org/rabin.pdf
68 -
69 -Ross N. Williams (1993): "A Painless Guide to CRC Error Detection Algorithms"
70 -http://www.zlib.net/crc_v3.txt
71 -
72 -Andrei Z. Broder (1993): "Some Applications of Rabin's Fingerprinting Method"
73 -http://www.xmailserver.org/rabin_apps.pdf
74 -
75 -Shuhong Gao and Daniel Panario (1997): "Tests and Constructions of Irreducible Polynomials over Finite Fields"
76 -http://www.math.clemson.edu/~sgao/papers/GP97a.pdf
77 -
78 -Andrew Kadatch, Bob Jenkins (2007): "Everything we know about CRC but afraid to forget"
79 -http://crcutil.googlecode.com/files/crc-doc.1.0.pdf
80 -
81 -*/
82 -package chunker
Godeps/_workspace/src/github.com/whyrusleeping/chunker/polynomials.go deleted
-278
@@ -1,278 +0,0 @@
1 -package chunker
2 -
3 -import (
4 - "crypto/rand"
5 - "encoding/binary"
6 - "errors"
7 - "fmt"
8 - "strconv"
9 -)
10 -
11 -// Pol is a polynomial from F_2[X].
12 -type Pol uint64
13 -
14 -// Add returns x+y.
15 -func (x Pol) Add(y Pol) Pol {
16 - r := Pol(uint64(x) ^ uint64(y))
17 - return r
18 -}
19 -
20 -// mulOverflows returns true if the multiplication would overflow uint64.
21 -// Code by Rob Pike, see
22 -// https://groups.google.com/d/msg/golang-nuts/h5oSN5t3Au4/KaNQREhZh0QJ
23 -func mulOverflows(a, b Pol) bool {
24 - if a <= 1 || b <= 1 {
25 - return false
26 - }
27 - c := a.mul(b)
28 - d := c.Div(b)
29 - if d != a {
30 - return true
31 - }
32 -
33 - return false
34 -}
35 -
36 -func (x Pol) mul(y Pol) Pol {
37 - if x == 0 || y == 0 {
38 - return 0
39 - }
40 -
41 - var res Pol
42 - for i := 0; i <= y.Deg(); i++ {
43 - if (y & (1 << uint(i))) > 0 {
44 - res = res.Add(x << uint(i))
45 - }
46 - }
47 -
48 - return res
49 -}
50 -
51 -// Mul returns x*y. When an overflow occurs, Mul panics.
52 -func (x Pol) Mul(y Pol) Pol {
53 - if mulOverflows(x, y) {
54 - panic("multiplication would overflow uint64")
55 - }
56 -
57 - return x.mul(y)
58 -}
59 -
60 -// Deg returns the degree of the polynomial x. If x is zero, -1 is returned.
61 -func (x Pol) Deg() int {
62 - // the degree of 0 is -1
63 - if x == 0 {
64 - return -1
65 - }
66 -
67 - var mask Pol = (1 << 63)
68 - for i := 63; i >= 0; i-- {
69 - // test if bit i is set
70 - if x&mask > 0 {
71 - // this is the degree of x
72 - return i
73 - }
74 - mask >>= 1
75 - }
76 -
77 - // fall-through, return -1
78 - return -1
79 -}
80 -
81 -// String returns the coefficients in hex.
82 -func (x Pol) String() string {
83 - return "0x" + strconv.FormatUint(uint64(x), 16)
84 -}
85 -
86 -// Expand returns the string representation of the polynomial x.
87 -func (x Pol) Expand() string {
88 - if x == 0 {
89 - return "0"
90 - }
91 -
92 - s := ""
93 - for i := x.Deg(); i > 1; i-- {
94 - if x&(1<<uint(i)) > 0 {
95 - s += fmt.Sprintf("+x^%d", i)
96 - }
97 - }
98 -
99 - if x&2 > 0 {
100 - s += "+x"
101 - }
102 -
103 - if x&1 > 0 {
104 - s += "+1"
105 - }
106 -
107 - return s[1:]
108 -}
109 -
110 -// DivMod returns x / d = q, and remainder r,
111 -// see https://en.wikipedia.org/wiki/Division_algorithm
112 -func (x Pol) DivMod(d Pol) (Pol, Pol) {
113 - if x == 0 {
114 - return 0, 0
115 - }
116 -
117 - if d == 0 {
118 - panic("division by zero")
119 - }
120 -
121 - D := d.Deg()
122 - diff := x.Deg() - D
123 - if diff < 0 {
124 - return 0, x
125 - }
126 -
127 - var q Pol
128 - for diff >= 0 {
129 - m := d << uint(diff)
130 - q |= (1 << uint(diff))
131 - x = x.Add(m)
132 -
133 - diff = x.Deg() - D
134 - }
135 -
136 - return q, x
137 -}
138 -
139 -// Div returns the integer division result x / d.
140 -func (x Pol) Div(d Pol) Pol {
141 - q, _ := x.DivMod(d)
142 - return q
143 -}
144 -
145 -// Mod returns the remainder of x / d
146 -func (x Pol) Mod(d Pol) Pol {
147 - _, r := x.DivMod(d)
148 - return r
149 -}
150 -
151 -// I really dislike having a function that does not terminate, so specify a
152 -// really large upper bound for finding a new irreducible polynomial, and
153 -// return an error when no irreducible polynomial has been found within
154 -// randPolMaxTries.
155 -const randPolMaxTries = 1e6
156 -
157 -// RandomPolynomial returns a new random irreducible polynomial of degree 53
158 -// (largest prime number below 64-8). There are (2^53-2/53) irreducible
159 -// polynomials of degree 53 in F_2[X], c.f. Michael O. Rabin (1981):
160 -// "Fingerprinting by Random Polynomials", page 4. If no polynomial could be
161 -// found in one million tries, an error is returned.
162 -func RandomPolynomial() (Pol, error) {
163 - for i := 0; i < randPolMaxTries; i++ {
164 - var f Pol
165 -
166 - // choose polynomial at random
167 - err := binary.Read(rand.Reader, binary.LittleEndian, &f)
168 - if err != nil {
169 - return 0, err
170 - }
171 -
172 - // mask away bits above bit 53
173 - f &= Pol((1 << 54) - 1)
174 -
175 - // set highest and lowest bit so that the degree is 53 and the
176 - // polynomial is not trivially reducible
177 - f |= (1 << 53) | 1
178 -
179 - // test if f is irreducible
180 - if f.Irreducible() {
181 - return f, nil
182 - }
183 - }
184 -
185 - // If this is reached, we haven't found an irreducible polynomial in
186 - // randPolMaxTries. This error is very unlikely to occur.
187 - return 0, errors.New("unable to find new random irreducible polynomial")
188 -}
189 -
190 -// GCD computes the Greatest Common Divisor x and f.
191 -func (x Pol) GCD(f Pol) Pol {
192 - if f == 0 {
193 - return x
194 - }
195 -
196 - if x == 0 {
197 - return f
198 - }
199 -
200 - if x.Deg() < f.Deg() {
201 - x, f = f, x
202 - }
203 -
204 - return f.GCD(x.Mod(f))
205 -}
206 -
207 -// Irreducible returns true iff x is irreducible over F_2. This function
208 -// uses Ben Or's reducibility test.
209 -//
210 -// For details see "Tests and Constructions of Irreducible Polynomials over
211 -// Finite Fields".
212 -func (x Pol) Irreducible() bool {
213 - for i := 1; i <= x.Deg()/2; i++ {
214 - if x.GCD(qp(uint(i), x)) != 1 {
215 - return false
216 - }
217 - }
218 -
219 - return true
220 -}
221 -
222 -// MulMod computes x*f mod g
223 -func (x Pol) MulMod(f, g Pol) Pol {
224 - if x == 0 || f == 0 {
225 - return 0
226 - }
227 -
228 - var res Pol
229 - for i := 0; i <= f.Deg(); i++ {
230 - if (f & (1 << uint(i))) > 0 {
231 - a := x
232 - for j := 0; j < i; j++ {
233 - a = a.Mul(2).Mod(g)
234 - }
235 - res = res.Add(a).Mod(g)
236 - }
237 - }
238 -
239 - return res
240 -}
241 -
242 -// qp computes the polynomial (x^(2^p)-x) mod g. This is needed for the
243 -// reducibility test.
244 -func qp(p uint, g Pol) Pol {
245 - num := (1 << p)
246 - i := 1
247 -
248 - // start with x
249 - res := Pol(2)
250 -
251 - for i < num {
252 - // repeatedly square res
253 - res = res.MulMod(res, g)
254 - i *= 2
255 - }
256 -
257 - // add x
258 - return res.Add(2).Mod(g)
259 -}
260 -
261 -func (p Pol) MarshalJSON() ([]byte, error) {
262 - buf := strconv.AppendUint([]byte{'"'}, uint64(p), 16)
263 - buf = append(buf, '"')
264 - return buf, nil
265 -}
266 -
267 -func (p *Pol) UnmarshalJSON(data []byte) error {
268 - if len(data) < 2 {
269 - return errors.New("invalid string for polynomial")
270 - }
271 - n, err := strconv.ParseUint(string(data[1:len(data)-1]), 16, 64)
272 - if err != nil {
273 - return err
274 - }
275 - *p = Pol(n)
276 -
277 - return nil
278 -}
Godeps/_workspace/src/github.com/whyrusleeping/chunker/polynomials_test.go deleted
-385
@@ -1,385 +0,0 @@
1 -package chunker_test
2 -
3 -import (
4 - "strconv"
5 - "testing"
6 -
7 - "github.com/restic/chunker"
8 - . "github.com/restic/restic/test"
9 -)
10 -
11 -var polAddTests = []struct {
12 - x, y chunker.Pol
13 - sum chunker.Pol
14 -}{
15 - {23, 16, 23 ^ 16},
16 - {0x9a7e30d1e855e0a0, 0x670102a1f4bcd414, 0xfd7f32701ce934b4},
17 - {0x9a7e30d1e855e0a0, 0x9a7e30d1e855e0a0, 0},
18 -}
19 -
20 -func TestPolAdd(t *testing.T) {
21 - for _, test := range polAddTests {
22 - Equals(t, test.sum, test.x.Add(test.y))
23 - Equals(t, test.sum, test.y.Add(test.x))
24 - }
25 -}
26 -
27 -func parseBin(s string) chunker.Pol {
28 - i, err := strconv.ParseUint(s, 2, 64)
29 - if err != nil {
30 - panic(err)
31 - }
32 -
33 - return chunker.Pol(i)
34 -}
35 -
36 -var polMulTests = []struct {
37 - x, y chunker.Pol
38 - res chunker.Pol
39 -}{
40 - {1, 2, 2},
41 - {
42 - parseBin("1101"),
43 - parseBin("10"),
44 - parseBin("11010"),
45 - },
46 - {
47 - parseBin("1101"),
48 - parseBin("11"),
49 - parseBin("10111"),
50 - },
51 - {
52 - 0x40000000,
53 - 0x40000000,
54 - 0x1000000000000000,
55 - },
56 - {
57 - parseBin("1010"),
58 - parseBin("100100"),
59 - parseBin("101101000"),
60 - },
61 - {
62 - parseBin("100"),
63 - parseBin("11"),
64 - parseBin("1100"),
65 - },
66 - {
67 - parseBin("11"),
68 - parseBin("110101"),
69 - parseBin("1011111"),
70 - },
71 - {
72 - parseBin("10011"),
73 - parseBin("110101"),
74 - parseBin("1100001111"),
75 - },
76 -}
77 -
78 -func TestPolMul(t *testing.T) {
79 - for i, test := range polMulTests {
80 - m := test.x.Mul(test.y)
81 - Assert(t, test.res == m,
82 - "TestPolMul failed for test %d: %v * %v: want %v, got %v",
83 - i, test.x, test.y, test.res, m)
84 - m = test.y.Mul(test.x)
85 - Assert(t, test.res == test.y.Mul(test.x),
86 - "TestPolMul failed for %d: %v * %v: want %v, got %v",
87 - i, test.x, test.y, test.res, m)
88 - }
89 -}
90 -
91 -func TestPolMulOverflow(t *testing.T) {
92 - defer func() {
93 - // try to recover overflow error
94 - err := recover()
95 -
96 - if e, ok := err.(string); ok && e == "multiplication would overflow uint64" {
97 - return
98 - } else {
99 - t.Logf("invalid error raised: %v", err)
100 - // re-raise error if not overflow
101 - panic(err)
102 - }
103 - }()
104 -
105 - x := chunker.Pol(1 << 63)
106 - x.Mul(2)
107 - t.Fatal("overflow test did not panic")
108 -}
109 -
110 -var polDivTests = []struct {
111 - x, y chunker.Pol
112 - res chunker.Pol
113 -}{
114 - {10, 50, 0},
115 - {0, 1, 0},
116 - {
117 - parseBin("101101000"), // 0x168
118 - parseBin("1010"), // 0xa
119 - parseBin("100100"), // 0x24
120 - },
121 - {2, 2, 1},
122 - {
123 - 0x8000000000000000,
124 - 0x8000000000000000,
125 - 1,
126 - },
127 - {
128 - parseBin("1100"),
129 - parseBin("100"),
130 - parseBin("11"),
131 - },
132 - {
133 - parseBin("1100001111"),
134 - parseBin("10011"),
135 - parseBin("110101"),
136 - },
137 -}
138 -
139 -func TestPolDiv(t *testing.T) {
140 - for i, test := range polDivTests {
141 - m := test.x.Div(test.y)
142 - Assert(t, test.res == m,
143 - "TestPolDiv failed for test %d: %v * %v: want %v, got %v",
144 - i, test.x, test.y, test.res, m)
145 - }
146 -}
147 -
148 -var polModTests = []struct {
149 - x, y chunker.Pol
150 - res chunker.Pol
151 -}{
152 - {10, 50, 10},
153 - {0, 1, 0},
154 - {
155 - parseBin("101101001"),
156 - parseBin("1010"),
157 - parseBin("1"),
158 - },
159 - {2, 2, 0},
160 - {
161 - 0x8000000000000000,
162 - 0x8000000000000000,
163 - 0,
164 - },
165 - {
166 - parseBin("1100"),
167 - parseBin("100"),
168 - parseBin("0"),
169 - },
170 - {
171 - parseBin("1100001111"),
172 - parseBin("10011"),
173 - parseBin("0"),
174 - },
175 -}
176 -
177 -func TestPolModt(t *testing.T) {
178 - for _, test := range polModTests {
179 - Equals(t, test.res, test.x.Mod(test.y))
180 - }
181 -}
182 -
183 -func BenchmarkPolDivMod(t *testing.B) {
184 - f := chunker.Pol(0x2482734cacca49)
185 - g := chunker.Pol(0x3af4b284899)
186 -
187 - for i := 0; i < t.N; i++ {
188 - g.DivMod(f)
189 - }
190 -}
191 -
192 -func BenchmarkPolDiv(t *testing.B) {
193 - f := chunker.Pol(0x2482734cacca49)
194 - g := chunker.Pol(0x3af4b284899)
195 -
196 - for i := 0; i < t.N; i++ {
197 - g.Div(f)
198 - }
199 -}
200 -
201 -func BenchmarkPolMod(t *testing.B) {
202 - f := chunker.Pol(0x2482734cacca49)
203 - g := chunker.Pol(0x3af4b284899)
204 -
205 - for i := 0; i < t.N; i++ {
206 - g.Mod(f)
207 - }
208 -}
209 -
210 -func BenchmarkPolDeg(t *testing.B) {
211 - f := chunker.Pol(0x3af4b284899)
212 - d := f.Deg()
213 - if d != 41 {
214 - t.Fatalf("BenchmalPolDeg: Wrong degree %d returned, expected %d",
215 - d, 41)
216 - }
217 -
218 - for i := 0; i < t.N; i++ {
219 - f.Deg()
220 - }
221 -}
222 -
223 -func TestRandomPolynomial(t *testing.T) {
224 - _, err := chunker.RandomPolynomial()
225 - OK(t, err)
226 -}
227 -
228 -func BenchmarkRandomPolynomial(t *testing.B) {
229 - for i := 0; i < t.N; i++ {
230 - _, err := chunker.RandomPolynomial()
231 - OK(t, err)
232 - }
233 -}
234 -
235 -func TestExpandPolynomial(t *testing.T) {
236 - pol := chunker.Pol(0x3DA3358B4DC173)
237 - s := pol.Expand()
238 - Equals(t, "x^53+x^52+x^51+x^50+x^48+x^47+x^45+x^41+x^40+x^37+x^36+x^34+x^32+x^31+x^27+x^25+x^24+x^22+x^19+x^18+x^16+x^15+x^14+x^8+x^6+x^5+x^4+x+1", s)
239 -}
240 -
241 -var polIrredTests = []struct {
242 - f chunker.Pol
243 - irred bool
244 -}{
245 - {0x38f1e565e288df, false},
246 - {0x3DA3358B4DC173, true},
247 - {0x30a8295b9d5c91, false},
248 - {0x255f4350b962cb, false},
249 - {0x267f776110a235, false},
250 - {0x2f4dae10d41227, false},
251 - {0x2482734cacca49, true},
252 - {0x312daf4b284899, false},
253 - {0x29dfb6553d01d1, false},
254 - {0x3548245eb26257, false},
255 - {0x3199e7ef4211b3, false},
256 - {0x362f39017dae8b, false},
257 - {0x200d57aa6fdacb, false},
258 - {0x35e0a4efa1d275, false},
259 - {0x2ced55b026577f, false},
260 - {0x260b012010893d, false},
261 - {0x2df29cbcd59e9d, false},
262 - {0x3f2ac7488bd429, false},
263 - {0x3e5cb1711669fb, false},
264 - {0x226d8de57a9959, false},
265 - {0x3c8de80aaf5835, false},
266 - {0x2026a59efb219b, false},
267 - {0x39dfa4d13fb231, false},
268 - {0x3143d0464b3299, false},
269 -}
270 -
271 -func TestPolIrreducible(t *testing.T) {
272 - for _, test := range polIrredTests {
273 - Assert(t, test.f.Irreducible() == test.irred,
274 - "Irreducibility test for Polynomial %v failed: got %v, wanted %v",
275 - test.f, test.f.Irreducible(), test.irred)
276 - }
277 -}
278 -
279 -func BenchmarkPolIrreducible(b *testing.B) {
280 - // find first irreducible polynomial
281 - var pol chunker.Pol
282 - for _, test := range polIrredTests {
283 - if test.irred {
284 - pol = test.f
285 - break
286 - }
287 - }
288 -
289 - for i := 0; i < b.N; i++ {
290 - Assert(b, pol.Irreducible(),
291 - "Irreducibility test for Polynomial %v failed", pol)
292 - }
293 -}
294 -
295 -var polGCDTests = []struct {
296 - f1 chunker.Pol
297 - f2 chunker.Pol
298 - gcd chunker.Pol
299 -}{
300 - {10, 50, 2},
301 - {0, 1, 1},
302 - {
303 - parseBin("101101001"),
304 - parseBin("1010"),
305 - parseBin("1"),
306 - },
307 - {2, 2, 2},
308 - {
309 - parseBin("1010"),
310 - parseBin("11"),
311 - parseBin("11"),
312 - },
313 - {
314 - 0x8000000000000000,
315 - 0x8000000000000000,
316 - 0x8000000000000000,
317 - },
318 - {
319 - parseBin("1100"),
320 - parseBin("101"),
321 - parseBin("11"),
322 - },
323 - {
324 - parseBin("1100001111"),
325 - parseBin("10011"),
326 - parseBin("10011"),
327 - },
328 - {
329 - 0x3DA3358B4DC173,
330 - 0x3DA3358B4DC173,
331 - 0x3DA3358B4DC173,
332 - },
333 - {
334 - 0x3DA3358B4DC173,
335 - 0x230d2259defd,
336 - 1,
337 - },
338 - {
339 - 0x230d2259defd,
340 - 0x51b492b3eff2,
341 - parseBin("10011"),
342 - },
343 -}
344 -
345 -func TestPolGCD(t *testing.T) {
346 - for i, test := range polGCDTests {
347 - gcd := test.f1.GCD(test.f2)
348 - Assert(t, test.gcd == gcd,
349 - "GCD test %d (%+v) failed: got %v, wanted %v",
350 - i, test, gcd, test.gcd)
351 - gcd = test.f2.GCD(test.f1)
352 - Assert(t, test.gcd == gcd,
353 - "GCD test %d (%+v) failed: got %v, wanted %v",
354 - i, test, gcd, test.gcd)
355 - }
356 -}
357 -
358 -var polMulModTests = []struct {
359 - f1 chunker.Pol
360 - f2 chunker.Pol
361 - g chunker.Pol
362 - mod chunker.Pol
363 -}{
364 - {
365 - 0x1230,
366 - 0x230,
367 - 0x55,
368 - 0x22,
369 - },
370 - {
371 - 0x0eae8c07dbbb3026,
372 - 0xd5d6db9de04771de,
373 - 0xdd2bda3b77c9,
374 - 0x425ae8595b7a,
375 - },
376 -}
377 -
378 -func TestPolMulMod(t *testing.T) {
379 - for i, test := range polMulModTests {
380 - mod := test.f1.MulMod(test.f2, test.g)
381 - Assert(t, mod == test.mod,
382 - "MulMod test %d (%+v) failed: got %v, wanted %v",
383 - i, test, mod, test.mod)
384 - }
385 -}