1
0
mirror of https://github.com/henrydcase/nobs.git synced 2024-11-26 09:01:20 +00:00
This commit is contained in:
Henry Case 2020-08-25 12:32:22 +01:00
parent 68ba33e34f
commit 516ea4f5e8
11 changed files with 93 additions and 234 deletions

View File

@ -1,91 +0,0 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package sha3
// This file provides functions for creating instances of the SHA-3
// and SHAKE hash functions, as well as utility functions for hashing
// bytes.
import (
"hash"
)
// New224 creates a new SHA3-224 hash.
// Its generic security strength is 224 bits against preimage attacks,
// and 112 bits against collision attacks.
func New224() hash.Hash {
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} }
// 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
}

View File

@ -1,27 +0,0 @@
// 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 }

View File

@ -1,18 +0,0 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.4
package sha3
import (
"crypto"
)
func init() {
crypto.RegisterHash(crypto.SHA3_224, New224)
crypto.RegisterHash(crypto.SHA3_256, New256)
crypto.RegisterHash(crypto.SHA3_384, New384)
crypto.RegisterHash(crypto.SHA3_512, New512)
}

View File

@ -4,6 +4,8 @@
package sha3 package sha3
import "hash"
// spongeDirection indicates the direction bytes are flowing through the sponge. // spongeDirection indicates the direction bytes are flowing through the sponge.
type spongeDirection int type spongeDirection int
@ -38,8 +40,9 @@ type state struct {
// [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf // [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf
// "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and // "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and
// Extendable-Output Functions (May 2014)" // Extendable-Output Functions (May 2014)"
dsbyte byte dsbyte byte
storage [maxRate]byte
storage storageBuf
// Specific to SHA-3 and SHAKE. // Specific to SHA-3 and SHAKE.
outputLen int // the default output size in bytes outputLen int // the default output size in bytes
@ -60,15 +63,15 @@ func (d *state) Reset() {
d.a[i] = 0 d.a[i] = 0
} }
d.state = spongeAbsorbing d.state = spongeAbsorbing
d.buf = d.storage[:0] d.buf = d.storage.asBytes()[:0]
} }
func (d *state) clone() *state { func (d *state) clone() *state {
ret := *d ret := *d
if ret.state == spongeAbsorbing { if ret.state == spongeAbsorbing {
ret.buf = ret.storage[:len(ret.buf)] ret.buf = ret.storage.asBytes()[:len(ret.buf)]
} else { } else {
ret.buf = ret.storage[d.rate-cap(d.buf) : d.rate] ret.buf = ret.storage.asBytes()[d.rate-cap(d.buf) : d.rate]
} }
return &ret return &ret
@ -82,13 +85,13 @@ func (d *state) permute() {
// If we're absorbing, we need to xor the input into the state // If we're absorbing, we need to xor the input into the state
// before applying the permutation. // before applying the permutation.
xorIn(d, d.buf) xorIn(d, d.buf)
d.buf = d.storage[:0] d.buf = d.storage.asBytes()[:0]
keccakF1600(&d.a) keccakF1600(&d.a)
case spongeSqueezing: case spongeSqueezing:
// If we're squeezing, we need to apply the permutatin before // If we're squeezing, we need to apply the permutatin before
// copying more output. // copying more output.
keccakF1600(&d.a) keccakF1600(&d.a)
d.buf = d.storage[:d.rate] d.buf = d.storage.asBytes()[:d.rate]
copyOut(d, d.buf) copyOut(d, d.buf)
} }
} }
@ -97,7 +100,7 @@ func (d *state) permute() {
// the multi-bitrate 10..1 padding rule, and permutes the state. // the multi-bitrate 10..1 padding rule, and permutes the state.
func (d *state) padAndPermute(dsbyte byte) { func (d *state) padAndPermute(dsbyte byte) {
if d.buf == nil { if d.buf == nil {
d.buf = d.storage[:0] d.buf = d.storage.asBytes()[:0]
} }
// Pad with this instance's domain-separator bits. We know that there's // 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, // at least one byte of space in d.buf because, if it were full,
@ -105,7 +108,7 @@ func (d *state) padAndPermute(dsbyte byte) {
// first one bit for the padding. See the comment in the state struct. // first one bit for the padding. See the comment in the state struct.
d.buf = append(d.buf, dsbyte) d.buf = append(d.buf, dsbyte)
zerosStart := len(d.buf) zerosStart := len(d.buf)
d.buf = d.storage[:d.rate] d.buf = d.storage.asBytes()[:d.rate]
for i := zerosStart; i < d.rate; i++ { for i := zerosStart; i < d.rate; i++ {
d.buf[i] = 0 d.buf[i] = 0
} }
@ -116,7 +119,7 @@ func (d *state) padAndPermute(dsbyte byte) {
// Apply the permutation // Apply the permutation
d.permute() d.permute()
d.state = spongeSqueezing d.state = spongeSqueezing
d.buf = d.storage[:d.rate] d.buf = d.storage.asBytes()[:d.rate]
copyOut(d, d.buf) copyOut(d, d.buf)
} }
@ -127,7 +130,7 @@ func (d *state) Write(p []byte) (written int, err error) {
panic("sha3: write to sponge after read") panic("sha3: write to sponge after read")
} }
if d.buf == nil { if d.buf == nil {
d.buf = d.storage[:0] d.buf = d.storage.asBytes()[:0]
} }
written = len(p) written = len(p)
@ -190,3 +193,63 @@ func (d *state) Sum(in []byte) []byte {
dup.Read(hash) dup.Read(hash)
return append(in, hash...) return append(in, hash...)
} }
// New224 creates a new SHA3-224 hash.
// Its generic security strength is 224 bits against preimage attacks,
// and 112 bits against collision attacks.
func New224() hash.Hash {
return &state{rate: 144, outputLen: 28, dsbyte: 0x06}
}
// New256 creates a new SHA3-256 hash.
// Its generic security strength is 256 bits against preimage attacks,
// and 128 bits against collision attacks.
func New256() hash.Hash {
return &state{rate: 136, outputLen: 32, dsbyte: 0x06}
}
// New384 creates a new SHA3-384 hash.
// Its generic security strength is 384 bits against preimage attacks,
// and 192 bits against collision attacks.
func New384() hash.Hash {
return &state{rate: 104, outputLen: 48, dsbyte: 0x06}
}
// New512 creates a new SHA3-512 hash.
// Its generic security strength is 512 bits against preimage attacks,
// and 256 bits against collision attacks.
func New512() hash.Hash {
return &state{rate: 72, outputLen: 64, dsbyte: 0x06}
}
// Sum224 returns the SHA3-224 digest of the data.
func Sum224(data []byte) (digest [28]byte) {
h := New224()
h.Write(data)
h.Sum(digest[:0])
return
}
// Sum256 returns the SHA3-256 digest of the data.
func Sum256(data []byte) (digest [32]byte) {
h := New256()
h.Write(data)
h.Sum(digest[:0])
return
}
// Sum384 returns the SHA3-384 digest of the data.
func Sum384(data []byte) (digest [48]byte) {
h := New384()
h.Write(data)
h.Sum(digest[:0])
return
}
// Sum512 returns the SHA3-512 digest of the data.
func Sum512(data []byte) (digest [64]byte) {
h := New512()
h.Write(data)
h.Sum(digest[:0])
return
}

View File

@ -31,11 +31,10 @@ const (
// with output-length equal to the KAT length for SHA-3, Keccak // with output-length equal to the KAT length for SHA-3, Keccak
// and SHAKE instances. // and SHAKE instances.
var testDigests = map[string]func() hash.Hash{ var testDigests = map[string]func() hash.Hash{
"SHA3-224": New224, "SHA3-224": New224,
"SHA3-256": New256, "SHA3-256": New256,
"SHA3-384": New384, "SHA3-384": New384,
"SHA3-512": New512, "SHA3-512": New512,
"Keccak-256": NewLegacyKeccak256,
} }
// testShakes contains functions that return sha3.ShakeHash instances for // testShakes contains functions that return sha3.ShakeHash instances for
@ -156,31 +155,6 @@ func TestKeccakKats(t *testing.T) {
}) })
} }
// TestKeccak does a basic test of the non-standardized Keccak hash functions.
func TestKeccak(t *testing.T) {
tests := []struct {
fn func() hash.Hash
data []byte
want string
}{
{
NewLegacyKeccak256,
[]byte("abc"),
"4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45",
},
}
for _, u := range tests {
h := u.fn()
h.Write(u.data)
got := h.Sum(nil)
want := decodeHex(u.want)
if !bytes.Equal(got, want) {
t.Errorf("unexpected hash for size %d: got '%x' want '%s'", h.Size()*8, got, u.want)
}
}
}
// TestUnalignedWrite tests that writing data in an arbitrary pattern with // TestUnalignedWrite tests that writing data in an arbitrary pattern with
// small input buffers. // small input buffers.
func TestUnalignedWrite(t *testing.T) { func TestUnalignedWrite(t *testing.T) {

View File

@ -116,9 +116,6 @@ func (c *state) Clone() ShakeHash {
// Its generic security strength is 128 bits against all attacks if at // Its generic security strength is 128 bits against all attacks if at
// least 32 bytes of its output are used. // least 32 bytes of its output are used.
func NewShake128() ShakeHash { func NewShake128() ShakeHash {
if h := newShake128Asm(); h != nil {
return h
}
return &state{rate: rate128, dsbyte: dsbyteShake} return &state{rate: rate128, dsbyte: dsbyteShake}
} }
@ -126,9 +123,6 @@ func NewShake128() ShakeHash {
// Its generic security strength is 256 bits against all attacks if // Its generic security strength is 256 bits against all attacks if
// at least 64 bytes of its output are used. // at least 64 bytes of its output are used.
func NewShake256() ShakeHash { func NewShake256() ShakeHash {
if h := newShake256Asm(); h != nil {
return h
}
return &state{rate: rate256, dsbyte: dsbyteShake} return &state{rate: rate256, dsbyte: dsbyteShake}
} }

View File

@ -1,19 +0,0 @@
// 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
}

View File

@ -6,6 +6,13 @@
package sha3 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 ( var (
xorIn = xorInGeneric xorIn = xorInGeneric
copyOut = copyOutGeneric copyOut = copyOutGeneric

View File

@ -9,9 +9,16 @@ package sha3
import "unsafe" 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))
}
func xorInUnaligned(d *state, buf []byte) { func xorInUnaligned(d *state, buf []byte) {
bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))
n := len(buf) n := len(buf)
bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8]
if n >= 72 { if n >= 72 {
d.a[0] ^= bw[0] d.a[0] ^= bw[0]
d.a[1] ^= bw[1] d.a[1] ^= bw[1]

View File

@ -4,8 +4,6 @@
package shake package shake
import "hash"
// spongeDirection indicates the direction bytes are flowing through the sponge. // spongeDirection indicates the direction bytes are flowing through the sponge.
type spongeDirection int type spongeDirection int
@ -193,7 +191,3 @@ func (d *state) Sum(in []byte) []byte {
dup.Read(hash) dup.Read(hash)
return append(in, hash...) return append(in, 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} }

View File

@ -112,31 +112,6 @@ func TestKeccakKats(t *testing.T) {
} }
} }
// TestKeccak does a basic test of the non-standardized Keccak hash functions.
func TestKeccak(t *testing.T) {
tests := []struct {
fn func() hash.Hash
data []byte
want string
}{
{
NewLegacyKeccak256,
[]byte("abc"),
"4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45",
},
}
for _, u := range tests {
h := u.fn()
h.Write(u.data)
got := h.Sum(nil)
want := decodeHex(u.want)
if !bytes.Equal(got, want) {
t.Errorf("unexpected hash for size %d: got '%x' want '%s'", h.Size()*8, got, u.want)
}
}
}
// TestUnalignedWrite tests that writing data in an arbitrary pattern with // TestUnalignedWrite tests that writing data in an arbitrary pattern with
// small input buffers. // small input buffers.
func TestUnalignedWrite(t *testing.T) { func TestUnalignedWrite(t *testing.T) {