forked from mirror/go-ethereum
parent
49975264a8
commit
33d233d3e1
@ -1,27 +0,0 @@ |
|||||||
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. |
|
@ -1,22 +0,0 @@ |
|||||||
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. |
|
@ -1,297 +0,0 @@ |
|||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package sha3 |
|
||||||
|
|
||||||
// Tests include all the ShortMsgKATs provided by the Keccak team at
|
|
||||||
// https://github.com/gvanas/KeccakCodePackage
|
|
||||||
//
|
|
||||||
// They only include the zero-bit case of the bitwise testvectors
|
|
||||||
// published by NIST in the draft of FIPS-202.
|
|
||||||
|
|
||||||
import ( |
|
||||||
"bytes" |
|
||||||
"compress/flate" |
|
||||||
"encoding/hex" |
|
||||||
"encoding/json" |
|
||||||
"hash" |
|
||||||
"os" |
|
||||||
"strings" |
|
||||||
"testing" |
|
||||||
) |
|
||||||
|
|
||||||
const ( |
|
||||||
testString = "brekeccakkeccak koax koax" |
|
||||||
katFilename = "testdata/keccakKats.json.deflate" |
|
||||||
) |
|
||||||
|
|
||||||
// Internal-use instances of SHAKE used to test against KATs.
|
|
||||||
func newHashShake128() hash.Hash { |
|
||||||
return &state{rate: 168, dsbyte: 0x1f, outputLen: 512} |
|
||||||
} |
|
||||||
func newHashShake256() hash.Hash { |
|
||||||
return &state{rate: 136, dsbyte: 0x1f, outputLen: 512} |
|
||||||
} |
|
||||||
|
|
||||||
// testDigests contains functions returning hash.Hash instances
|
|
||||||
// with output-length equal to the KAT length for both SHA-3 and
|
|
||||||
// SHAKE instances.
|
|
||||||
var testDigests = map[string]func() hash.Hash{ |
|
||||||
"SHA3-224": New224, |
|
||||||
"SHA3-256": New256, |
|
||||||
"SHA3-384": New384, |
|
||||||
"SHA3-512": New512, |
|
||||||
"SHAKE128": newHashShake128, |
|
||||||
"SHAKE256": newHashShake256, |
|
||||||
} |
|
||||||
|
|
||||||
// testShakes contains functions that return ShakeHash instances for
|
|
||||||
// testing the ShakeHash-specific interface.
|
|
||||||
var testShakes = map[string]func() ShakeHash{ |
|
||||||
"SHAKE128": NewShake128, |
|
||||||
"SHAKE256": NewShake256, |
|
||||||
} |
|
||||||
|
|
||||||
// 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) |
|
||||||
} |
|
Binary file not shown.
File diff suppressed because one or more lines are too long
@ -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 } |
2
crypto/sha3/keccakf_amd64.go → vendor/golang.org/x/crypto/sha3/keccakf_amd64.go
generated
vendored
2
crypto/sha3/keccakf_amd64.go → vendor/golang.org/x/crypto/sha3/keccakf_amd64.go
generated
vendored
@ -0,0 +1,289 @@ |
|||||||
|
// 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" |
||||||
|
) |
||||||
|
|
||||||
|
// 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 |
||||||
|
) |
||||||
|
|
||||||
|
// hasMSA6 reports whether the machine supports the SHA-3 and SHAKE function
|
||||||
|
// codes, as defined in message-security-assist extension 6.
|
||||||
|
func hasMSA6() bool |
||||||
|
|
||||||
|
// hasAsm caches the result of hasMSA6 (which might be expensive to call).
|
||||||
|
var hasAsm = hasMSA6() |
||||||
|
|
||||||
|
// 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(s.buf) % 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 hasAsm { |
||||||
|
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 hasAsm { |
||||||
|
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 hasAsm { |
||||||
|
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 hasAsm { |
||||||
|
return newAsmState(sha3_512) |
||||||
|
} |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// newShake128Asm returns an assembly implementation of SHAKE-128 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func newShake128Asm() ShakeHash { |
||||||
|
if hasAsm { |
||||||
|
return newAsmState(shake_128) |
||||||
|
} |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// newShake256Asm returns an assembly implementation of SHAKE-256 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func newShake256Asm() ShakeHash { |
||||||
|
if hasAsm { |
||||||
|
return newAsmState(shake_256) |
||||||
|
} |
||||||
|
return nil |
||||||
|
} |
@ -0,0 +1,49 @@ |
|||||||
|
// 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" |
||||||
|
|
||||||
|
TEXT ·hasMSA6(SB), NOSPLIT, $16-1 |
||||||
|
MOVD $0, R0 // KIMD-Query function code |
||||||
|
MOVD $tmp-16(SP), R1 // parameter block |
||||||
|
XC $16, (R1), (R1) // clear the parameter block |
||||||
|
WORD $0xB93E0002 // KIMD --, -- |
||||||
|
WORD $0x91FC1004 // TM 4(R1), 0xFC (test bits [32-37]) |
||||||
|
BVS yes |
||||||
|
|
||||||
|
no: |
||||||
|
MOVB $0, ret+0(FP) |
||||||
|
RET |
||||||
|
|
||||||
|
yes: |
||||||
|
MOVB $1, ret+0(FP) |
||||||
|
RET |
||||||
|
|
||||||
|
// func kimd(function code, params *[200]byte, src []byte) |
||||||
|
TEXT ·kimd(SB), NOFRAME|NOSPLIT, $0-40 |
||||||
|
MOVD function+0(FP), R0 |
||||||
|
MOVD params+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, params *[200]byte, dst, src []byte) |
||||||
|
TEXT ·klmd(SB), NOFRAME|NOSPLIT, $0-64 |
||||||
|
// TODO: SHAKE support |
||||||
|
MOVD function+0(FP), R0 |
||||||
|
MOVD params+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,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
crypto/sha3/xor_unaligned.go → vendor/golang.org/x/crypto/sha3/xor_unaligned.go
generated
vendored
0
crypto/sha3/xor_unaligned.go → vendor/golang.org/x/crypto/sha3/xor_unaligned.go
generated
vendored
Loading…
Reference in new issue