Skip to content

Commit

Permalink
lsh256 lsh512 alignment
Browse files Browse the repository at this point in the history
  • Loading branch information
RyuaNerin committed Jun 11, 2024
1 parent b20cd67 commit 579d155
Show file tree
Hide file tree
Showing 13 changed files with 202 additions and 54 deletions.
24 changes: 24 additions & 0 deletions internal/aligned/aligned.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package aligned

import (
"reflect"
"testing"
)

func TestIsAligned(t *testing.T, align uintptr, raw interface{}, fieldName string) {
v := reflect.ValueOf(raw)
for v.Kind() == reflect.Ptr {
v = v.Elem()
}
vt := v.Type()

vtf, ok := vt.FieldByName(fieldName)
if !ok {
t.Errorf("%s.%s not found", vt.Name(), fieldName)
return
}

if vtf.Offset&(align-1) != 0 {
t.Errorf("%s.%s is not Aligned. offset=%d", vt.Name(), fieldName, vtf.Offset)
}
}
8 changes: 6 additions & 2 deletions internal/binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ package internal

import "encoding/binary"

func ConsumeUint64(b []byte) ([]byte, uint64) {
return b[8:], binary.BigEndian.Uint64(b)
func ConsumeUint16(b []byte) ([]byte, uint16) {
return b[2:], binary.BigEndian.Uint16(b)
}

func ConsumeUint32(b []byte) ([]byte, uint32) {
return b[4:], binary.BigEndian.Uint32(b)
}

func ConsumeUint64(b []byte) ([]byte, uint64) {
return b[8:], binary.BigEndian.Uint64(b)
}
6 changes: 6 additions & 0 deletions internal/endian.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package internal

func AppendBigUint8(b []byte, v byte) []byte {
return append(b,
v,
)
}

func AppendBigUint16(b []byte, v uint16) []byte {
return append(b,
byte(v>>8),
Expand Down
33 changes: 19 additions & 14 deletions lsh256/asm.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,43 +18,48 @@ type simdSet struct {
}

func (simd *simdSet) NewContext(size int) hash.Hash {
ctx := new(lsh256ContextAsm)
ctx.simd = simd
ctx.size = size
ctx := &lsh256ContextAsm{
simd: simd,
algType: size,
}
ctx.Reset()
return ctx
}

func (simd *simdSet) Sum(size int, data []byte) [Size]byte {
var ctx lsh256ContextAsm
ctx.simd = simd
ctx.size = size
ctx := lsh256ContextAsm{
simd: simd,
algType: size,
}
ctx.Reset()
ctx.Write(data)

return ctx.checkSum()
}

const contextDataSize = 16 + 16 + 4*8 + 4*8 + 128

type lsh256ContextAsm struct {
//nolint:unused
data [contextDataSize]byte // 최상단으로 배치하여 aligned 문제 수정...
// 16 bytes aligned
algType int
_ uintptr
remainDataByteLen int
_ uintptr
cvL [4]uint64
cvR [4]uint64
lastBlock [BlockSize]byte

simd *simdSet
size int
}

func (ctx *lsh256ContextAsm) Size() int {
return ctx.size
return ctx.algType
}

func (ctx *lsh256ContextAsm) BlockSize() int {
return BlockSize
}

func (ctx *lsh256ContextAsm) Reset() {
ctx.simd.init(ctx, uint64(ctx.size))
ctx.simd.init(ctx, uint64(ctx.algType))
}

func (ctx *lsh256ContextAsm) Write(data []byte) (n int, err error) {
Expand All @@ -69,7 +74,7 @@ func (ctx *lsh256ContextAsm) Write(data []byte) (n int, err error) {
func (ctx *lsh256ContextAsm) Sum(p []byte) []byte {
ctx0 := *ctx
hash := ctx0.checkSum()
return append(p, hash[:ctx.size]...)
return append(p, hash[:ctx.algType]...)
}

func (ctx *lsh256ContextAsm) checkSum() (hash [Size]byte) {
Expand Down
11 changes: 11 additions & 0 deletions lsh256/asm_amd64_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ package lsh256
import (
"testing"

"github.com/RyuaNerin/go-krypto/internal/aligned"

. "github.com/RyuaNerin/testingutil"
)

Expand All @@ -17,6 +19,15 @@ var (
newAVX2 = simdSetAVX2.NewContext
)

func Test_Aligned(t *testing.T) {
var ctx lsh256ContextAsm
aligned.TestIsAligned(t, 16, &ctx, "algType")
aligned.TestIsAligned(t, 16, &ctx, "remainDataByteLen")
aligned.TestIsAligned(t, 16, &ctx, "cvL")
aligned.TestIsAligned(t, 16, &ctx, "cvR")
aligned.TestIsAligned(t, 16, &ctx, "lastBlock")
}

func Test_ShortWrite_SSE2(t *testing.T) { HTSWA(t, as, newSSE2, !hasSSE2) }
func Test_ShortWrite_SSSE3(t *testing.T) { HTSWA(t, as, newSSSE3, !hasSSSE3) }
func Test_ShortWrite_AVX2(t *testing.T) { HTSWA(t, as, newAVX2, !hasAVX2) }
Expand Down
11 changes: 11 additions & 0 deletions lsh256/asm_arm64_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,22 @@ package lsh256
import (
"testing"

"github.com/RyuaNerin/go-krypto/internal/aligned"

. "github.com/RyuaNerin/testingutil"
)

var newNEON = simdSetNEON.NewContext

func Test_Aligned(t *testing.T) {
var ctx lsh256ContextAsm
aligned.TestIsAligned(t, 16, &ctx, "algType")
aligned.TestIsAligned(t, 16, &ctx, "remainDataByteLen")
aligned.TestIsAligned(t, 16, &ctx, "cvL")
aligned.TestIsAligned(t, 16, &ctx, "cvR")
aligned.TestIsAligned(t, 16, &ctx, "lastBlock")
}

func Test_ShortWrite_NEON(t *testing.T) { HTSWA(t, as, newNEON, !hasNEON) }

func Test_LSH224_NEON(t *testing.T) { HT(t, newNEON(Size224), testCases224, !hasNEON) }
Expand Down
43 changes: 36 additions & 7 deletions lsh256/encoding_asm.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package lsh256

import (
"encoding"
"encoding/binary"
"errors"

"github.com/RyuaNerin/go-krypto/internal"
Expand All @@ -16,15 +15,32 @@ import (
const (
magic = "lsh\x00"
marshaledSize = len(magic) +
/*data*/ contextDataSize +
/*size*/ 2
1 + /* algType */
1 + /* remainDataByteLen */
4*8 + /* cvL */
4*8 + /* cvR */
BlockSize /* lastBlock */
)

func (ctx *lsh256ContextAsm) MarshalBinary() ([]byte, error) {
b := make([]byte, 0, marshaledSize)
b = append(b, magic...)
b = append(b, ctx.data[:]...)
b = internal.AppendBigUint16(b, uint16(ctx.size))

b = internal.AppendBigUint8(b, uint8(ctx.algType))

b = internal.AppendBigUint8(b, uint8(ctx.remainDataByteLen))

for _, v := range ctx.cvL {
b = internal.AppendBigUint64(b, v)
}

for _, v := range ctx.cvR {
b = internal.AppendBigUint64(b, v)
}

b = append(b, ctx.lastBlock[:ctx.remainDataByteLen]...)
b = b[:len(b)+len(ctx.lastBlock)-ctx.remainDataByteLen] // already zero

return b, nil
}

Expand All @@ -37,8 +53,21 @@ func (ctx *lsh256ContextAsm) UnmarshalBinary(b []byte) error {
}

b = b[len(magic):]
b = b[copy(ctx.data[:], b[:contextDataSize]):]
ctx.size = int(binary.BigEndian.Uint16(b))

ctx.algType = int(b[0])
ctx.remainDataByteLen = int(b[1])
b = b[2:]

for i := range ctx.cvL {
b, ctx.cvL[i] = internal.ConsumeUint64(b)
}

for i := range ctx.cvR {
b, ctx.cvR[i] = internal.ConsumeUint64(b)
}

copy(ctx.lastBlock[:], b)

return nil
}

Expand Down
12 changes: 6 additions & 6 deletions lsh256/generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,24 @@ import (
)

func newContextGo(size int) hash.Hash {
ctx := new(lsh256ContextGo)
ctx.outlenbytes = size
ctx := &lsh256ContextGo{
outlenbytes: size,
}
ctx.Reset()

return ctx
}

func sumGo(size int, data []byte) [Size]byte {
var ctx lsh256ContextGo
ctx.outlenbytes = size
ctx := lsh256ContextGo{
outlenbytes: size,
}
ctx.Reset()
ctx.Write(data)

return ctx.checkSum()
}

// java to go

const (
numStep = 26

Expand Down
33 changes: 19 additions & 14 deletions lsh512/asm.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,43 +18,48 @@ type simdSet struct {
}

func (simd *simdSet) NewContext(size int) hash.Hash {
ctx := new(lsh512ContextAsm)
ctx.simd = simd
ctx.size = size
ctx := &lsh512ContextAsm{
simd: simd,
algType: size,
}
ctx.Reset()
return ctx
}

func (simd *simdSet) Sum(size int, data []byte) [Size]byte {
var ctx lsh512ContextAsm
ctx.simd = simd
ctx.size = size
ctx := lsh512ContextAsm{
simd: simd,
algType: size,
}
ctx.Reset()
ctx.Write(data)

return ctx.checkSum()
}

const contextDataSize = 16 + 16 + 8*8 + 8*8 + 256

type lsh512ContextAsm struct {
//nolint:unused
data [contextDataSize]byte // 최상단으로 배치하여 aligned 문제 수정...
// 16 bytes aligned
algType int
_ uintptr
remainDataByteLen int
_ [1]uintptr
cvL [8]uint64
cvR [8]uint64
lastBlock [BlockSize]byte

simd *simdSet
size int
}

func (ctx *lsh512ContextAsm) Size() int {
return ctx.size
return ctx.algType
}

func (ctx *lsh512ContextAsm) BlockSize() int {
return BlockSize
}

func (ctx *lsh512ContextAsm) Reset() {
ctx.simd.init(ctx, uint64(ctx.size))
ctx.simd.init(ctx, uint64(ctx.algType))
}

func (ctx *lsh512ContextAsm) Write(data []byte) (n int, err error) {
Expand All @@ -69,7 +74,7 @@ func (ctx *lsh512ContextAsm) Write(data []byte) (n int, err error) {
func (ctx *lsh512ContextAsm) Sum(p []byte) []byte {
ctx0 := *ctx
hash := ctx0.checkSum()
return append(p, hash[:ctx.size]...)
return append(p, hash[:ctx.algType]...)
}

func (ctx *lsh512ContextAsm) checkSum() (hash [Size]byte) {
Expand Down
11 changes: 11 additions & 0 deletions lsh512/asm_amd64_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ package lsh512
import (
"testing"

"github.com/RyuaNerin/go-krypto/internal/aligned"

. "github.com/RyuaNerin/testingutil"
)

Expand All @@ -17,6 +19,15 @@ var (
newAVX2 = simdSetAVX2.NewContext
)

func Test_Aligned(t *testing.T) {
var ctx lsh512ContextAsm
aligned.TestIsAligned(t, 16, &ctx, "algType")
aligned.TestIsAligned(t, 16, &ctx, "remainDataByteLen")
aligned.TestIsAligned(t, 16, &ctx, "cvL")
aligned.TestIsAligned(t, 16, &ctx, "cvR")
aligned.TestIsAligned(t, 16, &ctx, "lastBlock")
}

func Test_ShortWrite_SSE2(t *testing.T) { HTSWA(t, as, newSSE2, !hasSSE2) }
func Test_ShortWrite_SSSE3(t *testing.T) { HTSWA(t, as, newSSSE3, !hasSSSE3) }
func Test_ShortWrite_AVX2(t *testing.T) { HTSWA(t, as, newAVX2, !hasAVX2) }
Expand Down
11 changes: 11 additions & 0 deletions lsh512/asm_arm64_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,22 @@ package lsh512
import (
"testing"

"github.com/RyuaNerin/go-krypto/internal/aligned"

. "github.com/RyuaNerin/testingutil"
)

var newNEON = simdSetNEON.NewContext

func Test_Aligned(t *testing.T) {
var ctx lsh512ContextAsm
aligned.TestIsAligned(t, 16, &ctx, "algType")
aligned.TestIsAligned(t, 16, &ctx, "remainDataByteLen")
aligned.TestIsAligned(t, 16, &ctx, "cvL")
aligned.TestIsAligned(t, 16, &ctx, "cvR")
aligned.TestIsAligned(t, 16, &ctx, "lastBlock")
}

func Test_ShortWrite_NEON(t *testing.T) { HTSWA(t, as, newNEON, !hasNEON) }

func Test_LSH512_224_NEON(t *testing.T) { HT(t, newNEON(Size224), testCases224, !hasNEON) }
Expand Down
Loading

0 comments on commit 579d155

Please sign in to comment.