Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: multiformats/go-multihash
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.0.14
Choose a base ref
...
head repository: multiformats/go-multihash
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.0.15
Choose a head ref
  • 18 commits
  • 18 files changed
  • 2 contributors

Commits on Mar 6, 2021

  1. Refactor registry system: no direct dependencies; expose standard has…

    …h.Hash; be a data carrier.
    
    ---
    
    Dependencies:
    
    Previously, depending on the go-mulithash package would create direct
    dependencies to several other modules for their various hash function
    implementations.  This meant that instead of go-multihash being a
    lightweight, easy-to-accept dependency itself, it became something
    which would noticably increase the size of your go.mod file,
    your package graph, your download sizes during development, and most
    concerningly, your compile output size in final products.
    
    Now, there is a registry system (see the Register function), and
    the main go-multihash package *only* populates the registry with hashes
    that are available from the golang standard library by default.
    This means you gain no transitive dependencies on other libraries
    by importing the go-multihash package, and your binaries will not
    be bloated by hashers you don't use.  (Your go.mod file may still
    show more repos; but they don't end up in your builds unless you
    actually refer to them).
    
    There are now several new packages in `go-multihash/register/*`.
    These can be imported to register the hashes in those packages.
    If you want all the hashes that were previously available, just make
    sure to import "go-mulithash/register/all" somewhere in your program.
    (You can register hashes, too, without making PRs to this library;
    these packages are just here for convenience and easy use.)
    
    **This is a breaking change** if you used hashes not found in the
    golang stdlib, such as blake2 and sha3.  However, to update,
    all you need to do is ensure the relevant `go-multihash/register/*`
    package is imported anywhere in your program -- an easy change.
    A `go-multihash/register/all` package can be imported to get a hasher
    registered for all of the same multihash codes as before (but will
    correspondingly add the dependency weight back too, of course).
    
    ---
    
    Standard hash.Hash:
    
    Previously, go-multihash had its own definition of a `HashFunc`
    interface, and only exposed hashing through the `multihash.Sum` method.
    The problem with this was these definitions did not support streaming:
    one had to have an entire chunk of memory loaded at once,
    in a single contiguous byte slice, in order to hash it.
    
    (A second, admittedly much more minor, problem with this was that one
    often had to write glue code to turn a `hash.Hash` into a
    `multihash.HashFunc`, and since most of golang uses the standard lib
    `hash.Hash` definition already, this was generally avoidable friction.)
    
    Now, the Register function operates in terms of standard `hash.Hash`,
    and there is a `GetHasher` function which can get you a `hash.Hash`.
    (Okay, to be more precise, these functions take and return a factory
    function for a `hash.Hash`.  You get the idea.)
    
    Since the standard `hash.Hash` interface can operate streamingly,
    now it's easy to use go-multihash in a streaming way.
    
    The `multihash.Sum` method works the same as always.
    
    ---
    
    Be a data carrier:
    
    Previously, go-multihash contained checks that any multihash indicator
    codes being handled were required to have a hash function registered
    for them.  This made it very difficult to use go-multihash in a
    "forward compatible" way (and it also made a lot of practical bumps
    for this dependency-extraction refactor).
    
    Now, go-multihash is willing to carry data, even if it doesn't know
    what kind of hash function would be associated with an indicator code.
    (Methods that you'd expect to parse things do still parse the varints,
    making sure they're sanely formatted.  They just don't inspect and
    whitelist the actual integers anymore.)
    
    I removed the `ValidCode` predicate entirely.  It doesn't seem to serve
    any good purpose anymore.
    
    ---
    
    Other:
    
    I have not touched the `Codes` and `Names` maps in this diff.
    I think we should probably review (and probably remove) these, and
    instead direct people to use the go-multicodec package instead,
    which has the two advantages of decoupling registration of an
    implementation versus simply having a description, and also being
    automatically generated from the multiformats table.
    However, I wanted to check on feelings about this before doing the work
    (especially because they're somewhat entangled with a bunch of the
    tests in this package, making their removal somewhat nontrivial).
    
    Most of the test files are now `package multihash_test`.
    This makes for some colorful diffs, but is not otherwise interesting.
    The reason for this is because the dependency separation process now
    requires the tests to import those `register/*` packages, and to
    avoid a cycle, that means, well, `package mulithash_test`.
    
    I think there's probably more work to be done in making this library
    really shine.  For example, in reviewing the `Encode` function,
    I see some allocations that look very likely to be avoidable... if the
    function was redesigned to be more aware of how it's likely to be used.
    However, I took no action on this, in part because this diff is big
    enough already, and in part because I think it might be reasonable to
    re-examine the relationship of this code to go-cid at the same time.
    
    I dropped `TestSmallerLengthHashID`.  It appeared to be testing an API
    that wasn't actually exported... and the nearest API that *is* exported
    (Sum) has a general contract of truncating a hash upon short length,
    so it was overall unclear what this test should be checking.
    Review might be needed on this.
    
    The situation for murmur3 is still in need of resolution.
    It's commented out entirely for now.  Questions are noted in the diff.
    
    There's a 'register/miniosha256' package which sets the sha2-256
    implementation to a non-stdlib one.  If you don't import this package,
    you still get a sha2-256; it's just the stdlib one.
    I did not include this in the 'register/all' group.
    (Maybe it's faster; maybe it's not; but it's definitely not required,
    and I'm getting some reports it also shows weird on profiles, so I tend
    to think maybe one should really have to explicitly ask for this one.)
    warpfork committed Mar 6, 2021
    Copy the full SHA
    9e12c3a View commit details
  2. Return to using constant pool from root package.

    It seems likely that we should replace many of these with values
    from https://github.com/multiformats/go-multicodec in the future,
    however, we have a new issue to track that:
    #137
    
    And as noted in
    #136 (comment)
    it's time to reign in the amount of work going on in this PR.
    warpfork committed Mar 6, 2021
    Copy the full SHA
    382c37a View commit details
  3. Optimize doubleSha256 construction.

    Avoid allocations with more reuse the same slice for results.
    warpfork committed Mar 6, 2021
    Copy the full SHA
    5647e22 View commit details
  4. Drop murmur3 implementation.

    Agreed upon in discussion at:
    #136 (comment)
    
    The "REVIEW" comments in the outgoing diff identify the concerns that
    led to this choice.
    warpfork committed Mar 6, 2021
    Copy the full SHA
    6897150 View commit details
  5. Copy the full SHA
    8c1b61b View commit details
  6. Copy the full SHA
    57ca955 View commit details
  7. Copy the full SHA
    10afd22 View commit details

