-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extract multi{codec,hash} registries better.
And, make a package which can be imported to register "all" of the multihashes. (Or at least all of them that you would've expected from go-multihash.) There are also packages that are split roughly per the transitive dependency it brings in, so you can pick and choose. This cascaded into more work than I might've expected. Turns out a handful of the things we have multihash identifiers for actually *do not* implement the standard hash.Hash contract at all. For these, I've made small shims. Test fixtures across the library switch to using sha2-512. Previously I had written a bunch of them to use sha3 variants, but since that is not in the standard library, I'm going to move away from that so as not to re-bloat the transitive dependency tree just for the tests and examples.
- Loading branch information
Showing
15 changed files
with
281 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
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 { | ||
main hash.Hash | ||
} | ||
|
||
func (x doubleSha256) Write(body []byte) (int, error) { | ||
return x.main.Write(body) | ||
} | ||
|
||
func (doubleSha256) BlockSize() int { | ||
return sha256.BlockSize | ||
} | ||
|
||
func (doubleSha256) Size() int { | ||
return sha256.Size | ||
} | ||
|
||
func (x doubleSha256) Reset() { | ||
x.main.Reset() | ||
} | ||
|
||
func (x doubleSha256) Sum(digest []byte) []byte { | ||
intermediate := [sha256.Size]byte{} | ||
x.main.Sum(intermediate[:]) | ||
h2 := sha256.New() | ||
h2.Write(intermediate[:]) | ||
return h2.Sum(digest) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package multihash | ||
|
||
import ( | ||
"crypto/md5" | ||
"crypto/sha1" | ||
"crypto/sha256" | ||
"crypto/sha512" | ||
"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 are registered here automatically. | ||
// | ||
// Packages which want to register more hashing functions (and have a multihash number reserved!) | ||
// are encouraged to do so at package init time. | ||
// (Doing this at package init time ensures this map can be accessed without race conditions.) | ||
// | ||
// The linking/cid.DefaultLinkSystem will use this map to find hashers | ||
// to use when serializing data and computing links, | ||
// and when loading data from storage and verifying its integrity. | ||
// | ||
// This registry map is only used for default behaviors. | ||
// If you don't want to rely on it, you can always construct your own LinkSystem. | ||
// (For this reason, there's no special effort made to detect conflicting registrations in this map. | ||
// If more than one package registers for the same multicodec indicator, and | ||
// you somehow end up with both in your import tree, and yet care about which wins: | ||
// then just don't use this registry anymore: make a LinkSystem that does what you need.) | ||
// This should never be done to make behavior alterations | ||
// (hash functions are well standardized and so is the multihash indicator table), | ||
// but may be relevant if one is really itching to try out different hash implementations for performance reasons. | ||
var Registry = make(map[uint64]func() hash.Hash) | ||
|
||
func init() { | ||
Registry[0x00] = func() hash.Hash { return &identityMultihash{} } | ||
Registry[0xd5] = md5.New | ||
Registry[0x11] = sha1.New | ||
Registry[0x12] = sha256.New | ||
Registry[0x13] = sha512.New | ||
// Registry[0x1f] = sha256.New224 // SOON | ||
// Registry[0x20] = sha512.New384 // SOON | ||
Registry[0x56] = func() hash.Hash { return &doubleSha256{} } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* | ||
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/ipld/go-ipld-prime/mulithash/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/ipld/go-ipld-prime/multihash/register/blake2" | ||
_ "github.com/ipld/go-ipld-prime/multihash/register/murmur3" | ||
_ "github.com/ipld/go-ipld-prime/multihash/register/sha3" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
This package has no purpose except to perform registration of multihashes. | ||
It is meant to be used as a side-effecting import, e.g. | ||
import ( | ||
_ "github.com/ipld/go-ipld-prime/mulithash/register/blake2" | ||
) | ||
This package registers several multihashes for the blake2 family | ||
(both the 's' and the 'b' variants, and in a variety of sizes). | ||
*/ | ||
package blake2 | ||
|
||
import ( | ||
"hash" | ||
|
||
"github.com/minio/blake2b-simd" | ||
"golang.org/x/crypto/blake2s" | ||
|
||
"github.com/ipld/go-ipld-prime/multihash" | ||
) | ||
|
||
const ( | ||
BLAKE2B_MIN = 0xb201 | ||
BLAKE2B_MAX = 0xb240 | ||
BLAKE2S_MIN = 0xb241 | ||
BLAKE2S_MAX = 0xb260 | ||
) | ||
|
||
func init() { | ||
// BLAKE2S | ||
// This package only enables support for 32byte (256 bit) blake2s. | ||
multihash.Registry[BLAKE2S_MIN+31] = func() hash.Hash { h, _ := blake2s.New256(nil); return h } | ||
|
||
// BLAKE2B | ||
// There's a whole range of these. | ||
for c := uint64(BLAKE2B_MIN); c <= BLAKE2B_MAX; c++ { | ||
size := int(c - BLAKE2B_MIN + 1) | ||
multihash.Registry[c] = func() hash.Hash { | ||
hasher, err := blake2b.New(&blake2b.Config{Size: uint8(size)}) | ||
if err != nil { | ||
panic(err) | ||
} | ||
return hasher | ||
} | ||
} | ||
} |
Oops, something went wrong.