mirror of
https://github.com/libp2p/go-libp2p.git
synced 2025-11-03 10:50:56 +08:00
remove multiple multihash deps
This commit is contained in:
@@ -9,7 +9,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
manet "QmU5s159q8cZuM1f9Vqti4LHu6y8zyVc5dxv2py81sdp6Q/go-multiaddr-net"
|
||||
manet "QmRCPT5WRph8aWXmaT2Rfn6ac98YRUUJnNURpD3hNAWp4f/go-multiaddr-net"
|
||||
ma "QmbWxL1aXQhBjc1XGjGF1f2KGBMCBYSuT2ThA8YXnXJK83/go-multiaddr"
|
||||
"github.com/cryptix/mdns"
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
manet "QmU5s159q8cZuM1f9Vqti4LHu6y8zyVc5dxv2py81sdp6Q/go-multiaddr-net"
|
||||
manet "QmRCPT5WRph8aWXmaT2Rfn6ac98YRUUJnNURpD3hNAWp4f/go-multiaddr-net"
|
||||
ma "QmbWxL1aXQhBjc1XGjGF1f2KGBMCBYSuT2ThA8YXnXJK83/go-multiaddr"
|
||||
|
||||
goprocess "QmSir6qPL1tjuxd8LkR8VZq6v625ExAUVs2eCLeqQuaPGU/goprocess"
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
manet "QmU5s159q8cZuM1f9Vqti4LHu6y8zyVc5dxv2py81sdp6Q/go-multiaddr-net"
|
||||
manet "QmRCPT5WRph8aWXmaT2Rfn6ac98YRUUJnNURpD3hNAWp4f/go-multiaddr-net"
|
||||
logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log"
|
||||
context "QmacZi9WygGK7Me8mH53pypyscHzU386aUZXpr28GZgUct/context"
|
||||
ma "QmbWxL1aXQhBjc1XGjGF1f2KGBMCBYSuT2ThA8YXnXJK83/go-multiaddr"
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
"time"
|
||||
|
||||
context "QmacZi9WygGK7Me8mH53pypyscHzU386aUZXpr28GZgUct/context"
|
||||
msgio "github.com/jbenet/go-msgio"
|
||||
travis "github.com/ipfs/go-libp2p/testutil/ci/travis"
|
||||
msgio "github.com/jbenet/go-msgio"
|
||||
)
|
||||
|
||||
func msgioWrap(c Conn) msgio.ReadWriter {
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"math/rand"
|
||||
"strings"
|
||||
|
||||
manet "QmU5s159q8cZuM1f9Vqti4LHu6y8zyVc5dxv2py81sdp6Q/go-multiaddr-net"
|
||||
manet "QmRCPT5WRph8aWXmaT2Rfn6ac98YRUUJnNURpD3hNAWp4f/go-multiaddr-net"
|
||||
context "QmacZi9WygGK7Me8mH53pypyscHzU386aUZXpr28GZgUct/context"
|
||||
ma "QmbWxL1aXQhBjc1XGjGF1f2KGBMCBYSuT2ThA8YXnXJK83/go-multiaddr"
|
||||
lgbl "util/eventlog/loggables"
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
manet "QmU5s159q8cZuM1f9Vqti4LHu6y8zyVc5dxv2py81sdp6Q/go-multiaddr-net"
|
||||
manet "QmRCPT5WRph8aWXmaT2Rfn6ac98YRUUJnNURpD3hNAWp4f/go-multiaddr-net"
|
||||
ma "QmbWxL1aXQhBjc1XGjGF1f2KGBMCBYSuT2ThA8YXnXJK83/go-multiaddr"
|
||||
)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
|
||||
logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log"
|
||||
|
||||
manet "QmU5s159q8cZuM1f9Vqti4LHu6y8zyVc5dxv2py81sdp6Q/go-multiaddr-net"
|
||||
manet "QmRCPT5WRph8aWXmaT2Rfn6ac98YRUUJnNURpD3hNAWp4f/go-multiaddr-net"
|
||||
context "QmacZi9WygGK7Me8mH53pypyscHzU386aUZXpr28GZgUct/context"
|
||||
ma "QmbWxL1aXQhBjc1XGjGF1f2KGBMCBYSuT2ThA8YXnXJK83/go-multiaddr"
|
||||
)
|
||||
|
||||
@@ -3,7 +3,7 @@ package addrutil
|
||||
import (
|
||||
"testing"
|
||||
|
||||
manet "QmU5s159q8cZuM1f9Vqti4LHu6y8zyVc5dxv2py81sdp6Q/go-multiaddr-net"
|
||||
manet "QmRCPT5WRph8aWXmaT2Rfn6ac98YRUUJnNURpD3hNAWp4f/go-multiaddr-net"
|
||||
ma "QmbWxL1aXQhBjc1XGjGF1f2KGBMCBYSuT2ThA8YXnXJK83/go-multiaddr"
|
||||
)
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
testutil "github.com/ipfs/go-libp2p/testutil"
|
||||
ci "github.com/ipfs/go-libp2p/testutil/ci"
|
||||
|
||||
manet "QmU5s159q8cZuM1f9Vqti4LHu6y8zyVc5dxv2py81sdp6Q/go-multiaddr-net"
|
||||
manet "QmRCPT5WRph8aWXmaT2Rfn6ac98YRUUJnNURpD3hNAWp4f/go-multiaddr-net"
|
||||
context "QmacZi9WygGK7Me8mH53pypyscHzU386aUZXpr28GZgUct/context"
|
||||
ma "QmbWxL1aXQhBjc1XGjGF1f2KGBMCBYSuT2ThA8YXnXJK83/go-multiaddr"
|
||||
)
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
|
||||
"QmSir6qPL1tjuxd8LkR8VZq6v625ExAUVs2eCLeqQuaPGU/goprocess"
|
||||
goprocessctx "QmSir6qPL1tjuxd8LkR8VZq6v625ExAUVs2eCLeqQuaPGU/goprocess/context"
|
||||
mafilter "QmYWqTn1i8yv9QRDzGPJ2yRudKzYCaC5Aqasbm8vwaG92E/multiaddr-filter"
|
||||
mafilter "QmXE4GFk66B5Ts362YWZosjiZLpP4QDmBTBadRZFffZ58U/multiaddr-filter"
|
||||
context "QmacZi9WygGK7Me8mH53pypyscHzU386aUZXpr28GZgUct/context"
|
||||
ma "QmbWxL1aXQhBjc1XGjGF1f2KGBMCBYSuT2ThA8YXnXJK83/go-multiaddr"
|
||||
ps "github.com/jbenet/go-peerstream"
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"QmU5s159q8cZuM1f9Vqti4LHu6y8zyVc5dxv2py81sdp6Q/go-multiaddr-net"
|
||||
"QmRCPT5WRph8aWXmaT2Rfn6ac98YRUUJnNURpD3hNAWp4f/go-multiaddr-net"
|
||||
conn "github.com/ipfs/go-libp2p/p2p/net/conn"
|
||||
addrutil "github.com/ipfs/go-libp2p/p2p/net/swarm/addr"
|
||||
peer "github.com/ipfs/go-libp2p/p2p/peer"
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
manet "QmU5s159q8cZuM1f9Vqti4LHu6y8zyVc5dxv2py81sdp6Q/go-multiaddr-net"
|
||||
manet "QmRCPT5WRph8aWXmaT2Rfn6ac98YRUUJnNURpD3hNAWp4f/go-multiaddr-net"
|
||||
context "QmacZi9WygGK7Me8mH53pypyscHzU386aUZXpr28GZgUct/context"
|
||||
ma "QmbWxL1aXQhBjc1XGjGF1f2KGBMCBYSuT2ThA8YXnXJK83/go-multiaddr"
|
||||
reuseport "github.com/jbenet/go-reuseport"
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
manet "QmU5s159q8cZuM1f9Vqti4LHu6y8zyVc5dxv2py81sdp6Q/go-multiaddr-net"
|
||||
manet "QmRCPT5WRph8aWXmaT2Rfn6ac98YRUUJnNURpD3hNAWp4f/go-multiaddr-net"
|
||||
logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log"
|
||||
ma "QmbWxL1aXQhBjc1XGjGF1f2KGBMCBYSuT2ThA8YXnXJK83/go-multiaddr"
|
||||
)
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
b58 "QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58"
|
||||
ma "QmbWxL1aXQhBjc1XGjGF1f2KGBMCBYSuT2ThA8YXnXJK83/go-multiaddr"
|
||||
mh "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash"
|
||||
mh "QmdsKjp5fcCT8PZ8JBMcdFsCbbmKwSLCU5xXbsnwb5DMxy/go-multihash"
|
||||
|
||||
logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log"
|
||||
ic "github.com/ipfs/go-libp2p/p2p/crypto"
|
||||
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
|
||||
ic "github.com/ipfs/go-libp2p/p2p/crypto"
|
||||
. "github.com/ipfs/go-libp2p/p2p/peer"
|
||||
u "util"
|
||||
tu "github.com/ipfs/go-libp2p/testutil"
|
||||
u "util"
|
||||
|
||||
b58 "QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58"
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
mh "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash"
|
||||
mh "QmdsKjp5fcCT8PZ8JBMcdFsCbbmKwSLCU5xXbsnwb5DMxy/go-multihash"
|
||||
|
||||
logging "QmWRypnfEwrgH4k93KEHN5hng7VjKYkWmzDYRuTZeh2Mgh/go-log"
|
||||
host "github.com/ipfs/go-libp2p/p2p/host"
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
},
|
||||
{
|
||||
"name": "go-multiaddr-net",
|
||||
"hash": "QmU5s159q8cZuM1f9Vqti4LHu6y8zyVc5dxv2py81sdp6Q",
|
||||
"hash": "QmRCPT5WRph8aWXmaT2Rfn6ac98YRUUJnNURpD3hNAWp4f",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
"name": "multiaddr-filter",
|
||||
"hash": "QmYWqTn1i8yv9QRDzGPJ2yRudKzYCaC5Aqasbm8vwaG92E",
|
||||
"hash": "QmXE4GFk66B5Ts362YWZosjiZLpP4QDmBTBadRZFffZ58U",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
utp "QmU5s159q8cZuM1f9Vqti4LHu6y8zyVc5dxv2py81sdp6Q/go-multiaddr-net/utp"
|
||||
utp "QmRCPT5WRph8aWXmaT2Rfn6ac98YRUUJnNURpD3hNAWp4f/go-multiaddr-net/utp"
|
||||
ma "QmbWxL1aXQhBjc1XGjGF1f2KGBMCBYSuT2ThA8YXnXJK83/go-multiaddr"
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
mautp "QmU5s159q8cZuM1f9Vqti4LHu6y8zyVc5dxv2py81sdp6Q/go-multiaddr-net/utp"
|
||||
mautp "QmRCPT5WRph8aWXmaT2Rfn6ac98YRUUJnNURpD3hNAWp4f/go-multiaddr-net/utp"
|
||||
ma "QmbWxL1aXQhBjc1XGjGF1f2KGBMCBYSuT2ThA8YXnXJK83/go-multiaddr"
|
||||
)
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
manet "QmU5s159q8cZuM1f9Vqti4LHu6y8zyVc5dxv2py81sdp6Q/go-multiaddr-net"
|
||||
manet "QmRCPT5WRph8aWXmaT2Rfn6ac98YRUUJnNURpD3hNAWp4f/go-multiaddr-net"
|
||||
ma "QmbWxL1aXQhBjc1XGjGF1f2KGBMCBYSuT2ThA8YXnXJK83/go-multiaddr"
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
mautp "QmU5s159q8cZuM1f9Vqti4LHu6y8zyVc5dxv2py81sdp6Q/go-multiaddr-net/utp"
|
||||
mautp "QmRCPT5WRph8aWXmaT2Rfn6ac98YRUUJnNURpD3hNAWp4f/go-multiaddr-net/utp"
|
||||
ma "QmbWxL1aXQhBjc1XGjGF1f2KGBMCBYSuT2ThA8YXnXJK83/go-multiaddr"
|
||||
)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
},
|
||||
{
|
||||
"name": "go-multihash",
|
||||
"hash": "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy",
|
||||
"hash": "QmdsKjp5fcCT8PZ8JBMcdFsCbbmKwSLCU5xXbsnwb5DMxy",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
],
|
||||
@@ -1 +0,0 @@
|
||||
1.0.0: QmanZCL6SXRfafiUEMCBLq2QR171uQSdXQ8YAdHXLd8Cwr
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
manet "QmU5s159q8cZuM1f9Vqti4LHu6y8zyVc5dxv2py81sdp6Q/go-multiaddr-net"
|
||||
manet "QmRCPT5WRph8aWXmaT2Rfn6ac98YRUUJnNURpD3hNAWp4f/go-multiaddr-net"
|
||||
)
|
||||
|
||||
var ErrInvalidFormat = errors.New("invalid multiaddr-filter format")
|
||||
@@ -5,7 +5,7 @@
|
||||
"gxDependencies": [
|
||||
{
|
||||
"name": "go-multiaddr-net",
|
||||
"hash": "QmU5s159q8cZuM1f9Vqti4LHu6y8zyVc5dxv2py81sdp6Q",
|
||||
"hash": "QmRCPT5WRph8aWXmaT2Rfn6ac98YRUUJnNURpD3hNAWp4f",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
],
|
||||
@@ -1,66 +0,0 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package sha3 implements the SHA-3 fixed-output-length hash functions and
|
||||
// the SHAKE variable-output-length hash functions defined by FIPS-202.
|
||||
//
|
||||
// Both types of hash function use the "sponge" construction and the Keccak
|
||||
// permutation. For a detailed specification see http://keccak.noekeon.org/
|
||||
//
|
||||
//
|
||||
// Guidance
|
||||
//
|
||||
// If you aren't sure what function you need, use SHAKE256 with at least 64
|
||||
// bytes of output. The SHAKE instances are faster than the SHA3 instances;
|
||||
// the latter have to allocate memory to conform to the hash.Hash interface.
|
||||
//
|
||||
// If you need a secret-key MAC (message authentication code), prepend the
|
||||
// secret key to the input, hash with SHAKE256 and read at least 32 bytes of
|
||||
// output.
|
||||
//
|
||||
//
|
||||
// Security strengths
|
||||
//
|
||||
// The SHA3-x (x equals 224, 256, 384, or 512) functions have a security
|
||||
// strength against preimage attacks of x bits. Since they only produce "x"
|
||||
// bits of output, their collision-resistance is only "x/2" bits.
|
||||
//
|
||||
// The SHAKE-256 and -128 functions have a generic security strength of 256 and
|
||||
// 128 bits against all attacks, provided that at least 2x bits of their output
|
||||
// is used. Requesting more than 64 or 32 bytes of output, respectively, does
|
||||
// not increase the collision-resistance of the SHAKE functions.
|
||||
//
|
||||
//
|
||||
// The sponge construction
|
||||
//
|
||||
// A sponge builds a pseudo-random function from a public pseudo-random
|
||||
// permutation, by applying the permutation to a state of "rate + capacity"
|
||||
// bytes, but hiding "capacity" of the bytes.
|
||||
//
|
||||
// A sponge starts out with a zero state. To hash an input using a sponge, up
|
||||
// to "rate" bytes of the input are XORed into the sponge's state. The sponge
|
||||
// is then "full" and the permutation is applied to "empty" it. This process is
|
||||
// repeated until all the input has been "absorbed". The input is then padded.
|
||||
// The digest is "squeezed" from the sponge in the same way, except that output
|
||||
// output is copied out instead of input being XORed in.
|
||||
//
|
||||
// A sponge is parameterized by its generic security strength, which is equal
|
||||
// to half its capacity; capacity + rate is equal to the permutation's width.
|
||||
// Since the KeccakF-1600 permutation is 1600 bits (200 bytes) wide, this means
|
||||
// that the security strength of a sponge instance is equal to (1600 - bitrate) / 2.
|
||||
//
|
||||
//
|
||||
// Recommendations
|
||||
//
|
||||
// The SHAKE functions are recommended for most new uses. They can produce
|
||||
// output of arbitrary length. SHAKE256, with an output length of at least
|
||||
// 64 bytes, provides 256-bit security against all attacks. The Keccak team
|
||||
// recommends it for most applications upgrading from SHA2-512. (NIST chose a
|
||||
// much stronger, but much slower, sponge instance for SHA3-512.)
|
||||
//
|
||||
// The SHA-3 functions are "drop-in" replacements for the SHA-2 functions.
|
||||
// They produce output of the same length, with the same security strengths
|
||||
// against all attacks. This means, in particular, that SHA3-256 only has
|
||||
// 128-bit collision resistance, because its output length is 32 bytes.
|
||||
package sha3
|
||||
@@ -1,65 +0,0 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sha3
|
||||
|
||||
// This file provides functions for creating instances of the SHA-3
|
||||
// and SHAKE hash functions, as well as utility functions for hashing
|
||||
// bytes.
|
||||
|
||||
import (
|
||||
"hash"
|
||||
)
|
||||
|
||||
// New224 creates a new SHA3-224 hash.
|
||||
// Its generic security strength is 224 bits against preimage attacks,
|
||||
// and 112 bits against collision attacks.
|
||||
func New224() hash.Hash { return &state{rate: 144, outputLen: 28, dsbyte: 0x06} }
|
||||
|
||||
// New256 creates a new SHA3-256 hash.
|
||||
// Its generic security strength is 256 bits against preimage attacks,
|
||||
// and 128 bits against collision attacks.
|
||||
func New256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x06} }
|
||||
|
||||
// New384 creates a new SHA3-384 hash.
|
||||
// Its generic security strength is 384 bits against preimage attacks,
|
||||
// and 192 bits against collision attacks.
|
||||
func New384() hash.Hash { return &state{rate: 104, outputLen: 48, dsbyte: 0x06} }
|
||||
|
||||
// New512 creates a new SHA3-512 hash.
|
||||
// Its generic security strength is 512 bits against preimage attacks,
|
||||
// and 256 bits against collision attacks.
|
||||
func New512() hash.Hash { return &state{rate: 72, outputLen: 64, dsbyte: 0x06} }
|
||||
|
||||
// Sum224 returns the SHA3-224 digest of the data.
|
||||
func Sum224(data []byte) (digest [28]byte) {
|
||||
h := New224()
|
||||
h.Write(data)
|
||||
h.Sum(digest[:0])
|
||||
return
|
||||
}
|
||||
|
||||
// Sum256 returns the SHA3-256 digest of the data.
|
||||
func Sum256(data []byte) (digest [32]byte) {
|
||||
h := New256()
|
||||
h.Write(data)
|
||||
h.Sum(digest[:0])
|
||||
return
|
||||
}
|
||||
|
||||
// Sum384 returns the SHA3-384 digest of the data.
|
||||
func Sum384(data []byte) (digest [48]byte) {
|
||||
h := New384()
|
||||
h.Write(data)
|
||||
h.Sum(digest[:0])
|
||||
return
|
||||
}
|
||||
|
||||
// Sum512 returns the SHA3-512 digest of the data.
|
||||
func Sum512(data []byte) (digest [64]byte) {
|
||||
h := New512()
|
||||
h.Write(data)
|
||||
h.Sum(digest[:0])
|
||||
return
|
||||
}
|
||||
@@ -1,410 +0,0 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sha3
|
||||
|
||||
// rc stores the round constants for use in the ι step.
|
||||
var rc = [24]uint64{
|
||||
0x0000000000000001,
|
||||
0x0000000000008082,
|
||||
0x800000000000808A,
|
||||
0x8000000080008000,
|
||||
0x000000000000808B,
|
||||
0x0000000080000001,
|
||||
0x8000000080008081,
|
||||
0x8000000000008009,
|
||||
0x000000000000008A,
|
||||
0x0000000000000088,
|
||||
0x0000000080008009,
|
||||
0x000000008000000A,
|
||||
0x000000008000808B,
|
||||
0x800000000000008B,
|
||||
0x8000000000008089,
|
||||
0x8000000000008003,
|
||||
0x8000000000008002,
|
||||
0x8000000000000080,
|
||||
0x000000000000800A,
|
||||
0x800000008000000A,
|
||||
0x8000000080008081,
|
||||
0x8000000000008080,
|
||||
0x0000000080000001,
|
||||
0x8000000080008008,
|
||||
}
|
||||
|
||||
// keccakF1600 applies the Keccak permutation to a 1600b-wide
|
||||
// state represented as a slice of 25 uint64s.
|
||||
func keccakF1600(a *[25]uint64) {
|
||||
// Implementation translated from Keccak-inplace.c
|
||||
// in the keccak reference code.
|
||||
var t, bc0, bc1, bc2, bc3, bc4, d0, d1, d2, d3, d4 uint64
|
||||
|
||||
for i := 0; i < 24; i += 4 {
|
||||
// Combines the 5 steps in each round into 2 steps.
|
||||
// Unrolls 4 rounds per loop and spreads some steps across rounds.
|
||||
|
||||
// Round 1
|
||||
bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
|
||||
bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
|
||||
bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
|
||||
bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
|
||||
bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
|
||||
d0 = bc4 ^ (bc1<<1 | bc1>>63)
|
||||
d1 = bc0 ^ (bc2<<1 | bc2>>63)
|
||||
d2 = bc1 ^ (bc3<<1 | bc3>>63)
|
||||
d3 = bc2 ^ (bc4<<1 | bc4>>63)
|
||||
d4 = bc3 ^ (bc0<<1 | bc0>>63)
|
||||
|
||||
bc0 = a[0] ^ d0
|
||||
t = a[6] ^ d1
|
||||
bc1 = t<<44 | t>>(64-44)
|
||||
t = a[12] ^ d2
|
||||
bc2 = t<<43 | t>>(64-43)
|
||||
t = a[18] ^ d3
|
||||
bc3 = t<<21 | t>>(64-21)
|
||||
t = a[24] ^ d4
|
||||
bc4 = t<<14 | t>>(64-14)
|
||||
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i]
|
||||
a[6] = bc1 ^ (bc3 &^ bc2)
|
||||
a[12] = bc2 ^ (bc4 &^ bc3)
|
||||
a[18] = bc3 ^ (bc0 &^ bc4)
|
||||
a[24] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[10] ^ d0
|
||||
bc2 = t<<3 | t>>(64-3)
|
||||
t = a[16] ^ d1
|
||||
bc3 = t<<45 | t>>(64-45)
|
||||
t = a[22] ^ d2
|
||||
bc4 = t<<61 | t>>(64-61)
|
||||
t = a[3] ^ d3
|
||||
bc0 = t<<28 | t>>(64-28)
|
||||
t = a[9] ^ d4
|
||||
bc1 = t<<20 | t>>(64-20)
|
||||
a[10] = bc0 ^ (bc2 &^ bc1)
|
||||
a[16] = bc1 ^ (bc3 &^ bc2)
|
||||
a[22] = bc2 ^ (bc4 &^ bc3)
|
||||
a[3] = bc3 ^ (bc0 &^ bc4)
|
||||
a[9] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[20] ^ d0
|
||||
bc4 = t<<18 | t>>(64-18)
|
||||
t = a[1] ^ d1
|
||||
bc0 = t<<1 | t>>(64-1)
|
||||
t = a[7] ^ d2
|
||||
bc1 = t<<6 | t>>(64-6)
|
||||
t = a[13] ^ d3
|
||||
bc2 = t<<25 | t>>(64-25)
|
||||
t = a[19] ^ d4
|
||||
bc3 = t<<8 | t>>(64-8)
|
||||
a[20] = bc0 ^ (bc2 &^ bc1)
|
||||
a[1] = bc1 ^ (bc3 &^ bc2)
|
||||
a[7] = bc2 ^ (bc4 &^ bc3)
|
||||
a[13] = bc3 ^ (bc0 &^ bc4)
|
||||
a[19] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[5] ^ d0
|
||||
bc1 = t<<36 | t>>(64-36)
|
||||
t = a[11] ^ d1
|
||||
bc2 = t<<10 | t>>(64-10)
|
||||
t = a[17] ^ d2
|
||||
bc3 = t<<15 | t>>(64-15)
|
||||
t = a[23] ^ d3
|
||||
bc4 = t<<56 | t>>(64-56)
|
||||
t = a[4] ^ d4
|
||||
bc0 = t<<27 | t>>(64-27)
|
||||
a[5] = bc0 ^ (bc2 &^ bc1)
|
||||
a[11] = bc1 ^ (bc3 &^ bc2)
|
||||
a[17] = bc2 ^ (bc4 &^ bc3)
|
||||
a[23] = bc3 ^ (bc0 &^ bc4)
|
||||
a[4] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[15] ^ d0
|
||||
bc3 = t<<41 | t>>(64-41)
|
||||
t = a[21] ^ d1
|
||||
bc4 = t<<2 | t>>(64-2)
|
||||
t = a[2] ^ d2
|
||||
bc0 = t<<62 | t>>(64-62)
|
||||
t = a[8] ^ d3
|
||||
bc1 = t<<55 | t>>(64-55)
|
||||
t = a[14] ^ d4
|
||||
bc2 = t<<39 | t>>(64-39)
|
||||
a[15] = bc0 ^ (bc2 &^ bc1)
|
||||
a[21] = bc1 ^ (bc3 &^ bc2)
|
||||
a[2] = bc2 ^ (bc4 &^ bc3)
|
||||
a[8] = bc3 ^ (bc0 &^ bc4)
|
||||
a[14] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
// Round 2
|
||||
bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
|
||||
bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
|
||||
bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
|
||||
bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
|
||||
bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
|
||||
d0 = bc4 ^ (bc1<<1 | bc1>>63)
|
||||
d1 = bc0 ^ (bc2<<1 | bc2>>63)
|
||||
d2 = bc1 ^ (bc3<<1 | bc3>>63)
|
||||
d3 = bc2 ^ (bc4<<1 | bc4>>63)
|
||||
d4 = bc3 ^ (bc0<<1 | bc0>>63)
|
||||
|
||||
bc0 = a[0] ^ d0
|
||||
t = a[16] ^ d1
|
||||
bc1 = t<<44 | t>>(64-44)
|
||||
t = a[7] ^ d2
|
||||
bc2 = t<<43 | t>>(64-43)
|
||||
t = a[23] ^ d3
|
||||
bc3 = t<<21 | t>>(64-21)
|
||||
t = a[14] ^ d4
|
||||
bc4 = t<<14 | t>>(64-14)
|
||||
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+1]
|
||||
a[16] = bc1 ^ (bc3 &^ bc2)
|
||||
a[7] = bc2 ^ (bc4 &^ bc3)
|
||||
a[23] = bc3 ^ (bc0 &^ bc4)
|
||||
a[14] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[20] ^ d0
|
||||
bc2 = t<<3 | t>>(64-3)
|
||||
t = a[11] ^ d1
|
||||
bc3 = t<<45 | t>>(64-45)
|
||||
t = a[2] ^ d2
|
||||
bc4 = t<<61 | t>>(64-61)
|
||||
t = a[18] ^ d3
|
||||
bc0 = t<<28 | t>>(64-28)
|
||||
t = a[9] ^ d4
|
||||
bc1 = t<<20 | t>>(64-20)
|
||||
a[20] = bc0 ^ (bc2 &^ bc1)
|
||||
a[11] = bc1 ^ (bc3 &^ bc2)
|
||||
a[2] = bc2 ^ (bc4 &^ bc3)
|
||||
a[18] = bc3 ^ (bc0 &^ bc4)
|
||||
a[9] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[15] ^ d0
|
||||
bc4 = t<<18 | t>>(64-18)
|
||||
t = a[6] ^ d1
|
||||
bc0 = t<<1 | t>>(64-1)
|
||||
t = a[22] ^ d2
|
||||
bc1 = t<<6 | t>>(64-6)
|
||||
t = a[13] ^ d3
|
||||
bc2 = t<<25 | t>>(64-25)
|
||||
t = a[4] ^ d4
|
||||
bc3 = t<<8 | t>>(64-8)
|
||||
a[15] = bc0 ^ (bc2 &^ bc1)
|
||||
a[6] = bc1 ^ (bc3 &^ bc2)
|
||||
a[22] = bc2 ^ (bc4 &^ bc3)
|
||||
a[13] = bc3 ^ (bc0 &^ bc4)
|
||||
a[4] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[10] ^ d0
|
||||
bc1 = t<<36 | t>>(64-36)
|
||||
t = a[1] ^ d1
|
||||
bc2 = t<<10 | t>>(64-10)
|
||||
t = a[17] ^ d2
|
||||
bc3 = t<<15 | t>>(64-15)
|
||||
t = a[8] ^ d3
|
||||
bc4 = t<<56 | t>>(64-56)
|
||||
t = a[24] ^ d4
|
||||
bc0 = t<<27 | t>>(64-27)
|
||||
a[10] = bc0 ^ (bc2 &^ bc1)
|
||||
a[1] = bc1 ^ (bc3 &^ bc2)
|
||||
a[17] = bc2 ^ (bc4 &^ bc3)
|
||||
a[8] = bc3 ^ (bc0 &^ bc4)
|
||||
a[24] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[5] ^ d0
|
||||
bc3 = t<<41 | t>>(64-41)
|
||||
t = a[21] ^ d1
|
||||
bc4 = t<<2 | t>>(64-2)
|
||||
t = a[12] ^ d2
|
||||
bc0 = t<<62 | t>>(64-62)
|
||||
t = a[3] ^ d3
|
||||
bc1 = t<<55 | t>>(64-55)
|
||||
t = a[19] ^ d4
|
||||
bc2 = t<<39 | t>>(64-39)
|
||||
a[5] = bc0 ^ (bc2 &^ bc1)
|
||||
a[21] = bc1 ^ (bc3 &^ bc2)
|
||||
a[12] = bc2 ^ (bc4 &^ bc3)
|
||||
a[3] = bc3 ^ (bc0 &^ bc4)
|
||||
a[19] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
// Round 3
|
||||
bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
|
||||
bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
|
||||
bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
|
||||
bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
|
||||
bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
|
||||
d0 = bc4 ^ (bc1<<1 | bc1>>63)
|
||||
d1 = bc0 ^ (bc2<<1 | bc2>>63)
|
||||
d2 = bc1 ^ (bc3<<1 | bc3>>63)
|
||||
d3 = bc2 ^ (bc4<<1 | bc4>>63)
|
||||
d4 = bc3 ^ (bc0<<1 | bc0>>63)
|
||||
|
||||
bc0 = a[0] ^ d0
|
||||
t = a[11] ^ d1
|
||||
bc1 = t<<44 | t>>(64-44)
|
||||
t = a[22] ^ d2
|
||||
bc2 = t<<43 | t>>(64-43)
|
||||
t = a[8] ^ d3
|
||||
bc3 = t<<21 | t>>(64-21)
|
||||
t = a[19] ^ d4
|
||||
bc4 = t<<14 | t>>(64-14)
|
||||
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+2]
|
||||
a[11] = bc1 ^ (bc3 &^ bc2)
|
||||
a[22] = bc2 ^ (bc4 &^ bc3)
|
||||
a[8] = bc3 ^ (bc0 &^ bc4)
|
||||
a[19] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[15] ^ d0
|
||||
bc2 = t<<3 | t>>(64-3)
|
||||
t = a[1] ^ d1
|
||||
bc3 = t<<45 | t>>(64-45)
|
||||
t = a[12] ^ d2
|
||||
bc4 = t<<61 | t>>(64-61)
|
||||
t = a[23] ^ d3
|
||||
bc0 = t<<28 | t>>(64-28)
|
||||
t = a[9] ^ d4
|
||||
bc1 = t<<20 | t>>(64-20)
|
||||
a[15] = bc0 ^ (bc2 &^ bc1)
|
||||
a[1] = bc1 ^ (bc3 &^ bc2)
|
||||
a[12] = bc2 ^ (bc4 &^ bc3)
|
||||
a[23] = bc3 ^ (bc0 &^ bc4)
|
||||
a[9] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[5] ^ d0
|
||||
bc4 = t<<18 | t>>(64-18)
|
||||
t = a[16] ^ d1
|
||||
bc0 = t<<1 | t>>(64-1)
|
||||
t = a[2] ^ d2
|
||||
bc1 = t<<6 | t>>(64-6)
|
||||
t = a[13] ^ d3
|
||||
bc2 = t<<25 | t>>(64-25)
|
||||
t = a[24] ^ d4
|
||||
bc3 = t<<8 | t>>(64-8)
|
||||
a[5] = bc0 ^ (bc2 &^ bc1)
|
||||
a[16] = bc1 ^ (bc3 &^ bc2)
|
||||
a[2] = bc2 ^ (bc4 &^ bc3)
|
||||
a[13] = bc3 ^ (bc0 &^ bc4)
|
||||
a[24] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[20] ^ d0
|
||||
bc1 = t<<36 | t>>(64-36)
|
||||
t = a[6] ^ d1
|
||||
bc2 = t<<10 | t>>(64-10)
|
||||
t = a[17] ^ d2
|
||||
bc3 = t<<15 | t>>(64-15)
|
||||
t = a[3] ^ d3
|
||||
bc4 = t<<56 | t>>(64-56)
|
||||
t = a[14] ^ d4
|
||||
bc0 = t<<27 | t>>(64-27)
|
||||
a[20] = bc0 ^ (bc2 &^ bc1)
|
||||
a[6] = bc1 ^ (bc3 &^ bc2)
|
||||
a[17] = bc2 ^ (bc4 &^ bc3)
|
||||
a[3] = bc3 ^ (bc0 &^ bc4)
|
||||
a[14] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[10] ^ d0
|
||||
bc3 = t<<41 | t>>(64-41)
|
||||
t = a[21] ^ d1
|
||||
bc4 = t<<2 | t>>(64-2)
|
||||
t = a[7] ^ d2
|
||||
bc0 = t<<62 | t>>(64-62)
|
||||
t = a[18] ^ d3
|
||||
bc1 = t<<55 | t>>(64-55)
|
||||
t = a[4] ^ d4
|
||||
bc2 = t<<39 | t>>(64-39)
|
||||
a[10] = bc0 ^ (bc2 &^ bc1)
|
||||
a[21] = bc1 ^ (bc3 &^ bc2)
|
||||
a[7] = bc2 ^ (bc4 &^ bc3)
|
||||
a[18] = bc3 ^ (bc0 &^ bc4)
|
||||
a[4] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
// Round 4
|
||||
bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
|
||||
bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
|
||||
bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
|
||||
bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
|
||||
bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
|
||||
d0 = bc4 ^ (bc1<<1 | bc1>>63)
|
||||
d1 = bc0 ^ (bc2<<1 | bc2>>63)
|
||||
d2 = bc1 ^ (bc3<<1 | bc3>>63)
|
||||
d3 = bc2 ^ (bc4<<1 | bc4>>63)
|
||||
d4 = bc3 ^ (bc0<<1 | bc0>>63)
|
||||
|
||||
bc0 = a[0] ^ d0
|
||||
t = a[1] ^ d1
|
||||
bc1 = t<<44 | t>>(64-44)
|
||||
t = a[2] ^ d2
|
||||
bc2 = t<<43 | t>>(64-43)
|
||||
t = a[3] ^ d3
|
||||
bc3 = t<<21 | t>>(64-21)
|
||||
t = a[4] ^ d4
|
||||
bc4 = t<<14 | t>>(64-14)
|
||||
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+3]
|
||||
a[1] = bc1 ^ (bc3 &^ bc2)
|
||||
a[2] = bc2 ^ (bc4 &^ bc3)
|
||||
a[3] = bc3 ^ (bc0 &^ bc4)
|
||||
a[4] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[5] ^ d0
|
||||
bc2 = t<<3 | t>>(64-3)
|
||||
t = a[6] ^ d1
|
||||
bc3 = t<<45 | t>>(64-45)
|
||||
t = a[7] ^ d2
|
||||
bc4 = t<<61 | t>>(64-61)
|
||||
t = a[8] ^ d3
|
||||
bc0 = t<<28 | t>>(64-28)
|
||||
t = a[9] ^ d4
|
||||
bc1 = t<<20 | t>>(64-20)
|
||||
a[5] = bc0 ^ (bc2 &^ bc1)
|
||||
a[6] = bc1 ^ (bc3 &^ bc2)
|
||||
a[7] = bc2 ^ (bc4 &^ bc3)
|
||||
a[8] = bc3 ^ (bc0 &^ bc4)
|
||||
a[9] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[10] ^ d0
|
||||
bc4 = t<<18 | t>>(64-18)
|
||||
t = a[11] ^ d1
|
||||
bc0 = t<<1 | t>>(64-1)
|
||||
t = a[12] ^ d2
|
||||
bc1 = t<<6 | t>>(64-6)
|
||||
t = a[13] ^ d3
|
||||
bc2 = t<<25 | t>>(64-25)
|
||||
t = a[14] ^ d4
|
||||
bc3 = t<<8 | t>>(64-8)
|
||||
a[10] = bc0 ^ (bc2 &^ bc1)
|
||||
a[11] = bc1 ^ (bc3 &^ bc2)
|
||||
a[12] = bc2 ^ (bc4 &^ bc3)
|
||||
a[13] = bc3 ^ (bc0 &^ bc4)
|
||||
a[14] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[15] ^ d0
|
||||
bc1 = t<<36 | t>>(64-36)
|
||||
t = a[16] ^ d1
|
||||
bc2 = t<<10 | t>>(64-10)
|
||||
t = a[17] ^ d2
|
||||
bc3 = t<<15 | t>>(64-15)
|
||||
t = a[18] ^ d3
|
||||
bc4 = t<<56 | t>>(64-56)
|
||||
t = a[19] ^ d4
|
||||
bc0 = t<<27 | t>>(64-27)
|
||||
a[15] = bc0 ^ (bc2 &^ bc1)
|
||||
a[16] = bc1 ^ (bc3 &^ bc2)
|
||||
a[17] = bc2 ^ (bc4 &^ bc3)
|
||||
a[18] = bc3 ^ (bc0 &^ bc4)
|
||||
a[19] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[20] ^ d0
|
||||
bc3 = t<<41 | t>>(64-41)
|
||||
t = a[21] ^ d1
|
||||
bc4 = t<<2 | t>>(64-2)
|
||||
t = a[22] ^ d2
|
||||
bc0 = t<<62 | t>>(64-62)
|
||||
t = a[23] ^ d3
|
||||
bc1 = t<<55 | t>>(64-55)
|
||||
t = a[24] ^ d4
|
||||
bc2 = t<<39 | t>>(64-39)
|
||||
a[20] = bc0 ^ (bc2 &^ bc1)
|
||||
a[21] = bc1 ^ (bc3 &^ bc2)
|
||||
a[22] = bc2 ^ (bc4 &^ bc3)
|
||||
a[23] = bc3 ^ (bc0 &^ bc4)
|
||||
a[24] = bc4 ^ (bc1 &^ bc0)
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"name": "crypto-sha3",
|
||||
"author": "whyrusleeping",
|
||||
"version": "1.0.0",
|
||||
"language": "go",
|
||||
"gx": {
|
||||
"dvcsimport": "golang.org/x/crypto/sha3"
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.4
|
||||
|
||||
package sha3
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
)
|
||||
|
||||
func init() {
|
||||
crypto.RegisterHash(crypto.SHA3_224, New224)
|
||||
crypto.RegisterHash(crypto.SHA3_256, New256)
|
||||
crypto.RegisterHash(crypto.SHA3_384, New384)
|
||||
crypto.RegisterHash(crypto.SHA3_512, New512)
|
||||
}
|
||||
@@ -1,193 +0,0 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sha3
|
||||
|
||||
// spongeDirection indicates the direction bytes are flowing through the sponge.
|
||||
type spongeDirection int
|
||||
|
||||
const (
|
||||
// spongeAbsorbing indicates that the sponge is absorbing input.
|
||||
spongeAbsorbing spongeDirection = iota
|
||||
// spongeSqueezing indicates that the sponge is being squeezed.
|
||||
spongeSqueezing
|
||||
)
|
||||
|
||||
const (
|
||||
// maxRate is the maximum size of the internal buffer. SHAKE-256
|
||||
// currently needs the largest buffer.
|
||||
maxRate = 168
|
||||
)
|
||||
|
||||
type state struct {
|
||||
// Generic sponge components.
|
||||
a [25]uint64 // main state of the hash
|
||||
buf []byte // points into storage
|
||||
rate int // the number of bytes of state to use
|
||||
|
||||
// dsbyte contains the "domain separation" bits and the first bit of
|
||||
// the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the
|
||||
// SHA-3 and SHAKE functions by appending bitstrings to the message.
|
||||
// Using a little-endian bit-ordering convention, these are "01" for SHA-3
|
||||
// and "1111" for SHAKE, or 00000010b and 00001111b, respectively. Then the
|
||||
// padding rule from section 5.1 is applied to pad the message to a multiple
|
||||
// of the rate, which involves adding a "1" bit, zero or more "0" bits, and
|
||||
// a final "1" bit. We merge the first "1" bit from the padding into dsbyte,
|
||||
// giving 00000110b (0x06) and 00011111b (0x1f).
|
||||
// [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf
|
||||
// "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and
|
||||
// Extendable-Output Functions (May 2014)"
|
||||
dsbyte byte
|
||||
storage [maxRate]byte
|
||||
|
||||
// Specific to SHA-3 and SHAKE.
|
||||
fixedOutput bool // whether this is a fixed-ouput-length instance
|
||||
outputLen int // the default output size in bytes
|
||||
state spongeDirection // whether the sponge is absorbing or squeezing
|
||||
}
|
||||
|
||||
// BlockSize returns the rate of sponge underlying this hash function.
|
||||
func (d *state) BlockSize() int { return d.rate }
|
||||
|
||||
// Size returns the output size of the hash function in bytes.
|
||||
func (d *state) Size() int { return d.outputLen }
|
||||
|
||||
// Reset clears the internal state by zeroing the sponge state and
|
||||
// the byte buffer, and setting Sponge.state to absorbing.
|
||||
func (d *state) Reset() {
|
||||
// Zero the permutation's state.
|
||||
for i := range d.a {
|
||||
d.a[i] = 0
|
||||
}
|
||||
d.state = spongeAbsorbing
|
||||
d.buf = d.storage[:0]
|
||||
}
|
||||
|
||||
func (d *state) clone() *state {
|
||||
ret := *d
|
||||
if ret.state == spongeAbsorbing {
|
||||
ret.buf = ret.storage[:len(ret.buf)]
|
||||
} else {
|
||||
ret.buf = ret.storage[d.rate-cap(d.buf) : d.rate]
|
||||
}
|
||||
|
||||
return &ret
|
||||
}
|
||||
|
||||
// permute applies the KeccakF-1600 permutation. It handles
|
||||
// any input-output buffering.
|
||||
func (d *state) permute() {
|
||||
switch d.state {
|
||||
case spongeAbsorbing:
|
||||
// If we're absorbing, we need to xor the input into the state
|
||||
// before applying the permutation.
|
||||
xorIn(d, d.buf)
|
||||
d.buf = d.storage[:0]
|
||||
keccakF1600(&d.a)
|
||||
case spongeSqueezing:
|
||||
// If we're squeezing, we need to apply the permutatin before
|
||||
// copying more output.
|
||||
keccakF1600(&d.a)
|
||||
d.buf = d.storage[:d.rate]
|
||||
copyOut(d, d.buf)
|
||||
}
|
||||
}
|
||||
|
||||
// pads appends the domain separation bits in dsbyte, applies
|
||||
// the multi-bitrate 10..1 padding rule, and permutes the state.
|
||||
func (d *state) padAndPermute(dsbyte byte) {
|
||||
if d.buf == nil {
|
||||
d.buf = d.storage[:0]
|
||||
}
|
||||
// Pad with this instance's domain-separator bits. We know that there's
|
||||
// at least one byte of space in d.buf because, if it were full,
|
||||
// permute would have been called to empty it. dsbyte also contains the
|
||||
// first one bit for the padding. See the comment in the state struct.
|
||||
d.buf = append(d.buf, dsbyte)
|
||||
zerosStart := len(d.buf)
|
||||
d.buf = d.storage[:d.rate]
|
||||
for i := zerosStart; i < d.rate; i++ {
|
||||
d.buf[i] = 0
|
||||
}
|
||||
// This adds the final one bit for the padding. Because of the way that
|
||||
// bits are numbered from the LSB upwards, the final bit is the MSB of
|
||||
// the last byte.
|
||||
d.buf[d.rate-1] ^= 0x80
|
||||
// Apply the permutation
|
||||
d.permute()
|
||||
d.state = spongeSqueezing
|
||||
d.buf = d.storage[:d.rate]
|
||||
copyOut(d, d.buf)
|
||||
}
|
||||
|
||||
// Write absorbs more data into the hash's state. It produces an error
|
||||
// if more data is written to the ShakeHash after writing
|
||||
func (d *state) Write(p []byte) (written int, err error) {
|
||||
if d.state != spongeAbsorbing {
|
||||
panic("sha3: write to sponge after read")
|
||||
}
|
||||
if d.buf == nil {
|
||||
d.buf = d.storage[:0]
|
||||
}
|
||||
written = len(p)
|
||||
|
||||
for len(p) > 0 {
|
||||
if len(d.buf) == 0 && len(p) >= d.rate {
|
||||
// The fast path; absorb a full "rate" bytes of input and apply the permutation.
|
||||
xorIn(d, p[:d.rate])
|
||||
p = p[d.rate:]
|
||||
keccakF1600(&d.a)
|
||||
} else {
|
||||
// The slow path; buffer the input until we can fill the sponge, and then xor it in.
|
||||
todo := d.rate - len(d.buf)
|
||||
if todo > len(p) {
|
||||
todo = len(p)
|
||||
}
|
||||
d.buf = append(d.buf, p[:todo]...)
|
||||
p = p[todo:]
|
||||
|
||||
// If the sponge is full, apply the permutation.
|
||||
if len(d.buf) == d.rate {
|
||||
d.permute()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Read squeezes an arbitrary number of bytes from the sponge.
|
||||
func (d *state) Read(out []byte) (n int, err error) {
|
||||
// If we're still absorbing, pad and apply the permutation.
|
||||
if d.state == spongeAbsorbing {
|
||||
d.padAndPermute(d.dsbyte)
|
||||
}
|
||||
|
||||
n = len(out)
|
||||
|
||||
// Now, do the squeezing.
|
||||
for len(out) > 0 {
|
||||
n := copy(out, d.buf)
|
||||
d.buf = d.buf[n:]
|
||||
out = out[n:]
|
||||
|
||||
// Apply the permutation if we've squeezed the sponge dry.
|
||||
if len(d.buf) == 0 {
|
||||
d.permute()
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Sum applies padding to the hash state and then squeezes out the desired
|
||||
// number of output bytes.
|
||||
func (d *state) Sum(in []byte) []byte {
|
||||
// Make a copy of the original hash so that caller can keep writing
|
||||
// and summing.
|
||||
dup := d.clone()
|
||||
hash := make([]byte, dup.outputLen)
|
||||
dup.Read(hash)
|
||||
return append(in, hash...)
|
||||
}
|
||||
@@ -1,306 +0,0 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sha3
|
||||
|
||||
// Tests include all the ShortMsgKATs provided by the Keccak team at
|
||||
// https://github.com/gvanas/KeccakCodePackage
|
||||
//
|
||||
// They only include the zero-bit case of the bitwise testvectors
|
||||
// published by NIST in the draft of FIPS-202.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/flate"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"hash"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
testString = "brekeccakkeccak koax koax"
|
||||
katFilename = "testdata/keccakKats.json.deflate"
|
||||
)
|
||||
|
||||
// Internal-use instances of SHAKE used to test against KATs.
|
||||
func newHashShake128() hash.Hash {
|
||||
return &state{rate: 168, dsbyte: 0x1f, outputLen: 512}
|
||||
}
|
||||
func newHashShake256() hash.Hash {
|
||||
return &state{rate: 136, dsbyte: 0x1f, outputLen: 512}
|
||||
}
|
||||
|
||||
// testDigests contains functions returning hash.Hash instances
|
||||
// with output-length equal to the KAT length for both SHA-3 and
|
||||
// SHAKE instances.
|
||||
var testDigests = map[string]func() hash.Hash{
|
||||
"SHA3-224": New224,
|
||||
"SHA3-256": New256,
|
||||
"SHA3-384": New384,
|
||||
"SHA3-512": New512,
|
||||
"SHAKE128": newHashShake128,
|
||||
"SHAKE256": newHashShake256,
|
||||
}
|
||||
|
||||
// testShakes contains functions that return ShakeHash instances for
|
||||
// testing the ShakeHash-specific interface.
|
||||
var testShakes = map[string]func() ShakeHash{
|
||||
"SHAKE128": NewShake128,
|
||||
"SHAKE256": NewShake256,
|
||||
}
|
||||
|
||||
// decodeHex converts a hex-encoded string into a raw byte string.
|
||||
func decodeHex(s string) []byte {
|
||||
b, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// structs used to marshal JSON test-cases.
|
||||
type KeccakKats struct {
|
||||
Kats map[string][]struct {
|
||||
Digest string `json:"digest"`
|
||||
Length int64 `json:"length"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
}
|
||||
|
||||
func testUnalignedAndGeneric(t *testing.T, testf func(impl string)) {
|
||||
xorInOrig, copyOutOrig := xorIn, copyOut
|
||||
xorIn, copyOut = xorInGeneric, copyOutGeneric
|
||||
testf("generic")
|
||||
if xorImplementationUnaligned != "generic" {
|
||||
xorIn, copyOut = xorInUnaligned, copyOutUnaligned
|
||||
testf("unaligned")
|
||||
}
|
||||
xorIn, copyOut = xorInOrig, copyOutOrig
|
||||
}
|
||||
|
||||
// TestKeccakKats tests the SHA-3 and Shake implementations against all the
|
||||
// ShortMsgKATs from https://github.com/gvanas/KeccakCodePackage
|
||||
// (The testvectors are stored in keccakKats.json.deflate due to their length.)
|
||||
func TestKeccakKats(t *testing.T) {
|
||||
testUnalignedAndGeneric(t, func(impl string) {
|
||||
// Read the KATs.
|
||||
deflated, err := os.Open(katFilename)
|
||||
if err != nil {
|
||||
t.Errorf("error opening %s: %s", katFilename, err)
|
||||
}
|
||||
file := flate.NewReader(deflated)
|
||||
dec := json.NewDecoder(file)
|
||||
var katSet KeccakKats
|
||||
err = dec.Decode(&katSet)
|
||||
if err != nil {
|
||||
t.Errorf("error decoding KATs: %s", err)
|
||||
}
|
||||
|
||||
// Do the KATs.
|
||||
for functionName, kats := range katSet.Kats {
|
||||
d := testDigests[functionName]()
|
||||
for _, kat := range kats {
|
||||
d.Reset()
|
||||
in, err := hex.DecodeString(kat.Message)
|
||||
if err != nil {
|
||||
t.Errorf("error decoding KAT: %s", err)
|
||||
}
|
||||
d.Write(in[:kat.Length/8])
|
||||
got := strings.ToUpper(hex.EncodeToString(d.Sum(nil)))
|
||||
if got != kat.Digest {
|
||||
t.Errorf("function=%s, implementation=%s, length=%d\nmessage:\n %s\ngot:\n %s\nwanted:\n %s",
|
||||
functionName, impl, kat.Length, kat.Message, got, kat.Digest)
|
||||
t.Logf("wanted %+v", kat)
|
||||
t.FailNow()
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TestUnalignedWrite tests that writing data in an arbitrary pattern with
|
||||
// small input buffers.
|
||||
func testUnalignedWrite(t *testing.T) {
|
||||
testUnalignedAndGeneric(t, func(impl string) {
|
||||
buf := sequentialBytes(0x10000)
|
||||
for alg, df := range testDigests {
|
||||
d := df()
|
||||
d.Reset()
|
||||
d.Write(buf)
|
||||
want := d.Sum(nil)
|
||||
d.Reset()
|
||||
for i := 0; i < len(buf); {
|
||||
// Cycle through offsets which make a 137 byte sequence.
|
||||
// Because 137 is prime this sequence should exercise all corner cases.
|
||||
offsets := [17]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1}
|
||||
for _, j := range offsets {
|
||||
if v := len(buf) - i; v < j {
|
||||
j = v
|
||||
}
|
||||
d.Write(buf[i : i+j])
|
||||
i += j
|
||||
}
|
||||
}
|
||||
got := d.Sum(nil)
|
||||
if !bytes.Equal(got, want) {
|
||||
t.Errorf("Unaligned writes, implementation=%s, alg=%s\ngot %q, want %q", impl, alg, got, want)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TestAppend checks that appending works when reallocation is necessary.
|
||||
func TestAppend(t *testing.T) {
|
||||
testUnalignedAndGeneric(t, func(impl string) {
|
||||
d := New224()
|
||||
|
||||
for capacity := 2; capacity <= 66; capacity += 64 {
|
||||
// The first time around the loop, Sum will have to reallocate.
|
||||
// The second time, it will not.
|
||||
buf := make([]byte, 2, capacity)
|
||||
d.Reset()
|
||||
d.Write([]byte{0xcc})
|
||||
buf = d.Sum(buf)
|
||||
expected := "0000DF70ADC49B2E76EEE3A6931B93FA41841C3AF2CDF5B32A18B5478C39"
|
||||
if got := strings.ToUpper(hex.EncodeToString(buf)); got != expected {
|
||||
t.Errorf("got %s, want %s", got, expected)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TestAppendNoRealloc tests that appending works when no reallocation is necessary.
|
||||
func TestAppendNoRealloc(t *testing.T) {
|
||||
testUnalignedAndGeneric(t, func(impl string) {
|
||||
buf := make([]byte, 1, 200)
|
||||
d := New224()
|
||||
d.Write([]byte{0xcc})
|
||||
buf = d.Sum(buf)
|
||||
expected := "00DF70ADC49B2E76EEE3A6931B93FA41841C3AF2CDF5B32A18B5478C39"
|
||||
if got := strings.ToUpper(hex.EncodeToString(buf)); got != expected {
|
||||
t.Errorf("%s: got %s, want %s", impl, got, expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TestSqueezing checks that squeezing the full output a single time produces
|
||||
// the same output as repeatedly squeezing the instance.
|
||||
func TestSqueezing(t *testing.T) {
|
||||
testUnalignedAndGeneric(t, func(impl string) {
|
||||
for functionName, newShakeHash := range testShakes {
|
||||
d0 := newShakeHash()
|
||||
d0.Write([]byte(testString))
|
||||
ref := make([]byte, 32)
|
||||
d0.Read(ref)
|
||||
|
||||
d1 := newShakeHash()
|
||||
d1.Write([]byte(testString))
|
||||
var multiple []byte
|
||||
for _ = range ref {
|
||||
one := make([]byte, 1)
|
||||
d1.Read(one)
|
||||
multiple = append(multiple, one...)
|
||||
}
|
||||
if !bytes.Equal(ref, multiple) {
|
||||
t.Errorf("%s (%s): squeezing %d bytes one at a time failed", functionName, impl, len(ref))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// sequentialBytes produces a buffer of size consecutive bytes 0x00, 0x01, ..., used for testing.
|
||||
func sequentialBytes(size int) []byte {
|
||||
result := make([]byte, size)
|
||||
for i := range result {
|
||||
result[i] = byte(i)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// BenchmarkPermutationFunction measures the speed of the permutation function
|
||||
// with no input data.
|
||||
func BenchmarkPermutationFunction(b *testing.B) {
|
||||
b.SetBytes(int64(200))
|
||||
var lanes [25]uint64
|
||||
for i := 0; i < b.N; i++ {
|
||||
keccakF1600(&lanes)
|
||||
}
|
||||
}
|
||||
|
||||
// benchmarkHash tests the speed to hash num buffers of buflen each.
|
||||
func benchmarkHash(b *testing.B, h hash.Hash, size, num int) {
|
||||
b.StopTimer()
|
||||
h.Reset()
|
||||
data := sequentialBytes(size)
|
||||
b.SetBytes(int64(size * num))
|
||||
b.StartTimer()
|
||||
|
||||
var state []byte
|
||||
for i := 0; i < b.N; i++ {
|
||||
for j := 0; j < num; j++ {
|
||||
h.Write(data)
|
||||
}
|
||||
state = h.Sum(state[:0])
|
||||
}
|
||||
b.StopTimer()
|
||||
h.Reset()
|
||||
}
|
||||
|
||||
// benchmarkShake is specialized to the Shake instances, which don't
|
||||
// require a copy on reading output.
|
||||
func benchmarkShake(b *testing.B, h ShakeHash, size, num int) {
|
||||
b.StopTimer()
|
||||
h.Reset()
|
||||
data := sequentialBytes(size)
|
||||
d := make([]byte, 32)
|
||||
|
||||
b.SetBytes(int64(size * num))
|
||||
b.StartTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
h.Reset()
|
||||
for j := 0; j < num; j++ {
|
||||
h.Write(data)
|
||||
}
|
||||
h.Read(d)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSha3_512_MTU(b *testing.B) { benchmarkHash(b, New512(), 1350, 1) }
|
||||
func BenchmarkSha3_384_MTU(b *testing.B) { benchmarkHash(b, New384(), 1350, 1) }
|
||||
func BenchmarkSha3_256_MTU(b *testing.B) { benchmarkHash(b, New256(), 1350, 1) }
|
||||
func BenchmarkSha3_224_MTU(b *testing.B) { benchmarkHash(b, New224(), 1350, 1) }
|
||||
|
||||
func BenchmarkShake128_MTU(b *testing.B) { benchmarkShake(b, NewShake128(), 1350, 1) }
|
||||
func BenchmarkShake256_MTU(b *testing.B) { benchmarkShake(b, NewShake256(), 1350, 1) }
|
||||
func BenchmarkShake256_16x(b *testing.B) { benchmarkShake(b, NewShake256(), 16, 1024) }
|
||||
func BenchmarkShake256_1MiB(b *testing.B) { benchmarkShake(b, NewShake256(), 1024, 1024) }
|
||||
|
||||
func BenchmarkSha3_512_1MiB(b *testing.B) { benchmarkHash(b, New512(), 1024, 1024) }
|
||||
|
||||
func Example_sum() {
|
||||
buf := []byte("some data to hash")
|
||||
// A hash needs to be 64 bytes long to have 256-bit collision resistance.
|
||||
h := make([]byte, 64)
|
||||
// Compute a 64-byte hash of buf and put it in h.
|
||||
ShakeSum256(h, buf)
|
||||
}
|
||||
|
||||
func Example_mac() {
|
||||
k := []byte("this is a secret key; you should generate a strong random key that's at least 32 bytes long")
|
||||
buf := []byte("and this is some data to authenticate")
|
||||
// A MAC with 32 bytes of output has 256-bit security strength -- if you use at least a 32-byte-long key.
|
||||
h := make([]byte, 32)
|
||||
d := NewShake256()
|
||||
// Write the key into the hash.
|
||||
d.Write(k)
|
||||
// Now write the data.
|
||||
d.Write(buf)
|
||||
// Read 32 bytes of output from the hash into h.
|
||||
d.Read(h)
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sha3
|
||||
|
||||
// This file defines the ShakeHash interface, and provides
|
||||
// functions for creating SHAKE instances, as well as utility
|
||||
// functions for hashing bytes to arbitrary-length output.
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
// ShakeHash defines the interface to hash functions that
|
||||
// support arbitrary-length output.
|
||||
type ShakeHash interface {
|
||||
// Write absorbs more data into the hash's state. It panics if input is
|
||||
// written to it after output has been read from it.
|
||||
io.Writer
|
||||
|
||||
// Read reads more output from the hash; reading affects the hash's
|
||||
// state. (ShakeHash.Read is thus very different from Hash.Sum)
|
||||
// It never returns an error.
|
||||
io.Reader
|
||||
|
||||
// Clone returns a copy of the ShakeHash in its current state.
|
||||
Clone() ShakeHash
|
||||
|
||||
// Reset resets the ShakeHash to its initial state.
|
||||
Reset()
|
||||
}
|
||||
|
||||
func (d *state) Clone() ShakeHash {
|
||||
return d.clone()
|
||||
}
|
||||
|
||||
// NewShake128 creates a new SHAKE128 variable-output-length ShakeHash.
|
||||
// Its generic security strength is 128 bits against all attacks if at
|
||||
// least 32 bytes of its output are used.
|
||||
func NewShake128() ShakeHash { return &state{rate: 168, dsbyte: 0x1f} }
|
||||
|
||||
// NewShake256 creates a new SHAKE128 variable-output-length ShakeHash.
|
||||
// Its generic security strength is 256 bits against all attacks if
|
||||
// at least 64 bytes of its output are used.
|
||||
func NewShake256() ShakeHash { return &state{rate: 136, dsbyte: 0x1f} }
|
||||
|
||||
// ShakeSum128 writes an arbitrary-length digest of data into hash.
|
||||
func ShakeSum128(hash, data []byte) {
|
||||
h := NewShake128()
|
||||
h.Write(data)
|
||||
h.Read(hash)
|
||||
}
|
||||
|
||||
// ShakeSum256 writes an arbitrary-length digest of data into hash.
|
||||
func ShakeSum256(hash, data []byte) {
|
||||
h := NewShake256()
|
||||
h.Write(data)
|
||||
h.Read(hash)
|
||||
}
|
||||
Binary file not shown.
@@ -1,16 +0,0 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !amd64,!386 appengine
|
||||
|
||||
package sha3
|
||||
|
||||
var (
|
||||
xorIn = xorInGeneric
|
||||
copyOut = copyOutGeneric
|
||||
xorInUnaligned = xorInGeneric
|
||||
copyOutUnaligned = copyOutGeneric
|
||||
)
|
||||
|
||||
const xorImplementationUnaligned = "generic"
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sha3
|
||||
|
||||
import "encoding/binary"
|
||||
|
||||
// xorInGeneric xors the bytes in buf into the state; it
|
||||
// makes no non-portable assumptions about memory layout
|
||||
// or alignment.
|
||||
func xorInGeneric(d *state, buf []byte) {
|
||||
n := len(buf) / 8
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
a := binary.LittleEndian.Uint64(buf)
|
||||
d.a[i] ^= a
|
||||
buf = buf[8:]
|
||||
}
|
||||
}
|
||||
|
||||
// copyOutGeneric copies ulint64s to a byte buffer.
|
||||
func copyOutGeneric(d *state, b []byte) {
|
||||
for i := 0; len(b) >= 8; i++ {
|
||||
binary.LittleEndian.PutUint64(b, d.a[i])
|
||||
b = b[8:]
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build amd64 386
|
||||
// +build !appengine
|
||||
|
||||
package sha3
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func xorInUnaligned(d *state, buf []byte) {
|
||||
bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))
|
||||
n := len(buf)
|
||||
if n >= 72 {
|
||||
d.a[0] ^= bw[0]
|
||||
d.a[1] ^= bw[1]
|
||||
d.a[2] ^= bw[2]
|
||||
d.a[3] ^= bw[3]
|
||||
d.a[4] ^= bw[4]
|
||||
d.a[5] ^= bw[5]
|
||||
d.a[6] ^= bw[6]
|
||||
d.a[7] ^= bw[7]
|
||||
d.a[8] ^= bw[8]
|
||||
}
|
||||
if n >= 104 {
|
||||
d.a[9] ^= bw[9]
|
||||
d.a[10] ^= bw[10]
|
||||
d.a[11] ^= bw[11]
|
||||
d.a[12] ^= bw[12]
|
||||
}
|
||||
if n >= 136 {
|
||||
d.a[13] ^= bw[13]
|
||||
d.a[14] ^= bw[14]
|
||||
d.a[15] ^= bw[15]
|
||||
d.a[16] ^= bw[16]
|
||||
}
|
||||
if n >= 144 {
|
||||
d.a[17] ^= bw[17]
|
||||
}
|
||||
if n >= 168 {
|
||||
d.a[18] ^= bw[18]
|
||||
d.a[19] ^= bw[19]
|
||||
d.a[20] ^= bw[20]
|
||||
}
|
||||
}
|
||||
|
||||
func copyOutUnaligned(d *state, buf []byte) {
|
||||
ab := (*[maxRate]uint8)(unsafe.Pointer(&d.a[0]))
|
||||
copy(buf, ab[:])
|
||||
}
|
||||
|
||||
var (
|
||||
xorIn = xorInUnaligned
|
||||
copyOut = copyOutUnaligned
|
||||
)
|
||||
|
||||
const xorImplementationUnaligned = "unaligned"
|
||||
@@ -1 +0,0 @@
|
||||
1.0.0: QmVdADza4QFVAR9xqAxRQjt9vTZJ6UrVLgBstKua1Xg7he
|
||||
@@ -1,11 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.3
|
||||
- release
|
||||
- tip
|
||||
|
||||
script:
|
||||
- make test
|
||||
|
||||
env: TEST_VERBOSE=1
|
||||
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Juan Batiz-Benet
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -1,11 +0,0 @@
|
||||
test: go_test other_tests
|
||||
|
||||
other_tests:
|
||||
cd test && make test
|
||||
|
||||
go_test: go_deps
|
||||
go test -race -cpu=5 -v ./...
|
||||
|
||||
go_deps:
|
||||
go get golang.org/x/crypto/sha3
|
||||
go get github.com/jbenet/go-base58
|
||||
@@ -1,45 +0,0 @@
|
||||
# go-multihash
|
||||
|
||||

|
||||
|
||||
[multihash](//github.com/jbenet/multihash) implementation in Go.
|
||||
|
||||
## Example
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/jbenet/go-multihash"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// ignores errors for simplicity.
|
||||
// don't do that at home.
|
||||
|
||||
buf, _ := hex.DecodeString("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33")
|
||||
mhbuf, _ := multihash.EncodeName(buf, "sha1");
|
||||
mhhex := hex.EncodeToString(mhbuf)
|
||||
fmt.Printf("hex: %v\n", mhhex);
|
||||
|
||||
o, _ := multihash.Decode(mhbuf);
|
||||
mhhex = hex.EncodeToString(o.Digest);
|
||||
fmt.Printf("obj: %v 0x%x %d %s\n", o.Name, o.Code, o.Length, mhhex);
|
||||
}
|
||||
```
|
||||
|
||||
Run [test/foo.go](test/foo.go)
|
||||
|
||||
```
|
||||
> cd test/
|
||||
> go build
|
||||
> ./test
|
||||
hex: 11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33
|
||||
obj: sha1 0x11 20 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
@@ -1,79 +0,0 @@
|
||||
package multihash
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Reader is an io.Reader wrapper that exposes a function
|
||||
// to read a whole multihash, parse it, and return it.
|
||||
type Reader interface {
|
||||
io.Reader
|
||||
|
||||
ReadMultihash() (Multihash, error)
|
||||
}
|
||||
|
||||
// Writer is an io.Writer wrapper that exposes a function
|
||||
// to write a whole multihash.
|
||||
type Writer interface {
|
||||
io.Writer
|
||||
|
||||
WriteMultihash(Multihash) error
|
||||
}
|
||||
|
||||
// NewReader wraps an io.Reader with a multihash.Reader
|
||||
func NewReader(r io.Reader) Reader {
|
||||
return &mhReader{r}
|
||||
}
|
||||
|
||||
// NewWriter wraps an io.Writer with a multihash.Writer
|
||||
func NewWriter(w io.Writer) Writer {
|
||||
return &mhWriter{w}
|
||||
}
|
||||
|
||||
type mhReader struct {
|
||||
r io.Reader
|
||||
}
|
||||
|
||||
func (r *mhReader) Read(buf []byte) (n int, err error) {
|
||||
return r.r.Read(buf)
|
||||
}
|
||||
|
||||
func (r *mhReader) ReadMultihash() (Multihash, error) {
|
||||
mhhdr := make([]byte, 2)
|
||||
if _, err := io.ReadFull(r.r, mhhdr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// first byte is the algo, the second is the length.
|
||||
|
||||
// (varints someday...)
|
||||
length := uint(mhhdr[1])
|
||||
|
||||
if length > 127 {
|
||||
return nil, fmt.Errorf("varints not yet supported (length is %d)", length)
|
||||
}
|
||||
|
||||
buf := make([]byte, length+2)
|
||||
buf[0] = mhhdr[0]
|
||||
buf[1] = mhhdr[1]
|
||||
|
||||
if _, err := io.ReadFull(r.r, buf[2:]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return Cast(buf)
|
||||
}
|
||||
|
||||
type mhWriter struct {
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
func (w *mhWriter) Write(buf []byte) (n int, err error) {
|
||||
return w.w.Write(buf)
|
||||
}
|
||||
|
||||
func (w *mhWriter) WriteMultihash(m Multihash) error {
|
||||
_, err := w.w.Write([]byte(m))
|
||||
return err
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
package multihash
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestReader(t *testing.T) {
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
for _, tc := range testCases {
|
||||
m, err := tc.Multihash()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
buf.Write([]byte(m))
|
||||
}
|
||||
|
||||
r := NewReader(&buf)
|
||||
|
||||
for _, tc := range testCases {
|
||||
h, err := tc.Multihash()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
h2, err := r.ReadMultihash()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !bytes.Equal(h, h2) {
|
||||
t.Error("h and h2 should be equal")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriter(t *testing.T) {
|
||||
|
||||
var buf bytes.Buffer
|
||||
w := NewWriter(&buf)
|
||||
|
||||
for _, tc := range testCases {
|
||||
m, err := tc.Multihash()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := w.WriteMultihash(m); err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
buf2 := make([]byte, len(m))
|
||||
if _, err := io.ReadFull(&buf, buf2); err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !bytes.Equal(m, buf2) {
|
||||
t.Error("m and buf2 should be equal")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,188 +0,0 @@
|
||||
package multihash
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
b58 "QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58"
|
||||
)
|
||||
|
||||
// errors
|
||||
var (
|
||||
ErrUnknownCode = errors.New("unknown multihash code")
|
||||
ErrTooShort = errors.New("multihash too short. must be > 3 bytes")
|
||||
ErrTooLong = errors.New("multihash too long. must be < 129 bytes")
|
||||
ErrLenNotSupported = errors.New("multihash does not yet support digests longer than 127 bytes")
|
||||
)
|
||||
|
||||
// ErrInconsistentLen is returned when a decoded multihash has an inconsistent length
|
||||
type ErrInconsistentLen struct {
|
||||
dm *DecodedMultihash
|
||||
}
|
||||
|
||||
func (e ErrInconsistentLen) Error() string {
|
||||
return fmt.Sprintf("multihash length inconsistent: %v", e.dm)
|
||||
}
|
||||
|
||||
// constants
|
||||
const (
|
||||
SHA1 = 0x11
|
||||
SHA2_256 = 0x12
|
||||
SHA2_512 = 0x13
|
||||
SHA3 = 0x14
|
||||
BLAKE2B = 0x40
|
||||
BLAKE2S = 0x41
|
||||
)
|
||||
|
||||
// Names maps the name of a hash to the code
|
||||
var Names = map[string]int{
|
||||
"sha1": SHA1,
|
||||
"sha2-256": SHA2_256,
|
||||
"sha2-512": SHA2_512,
|
||||
"sha3": SHA3,
|
||||
"blake2b": BLAKE2B,
|
||||
"blake2s": BLAKE2S,
|
||||
}
|
||||
|
||||
// Codes maps a hash code to it's name
|
||||
var Codes = map[int]string{
|
||||
SHA1: "sha1",
|
||||
SHA2_256: "sha2-256",
|
||||
SHA2_512: "sha2-512",
|
||||
SHA3: "sha3",
|
||||
BLAKE2B: "blake2b",
|
||||
BLAKE2S: "blake2s",
|
||||
}
|
||||
|
||||
// DefaultLengths maps a hash code to it's default length
|
||||
var DefaultLengths = map[int]int{
|
||||
SHA1: 20,
|
||||
SHA2_256: 32,
|
||||
SHA2_512: 64,
|
||||
SHA3: 64,
|
||||
BLAKE2B: 64,
|
||||
BLAKE2S: 32,
|
||||
}
|
||||
|
||||
type DecodedMultihash struct {
|
||||
Code int
|
||||
Name string
|
||||
Length int
|
||||
Digest []byte
|
||||
}
|
||||
|
||||
type Multihash []byte
|
||||
|
||||
func (m *Multihash) HexString() string {
|
||||
return hex.EncodeToString([]byte(*m))
|
||||
}
|
||||
|
||||
func (m *Multihash) String() string {
|
||||
return m.HexString()
|
||||
}
|
||||
|
||||
func FromHexString(s string) (Multihash, error) {
|
||||
b, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
return Multihash{}, err
|
||||
}
|
||||
|
||||
return Cast(b)
|
||||
}
|
||||
|
||||
func (m Multihash) B58String() string {
|
||||
return b58.Encode([]byte(m))
|
||||
}
|
||||
|
||||
func FromB58String(s string) (m Multihash, err error) {
|
||||
// panic handler, in case we try accessing bytes incorrectly.
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
m = Multihash{}
|
||||
err = e.(error)
|
||||
}
|
||||
}()
|
||||
|
||||
//b58 smells like it can panic...
|
||||
b := b58.Decode(s)
|
||||
return Cast(b)
|
||||
}
|
||||
|
||||
func Cast(buf []byte) (Multihash, error) {
|
||||
dm, err := Decode(buf)
|
||||
if err != nil {
|
||||
return Multihash{}, err
|
||||
}
|
||||
|
||||
if !ValidCode(dm.Code) {
|
||||
return Multihash{}, ErrUnknownCode
|
||||
}
|
||||
|
||||
return Multihash(buf), nil
|
||||
}
|
||||
|
||||
// Decode a hash from the given Multihash.
|
||||
func Decode(buf []byte) (*DecodedMultihash, error) {
|
||||
|
||||
if len(buf) < 3 {
|
||||
return nil, ErrTooShort
|
||||
}
|
||||
|
||||
if len(buf) > 129 {
|
||||
return nil, ErrTooLong
|
||||
}
|
||||
|
||||
dm := &DecodedMultihash{
|
||||
Code: int(uint8(buf[0])),
|
||||
Name: Codes[int(uint8(buf[0]))],
|
||||
Length: int(uint8(buf[1])),
|
||||
Digest: buf[2:],
|
||||
}
|
||||
|
||||
if len(dm.Digest) != dm.Length {
|
||||
return nil, ErrInconsistentLen{dm}
|
||||
}
|
||||
|
||||
return dm, nil
|
||||
}
|
||||
|
||||
// Encode a hash digest along with the specified function code.
|
||||
// Note: the length is derived from the length of the digest itself.
|
||||
func Encode(buf []byte, code int) ([]byte, error) {
|
||||
|
||||
if !ValidCode(code) {
|
||||
return nil, ErrUnknownCode
|
||||
}
|
||||
|
||||
if len(buf) > 127 {
|
||||
return nil, ErrLenNotSupported
|
||||
}
|
||||
|
||||
pre := make([]byte, 2)
|
||||
pre[0] = byte(uint8(code))
|
||||
pre[1] = byte(uint8(len(buf)))
|
||||
return append(pre, buf...), nil
|
||||
}
|
||||
|
||||
func EncodeName(buf []byte, name string) ([]byte, error) {
|
||||
return Encode(buf, Names[name])
|
||||
}
|
||||
|
||||
// ValidCode checks whether a multihash code is valid.
|
||||
func ValidCode(code int) bool {
|
||||
if AppCode(code) {
|
||||
return true
|
||||
}
|
||||
|
||||
if _, ok := Codes[code]; ok {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// AppCode checks whether a multihash code is part of the App range.
|
||||
func AppCode(code int) bool {
|
||||
return code >= 0 && code < 0x10
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
multihash
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
artifacts:
|
||||
- LICENSE
|
||||
- README.md
|
||||
- install.dist.sh
|
||||
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Juan Batiz-Benet
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -1,118 +0,0 @@
|
||||
# multihash tool
|
||||
|
||||
The `multihash` tool uses `go-multihash` to hash things much like `shasum`.
|
||||
|
||||
Warning: this is a **multihash** tool! Its digests follow the [multihash](https://github.com/jbenet/multihash) format.
|
||||
|
||||
### Install
|
||||
|
||||
- From Source:
|
||||
```
|
||||
go get github.com/jbenet/go-multihash/multihash
|
||||
```
|
||||
- Precompiled Binaries: https://gobuilder.me/github.com/jbenet/go-multihash/multihash
|
||||
|
||||
### Usage
|
||||
|
||||
```sh
|
||||
> multihash -h
|
||||
usage: ./multihash [options] [FILE]
|
||||
Print or check multihash checksums.
|
||||
With no FILE, or when FILE is -, read standard input.
|
||||
|
||||
Options:
|
||||
-a="sha2-256": one of: sha1, sha2-256, sha2-512, sha3 (shorthand)
|
||||
-algorithm="sha2-256": one of: sha1, sha2-256, sha2-512, sha3
|
||||
-c="": check checksum matches (shorthand)
|
||||
-check="": check checksum matches
|
||||
-e="base58": one of: raw, hex, base58, base64 (shorthand)
|
||||
-encoding="base58": one of: raw, hex, base58, base64
|
||||
-l=-1: checksums length in bits (truncate). -1 is default (shorthand)
|
||||
-length=-1: checksums length in bits (truncate). -1 is default
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
#### Input
|
||||
|
||||
```sh
|
||||
# from stdin
|
||||
> multihash < main.go
|
||||
QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8
|
||||
|
||||
# from file
|
||||
> ./multihash main.go
|
||||
QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8
|
||||
|
||||
# from stdin "filename"
|
||||
> multihash - < main.go
|
||||
QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8
|
||||
```
|
||||
|
||||
#### Algorithms
|
||||
|
||||
```sh
|
||||
> multihash -a ?
|
||||
error: algorithm '?' not one of: sha1, sha2-256, sha2-512, sha3
|
||||
|
||||
> multihash -a sha1 < main.go
|
||||
5drkbcqJUo6fZVvcZJeVEVWAgndvLm
|
||||
|
||||
> multihash -a sha2-256 < main.go
|
||||
QmcK3s36goo9v2HYcfTrDKKwxaxmJJ59etodQQFYsL5T5N
|
||||
|
||||
> multihash -a sha2-512 < main.go
|
||||
8VuDcW4CooyPQA8Cc4eYpwjhyDJZqu5m5ZMDFzWULYsVS8d119JaGeNWsZbZ2ZG2kPtbrMx31MidokCigaD65yUPAs
|
||||
|
||||
> multihash -a sha3 < main.go
|
||||
8tWDCTfAX24DYmzNixTj2ARJkqwRG736VHx5aJppmqRjhW9QT1EuTgKUmu9Pmunzq292jzPKxb2VxSsTXmjFY1HD3B
|
||||
```
|
||||
|
||||
#### Encodings
|
||||
|
||||
```sh
|
||||
> multihash -e raw < main.go
|
||||
Ϛ<><CF9A><EFBFBD><EFBFBD><EFBFBD>I<EFBFBD>5 S<><53>WG><3E><><EFBFBD>_<EFBFBD><5F>]g<><67><EFBFBD><EFBFBD><EFBFBD>u
|
||||
|
||||
> multihash -e hex < main.go
|
||||
1220cf9aa2b8a38b9b49d135095390059a57473e97aceb5fcae25d67a8b6feb58275
|
||||
|
||||
> multihash -e base64 < main.go
|
||||
EiDPmqK4o4ubSdE1CVOQBZpXRz6XrOtfyuJdZ6i2/rWCdQ==
|
||||
|
||||
> multihash -e base58 < main.go
|
||||
Qmf1QjEXDmqBm7RqHKqFGNUyhzUjnX7cmgKMrGzzPceZDQ
|
||||
```
|
||||
|
||||
#### Digest Length
|
||||
|
||||
```sh
|
||||
# we're outputing hex (good byte alignment) to show the codes changing
|
||||
# notice the multihash code (first 2 chars) differs!
|
||||
> multihash -e hex -a sha2-256 -l 256 < main.go
|
||||
1220cf9aa2b8a38b9b49d135095390059a57473e97aceb5fcae25d67a8b6feb58275
|
||||
> multihash -e hex -a sha2-512 -l 256 < main.go
|
||||
132047a4b6c629f5545f529b0ff461dc09119969f3593186277a1cc7a8ea3560a6f1
|
||||
> multihash -e hex -a sha3 -l 256 < main.go
|
||||
14206b9222a1a47939e665261bd2b5573e55e7988675223adde73c1011066ad66335
|
||||
|
||||
# notice the multihash length (next 2 chars) differs!
|
||||
> multihash -e hex -a sha2-256 -l 256 < main.go
|
||||
1220cf9aa2b8a38b9b49d135095390059a57473e97aceb5fcae25d67a8b6feb58275
|
||||
> multihash -e hex -a sha2-256 -l 200 < main.go
|
||||
1219cf9aa2b8a38b9b49d135095390059a57473e97aceb5fcae25d
|
||||
```
|
||||
|
||||
#### Verify Checksum
|
||||
|
||||
```sh
|
||||
> multihash -c QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8 < main.go
|
||||
OK checksums match (-q for no output)
|
||||
|
||||
> multihash -c QmcKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa < main.go
|
||||
error: computed checksum did not match (-q for no output)
|
||||
|
||||
# works with other arguments too
|
||||
> multihash -e hex -l 128 -c "12102ffc284a1e82bf51e567c75b2ae6edb9" < main.go
|
||||
OK checksums match (-q for no output)
|
||||
```
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
bin=multihash
|
||||
|
||||
# this script is currently brain dead.
|
||||
# it merely tries two locations.
|
||||
# in the future maybe use value of $PATH.
|
||||
|
||||
binpath=/usr/local/bin
|
||||
if [ -d "$binpath" ]; then
|
||||
mv "$bin" "$binpath/$bin"
|
||||
echo "installed $binpath/$bin"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
binpath=/usr/bin
|
||||
if [ -d "$binpath" ]; then
|
||||
mv "$bin" "$binpath/$bin"
|
||||
echo "installed $binpath/$bin"
|
||||
exit 0
|
||||
fi
|
||||
@@ -1,132 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
mh "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash"
|
||||
mhopts "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/opts"
|
||||
)
|
||||
|
||||
var usage = `usage: %s [options] [FILE]
|
||||
Print or check multihash checksums.
|
||||
With no FILE, or when FILE is -, read standard input.
|
||||
|
||||
Options:
|
||||
`
|
||||
|
||||
// flags
|
||||
var opts *mhopts.Options
|
||||
var checkRaw string
|
||||
var checkMh mh.Multihash
|
||||
var inputFilename string
|
||||
var quiet bool
|
||||
|
||||
func init() {
|
||||
flag.Usage = func() {
|
||||
fmt.Fprintf(os.Stderr, usage, os.Args[0])
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
|
||||
opts = mhopts.SetupFlags(flag.CommandLine)
|
||||
|
||||
checkStr := "check checksum matches"
|
||||
flag.StringVar(&checkRaw, "check", "", checkStr)
|
||||
flag.StringVar(&checkRaw, "c", "", checkStr+" (shorthand)")
|
||||
|
||||
quietStr := "quiet output (no newline on checksum, no error text)"
|
||||
flag.BoolVar(&quiet, "quiet", false, quietStr)
|
||||
flag.BoolVar(&quiet, "q", false, quietStr+" (shorthand)")
|
||||
}
|
||||
|
||||
func parseFlags(o *mhopts.Options) error {
|
||||
flag.Parse()
|
||||
if err := o.ParseError(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if checkRaw != "" {
|
||||
var err error
|
||||
checkMh, err = mhopts.Decode(o.Encoding, checkRaw)
|
||||
if err != nil {
|
||||
return fmt.Errorf("fail to decode check '%s': %s", checkRaw, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getInput() (io.ReadCloser, error) {
|
||||
args := flag.Args()
|
||||
|
||||
switch {
|
||||
case len(args) < 1:
|
||||
inputFilename = "-"
|
||||
return os.Stdin, nil
|
||||
case args[0] == "-":
|
||||
inputFilename = "-"
|
||||
return os.Stdin, nil
|
||||
default:
|
||||
inputFilename = args[0]
|
||||
f, err := os.Open(args[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open '%s': %s", args[0], err)
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
}
|
||||
func printHash(o *mhopts.Options, r io.Reader) error {
|
||||
h, err := o.Multihash(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s, err := mhopts.Encode(o.Encoding, h)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if quiet {
|
||||
fmt.Print(s)
|
||||
} else {
|
||||
fmt.Println(s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
checkErr := func(err error) {
|
||||
if err != nil {
|
||||
die("error: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
err := parseFlags(opts)
|
||||
checkErr(err)
|
||||
|
||||
inp, err := getInput()
|
||||
checkErr(err)
|
||||
|
||||
if checkMh != nil {
|
||||
err = opts.Check(inp, checkMh)
|
||||
checkErr(err)
|
||||
if !quiet {
|
||||
fmt.Println("OK checksums match (-q for no output)")
|
||||
}
|
||||
} else {
|
||||
err = printHash(opts, inp)
|
||||
checkErr(err)
|
||||
}
|
||||
inp.Close()
|
||||
}
|
||||
|
||||
func die(v ...interface{}) {
|
||||
if !quiet {
|
||||
fmt.Fprint(os.Stderr, v...)
|
||||
fmt.Fprint(os.Stderr, "\n")
|
||||
}
|
||||
// flag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
@@ -1,270 +0,0 @@
|
||||
package multihash
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// maybe silly, but makes it so changing
|
||||
// the table accidentally has to happen twice.
|
||||
var tCodes = map[int]string{
|
||||
0x11: "sha1",
|
||||
0x12: "sha2-256",
|
||||
0x13: "sha2-512",
|
||||
0x14: "sha3",
|
||||
0x40: "blake2b",
|
||||
0x41: "blake2s",
|
||||
}
|
||||
|
||||
type TestCase struct {
|
||||
hex string
|
||||
code int
|
||||
name string
|
||||
}
|
||||
|
||||
var testCases = []TestCase{
|
||||
TestCase{"0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33", 0x11, "sha1"},
|
||||
TestCase{"0beec7b5", 0x11, "sha1"},
|
||||
TestCase{"2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae", 0x12, "sha2-256"},
|
||||
TestCase{"2c26b46b", 0x12, "sha2-256"},
|
||||
TestCase{"0beec7b5ea3f0fdbc9", 0x40, "blake2b"},
|
||||
}
|
||||
|
||||
func (tc TestCase) Multihash() (Multihash, error) {
|
||||
ob, err := hex.DecodeString(tc.hex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b := make([]byte, 2+len(ob))
|
||||
b[0] = byte(uint8(tc.code))
|
||||
b[1] = byte(uint8(len(ob)))
|
||||
copy(b[2:], ob)
|
||||
return Cast(b)
|
||||
}
|
||||
|
||||
func TestEncode(t *testing.T) {
|
||||
for _, tc := range testCases {
|
||||
ob, err := hex.DecodeString(tc.hex)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
pre := make([]byte, 2)
|
||||
pre[0] = byte(uint8(tc.code))
|
||||
pre[1] = byte(uint8(len(ob)))
|
||||
nb := append(pre, ob...)
|
||||
|
||||
encC, err := Encode(ob, tc.code)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !bytes.Equal(encC, nb) {
|
||||
t.Error("encoded byte mismatch: ", encC, nb)
|
||||
}
|
||||
|
||||
encN, err := EncodeName(ob, tc.name)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !bytes.Equal(encN, nb) {
|
||||
t.Error("encoded byte mismatch: ", encN, nb)
|
||||
}
|
||||
|
||||
h, err := tc.Multihash()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !bytes.Equal(h, nb) {
|
||||
t.Error("Multihash func mismatch.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleEncodeName() {
|
||||
// ignores errors for simplicity - don't do that at home.
|
||||
buf, _ := hex.DecodeString("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33")
|
||||
mhbuf, _ := EncodeName(buf, "sha1")
|
||||
mhhex := hex.EncodeToString(mhbuf)
|
||||
fmt.Printf("hex: %v\n", mhhex)
|
||||
|
||||
// Output:
|
||||
// hex: 11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33
|
||||
}
|
||||
|
||||
func TestDecode(t *testing.T) {
|
||||
for _, tc := range testCases {
|
||||
ob, err := hex.DecodeString(tc.hex)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
pre := make([]byte, 2)
|
||||
pre[0] = byte(uint8(tc.code))
|
||||
pre[1] = byte(uint8(len(ob)))
|
||||
nb := append(pre, ob...)
|
||||
|
||||
dec, err := Decode(nb)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if dec.Code != tc.code {
|
||||
t.Error("decoded code mismatch: ", dec.Code, tc.code)
|
||||
}
|
||||
|
||||
if dec.Name != tc.name {
|
||||
t.Error("decoded name mismatch: ", dec.Name, tc.name)
|
||||
}
|
||||
|
||||
if dec.Length != len(ob) {
|
||||
t.Error("decoded length mismatch: ", dec.Length, len(ob))
|
||||
}
|
||||
|
||||
if !bytes.Equal(dec.Digest, ob) {
|
||||
t.Error("decoded byte mismatch: ", dec.Digest, ob)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTable(t *testing.T) {
|
||||
for k, v := range tCodes {
|
||||
if Codes[k] != v {
|
||||
t.Error("Table mismatch: ", Codes[k], v)
|
||||
}
|
||||
if Names[v] != k {
|
||||
t.Error("Table mismatch: ", Names[v], k)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleDecode() {
|
||||
// ignores errors for simplicity - don't do that at home.
|
||||
buf, _ := hex.DecodeString("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33")
|
||||
mhbuf, _ := EncodeName(buf, "sha1")
|
||||
o, _ := Decode(mhbuf)
|
||||
mhhex := hex.EncodeToString(o.Digest)
|
||||
fmt.Printf("obj: %v 0x%x %d %s\n", o.Name, o.Code, o.Length, mhhex)
|
||||
|
||||
// Output:
|
||||
// obj: sha1 0x11 20 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33
|
||||
}
|
||||
|
||||
func TestValidCode(t *testing.T) {
|
||||
for i := 0; i < 0xff; i++ {
|
||||
_, ok := tCodes[i]
|
||||
b := AppCode(i) || ok
|
||||
|
||||
if ValidCode(i) != b {
|
||||
t.Error("ValidCode incorrect for: ", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppCode(t *testing.T) {
|
||||
for i := 0; i < 0xff; i++ {
|
||||
b := i >= 0 && i < 0x10
|
||||
if AppCode(i) != b {
|
||||
t.Error("AppCode incorrect for: ", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCast(t *testing.T) {
|
||||
for _, tc := range testCases {
|
||||
ob, err := hex.DecodeString(tc.hex)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
pre := make([]byte, 2)
|
||||
pre[0] = byte(uint8(tc.code))
|
||||
pre[1] = byte(uint8(len(ob)))
|
||||
nb := append(pre, ob...)
|
||||
|
||||
if _, err := Cast(nb); err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if _, err = Cast(ob); err == nil {
|
||||
t.Error("cast failed to detect non-multihash")
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHex(t *testing.T) {
|
||||
for _, tc := range testCases {
|
||||
ob, err := hex.DecodeString(tc.hex)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
pre := make([]byte, 2)
|
||||
pre[0] = byte(uint8(tc.code))
|
||||
pre[1] = byte(uint8(len(ob)))
|
||||
nb := append(pre, ob...)
|
||||
|
||||
hs := hex.EncodeToString(nb)
|
||||
mh, err := FromHexString(hs)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !bytes.Equal(mh, nb) {
|
||||
t.Error("FromHexString failed", nb, mh)
|
||||
continue
|
||||
}
|
||||
|
||||
if mh.HexString() != hs {
|
||||
t.Error("Multihash.HexString failed", hs, mh.HexString)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEncode(b *testing.B) {
|
||||
tc := testCases[0]
|
||||
ob, err := hex.DecodeString(tc.hex)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
Encode(ob, tc.code)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecode(b *testing.B) {
|
||||
tc := testCases[0]
|
||||
ob, err := hex.DecodeString(tc.hex)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
pre := make([]byte, 2)
|
||||
pre[0] = byte(uint8(tc.code))
|
||||
pre[1] = byte(uint8(len(ob)))
|
||||
nb := append(pre, ob...)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
Decode(nb)
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
# mhopts - multihash options for writing commands
|
||||
|
||||
`mhopts` is a small package that helps to write commands which
|
||||
may take multihash options. Check it out in action:
|
||||
|
||||
- [multihash](../multihash)
|
||||
- [hashpipe](https://github.com/jbenet/go-hashpipe)
|
||||
|
||||
Godoc: [https://godoc.org/github.com/jbenet/go-multihash/opts](https://godoc.org/github.com/jbenet/go-multihash/opts)
|
||||
@@ -1,40 +0,0 @@
|
||||
package opts
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
base58 "QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58"
|
||||
mh "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash"
|
||||
)
|
||||
|
||||
func Decode(encoding, digest string) (mh.Multihash, error) {
|
||||
switch encoding {
|
||||
case "raw":
|
||||
return mh.Cast([]byte(digest))
|
||||
case "hex":
|
||||
return hex.DecodeString(digest)
|
||||
case "base58":
|
||||
return base58.Decode(digest), nil
|
||||
case "base64":
|
||||
return base64.StdEncoding.DecodeString(digest)
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown encoding: %s", encoding)
|
||||
}
|
||||
}
|
||||
|
||||
func Encode(encoding string, hash mh.Multihash) (string, error) {
|
||||
switch encoding {
|
||||
case "raw":
|
||||
return string(hash), nil
|
||||
case "hex":
|
||||
return hex.EncodeToString(hash), nil
|
||||
case "base58":
|
||||
return base58.Encode(hash), nil
|
||||
case "base64":
|
||||
return base64.StdEncoding.EncodeToString(hash), nil
|
||||
default:
|
||||
return "", fmt.Errorf("unknown encoding: %s", encoding)
|
||||
}
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
// Package opts helps to write commands which may take multihash
|
||||
// options.
|
||||
package opts
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
mh "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash"
|
||||
)
|
||||
|
||||
// package errors
|
||||
var (
|
||||
ErrMatch = errors.New("multihash checksums did not match")
|
||||
)
|
||||
|
||||
// Options is a struct used to parse cli flags.
|
||||
type Options struct {
|
||||
Encoding string
|
||||
Algorithm string
|
||||
AlgorithmCode int
|
||||
Length int
|
||||
|
||||
fs *flag.FlagSet
|
||||
}
|
||||
|
||||
// FlagValues are the values the various option flags can take.
|
||||
var FlagValues = struct {
|
||||
Encodings []string
|
||||
Algorithms []string
|
||||
}{
|
||||
Encodings: []string{"raw", "hex", "base58", "base64"},
|
||||
Algorithms: []string{"sha1", "sha2-256", "sha2-512", "sha3"},
|
||||
}
|
||||
|
||||
// SetupFlags adds multihash related options to given flagset.
|
||||
func SetupFlags(f *flag.FlagSet) *Options {
|
||||
// TODO: add arg for adding opt prefix and/or overriding opts
|
||||
|
||||
o := new(Options)
|
||||
algoStr := "one of: " + strings.Join(FlagValues.Algorithms, ", ")
|
||||
f.StringVar(&o.Algorithm, "algorithm", "sha2-256", algoStr)
|
||||
f.StringVar(&o.Algorithm, "a", "sha2-256", algoStr+" (shorthand)")
|
||||
|
||||
encStr := "one of: " + strings.Join(FlagValues.Encodings, ", ")
|
||||
f.StringVar(&o.Encoding, "encoding", "base58", encStr)
|
||||
f.StringVar(&o.Encoding, "e", "base58", encStr+" (shorthand)")
|
||||
|
||||
lengthStr := "checksums length in bits (truncate). -1 is default"
|
||||
f.IntVar(&o.Length, "length", -1, lengthStr)
|
||||
f.IntVar(&o.Length, "l", -1, lengthStr+" (shorthand)")
|
||||
return o
|
||||
}
|
||||
|
||||
// Parse parses the values of flags from given argument slice.
|
||||
// It is equivalent to flags.Parse(args)
|
||||
func (o *Options) Parse(args []string) error {
|
||||
if err := o.fs.Parse(args); err != nil {
|
||||
return err
|
||||
}
|
||||
return o.ParseError()
|
||||
}
|
||||
|
||||
// ParseError checks the parsed options for errors.
|
||||
func (o *Options) ParseError() error {
|
||||
if !strIn(o.Encoding, FlagValues.Encodings) {
|
||||
return fmt.Errorf("encoding '%s' not %s", o.Encoding, FlagValues.Encodings)
|
||||
}
|
||||
|
||||
if !strIn(o.Algorithm, FlagValues.Algorithms) {
|
||||
return fmt.Errorf("algorithm '%s' not %s", o.Algorithm, FlagValues.Algorithms)
|
||||
}
|
||||
|
||||
var found bool
|
||||
o.AlgorithmCode, found = mh.Names[o.Algorithm]
|
||||
if !found {
|
||||
return fmt.Errorf("algorithm '%s' not found (lib error, pls report).", o.Algorithm)
|
||||
}
|
||||
|
||||
if o.Length >= 0 {
|
||||
if o.Length%8 != 0 {
|
||||
return fmt.Errorf("length must be multiple of 8")
|
||||
}
|
||||
o.Length = o.Length / 8
|
||||
|
||||
if o.Length > mh.DefaultLengths[o.AlgorithmCode] {
|
||||
o.Length = mh.DefaultLengths[o.AlgorithmCode]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// strIn checks wither string a is in set.
|
||||
func strIn(a string, set []string) bool {
|
||||
for _, s := range set {
|
||||
if s == a {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Check reads all the data in r, calculates its multihash,
|
||||
// and checks it matches h1
|
||||
func (o *Options) Check(r io.Reader, h1 mh.Multihash) error {
|
||||
h2, err := o.Multihash(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !bytes.Equal(h1, h2) {
|
||||
return fmt.Errorf("computed checksum did not match")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Multihash reads all the data in r and calculates its multihash.
|
||||
func (o *Options) Multihash(r io.Reader) (mh.Multihash, error) {
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mh.Sum(b, o.AlgorithmCode, o.Length)
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"name": "go-multihash",
|
||||
"author": "whyrusleeping",
|
||||
"version": "1.0.0",
|
||||
"gxDependencies": [
|
||||
{
|
||||
"name": "go-base58",
|
||||
"hash": "QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
"name": "crypto-sha3",
|
||||
"hash": "QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
],
|
||||
"language": "go",
|
||||
"gx": {
|
||||
"dvcsimport": "github.com/jbenet/go-multihash"
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package multihash
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
sha3 "QmY1q6BMPywiUXEKAjehsgmPaBeLHTzs3FNaptUsbmpngb/crypto-sha3"
|
||||
)
|
||||
|
||||
var ErrSumNotSupported = errors.New("Function not implemented. Complain to lib maintainer.")
|
||||
|
||||
func Sum(data []byte, code int, length int) (Multihash, error) {
|
||||
m := Multihash{}
|
||||
err := error(nil)
|
||||
if !ValidCode(code) {
|
||||
return m, fmt.Errorf("invalid multihash code %d", code)
|
||||
}
|
||||
|
||||
var d []byte
|
||||
switch code {
|
||||
case SHA1:
|
||||
d = sumSHA1(data)
|
||||
case SHA2_256:
|
||||
d = sumSHA256(data)
|
||||
case SHA2_512:
|
||||
d = sumSHA512(data)
|
||||
case SHA3:
|
||||
d, err = sumSHA3(data)
|
||||
default:
|
||||
return m, ErrSumNotSupported
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return m, err
|
||||
}
|
||||
|
||||
if length < 0 {
|
||||
var ok bool
|
||||
length, ok = DefaultLengths[code]
|
||||
if !ok {
|
||||
return m, fmt.Errorf("no default length for code %d", code)
|
||||
}
|
||||
}
|
||||
|
||||
return Encode(d[0:length], code)
|
||||
}
|
||||
|
||||
func sumSHA1(data []byte) []byte {
|
||||
a := sha1.Sum(data)
|
||||
return a[0:20]
|
||||
}
|
||||
|
||||
func sumSHA256(data []byte) []byte {
|
||||
a := sha256.Sum256(data)
|
||||
return a[0:32]
|
||||
}
|
||||
|
||||
func sumSHA512(data []byte) []byte {
|
||||
a := sha512.Sum512(data)
|
||||
return a[0:64]
|
||||
}
|
||||
|
||||
func sumSHA3(data []byte) ([]byte, error) {
|
||||
h := sha3.New512()
|
||||
if _, err := h.Write(data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return h.Sum(nil), nil
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package multihash
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type SumTestCase struct {
|
||||
code int
|
||||
length int
|
||||
input string
|
||||
hex string
|
||||
}
|
||||
|
||||
var sumTestCases = []SumTestCase{
|
||||
SumTestCase{SHA1, -1, "foo", "11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"},
|
||||
SumTestCase{SHA1, 10, "foo", "110a0beec7b5ea3f0fdbc95d"},
|
||||
SumTestCase{SHA2_256, -1, "foo", "12202c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"},
|
||||
SumTestCase{SHA2_256, 16, "foo", "12102c26b46b68ffc68ff99b453c1d304134"},
|
||||
SumTestCase{SHA2_512, -1, "foo", "1340f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7"},
|
||||
SumTestCase{SHA2_512, 32, "foo", "1320f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc663832"},
|
||||
}
|
||||
|
||||
func TestSum(t *testing.T) {
|
||||
|
||||
for _, tc := range sumTestCases {
|
||||
|
||||
m1, err := FromHexString(tc.hex)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
m2, err := Sum([]byte(tc.input), tc.code, tc.length)
|
||||
if err != nil {
|
||||
t.Error(tc.code, "sum failed.", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !bytes.Equal(m1, m2) {
|
||||
t.Error(tc.code, "sum failed.", m1, m2)
|
||||
}
|
||||
|
||||
s1 := m1.HexString()
|
||||
if s1 != tc.hex {
|
||||
t.Error("hex strings not the same")
|
||||
}
|
||||
|
||||
s2 := m1.B58String()
|
||||
m3, err := FromB58String(s2)
|
||||
if err != nil {
|
||||
t.Error("failed to decode b58")
|
||||
} else if !bytes.Equal(m3, m1) {
|
||||
t.Error("b58 failing bytes")
|
||||
} else if s2 != m3.B58String() {
|
||||
t.Error("b58 failing string")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSum(b *testing.B) {
|
||||
tc := sumTestCases[0]
|
||||
for i := 0; i < b.N; i++ {
|
||||
Sum([]byte(tc.input), tc.code, tc.length)
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
bin/multihash
|
||||
@@ -1,25 +0,0 @@
|
||||
BINS = bin/multihash
|
||||
MULTIHASH_ROOT = ../
|
||||
MULTIHASH_CMD = ../multihash
|
||||
|
||||
all: deps
|
||||
|
||||
deps: bins
|
||||
|
||||
clean:
|
||||
rm $(BINS)
|
||||
|
||||
bins: $(BINS)
|
||||
|
||||
bin/multihash: $(MULTIHASH_ROOT)/**/*.go
|
||||
go build -o bin/multihash $(MULTIHASH_CMD)
|
||||
|
||||
test: test_expensive
|
||||
|
||||
test_expensive:
|
||||
cd sharness && make TEST_EXPENSIVE=1
|
||||
|
||||
test_cheap:
|
||||
cd sharness && make
|
||||
|
||||
.PHONY: all clean
|
||||
@@ -1,3 +0,0 @@
|
||||
lib/sharness/
|
||||
test-results/
|
||||
trash directory.*.sh/
|
||||
@@ -1,37 +0,0 @@
|
||||
# Run tests
|
||||
#
|
||||
# Copyright (c) 2014 Christian Couder
|
||||
# MIT Licensed; see the LICENSE file in this repository.
|
||||
#
|
||||
|
||||
# NOTE: run with TEST_VERBOSE=1 for verbose sharness tests.
|
||||
|
||||
T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh))
|
||||
BINS = bin/multihash
|
||||
SHARNESS = lib/sharness/sharness.sh
|
||||
|
||||
all: clean deps $(T) aggregate
|
||||
|
||||
clean:
|
||||
@echo "*** $@ ***"
|
||||
-rm -rf test-results
|
||||
|
||||
$(T):
|
||||
@echo "*** $@ ***"
|
||||
./$@
|
||||
|
||||
aggregate:
|
||||
@echo "*** $@ ***"
|
||||
lib/test-aggregate-results.sh
|
||||
|
||||
deps: $(SHARNESS) $(BINS)
|
||||
|
||||
$(SHARNESS):
|
||||
@echo "*** installing $@ ***"
|
||||
lib/install-sharness.sh
|
||||
|
||||
bin/%:
|
||||
@echo "*** installing $@ ***"
|
||||
cd .. && make $@
|
||||
|
||||
.PHONY: all clean $(T) aggregate
|
||||
@@ -1,26 +0,0 @@
|
||||
#!/bin/sh
|
||||
# install sharness.sh
|
||||
#
|
||||
# Copyright (c) 2014 Juan Batiz-Benet
|
||||
# MIT Licensed; see the LICENSE file in this repository.
|
||||
#
|
||||
|
||||
# settings
|
||||
version=50229a79ba22b2f13ccd82451d86570fecbd194c
|
||||
urlprefix=https://github.com/mlafeldt/sharness.git
|
||||
clonedir=lib
|
||||
sharnessdir=sharness
|
||||
|
||||
die() {
|
||||
echo >&2 "$@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
mkdir -p "$clonedir" || die "Could not create '$clonedir' directory"
|
||||
cd "$clonedir" || die "Could not cd into '$clonedir' directory"
|
||||
|
||||
git clone "$urlprefix" || die "Could not clone '$urlprefix'"
|
||||
cd "$sharnessdir" || die "Could not cd into '$sharnessdir' directory"
|
||||
git checkout "$version" || die "Could not checkout '$version'"
|
||||
|
||||
exit 0
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Script to aggregate results using Sharness
|
||||
#
|
||||
# Copyright (c) 2014 Christian Couder
|
||||
# MIT Licensed; see the LICENSE file in this repository.
|
||||
#
|
||||
|
||||
SHARNESS_AGGREGATE="lib/sharness/aggregate-results.sh"
|
||||
|
||||
test -f "$SHARNESS_AGGREGATE" || {
|
||||
echo >&2 "Cannot find: $SHARNESS_AGGREGATE"
|
||||
echo >&2 "Please check Sharness installation."
|
||||
exit 1
|
||||
}
|
||||
|
||||
ls test-results/t*-*.sh.*.counts | "$SHARNESS_AGGREGATE"
|
||||
@@ -1,43 +0,0 @@
|
||||
# Test framework for go-ipfs
|
||||
#
|
||||
# Copyright (c) 2014 Christian Couder
|
||||
# MIT Licensed; see the LICENSE file in this repository.
|
||||
#
|
||||
# We are using sharness (https://github.com/mlafeldt/sharness)
|
||||
# which was extracted from the Git test framework.
|
||||
|
||||
# Use the multihash tool to test against
|
||||
|
||||
# Add current directory to path, for multihash tool.
|
||||
PATH=$(pwd)/bin:${PATH}
|
||||
|
||||
# Set sharness verbosity. we set the env var directly as
|
||||
# it's too late to pass in --verbose, and --verbose is harder
|
||||
# to pass through in some cases.
|
||||
test "$TEST_VERBOSE" = 1 && verbose=t
|
||||
|
||||
# assert the `multihash` we're using is the right one.
|
||||
if test `which multihash` != $(pwd)/bin/multihash; then
|
||||
echo >&2 "Cannot find the tests' local multihash tool."
|
||||
echo >&2 "Please check test and multihash tool installation."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SHARNESS_LIB="lib/sharness/sharness.sh"
|
||||
|
||||
. "$SHARNESS_LIB" || {
|
||||
echo >&2 "Cannot source: $SHARNESS_LIB"
|
||||
echo >&2 "Please check Sharness installation."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Please put go-multihash specific shell functions below
|
||||
|
||||
for hashbin in sha1sum shasum; do
|
||||
if type "$hashbin"; then
|
||||
export SHASUMBIN="$hashbin" &&
|
||||
test_set_prereq SHASUM &&
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2015 Christian Couder
|
||||
# MIT Licensed; see the LICENSE file in this repository.
|
||||
#
|
||||
|
||||
test_description="Basic tests"
|
||||
|
||||
. lib/test-lib.sh
|
||||
|
||||
test_expect_success "current dir is writable" '
|
||||
echo "It works!" >test.txt
|
||||
'
|
||||
|
||||
test_expect_success "multihash is available" '
|
||||
type multihash
|
||||
'
|
||||
|
||||
test_expect_success "multihash help output looks good" '
|
||||
test_must_fail multihash -h 2>help.txt &&
|
||||
cat help.txt | egrep -i "^usage:" >/dev/null &&
|
||||
cat help.txt | egrep -i "multihash .*options.*file" >/dev/null
|
||||
'
|
||||
|
||||
test_done
|
||||
@@ -1,31 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2015 Christian Couder
|
||||
# MIT Licensed; see the LICENSE file in this repository.
|
||||
#
|
||||
|
||||
test_description="sha1 tests"
|
||||
|
||||
. lib/test-lib.sh
|
||||
|
||||
test_expect_success "setup sha1 tests" '
|
||||
echo "Hash me!" >hash_me.txt &&
|
||||
SHA1=bc6f2c3cd945bc754789e50b2f68deee2f421810 &&
|
||||
echo "1114$SHA1" >actual
|
||||
'
|
||||
|
||||
test_expect_success "'multihash -a=sha1 -e=hex' works" '
|
||||
multihash -a=sha1 -e=hex hash_me.txt >expected
|
||||
'
|
||||
|
||||
test_expect_success "'multihash -a=sha1 -e=hex' output looks good" '
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success SHASUM "check hash using shasum" '
|
||||
echo "$SHA1 hash_me.txt" >actual &&
|
||||
$SHASUMBIN hash_me.txt >expected &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_done
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
mh "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash"
|
||||
mhopts "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash/opts"
|
||||
mh "QmdsKjp5fcCT8PZ8JBMcdFsCbbmKwSLCU5xXbsnwb5DMxy/go-multihash"
|
||||
mhopts "QmdsKjp5fcCT8PZ8JBMcdFsCbbmKwSLCU5xXbsnwb5DMxy/go-multihash/opts"
|
||||
)
|
||||
|
||||
var usage = `usage: %s [options] [FILE]
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
base58 "QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58"
|
||||
mh "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash"
|
||||
mh "QmdsKjp5fcCT8PZ8JBMcdFsCbbmKwSLCU5xXbsnwb5DMxy/go-multihash"
|
||||
)
|
||||
|
||||
func Decode(encoding, digest string) (mh.Multihash, error) {
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
mh "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash"
|
||||
mh "QmdsKjp5fcCT8PZ8JBMcdFsCbbmKwSLCU5xXbsnwb5DMxy/go-multihash"
|
||||
)
|
||||
|
||||
// package errors
|
||||
|
||||
2
vendor/util/util.go
vendored
2
vendor/util/util.go
vendored
@@ -13,7 +13,7 @@ import (
|
||||
"time"
|
||||
|
||||
b58 "QmNsoHoCVhgXcv1Yg45jtkMgimxorTAN36fV9AQMFXHHAQ/go-base58"
|
||||
mh "QmdeauTdyf38KDQB4Cc4CurPWRRb5pej27NCXPA7kbPTJy/go-multihash"
|
||||
mh "QmdsKjp5fcCT8PZ8JBMcdFsCbbmKwSLCU5xXbsnwb5DMxy/go-multihash"
|
||||
)
|
||||
|
||||
// Debug is a global flag for debugging.
|
||||
|
||||
Reference in New Issue
Block a user