Commits on Mar 8, 2021

  1. Copy the full SHA
    442f64a View commit details

Commits on Mar 9, 2021

  1. Resolving review topics around Encode function.

    Leaving the error return in, per
    #136 (comment)
    
    May also be interesting to note: I did check if ValidCode (or, roughly
    the same thing but perhaps renamed to KnownCode) could be reintroduced,
    and the answer is... actually no, not without broaching other issues.
    A body of `_, ok := registry[code]` is enough to open a can of worms.
    See
    #136 (comment)
    warpfork committed Mar 9, 2021
    Copy the full SHA
    67c208a View commit details

Commits on Mar 10, 2021

  1. Replace need for DefaultLength in opts processing.

    This creates a hasher long enough to ask it its properties.
    This is arguably creating garbage; on the other hand, I don't think
    this is a codepath ever likely to be used in a hot loop anywhere.
    We can extract this to something that caches the properties later
    if it proves necessary.
    
    It quietly defaults to zero for unknown codes.  I don't know if this
    makes sense, but it's what the old code would have done, so it's what
    the new code will do, and I'm not looking deeper into it.
    At this point I'm just trying to make surgically minimal alterations
    and get this changeset as a whole wrapped up so things can move on.
    warpfork committed Mar 10, 2021
    Copy the full SHA
    bc5cc89 View commit details
  2. Proactively reject registration of nil functions.

    Surely no one would try to do this, nor then be surprised if it
    creates problems.  On the other hand: if someone *does* do this, and
    the error doesn't appear until arbitrarily far away when the map is
    read, it's a pain to diagnose... and checking it up front is cheap.
    So, here we go: check it up front.
    warpfork committed Mar 10, 2021
    Copy the full SHA
    7be6719 View commit details
  3. Improve situation around ErrSumNotSupported.

    The number that's missing is now reported in the error.
    This is done using the golang error wrap feature.
    
    We're keeping a constant value for ErrSumNotSupported for
    compatibility and change avoidance reasons.
    
    Code that cares about this exact error will still have to change;
    it is now necessary to use `errors.Is` to detect it.
    
    The text in the ErrSumNotSupported value is also updated,
    because the text no longer made sense given an open registry system.
    As a target-of-opportunity fix, it also now follows golang normative
    conventions for error messages (no capitalization, no punctuation).
    warpfork committed Mar 10, 2021
    Copy the full SHA
    cbd218c View commit details
  4. Revive TestSmallerLengthHashID, and add a special case for identity m…

    …ultihash that rejects truncations.
    
    See #136 (comment)
    for discussion.
    
    This change means Sum behaves slightly differently for identity
    multihashes than it does for any other multihash.  I'm not keeping
    score on the number of ways identity multihash is weird anymore,
    just documenting it and keeping tests passing.
    
    The error message is lifted from the old `sumID` function verbatim.
    warpfork committed Mar 10, 2021
    Copy the full SHA
    393ba0d View commit details
  5. travis: update go version.

    We'll need something a little more recent than 1.11.x to be able to
    use the fmt "%w" and errors.Is features.
    warpfork committed Mar 10, 2021
    Copy the full SHA
    aff2570 View commit details
  6. update dependencies, and go mod tidy.

    I swear I did not mean to be doing this on a branch, but:
    https://travis-ci.com/github/multiformats/go-multihash/builds/219591152
    
    - it became necessary to update the go version in CI for %w features
    
    - that apparently adds pointer alignment checking to the compiler...
    
    - which flunks some stuff in x/crypto...
    
    So, okay, we're updating libraries now!
    warpfork committed Mar 10, 2021
    Copy the full SHA
    4b5e8aa View commit details
  7. Reintroduce DefaultLengths; populate during Register.

    While it was possible to remove all use of this from this repo, when
    attempting propagate changes to downstreams consuming it, it became
    apparently that other repos also rely on this symbol.
    
    Whether or not those usages are important and intentional, whether
    they're actually worth maintaining, and whether they'd be replacable
    with other approaches... is not considered at this time.
    (Probably we should be asking this!  The first occasions where this
    cropped up are in other functions that have been marked "deprecated"
    since... 2018!  But... chasing those things down and straightening
    them out is becoming problematic.  Perhaps we'll be more ready to
    revisit these things at a later date.)
    warpfork committed Mar 10, 2021
    Copy the full SHA
    1a96911 View commit details

