mirror of https://github.com/ethereum/go-ethereum
Revision: 1f22c0103821b9390939b6776727195525381532pull/2242/head
parent
0a1da69fac
commit
e4b138a593
@ -0,0 +1,27 @@ |
||||
Copyright (c) 2009 The Go Authors. All rights reserved. |
||||
|
||||
Redistribution and use in source and binary forms, with or without |
||||
modification, are permitted provided that the following conditions are |
||||
met: |
||||
|
||||
* Redistributions of source code must retain the above copyright |
||||
notice, this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above |
||||
copyright notice, this list of conditions and the following disclaimer |
||||
in the documentation and/or other materials provided with the |
||||
distribution. |
||||
* Neither the name of Google Inc. nor the names of its |
||||
contributors may be used to endorse or promote products derived from |
||||
this software without specific prior written permission. |
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
@ -0,0 +1,22 @@ |
||||
Additional IP Rights Grant (Patents) |
||||
|
||||
"This implementation" means the copyrightable works distributed by |
||||
Google as part of the Go project. |
||||
|
||||
Google hereby grants to You a perpetual, worldwide, non-exclusive, |
||||
no-charge, royalty-free, irrevocable (except as stated in this section) |
||||
patent license to make, have made, use, offer to sell, sell, import, |
||||
transfer and otherwise run, modify and propagate the contents of this |
||||
implementation of Go, where such license applies only to those patent |
||||
claims, both currently owned or controlled by Google and acquired in |
||||
the future, licensable by Google that are necessarily infringed by this |
||||
implementation of Go. This grant does not include claims that would be |
||||
infringed only as a consequence of further modification of this |
||||
implementation. If you or your agent or exclusive licensee institute or |
||||
order or agree to the institution of patent litigation against any |
||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging |
||||
that this implementation of Go or any code incorporated within this |
||||
implementation of Go constitutes direct or contributory patent |
||||
infringement, or inducement of patent infringement, then any patent |
||||
rights granted to you under this License for this implementation of Go |
||||
shall terminate as of the date such litigation is filed. |
@ -0,0 +1,66 @@ |
||||
// 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 // import "golang.org/x/crypto/sha3"
|
@ -0,0 +1,65 @@ |
||||
// 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 |
||||
} |
@ -0,0 +1,410 @@ |
||||
// 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) |
||||
} |
||||
} |
@ -0,0 +1,18 @@ |
||||
// 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) |
||||
} |
@ -0,0 +1,193 @@ |
||||
// 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...) |
||||
} |
@ -0,0 +1,306 @@ |
||||
// 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) |
||||
} |
@ -0,0 +1,60 @@ |
||||
// 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.
@ -0,0 +1,16 @@ |
||||
// 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" |
@ -0,0 +1,28 @@ |
||||
// 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:] |
||||
} |
||||
} |
@ -0,0 +1,58 @@ |
||||
// 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" |
Loading…
Reference in new issue