Skip to content

Commit

Permalink
Fix issue dedis#441 (dedis#506)
Browse files Browse the repository at this point in the history
* Add Reset() to xof interface
* Add Reset() to blake2x
* Add Reset() to keccak
* Add test for xof Reset()
* Add missing blake2xs test
* Simplify New()
  • Loading branch information
K1li4nL authored Apr 2, 2024
1 parent 8d0e909 commit fc615d5
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 17 deletions.
3 changes: 3 additions & 0 deletions xof.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ type XOF interface {
// with that key.
Reseed()

// Restore a XOF to its initial state.
Reset()

// Clone returns a copy of the XOF in its current state.
Clone() XOF
}
Expand Down
21 changes: 15 additions & 6 deletions xof/blake2xb/blake.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

type xof struct {
impl blake2b.XOF
seed []byte
// key is here to not make excess garbage during repeated calls
// to XORKeyStream.
key []byte
Expand All @@ -22,18 +23,21 @@ func New(seed []byte) kyber.XOF {
seed1 = seed[0:blake2b.Size]
seed2 = seed[blake2b.Size:]
}

b, err := blake2b.NewXOF(blake2b.OutputLengthUnknown, seed1)
if err != nil {
panic("blake2b.NewXOF should not return error: " + err.Error())
}

if seed2 != nil {
_, err := b.Write(seed2)
if err != nil {
panic("blake2b.XOF.Write should not return error: " + err.Error())
}
_, err = b.Write(seed2)
if err != nil {
panic("blake2b.XOF.Write should not return error: " + err.Error())
}
return &xof{impl: b}

seedCopy := make([]byte, len(seed2))
copy(seedCopy, seed2)

return &xof{impl: b, seed: seedCopy}
}

func (x *xof) Clone() kyber.XOF {
Expand Down Expand Up @@ -61,6 +65,11 @@ func (x *xof) Reseed() {
x.impl = y.(*xof).impl
}

func (x *xof) Reset() {
x.impl.Reset()
x.impl.Write(x.seed)
}

func (x *xof) XORKeyStream(dst, src []byte) {
if len(dst) < len(src) {
panic("dst too short")
Expand Down
21 changes: 15 additions & 6 deletions xof/blake2xs/blake.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

type xof struct {
impl blake2s.XOF
seed []byte
// key is here to not make excess garbage during repeated calls
// to XORKeyStream.
key []byte
Expand All @@ -22,18 +23,21 @@ func New(seed []byte) kyber.XOF {
seed1 = seed[0:blake2s.Size]
seed2 = seed[blake2s.Size:]
}

b, err := blake2s.NewXOF(blake2s.OutputLengthUnknown, seed1)
if err != nil {
panic("blake2s.NewXOF should not return error: " + err.Error())
}

if seed2 != nil {
_, err := b.Write(seed2)
if err != nil {
panic("blake2s.XOF.Write should not return error: " + err.Error())
}
_, err = b.Write(seed2)
if err != nil {
panic("blake2s.XOF.Write should not return error: " + err.Error())
}
return &xof{impl: b}

seedCopy := make([]byte, len(seed2))
copy(seedCopy, seed2)

return &xof{impl: b, seed: seedCopy}
}

func (x *xof) Clone() kyber.XOF {
Expand Down Expand Up @@ -61,6 +65,11 @@ func (x *xof) Reseed() {
x.impl = y.(*xof).impl
}

func (x *xof) Reset() {
x.impl.Reset()
x.impl.Write(x.seed)
}

func (x *xof) XORKeyStream(dst, src []byte) {
if len(dst) < len(src) {
panic("dst too short")
Expand Down
12 changes: 10 additions & 2 deletions xof/keccak/keccak.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import (
)

type xof struct {
sh sha3.ShakeHash
sh sha3.ShakeHash
seed []byte
// key is here to not make excess garbage during repeated calls
// to XORKeyStream.
key []byte
Expand All @@ -17,8 +18,10 @@ type xof struct {
// New creates a new XOF using the Shake256 hash.
func New(seed []byte) kyber.XOF {
sh := sha3.NewShake256()
seedCopy := make([]byte, len(seed))
copy(seedCopy, seed)
sh.Write(seed)
return &xof{sh: sh}
return &xof{sh: sh, seed: seedCopy}
}

func (x *xof) Clone() kyber.XOF {
Expand All @@ -36,6 +39,11 @@ func (x *xof) Reseed() {
x.sh.Write(x.key)
}

func (x *xof) Reset() {
x.sh.Reset()
x.sh.Write(x.seed)
}

func (x *xof) Read(dst []byte) (int, error) {
return x.sh.Read(dst)
}
Expand Down
49 changes: 46 additions & 3 deletions xof/xof_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,30 @@ package xof

import (
"bytes"
"crypto/sha512"
"math"
"testing"

"github.com/stretchr/testify/require"
"go.dedis.ch/kyber/v3"
"go.dedis.ch/kyber/v3/xof/blake2xb"
"go.dedis.ch/kyber/v3/xof/blake2xs"
"go.dedis.ch/kyber/v3/xof/keccak"
)

type blakeF struct{}
type blake2xbF struct{}

func (b *blakeF) XOF(seed []byte) kyber.XOF { return blake2xb.New(seed) }
func (b *blake2xbF) XOF(seed []byte) kyber.XOF { return blake2xb.New(seed) }

type blake2xsF struct{}

func (b *blake2xsF) XOF(seed []byte) kyber.XOF { return blake2xs.New(seed) }

type keccakF struct{}

func (b *keccakF) XOF(seed []byte) kyber.XOF { return keccak.New(seed) }

var impls = []kyber.XOFFactory{&blakeF{}, &keccakF{}}
var impls = []kyber.XOFFactory{&blake2xbF{}, &blake2xsF{}, &keccakF{}}

func TestEncDec(t *testing.T) {
lengths := []int{0, 1, 16, 1024, 8192}
Expand Down Expand Up @@ -214,6 +220,43 @@ func testReseed(t *testing.T, s kyber.XOFFactory) {
}
}

func TestResetNoSeed(t *testing.T) {
for _, impl := range impls {
testReset(t, impl, nil)
}
}

func TestResetShortSeed(t *testing.T) {
shortSeed := []byte("short")
for _, impl := range impls {
testReset(t, impl, shortSeed)
}
}

func TestResetLongSeed(t *testing.T) {
longSeed := sha512.New().Sum([]byte("long"))
for _, impl := range impls {
testReset(t, impl, longSeed)
}
}

func testReset(t *testing.T, impl kyber.XOFFactory, seed []byte) {
t.Logf("implementation %T", impl)
nbrBytes := 1024
x := impl.XOF(seed)

beforeResetBytes := make([]byte, nbrBytes)
afterResetBytes := make([]byte, nbrBytes)
x.Read(beforeResetBytes)

x.Reset()
x.Read(afterResetBytes)

if !bytes.Equal(beforeResetBytes, afterResetBytes) {
t.Fatal("reset doesn't restore initial states")
}
}

func TestEncDecMismatch(t *testing.T) {
for _, i := range impls {
testEncDecMismatch(t, i)
Expand Down

0 comments on commit fc615d5

Please sign in to comment.