Commits on Mar 11, 2021

  1. Add core package (min deps) and give root package full transitive dep…

    …s again.
    
    The transitive dependencies in the root package are still managed by
    this whole registry system (which now resides in the 'core' package),
    so we have parity and *mostly* just one suite of code to maintain.
    
    You can now use this 'core' package when interested in dependency
    minimization.  In exchange, the "register/*" imports may be required.
    
    You can just also just yank updates to go-multihash, and if you were
    already using it (and happen to be using one of these
    now-optional(-but-only-if-you-use-core))... nothing should actually
    change; the "register/*" imports won't be required because the
    root package does them for you.
    
    Some constants are replicated.  This was the minimum step necessary
    to avoid import cycles.  I'm not spending time prettifying it because
    we really probably ought to be refactoring this to use the package
    of constants in go-multicodec that's automatically generated, and
    yet, that is a scope limit we're trying not to cross during this
    changeset.
    warpfork committed Mar 11, 2021
    Copy the full SHA
    cebc9f8 View commit details
  2. Merge pull request #136 from multiformats/dependency-separation

    Refactor registry system: no direct dependencies; expose standard hash.Hash; be a data carrier.
    Stebalien authored Mar 11, 2021

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c3ba253 View commit details
Showing with 462 additions and 378 deletions.
  1. +1 −1 .travis.yml
  2. +34 −0 core/errata.go
  3. +26 −0 core/magic.go
  4. +77 −0 core/registry.go
  5. +5 −5 go.mod
  6. +14 −16 go.sum
  7. +4 −39 multihash.go
  8. +2 −0 multihash/main.go
  9. +0 −10 multihash_test.go
  10. +7 −2 opts/opts.go
  11. +22 −0 register/all/multihash_all.go
  12. +63 −0 register/blake2/multihash_blake2.go
  13. +23 −0 register/miniosha256/multihash_miniosha256.go
  14. +62 −0 register/sha3/multihash_sha3.go
  15. +31 −0 registry.go
  16. +7 −4 spec_test.go
  17. +25 −214 sum.go
  18. +59 −87 sum_test.go
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ os:
language: go

