mirror of https://github.com/grafana/loki
Added Sha3 as alternative (#2480)
* Added Sha3 as alternative * Added crypto x dependency to modules.txt * CI not picking up explicit module def * CI not picking up explicit module def * CI not picking up explicit module def * add x/crypto/sha3/ to vendor dir * Implemented review feedback * doc fix * Update docs/sources/clients/promtail/stages/replace.md Co-authored-by: Ed Welch <ed@oqqer.com> * Update docs/sources/clients/promtail/stages/template.md Co-authored-by: Ed Welch <ed@oqqer.com> Co-authored-by: Ed Welch <ed@oqqer.com>pull/2500/head
parent
cf64b70db3
commit
8ff8b42899
@ -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
|
||||
// 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,97 @@ |
||||
// 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 { |
||||
if h := new224Asm(); h != nil { |
||||
return h |
||||
} |
||||
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 { |
||||
if h := new256Asm(); h != nil { |
||||
return h |
||||
} |
||||
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 { |
||||
if h := new384Asm(); h != nil { |
||||
return h |
||||
} |
||||
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 { |
||||
if h := new512Asm(); h != nil { |
||||
return h |
||||
} |
||||
return &state{rate: 72, outputLen: 64, dsbyte: 0x06} |
||||
} |
||||
|
||||
// NewLegacyKeccak256 creates a new Keccak-256 hash.
|
||||
//
|
||||
// Only use this function if you require compatibility with an existing cryptosystem
|
||||
// that uses non-standard padding. All other users should use New256 instead.
|
||||
func NewLegacyKeccak256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x01} } |
||||
|
||||
// NewLegacyKeccak512 creates a new Keccak-512 hash.
|
||||
//
|
||||
// Only use this function if you require compatibility with an existing cryptosystem
|
||||
// that uses non-standard padding. All other users should use New512 instead.
|
||||
func NewLegacyKeccak512() hash.Hash { return &state{rate: 72, outputLen: 64, dsbyte: 0x01} } |
||||
|
||||
// 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,27 @@ |
||||
// Copyright 2017 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 gccgo appengine !s390x
|
||||
|
||||
package sha3 |
||||
|
||||
import ( |
||||
"hash" |
||||
) |
||||
|
||||
// new224Asm returns an assembly implementation of SHA3-224 if available,
|
||||
// otherwise it returns nil.
|
||||
func new224Asm() hash.Hash { return nil } |
||||
|
||||
// new256Asm returns an assembly implementation of SHA3-256 if available,
|
||||
// otherwise it returns nil.
|
||||
func new256Asm() hash.Hash { return nil } |
||||
|
||||
// new384Asm returns an assembly implementation of SHA3-384 if available,
|
||||
// otherwise it returns nil.
|
||||
func new384Asm() hash.Hash { return nil } |
||||
|
||||
// new512Asm returns an assembly implementation of SHA3-512 if available,
|
||||
// otherwise it returns nil.
|
||||
func new512Asm() hash.Hash { return nil } |
||||
@ -0,0 +1,412 @@ |
||||
// 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 !amd64 appengine gccgo
|
||||
|
||||
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,13 @@ |
||||
// 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,!appengine,!gccgo
|
||||
|
||||
package sha3 |
||||
|
||||
// This function is implemented in keccakf_amd64.s.
|
||||
|
||||
//go:noescape
|
||||
|
||||
func keccakF1600(a *[25]uint64) |
||||
@ -0,0 +1,390 @@ |
||||
// 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,!appengine,!gccgo |
||||
|
||||
// This code was translated into a form compatible with 6a from the public |
||||
// domain sources at https://github.com/gvanas/KeccakCodePackage |
||||
|
||||
// Offsets in state |
||||
#define _ba (0*8) |
||||
#define _be (1*8) |
||||
#define _bi (2*8) |
||||
#define _bo (3*8) |
||||
#define _bu (4*8) |
||||
#define _ga (5*8) |
||||
#define _ge (6*8) |
||||
#define _gi (7*8) |
||||
#define _go (8*8) |
||||
#define _gu (9*8) |
||||
#define _ka (10*8) |
||||
#define _ke (11*8) |
||||
#define _ki (12*8) |
||||
#define _ko (13*8) |
||||
#define _ku (14*8) |
||||
#define _ma (15*8) |
||||
#define _me (16*8) |
||||
#define _mi (17*8) |
||||
#define _mo (18*8) |
||||
#define _mu (19*8) |
||||
#define _sa (20*8) |
||||
#define _se (21*8) |
||||
#define _si (22*8) |
||||
#define _so (23*8) |
||||
#define _su (24*8) |
||||
|
||||
// Temporary registers |
||||
#define rT1 AX |
||||
|
||||
// Round vars |
||||
#define rpState DI |
||||
#define rpStack SP |
||||
|
||||
#define rDa BX |
||||
#define rDe CX |
||||
#define rDi DX |
||||
#define rDo R8 |
||||
#define rDu R9 |
||||
|
||||
#define rBa R10 |
||||
#define rBe R11 |
||||
#define rBi R12 |
||||
#define rBo R13 |
||||
#define rBu R14 |
||||
|
||||
#define rCa SI |
||||
#define rCe BP |
||||
#define rCi rBi |
||||
#define rCo rBo |
||||
#define rCu R15 |
||||
|
||||
#define MOVQ_RBI_RCE MOVQ rBi, rCe |
||||
#define XORQ_RT1_RCA XORQ rT1, rCa |
||||
#define XORQ_RT1_RCE XORQ rT1, rCe |
||||
#define XORQ_RBA_RCU XORQ rBa, rCu |
||||
#define XORQ_RBE_RCU XORQ rBe, rCu |
||||
#define XORQ_RDU_RCU XORQ rDu, rCu |
||||
#define XORQ_RDA_RCA XORQ rDa, rCa |
||||
#define XORQ_RDE_RCE XORQ rDe, rCe |
||||
|
||||
#define mKeccakRound(iState, oState, rc, B_RBI_RCE, G_RT1_RCA, G_RT1_RCE, G_RBA_RCU, K_RT1_RCA, K_RT1_RCE, K_RBA_RCU, M_RT1_RCA, M_RT1_RCE, M_RBE_RCU, S_RDU_RCU, S_RDA_RCA, S_RDE_RCE) \ |
||||
/* Prepare round */ \ |
||||
MOVQ rCe, rDa; \
|
||||
ROLQ $1, rDa; \
|
||||
\ |
||||
MOVQ _bi(iState), rCi; \
|
||||
XORQ _gi(iState), rDi; \
|
||||
XORQ rCu, rDa; \
|
||||
XORQ _ki(iState), rCi; \
|
||||
XORQ _mi(iState), rDi; \
|
||||
XORQ rDi, rCi; \
|
||||
\ |
||||
MOVQ rCi, rDe; \
|
||||
ROLQ $1, rDe; \
|
||||
\ |
||||
MOVQ _bo(iState), rCo; \
|
||||
XORQ _go(iState), rDo; \
|
||||
XORQ rCa, rDe; \
|
||||
XORQ _ko(iState), rCo; \
|
||||
XORQ _mo(iState), rDo; \
|
||||
XORQ rDo, rCo; \
|
||||
\ |
||||
MOVQ rCo, rDi; \
|
||||
ROLQ $1, rDi; \
|
||||
\ |
||||
MOVQ rCu, rDo; \
|
||||
XORQ rCe, rDi; \
|
||||
ROLQ $1, rDo; \
|
||||
\ |
||||
MOVQ rCa, rDu; \
|
||||
XORQ rCi, rDo; \
|
||||
ROLQ $1, rDu; \
|
||||
\ |
||||
/* Result b */ \ |
||||
MOVQ _ba(iState), rBa; \
|
||||
MOVQ _ge(iState), rBe; \
|
||||
XORQ rCo, rDu; \
|
||||
MOVQ _ki(iState), rBi; \
|
||||
MOVQ _mo(iState), rBo; \
|
||||
MOVQ _su(iState), rBu; \
|
||||
XORQ rDe, rBe; \
|
||||
ROLQ $44, rBe; \
|
||||
XORQ rDi, rBi; \
|
||||
XORQ rDa, rBa; \
|
||||
ROLQ $43, rBi; \
|
||||
\ |
||||
MOVQ rBe, rCa; \
|
||||
MOVQ rc, rT1; \
|
||||
ORQ rBi, rCa; \
|
||||
XORQ rBa, rT1; \
|
||||
XORQ rT1, rCa; \
|
||||
MOVQ rCa, _ba(oState); \
|
||||
\ |
||||
XORQ rDu, rBu; \
|
||||
ROLQ $14, rBu; \
|
||||
MOVQ rBa, rCu; \
|
||||
ANDQ rBe, rCu; \
|
||||
XORQ rBu, rCu; \
|
||||
MOVQ rCu, _bu(oState); \
|
||||
\ |
||||
XORQ rDo, rBo; \
|
||||
ROLQ $21, rBo; \
|
||||
MOVQ rBo, rT1; \
|
||||
ANDQ rBu, rT1; \
|
||||
XORQ rBi, rT1; \
|
||||
MOVQ rT1, _bi(oState); \
|
||||
\ |
||||
NOTQ rBi; \
|
||||
ORQ rBa, rBu; \
|
||||
ORQ rBo, rBi; \
|
||||
XORQ rBo, rBu; \
|
||||
XORQ rBe, rBi; \
|
||||
MOVQ rBu, _bo(oState); \
|
||||
MOVQ rBi, _be(oState); \
|
||||
B_RBI_RCE; \
|
||||
\ |
||||
/* Result g */ \ |
||||
MOVQ _gu(iState), rBe; \
|
||||
XORQ rDu, rBe; \
|
||||
MOVQ _ka(iState), rBi; \
|
||||
ROLQ $20, rBe; \
|
||||
XORQ rDa, rBi; \
|
||||
ROLQ $3, rBi; \
|
||||
MOVQ _bo(iState), rBa; \
|
||||
MOVQ rBe, rT1; \
|
||||
ORQ rBi, rT1; \
|
||||
XORQ rDo, rBa; \
|
||||
MOVQ _me(iState), rBo; \
|
||||
MOVQ _si(iState), rBu; \
|
||||
ROLQ $28, rBa; \
|
||||
XORQ rBa, rT1; \
|
||||
MOVQ rT1, _ga(oState); \
|
||||
G_RT1_RCA; \
|
||||
\ |
||||
XORQ rDe, rBo; \
|
||||
ROLQ $45, rBo; \
|
||||
MOVQ rBi, rT1; \
|
||||
ANDQ rBo, rT1; \
|
||||
XORQ rBe, rT1; \
|
||||
MOVQ rT1, _ge(oState); \
|
||||
G_RT1_RCE; \
|
||||
\ |
||||
XORQ rDi, rBu; \
|
||||
ROLQ $61, rBu; \
|
||||
MOVQ rBu, rT1; \
|
||||
ORQ rBa, rT1; \
|
||||
XORQ rBo, rT1; \
|
||||
MOVQ rT1, _go(oState); \
|
||||
\ |
||||
ANDQ rBe, rBa; \
|
||||
XORQ rBu, rBa; \
|
||||
MOVQ rBa, _gu(oState); \
|
||||
NOTQ rBu; \
|
||||
G_RBA_RCU; \
|
||||
\ |
||||
ORQ rBu, rBo; \
|
||||
XORQ rBi, rBo; \
|
||||
MOVQ rBo, _gi(oState); \
|
||||
\ |
||||
/* Result k */ \ |
||||
MOVQ _be(iState), rBa; \
|
||||
MOVQ _gi(iState), rBe; \
|
||||
MOVQ _ko(iState), rBi; \
|
||||
MOVQ _mu(iState), rBo; \
|
||||
MOVQ _sa(iState), rBu; \
|
||||
XORQ rDi, rBe; \
|
||||
ROLQ $6, rBe; \
|
||||
XORQ rDo, rBi; \
|
||||
ROLQ $25, rBi; \
|
||||
MOVQ rBe, rT1; \
|
||||
ORQ rBi, rT1; \
|
||||
XORQ rDe, rBa; \
|
||||
ROLQ $1, rBa; \
|
||||
XORQ rBa, rT1; \
|
||||
MOVQ rT1, _ka(oState); \
|
||||
K_RT1_RCA; \
|
||||
\ |
||||
XORQ rDu, rBo; \
|
||||
ROLQ $8, rBo; \
|
||||
MOVQ rBi, rT1; \
|
||||
ANDQ rBo, rT1; \
|
||||
XORQ rBe, rT1; \
|
||||
MOVQ rT1, _ke(oState); \
|
||||
K_RT1_RCE; \
|
||||
\ |
||||
XORQ rDa, rBu; \
|
||||
ROLQ $18, rBu; \
|
||||
NOTQ rBo; \
|
||||
MOVQ rBo, rT1; \
|
||||
ANDQ rBu, rT1; \
|
||||
XORQ rBi, rT1; \
|
||||
MOVQ rT1, _ki(oState); \
|
||||
\ |
||||
MOVQ rBu, rT1; \
|
||||
ORQ rBa, rT1; \
|
||||
XORQ rBo, rT1; \
|
||||
MOVQ rT1, _ko(oState); \
|
||||
\ |
||||
ANDQ rBe, rBa; \
|
||||
XORQ rBu, rBa; \
|
||||
MOVQ rBa, _ku(oState); \
|
||||
K_RBA_RCU; \
|
||||
\ |
||||
/* Result m */ \ |
||||
MOVQ _ga(iState), rBe; \
|
||||
XORQ rDa, rBe; \
|
||||
MOVQ _ke(iState), rBi; \
|
||||
ROLQ $36, rBe; \
|
||||
XORQ rDe, rBi; \
|
||||
MOVQ _bu(iState), rBa; \
|
||||
ROLQ $10, rBi; \
|
||||
MOVQ rBe, rT1; \
|
||||
MOVQ _mi(iState), rBo; \
|
||||
ANDQ rBi, rT1; \
|
||||
XORQ rDu, rBa; \
|
||||
MOVQ _so(iState), rBu; \
|
||||
ROLQ $27, rBa; \
|
||||
XORQ rBa, rT1; \
|
||||
MOVQ rT1, _ma(oState); \
|
||||
M_RT1_RCA; \
|
||||
\ |
||||
XORQ rDi, rBo; \
|
||||
ROLQ $15, rBo; \
|
||||
MOVQ rBi, rT1; \
|
||||
ORQ rBo, rT1; \
|
||||
XORQ rBe, rT1; \
|
||||
MOVQ rT1, _me(oState); \
|
||||
M_RT1_RCE; \
|
||||
\ |
||||
XORQ rDo, rBu; \
|
||||
ROLQ $56, rBu; \
|
||||
NOTQ rBo; \
|
||||
MOVQ rBo, rT1; \
|
||||
ORQ rBu, rT1; \
|
||||
XORQ rBi, rT1; \
|
||||
MOVQ rT1, _mi(oState); \
|
||||
\ |
||||
ORQ rBa, rBe; \
|
||||
XORQ rBu, rBe; \
|
||||
MOVQ rBe, _mu(oState); \
|
||||
\ |
||||
ANDQ rBa, rBu; \
|
||||
XORQ rBo, rBu; \
|
||||
MOVQ rBu, _mo(oState); \
|
||||
M_RBE_RCU; \
|
||||
\ |
||||
/* Result s */ \ |
||||
MOVQ _bi(iState), rBa; \
|
||||
MOVQ _go(iState), rBe; \
|
||||
MOVQ _ku(iState), rBi; \
|
||||
XORQ rDi, rBa; \
|
||||
MOVQ _ma(iState), rBo; \
|
||||
ROLQ $62, rBa; \
|
||||
XORQ rDo, rBe; \
|
||||
MOVQ _se(iState), rBu; \
|
||||
ROLQ $55, rBe; \
|
||||
\ |
||||
XORQ rDu, rBi; \
|
||||
MOVQ rBa, rDu; \
|
||||
XORQ rDe, rBu; \
|
||||
ROLQ $2, rBu; \
|
||||
ANDQ rBe, rDu; \
|
||||
XORQ rBu, rDu; \
|
||||
MOVQ rDu, _su(oState); \
|
||||
\ |
||||
ROLQ $39, rBi; \
|
||||
S_RDU_RCU; \
|
||||
NOTQ rBe; \
|
||||
XORQ rDa, rBo; \
|
||||
MOVQ rBe, rDa; \
|
||||
ANDQ rBi, rDa; \
|
||||
XORQ rBa, rDa; \
|
||||
MOVQ rDa, _sa(oState); \
|
||||
S_RDA_RCA; \
|
||||
\ |
||||
ROLQ $41, rBo; \
|
||||
MOVQ rBi, rDe; \
|
||||
ORQ rBo, rDe; \
|
||||
XORQ rBe, rDe; \
|
||||
MOVQ rDe, _se(oState); \
|
||||
S_RDE_RCE; \
|
||||
\ |
||||
MOVQ rBo, rDi; \
|
||||
MOVQ rBu, rDo; \
|
||||
ANDQ rBu, rDi; \
|
||||
ORQ rBa, rDo; \
|
||||
XORQ rBi, rDi; \
|
||||
XORQ rBo, rDo; \
|
||||
MOVQ rDi, _si(oState); \
|
||||
MOVQ rDo, _so(oState) \ |
||||
|
||||
// func keccakF1600(state *[25]uint64) |
||||
TEXT ·keccakF1600(SB), 0, $200-8 |
||||
MOVQ state+0(FP), rpState |
||||
|
||||
// Convert the user state into an internal state |
||||
NOTQ _be(rpState) |
||||
NOTQ _bi(rpState) |
||||
NOTQ _go(rpState) |
||||
NOTQ _ki(rpState) |
||||
NOTQ _mi(rpState) |
||||
NOTQ _sa(rpState) |
||||
|
||||
// Execute the KeccakF permutation |
||||
MOVQ _ba(rpState), rCa |
||||
MOVQ _be(rpState), rCe |
||||
MOVQ _bu(rpState), rCu |
||||
|
||||
XORQ _ga(rpState), rCa |
||||
XORQ _ge(rpState), rCe |
||||
XORQ _gu(rpState), rCu |
||||
|
||||
XORQ _ka(rpState), rCa |
||||
XORQ _ke(rpState), rCe |
||||
XORQ _ku(rpState), rCu |
||||
|
||||
XORQ _ma(rpState), rCa |
||||
XORQ _me(rpState), rCe |
||||
XORQ _mu(rpState), rCu |
||||
|
||||
XORQ _sa(rpState), rCa |
||||
XORQ _se(rpState), rCe |
||||
MOVQ _si(rpState), rDi |
||||
MOVQ _so(rpState), rDo |
||||
XORQ _su(rpState), rCu |
||||
|
||||
mKeccakRound(rpState, rpStack, $0x0000000000000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpStack, rpState, $0x0000000000008082, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpState, rpStack, $0x800000000000808a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpStack, rpState, $0x8000000080008000, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpState, rpStack, $0x000000000000808b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpStack, rpState, $0x0000000080000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpState, rpStack, $0x8000000080008081, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpStack, rpState, $0x8000000000008009, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpState, rpStack, $0x000000000000008a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpStack, rpState, $0x0000000000000088, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpState, rpStack, $0x0000000080008009, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpStack, rpState, $0x000000008000000a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpState, rpStack, $0x000000008000808b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpStack, rpState, $0x800000000000008b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpState, rpStack, $0x8000000000008089, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpStack, rpState, $0x8000000000008003, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpState, rpStack, $0x8000000000008002, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpStack, rpState, $0x8000000000000080, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpState, rpStack, $0x000000000000800a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpStack, rpState, $0x800000008000000a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpState, rpStack, $0x8000000080008081, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpStack, rpState, $0x8000000000008080, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpState, rpStack, $0x0000000080000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE) |
||||
mKeccakRound(rpStack, rpState, $0x8000000080008008, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP) |
||||
|
||||
// Revert the internal state to the user state |
||||
NOTQ _be(rpState) |
||||
NOTQ _bi(rpState) |
||||
NOTQ _go(rpState) |
||||
NOTQ _ki(rpState) |
||||
NOTQ _mi(rpState) |
||||
NOTQ _sa(rpState) |
||||
|
||||
RET |
||||
@ -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 storageBuf |
||||
|
||||
// Specific to SHA-3 and SHAKE.
|
||||
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.asBytes()[:0] |
||||
} |
||||
|
||||
func (d *state) clone() *state { |
||||
ret := *d |
||||
if ret.state == spongeAbsorbing { |
||||
ret.buf = ret.storage.asBytes()[:len(ret.buf)] |
||||
} else { |
||||
ret.buf = ret.storage.asBytes()[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.asBytes()[: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.asBytes()[: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.asBytes()[: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.asBytes()[: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.asBytes()[: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.asBytes()[: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,284 @@ |
||||
// Copyright 2017 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 !gccgo,!appengine
|
||||
|
||||
package sha3 |
||||
|
||||
// This file contains code for using the 'compute intermediate
|
||||
// message digest' (KIMD) and 'compute last message digest' (KLMD)
|
||||
// instructions to compute SHA-3 and SHAKE hashes on IBM Z.
|
||||
|
||||
import ( |
||||
"hash" |
||||
|
||||
"golang.org/x/sys/cpu" |
||||
) |
||||
|
||||
// codes represent 7-bit KIMD/KLMD function codes as defined in
|
||||
// the Principles of Operation.
|
||||
type code uint64 |
||||
|
||||
const ( |
||||
// function codes for KIMD/KLMD
|
||||
sha3_224 code = 32 |
||||
sha3_256 = 33 |
||||
sha3_384 = 34 |
||||
sha3_512 = 35 |
||||
shake_128 = 36 |
||||
shake_256 = 37 |
||||
nopad = 0x100 |
||||
) |
||||
|
||||
// kimd is a wrapper for the 'compute intermediate message digest' instruction.
|
||||
// src must be a multiple of the rate for the given function code.
|
||||
//go:noescape
|
||||
func kimd(function code, chain *[200]byte, src []byte) |
||||
|
||||
// klmd is a wrapper for the 'compute last message digest' instruction.
|
||||
// src padding is handled by the instruction.
|
||||
//go:noescape
|
||||
func klmd(function code, chain *[200]byte, dst, src []byte) |
||||
|
||||
type asmState struct { |
||||
a [200]byte // 1600 bit state
|
||||
buf []byte // care must be taken to ensure cap(buf) is a multiple of rate
|
||||
rate int // equivalent to block size
|
||||
storage [3072]byte // underlying storage for buf
|
||||
outputLen int // output length if fixed, 0 if not
|
||||
function code // KIMD/KLMD function code
|
||||
state spongeDirection // whether the sponge is absorbing or squeezing
|
||||
} |
||||
|
||||
func newAsmState(function code) *asmState { |
||||
var s asmState |
||||
s.function = function |
||||
switch function { |
||||
case sha3_224: |
||||
s.rate = 144 |
||||
s.outputLen = 28 |
||||
case sha3_256: |
||||
s.rate = 136 |
||||
s.outputLen = 32 |
||||
case sha3_384: |
||||
s.rate = 104 |
||||
s.outputLen = 48 |
||||
case sha3_512: |
||||
s.rate = 72 |
||||
s.outputLen = 64 |
||||
case shake_128: |
||||
s.rate = 168 |
||||
case shake_256: |
||||
s.rate = 136 |
||||
default: |
||||
panic("sha3: unrecognized function code") |
||||
} |
||||
|
||||
// limit s.buf size to a multiple of s.rate
|
||||
s.resetBuf() |
||||
return &s |
||||
} |
||||
|
||||
func (s *asmState) clone() *asmState { |
||||
c := *s |
||||
c.buf = c.storage[:len(s.buf):cap(s.buf)] |
||||
return &c |
||||
} |
||||
|
||||
// copyIntoBuf copies b into buf. It will panic if there is not enough space to
|
||||
// store all of b.
|
||||
func (s *asmState) copyIntoBuf(b []byte) { |
||||
bufLen := len(s.buf) |
||||
s.buf = s.buf[:len(s.buf)+len(b)] |
||||
copy(s.buf[bufLen:], b) |
||||
} |
||||
|
||||
// resetBuf points buf at storage, sets the length to 0 and sets cap to be a
|
||||
// multiple of the rate.
|
||||
func (s *asmState) resetBuf() { |
||||
max := (cap(s.storage) / s.rate) * s.rate |
||||
s.buf = s.storage[:0:max] |
||||
} |
||||
|
||||
// Write (via the embedded io.Writer interface) adds more data to the running hash.
|
||||
// It never returns an error.
|
||||
func (s *asmState) Write(b []byte) (int, error) { |
||||
if s.state != spongeAbsorbing { |
||||
panic("sha3: write to sponge after read") |
||||
} |
||||
length := len(b) |
||||
for len(b) > 0 { |
||||
if len(s.buf) == 0 && len(b) >= cap(s.buf) { |
||||
// Hash the data directly and push any remaining bytes
|
||||
// into the buffer.
|
||||
remainder := len(b) % s.rate |
||||
kimd(s.function, &s.a, b[:len(b)-remainder]) |
||||
if remainder != 0 { |
||||
s.copyIntoBuf(b[len(b)-remainder:]) |
||||
} |
||||
return length, nil |
||||
} |
||||
|
||||
if len(s.buf) == cap(s.buf) { |
||||
// flush the buffer
|
||||
kimd(s.function, &s.a, s.buf) |
||||
s.buf = s.buf[:0] |
||||
} |
||||
|
||||
// copy as much as we can into the buffer
|
||||
n := len(b) |
||||
if len(b) > cap(s.buf)-len(s.buf) { |
||||
n = cap(s.buf) - len(s.buf) |
||||
} |
||||
s.copyIntoBuf(b[:n]) |
||||
b = b[n:] |
||||
} |
||||
return length, nil |
||||
} |
||||
|
||||
// Read squeezes an arbitrary number of bytes from the sponge.
|
||||
func (s *asmState) Read(out []byte) (n int, err error) { |
||||
n = len(out) |
||||
|
||||
// need to pad if we were absorbing
|
||||
if s.state == spongeAbsorbing { |
||||
s.state = spongeSqueezing |
||||
|
||||
// write hash directly into out if possible
|
||||
if len(out)%s.rate == 0 { |
||||
klmd(s.function, &s.a, out, s.buf) // len(out) may be 0
|
||||
s.buf = s.buf[:0] |
||||
return |
||||
} |
||||
|
||||
// write hash into buffer
|
||||
max := cap(s.buf) |
||||
if max > len(out) { |
||||
max = (len(out)/s.rate)*s.rate + s.rate |
||||
} |
||||
klmd(s.function, &s.a, s.buf[:max], s.buf) |
||||
s.buf = s.buf[:max] |
||||
} |
||||
|
||||
for len(out) > 0 { |
||||
// flush the buffer
|
||||
if len(s.buf) != 0 { |
||||
c := copy(out, s.buf) |
||||
out = out[c:] |
||||
s.buf = s.buf[c:] |
||||
continue |
||||
} |
||||
|
||||
// write hash directly into out if possible
|
||||
if len(out)%s.rate == 0 { |
||||
klmd(s.function|nopad, &s.a, out, nil) |
||||
return |
||||
} |
||||
|
||||
// write hash into buffer
|
||||
s.resetBuf() |
||||
if cap(s.buf) > len(out) { |
||||
s.buf = s.buf[:(len(out)/s.rate)*s.rate+s.rate] |
||||
} |
||||
klmd(s.function|nopad, &s.a, s.buf, nil) |
||||
} |
||||
return |
||||
} |
||||
|
||||
// Sum appends the current hash to b and returns the resulting slice.
|
||||
// It does not change the underlying hash state.
|
||||
func (s *asmState) Sum(b []byte) []byte { |
||||
if s.outputLen == 0 { |
||||
panic("sha3: cannot call Sum on SHAKE functions") |
||||
} |
||||
|
||||
// Copy the state to preserve the original.
|
||||
a := s.a |
||||
|
||||
// Hash the buffer. Note that we don't clear it because we
|
||||
// aren't updating the state.
|
||||
klmd(s.function, &a, nil, s.buf) |
||||
return append(b, a[:s.outputLen]...) |
||||
} |
||||
|
||||
// Reset resets the Hash to its initial state.
|
||||
func (s *asmState) Reset() { |
||||
for i := range s.a { |
||||
s.a[i] = 0 |
||||
} |
||||
s.resetBuf() |
||||
s.state = spongeAbsorbing |
||||
} |
||||
|
||||
// Size returns the number of bytes Sum will return.
|
||||
func (s *asmState) Size() int { |
||||
return s.outputLen |
||||
} |
||||
|
||||
// BlockSize returns the hash's underlying block size.
|
||||
// The Write method must be able to accept any amount
|
||||
// of data, but it may operate more efficiently if all writes
|
||||
// are a multiple of the block size.
|
||||
func (s *asmState) BlockSize() int { |
||||
return s.rate |
||||
} |
||||
|
||||
// Clone returns a copy of the ShakeHash in its current state.
|
||||
func (s *asmState) Clone() ShakeHash { |
||||
return s.clone() |
||||
} |
||||
|
||||
// new224Asm returns an assembly implementation of SHA3-224 if available,
|
||||
// otherwise it returns nil.
|
||||
func new224Asm() hash.Hash { |
||||
if cpu.S390X.HasSHA3 { |
||||
return newAsmState(sha3_224) |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// new256Asm returns an assembly implementation of SHA3-256 if available,
|
||||
// otherwise it returns nil.
|
||||
func new256Asm() hash.Hash { |
||||
if cpu.S390X.HasSHA3 { |
||||
return newAsmState(sha3_256) |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// new384Asm returns an assembly implementation of SHA3-384 if available,
|
||||
// otherwise it returns nil.
|
||||
func new384Asm() hash.Hash { |
||||
if cpu.S390X.HasSHA3 { |
||||
return newAsmState(sha3_384) |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// new512Asm returns an assembly implementation of SHA3-512 if available,
|
||||
// otherwise it returns nil.
|
||||
func new512Asm() hash.Hash { |
||||
if cpu.S390X.HasSHA3 { |
||||
return newAsmState(sha3_512) |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// newShake128Asm returns an assembly implementation of SHAKE-128 if available,
|
||||
// otherwise it returns nil.
|
||||
func newShake128Asm() ShakeHash { |
||||
if cpu.S390X.HasSHA3 { |
||||
return newAsmState(shake_128) |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// newShake256Asm returns an assembly implementation of SHAKE-256 if available,
|
||||
// otherwise it returns nil.
|
||||
func newShake256Asm() ShakeHash { |
||||
if cpu.S390X.HasSHA3 { |
||||
return newAsmState(shake_256) |
||||
} |
||||
return nil |
||||
} |
||||
@ -0,0 +1,33 @@ |
||||
// Copyright 2017 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 !gccgo,!appengine |
||||
|
||||
#include "textflag.h" |
||||
|
||||
// func kimd(function code, chain *[200]byte, src []byte) |
||||
TEXT ·kimd(SB), NOFRAME|NOSPLIT, $0-40 |
||||
MOVD function+0(FP), R0 |
||||
MOVD chain+8(FP), R1 |
||||
LMG src+16(FP), R2, R3 // R2=base, R3=len |
||||
|
||||
continue: |
||||
WORD $0xB93E0002 // KIMD --, R2 |
||||
BVS continue // continue if interrupted |
||||
MOVD $0, R0 // reset R0 for pre-go1.8 compilers |
||||
RET |
||||
|
||||
// func klmd(function code, chain *[200]byte, dst, src []byte) |
||||
TEXT ·klmd(SB), NOFRAME|NOSPLIT, $0-64 |
||||
// TODO: SHAKE support |
||||
MOVD function+0(FP), R0 |
||||
MOVD chain+8(FP), R1 |
||||
LMG dst+16(FP), R2, R3 // R2=base, R3=len |
||||
LMG src+40(FP), R4, R5 // R4=base, R5=len |
||||
|
||||
continue: |
||||
WORD $0xB93F0024 // KLMD R2, R4 |
||||
BVS continue // continue if interrupted |
||||
MOVD $0, R0 // reset R0 for pre-go1.8 compilers |
||||
RET |
||||
@ -0,0 +1,173 @@ |
||||
// 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 and cSHAKE instances, as well as utility
|
||||
// functions for hashing bytes to arbitrary-length output.
|
||||
//
|
||||
//
|
||||
// SHAKE implementation is based on FIPS PUB 202 [1]
|
||||
// cSHAKE implementations is based on NIST SP 800-185 [2]
|
||||
//
|
||||
// [1] https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
|
||||
// [2] https://doi.org/10.6028/NIST.SP.800-185
|
||||
|
||||
import ( |
||||
"encoding/binary" |
||||
"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() |
||||
} |
||||
|
||||
// cSHAKE specific context
|
||||
type cshakeState struct { |
||||
*state // SHA-3 state context and Read/Write operations
|
||||
|
||||
// initBlock is the cSHAKE specific initialization set of bytes. It is initialized
|
||||
// by newCShake function and stores concatenation of N followed by S, encoded
|
||||
// by the method specified in 3.3 of [1].
|
||||
// It is stored here in order for Reset() to be able to put context into
|
||||
// initial state.
|
||||
initBlock []byte |
||||
} |
||||
|
||||
// Consts for configuring initial SHA-3 state
|
||||
const ( |
||||
dsbyteShake = 0x1f |
||||
dsbyteCShake = 0x04 |
||||
rate128 = 168 |
||||
rate256 = 136 |
||||
) |
||||
|
||||
func bytepad(input []byte, w int) []byte { |
||||
// leftEncode always returns max 9 bytes
|
||||
buf := make([]byte, 0, 9+len(input)+w) |
||||
buf = append(buf, leftEncode(uint64(w))...) |
||||
buf = append(buf, input...) |
||||
padlen := w - (len(buf) % w) |
||||
return append(buf, make([]byte, padlen)...) |
||||
} |
||||
|
||||
func leftEncode(value uint64) []byte { |
||||
var b [9]byte |
||||
binary.BigEndian.PutUint64(b[1:], value) |
||||
// Trim all but last leading zero bytes
|
||||
i := byte(1) |
||||
for i < 8 && b[i] == 0 { |
||||
i++ |
||||
} |
||||
// Prepend number of encoded bytes
|
||||
b[i-1] = 9 - i |
||||
return b[i-1:] |
||||
} |
||||
|
||||
func newCShake(N, S []byte, rate int, dsbyte byte) ShakeHash { |
||||
c := cshakeState{state: &state{rate: rate, dsbyte: dsbyte}} |
||||
|
||||
// leftEncode returns max 9 bytes
|
||||
c.initBlock = make([]byte, 0, 9*2+len(N)+len(S)) |
||||
c.initBlock = append(c.initBlock, leftEncode(uint64(len(N)*8))...) |
||||
c.initBlock = append(c.initBlock, N...) |
||||
c.initBlock = append(c.initBlock, leftEncode(uint64(len(S)*8))...) |
||||
c.initBlock = append(c.initBlock, S...) |
||||
c.Write(bytepad(c.initBlock, c.rate)) |
||||
return &c |
||||
} |
||||
|
||||
// Reset resets the hash to initial state.
|
||||
func (c *cshakeState) Reset() { |
||||
c.state.Reset() |
||||
c.Write(bytepad(c.initBlock, c.rate)) |
||||
} |
||||
|
||||
// Clone returns copy of a cSHAKE context within its current state.
|
||||
func (c *cshakeState) Clone() ShakeHash { |
||||
b := make([]byte, len(c.initBlock)) |
||||
copy(b, c.initBlock) |
||||
return &cshakeState{state: c.clone(), initBlock: b} |
||||
} |
||||
|
||||
// Clone returns copy of SHAKE context within its current state.
|
||||
func (c *state) Clone() ShakeHash { |
||||
return c.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 { |
||||
if h := newShake128Asm(); h != nil { |
||||
return h |
||||
} |
||||
return &state{rate: rate128, dsbyte: dsbyteShake} |
||||
} |
||||
|
||||
// NewShake256 creates a new SHAKE256 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 { |
||||
if h := newShake256Asm(); h != nil { |
||||
return h |
||||
} |
||||
return &state{rate: rate256, dsbyte: dsbyteShake} |
||||
} |
||||
|
||||
// NewCShake128 creates a new instance of cSHAKE128 variable-output-length ShakeHash,
|
||||
// a customizable variant of SHAKE128.
|
||||
// N is used to define functions based on cSHAKE, it can be empty when plain cSHAKE is
|
||||
// desired. S is a customization byte string used for domain separation - two cSHAKE
|
||||
// computations on same input with different S yield unrelated outputs.
|
||||
// When N and S are both empty, this is equivalent to NewShake128.
|
||||
func NewCShake128(N, S []byte) ShakeHash { |
||||
if len(N) == 0 && len(S) == 0 { |
||||
return NewShake128() |
||||
} |
||||
return newCShake(N, S, rate128, dsbyteCShake) |
||||
} |
||||
|
||||
// NewCShake256 creates a new instance of cSHAKE256 variable-output-length ShakeHash,
|
||||
// a customizable variant of SHAKE256.
|
||||
// N is used to define functions based on cSHAKE, it can be empty when plain cSHAKE is
|
||||
// desired. S is a customization byte string used for domain separation - two cSHAKE
|
||||
// computations on same input with different S yield unrelated outputs.
|
||||
// When N and S are both empty, this is equivalent to NewShake256.
|
||||
func NewCShake256(N, S []byte) ShakeHash { |
||||
if len(N) == 0 && len(S) == 0 { |
||||
return NewShake256() |
||||
} |
||||
return newCShake(N, S, rate256, dsbyteCShake) |
||||
} |
||||
|
||||
// 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) |
||||
} |
||||
@ -0,0 +1,19 @@ |
||||
// Copyright 2017 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 gccgo appengine !s390x
|
||||
|
||||
package sha3 |
||||
|
||||
// newShake128Asm returns an assembly implementation of SHAKE-128 if available,
|
||||
// otherwise it returns nil.
|
||||
func newShake128Asm() ShakeHash { |
||||
return nil |
||||
} |
||||
|
||||
// newShake256Asm returns an assembly implementation of SHAKE-256 if available,
|
||||
// otherwise it returns nil.
|
||||
func newShake256Asm() ShakeHash { |
||||
return nil |
||||
} |
||||
@ -0,0 +1,23 @@ |
||||
// 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,!ppc64le appengine
|
||||
|
||||
package sha3 |
||||
|
||||
// A storageBuf is an aligned array of maxRate bytes.
|
||||
type storageBuf [maxRate]byte |
||||
|
||||
func (b *storageBuf) asBytes() *[maxRate]byte { |
||||
return (*[maxRate]byte)(b) |
||||
} |
||||
|
||||
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,76 @@ |
||||
// 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 ppc64le
|
||||
// +build !appengine
|
||||
|
||||
package sha3 |
||||
|
||||
import "unsafe" |
||||
|
||||
// A storageBuf is an aligned array of maxRate bytes.
|
||||
type storageBuf [maxRate / 8]uint64 |
||||
|
||||
func (b *storageBuf) asBytes() *[maxRate]byte { |
||||
return (*[maxRate]byte)(unsafe.Pointer(b)) |
||||
} |
||||
|
||||
//go:nocheckptr
|
||||
//
|
||||
// xorInUnaligned intentionally reads the input buffer as an unaligned slice of
|
||||
// integers. The language spec is not clear on whether that is allowed.
|
||||
// See:
|
||||
// https://golang.org/issue/37644
|
||||
// https://golang.org/issue/37298
|
||||
// https://golang.org/issue/35381
|
||||
|
||||
// xorInUnaligned uses unaligned reads and writes to update d.a to contain d.a
|
||||
// XOR buf.
|
||||
func xorInUnaligned(d *state, buf []byte) { |
||||
n := len(buf) |
||||
bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8] |
||||
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