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