go:
- 1.11.x
- 1.15.x

env:
global:
34 changes: 34 additions & 0 deletions core/errata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package multihash

import (
"bytes"
"crypto/sha256"
"hash"
)

type identityMultihash struct {
bytes.Buffer
}

func (identityMultihash) BlockSize() int {
return 32 // A prefered block size is nonsense for the "identity" "hash". An arbitrary but unsurprising and positive nonzero number has been chosen to minimize the odds of fascinating bugs.
}

func (x *identityMultihash) Size() int {
return x.Len()
}

func (x *identityMultihash) Sum(digest []byte) []byte {
return x.Bytes()
}

type doubleSha256 struct {
hash.Hash
}

func (x doubleSha256) Sum(digest []byte) []byte {
digest = x.Hash.Sum(digest)
h2 := sha256.New()
h2.Write(digest)
return h2.Sum(digest[0:0])
}
26 changes: 26 additions & 0 deletions core/magic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package multihash

import "errors"

// ErrSumNotSupported is returned when the Sum function code is not implemented
var ErrSumNotSupported = errors.New("no such hash registered")

// constants
const (
IDENTITY = 0x00
SHA1 = 0x11
SHA2_256 = 0x12
SHA2_512 = 0x13
SHA3_224 = 0x17
SHA3_256 = 0x16
SHA3_384 = 0x15
SHA3_512 = 0x14
KECCAK_224 = 0x1A
KECCAK_256 = 0x1B
KECCAK_384 = 0x1C
KECCAK_512 = 0x1D
SHAKE_128 = 0x18
SHAKE_256 = 0x19
MD5 = 0xd5
DBL_SHA2_256 = 0x56
)
77 changes: 77 additions & 0 deletions core/registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package multihash

import (
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"fmt"
"hash"
)

// registry is a simple map which maps a multihash indicator number
// to a standard golang Hash interface.
//
// Multihash indicator numbers are reserved and described in
// https://github.com/multiformats/multicodec/blob/master/table.csv .
// The keys used in this map must match those reservations.
//
// Hashers which are available in the golang stdlib will be registered automatically.
// Others can be added using the Register function.
var registry = make(map[uint64]func() hash.Hash)

// Register adds a new hash to the set available from GetHasher and Sum.
//
// Register has a global effect and should only be used at package init time to avoid data races.
//
// The indicator code should be per the numbers reserved and described in
// https://github.com/multiformats/multicodec/blob/master/table.csv .
//
// If Register is called with the same indicator code more than once, the last call wins.
// In practice, this means that if an application has a strong opinion about what implementation to use for a certain hash
// (e.g., perhaps they want to override the sha256 implementation to use a special hand-rolled assembly variant
// rather than the stdlib one which is registered by default),
// then this can be done by making a Register call with that effect at init time in the application's main package.
// This should have the desired effect because the root of the import tree has its init time effect last.
func Register(indicator uint64, hasherFactory func() hash.Hash) {
if hasherFactory == nil {
panic("not sensible to attempt to register a nil function")
}
registry[indicator] = hasherFactory
DefaultLengths[indicator] = hasherFactory().Size()
}

