From f744c3534db579401ab03d66b0af7c95fdef712a Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sat, 3 Sep 2016 20:56:21 +0200 Subject: [PATCH] Update chunker --- vendor/manifest | 2 +- .../github.com/restic/chunker/chunker_test.go | 3 + .../github.com/restic/chunker/polynomials.go | 65 ++++++++++++++----- .../restic/chunker/polynomials_test.go | 19 ++++++ 4 files changed, 71 insertions(+), 18 deletions(-) diff --git a/vendor/manifest b/vendor/manifest index 47360c1d2..eb13e43ab 100644 --- a/vendor/manifest +++ b/vendor/manifest @@ -46,7 +46,7 @@ { "importpath": "github.com/restic/chunker", "repository": "https://github.com/restic/chunker", - "revision": "d1a97fa6e55ab338a8ceb769d72f856a56e9379a", + "revision": "49e9b5212b022a1ab373faf981ed4f2fc807502a", "branch": "master" }, { diff --git a/vendor/src/github.com/restic/chunker/chunker_test.go b/vendor/src/github.com/restic/chunker/chunker_test.go index 7277aa95d..9ef7fd27d 100644 --- a/vendor/src/github.com/restic/chunker/chunker_test.go +++ b/vendor/src/github.com/restic/chunker/chunker_test.go @@ -175,6 +175,9 @@ func TestChunkerWithRandomPolynomial(t *testing.T) { // make sure that first chunk is different c, err := ch.Next(nil) + if err != nil { + t.Fatal(err.Error()) + } if c.Cut == chunks1[0].CutFP { t.Fatal("Cut point is the same") diff --git a/vendor/src/github.com/restic/chunker/polynomials.go b/vendor/src/github.com/restic/chunker/polynomials.go index 801f9a231..3374c21c4 100644 --- a/vendor/src/github.com/restic/chunker/polynomials.go +++ b/vendor/src/github.com/restic/chunker/polynomials.go @@ -5,6 +5,7 @@ import ( "encoding/binary" "errors" "fmt" + "io" "strconv" ) @@ -64,18 +65,40 @@ func (x Pol) Deg() int { return -1 } - var mask Pol = (1 << 63) - for i := 63; i >= 0; i-- { - // test if bit i is set - if x&mask > 0 { - // this is the degree of x - return i - } - mask >>= 1 + // see https://graphics.stanford.edu/~seander/bithacks.html#IntegerLog + + r := 0 + if uint64(x)&0xffffffff00000000 > 0 { + x >>= 32 + r |= 32 } - // fall-through, return -1 - return -1 + if uint64(x)&0xffff0000 > 0 { + x >>= 16 + r |= 16 + } + + if uint64(x)&0xff00 > 0 { + x >>= 8 + r |= 8 + } + + if uint64(x)&0xf0 > 0 { + x >>= 4 + r |= 4 + } + + if uint64(x)&0xc > 0 { + x >>= 2 + r |= 2 + } + + if uint64(x)&0x2 > 0 { + x >>= 1 + r |= 1 + } + + return r } // String returns the coefficients in hex. @@ -154,17 +177,25 @@ func (x Pol) Mod(d Pol) Pol { // randPolMaxTries. const randPolMaxTries = 1e6 -// RandomPolynomial returns a new random irreducible polynomial of degree 53 -// (largest prime number below 64-8). There are (2^53-2/53) irreducible -// polynomials of degree 53 in F_2[X], c.f. Michael O. Rabin (1981): -// "Fingerprinting by Random Polynomials", page 4. If no polynomial could be -// found in one million tries, an error is returned. +// RandomPolynomial returns a new random irreducible polynomial +// of degree 53 using the default System CSPRNG as source. +// It is equivalent to calling DerivePolynomial(rand.Reader). func RandomPolynomial() (Pol, error) { + return DerivePolynomial(rand.Reader) +} + +// DerivePolynomial returns an irreducible polynomial of degree 53 +// (largest prime number below 64-8) by reading bytes from source. +// There are (2^53-2/53) irreducible polynomials of degree 53 in +// F_2[X], c.f. Michael O. Rabin (1981): "Fingerprinting by Random +// Polynomials", page 4. If no polynomial could be found in one +// million tries, an error is returned. +func DerivePolynomial(source io.Reader) (Pol, error) { for i := 0; i < randPolMaxTries; i++ { var f Pol - // choose polynomial at random - err := binary.Read(rand.Reader, binary.LittleEndian, &f) + // choose polynomial at (pseudo)random + err := binary.Read(source, binary.LittleEndian, &f) if err != nil { return 0, err } diff --git a/vendor/src/github.com/restic/chunker/polynomials_test.go b/vendor/src/github.com/restic/chunker/polynomials_test.go index 7caa09883..741b0ea18 100644 --- a/vendor/src/github.com/restic/chunker/polynomials_test.go +++ b/vendor/src/github.com/restic/chunker/polynomials_test.go @@ -150,6 +150,25 @@ func TestPolDiv(t *testing.T) { } } +func TestPolDeg(t *testing.T) { + var x Pol + if x.Deg() != -1 { + t.Errorf("deg(0) is not -1: %v", x.Deg()) + } + + x = 1 + if x.Deg() != 0 { + t.Errorf("deg(1) is not 0: %v", x.Deg()) + } + + for i := 0; i < 64; i++ { + x = 1 << uint(i) + if x.Deg() != i { + t.Errorf("deg(1<<%d) is not %d: %v", i, i, x.Deg()) + } + } +} + var polModTests = []struct { x, y Pol res Pol