// GetHasher returns a new hash.Hash according to the indicator code number provided.
//
// The indicator code should be per the numbers reserved and described in
// https://github.com/multiformats/multicodec/blob/master/table.csv .
//
// The actual hashers available are determined by what has been registered.
// The registry automatically contains those hashers which are available in the golang standard libraries
// (which includes md5, sha1, sha256, sha384, sha512, and the "identity" mulithash, among others).
// Other hash implementations can be made available by using the Register function.
// The 'go-mulithash/register/*' packages can also be imported to gain more common hash functions.
//
// If an error is returned, it will match `errors.Is(err, ErrSumNotSupported)`.
func GetHasher(indicator uint64) (hash.Hash, error) {
factory, exists := registry[indicator]
if !exists {
return nil, fmt.Errorf("unknown multihash code %d (0x%x): %w", indicator, indicator, ErrSumNotSupported)
}
return factory(), nil
}

// DefaultLengths maps a multihash indicator code to the output size for that hash, in units of bytes.
//
// This map is populated when a hash function is registered by the Register function.
// It's effectively a shortcut for asking Size() on the hash.Hash.
var DefaultLengths = map[uint64]int{}

func init() {
Register(IDENTITY, func() hash.Hash { return &identityMultihash{} })
Register(MD5, md5.New)
Register(SHA1, sha1.New)
Register(SHA2_256, sha256.New)
Register(SHA2_512, sha512.New)
Register(DBL_SHA2_256, func() hash.Hash { return &doubleSha256{sha256.New()} })
}
10 changes: 5 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
@@ -2,11 +2,11 @@ module github.com/multiformats/go-multihash

require (
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771
github.com/mr-tron/base58 v1.1.3
github.com/multiformats/go-varint v0.0.5
github.com/spaolacci/murmur3 v1.1.0
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8
github.com/minio/sha256-simd v1.0.0
github.com/mr-tron/base58 v1.2.0
github.com/multiformats/go-varint v0.0.6
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 // indirect
)

go 1.13
30 changes: 14 additions & 16 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
github.com/klauspost/cpuid/v2 v2.0.4 h1:g0I61F2K2DjRHz1cnxlkNSBIaePVoJIjjnHui8QHbiw=
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g=
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771 h1:MHkK1uRtFbVqvAgvWxafZe54+5uBxLluGylDiKgdhwo=
github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc=
github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/multiformats/go-varint v0.0.3 h1:1OZFaq4XbSNQE6ujqgr6/EIZlgHE7DmojAFsLqAJ26M=
github.com/multiformats/go-varint v0.0.3/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
github.com/multiformats/go-varint v0.0.4 h1:CplQWhUouUgTZ53vNFE8VoWr2VjaKXci+xyrKyyFuSw=
github.com/multiformats/go-varint v0.0.4/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
github.com/multiformats/go-varint v0.0.5 h1:XVZwSo04Cs3j/jS0uAEPpT3JY6DzMcVLLoWOSnCxOjg=
github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY=
github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 h1:46ULzRKLh1CwgRq2dC5SlBzEqqNCi8rreOZnNrbqcIY=
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
43 changes: 4 additions & 39 deletions multihash.go
Original file line number Diff line number Diff line change
@@ -80,7 +80,6 @@ func init() {
name := fmt.Sprintf("blake2b-%d", n*8)
Names[name] = c
Codes[c] = name
DefaultLengths[c] = int(n)
}

// Add blake2s (32 codes)
@@ -89,7 +88,6 @@ func init() {
name := fmt.Sprintf("blake2s-%d", n*8)
Names[name] = c
Codes[c] = name
DefaultLengths[c] = int(n)
}
}

@@ -142,28 +140,6 @@ var Codes = map[uint64]string{
MD5: "md5",
}

// DefaultLengths maps a hash code to it's default length
var DefaultLengths = map[uint64]int{
IDENTITY: -1,
SHA1: 20,
SHA2_256: 32,
SHA2_512: 64,
SHA3_224: 28,
SHA3_256: 32,
SHA3_384: 48,
SHA3_512: 64,
DBL_SHA2_256: 32,
KECCAK_224: 28,
KECCAK_256: 32,
MURMUR3_128: 4,
KECCAK_384: 48,
KECCAK_512: 64,
SHAKE_128: 32,
SHAKE_256: 64,
X11: 64,
MD5: 16,
}

func uvarint(buf []byte) (uint64, []byte, error) {
n, c, err := varint.FromUvarint(buf)
if err != nil {
@@ -231,15 +207,11 @@ func FromB58String(s string) (m Multihash, err error) {
// Cast casts a buffer onto a multihash, and returns an error
// if it does not work.
func Cast(buf []byte) (Multihash, error) {
dm, err := Decode(buf)
_, err := Decode(buf)
if err != nil {
return Multihash{}, err
}

if !ValidCode(dm.Code) {
return Multihash{}, ErrUnknownCode
}

return Multihash(buf), nil
}

@@ -266,11 +238,10 @@ func Decode(buf []byte) (*DecodedMultihash, error) {

// Encode a hash digest along with the specified function code.
// Note: the length is derived from the length of the digest itself.
//
// The error return is legacy; it is always nil.
func Encode(buf []byte, code uint64) ([]byte, error) {
if !ValidCode(code) {
return nil, ErrUnknownCode
}

// FUTURE: this function always causes heap allocs... but when used, this value is almost always going to be appended to another buffer (either as part of CID creation, or etc) -- should this whole function be rethought and alternatives offered?
newBuf := make([]byte, varint.UvarintSize(code)+varint.UvarintSize(uint64(len(buf)))+len(buf))
n := varint.PutUvarint(newBuf, code)
n += varint.PutUvarint(newBuf[n:], uint64(len(buf)))
@@ -285,12 +256,6 @@ func EncodeName(buf []byte, name string) ([]byte, error) {
return Encode(buf, Names[name])
}

// ValidCode checks whether a multihash code is valid.
func ValidCode(code uint64) bool {
_, ok := Codes[code]
return ok
}

// readMultihashFromBuf reads a multihash from the given buffer, returning the
// individual pieces of the multihash.
// Note: the returned digest is a slice over the passed in data and should be
2 changes: 2 additions & 0 deletions multihash/main.go
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@ import (

mh "github.com/multiformats/go-multihash"
mhopts "github.com/multiformats/go-multihash/opts"
_ "github.com/multiformats/go-multihash/register/all"
_ "github.com/multiformats/go-multihash/register/miniosha256"
)

var usage = `usage: %s [options] [FILE]
10 changes: 0 additions & 10 deletions multihash_test.go
Original file line number Diff line number Diff line change
@@ -224,16 +224,6 @@ func ExampleDecode() {
// obj: sha1 0x11 20 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33
}

func TestValidCode(t *testing.T) {
for i := uint64(0); i < 0xff; i++ {
_, ok := tCodes[i]

if ValidCode(i) != ok {
t.Error("ValidCode incorrect for: ", i)
}
}
}

func TestCast(t *testing.T) {
for _, tc := range testCases {
ob, err := hex.DecodeString(tc.hex)
9 changes: 7 additions & 2 deletions opts/opts.go
Original file line number Diff line number Diff line change
@@ -110,8 +110,13 @@ func (o *Options) ParseError() error {
}
o.Length = o.Length / 8

if o.Length > mh.DefaultLengths[o.AlgorithmCode] {
o.Length = mh.DefaultLengths[o.AlgorithmCode]
h, _ := mh.GetHasher(o.AlgorithmCode)
hsize := 0
if h != nil {
hsize = h.Size()
}
if o.Length > hsize {
o.Length = hsize
}
}
return nil
22 changes: 22 additions & 0 deletions register/all/multihash_all.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
This package has no purpose except to perform registration of mulithashes.
It is meant to be used as a side-effecting import, e.g.
import (
_ "github.com/multiformats/go-multihash/register/all"
)
This package registers many multihashes at once.
Importing it will increase the size of your dependency tree significantly.
It's recommended that you import this package if you're building some
kind of data broker application, which may need to handle many different kinds of hashes;
if you're building an application which you know only handles a specific hash,
importing this package may bloat your builds unnecessarily.
*/
package all

import (
_ "github.com/multiformats/go-multihash/register/blake2"
_ "github.com/multiformats/go-multihash/register/sha3"
)
Loading