Skip to content

Commit

Permalink
优化代码
Browse files Browse the repository at this point in the history
  • Loading branch information
deatil committed Mar 17, 2024
1 parent df18377 commit 4b1f6a7
Show file tree
Hide file tree
Showing 16 changed files with 286 additions and 1,208 deletions.
142 changes: 114 additions & 28 deletions chaskey/chaskey.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// Package chaskey implements the Chaskey MAC
package chaskey

import (
"fmt"
"hash"
"encoding/binary"
)

/*
http://mouha.be/chaskey/
Expand All @@ -10,49 +16,129 @@ https://eprint.iacr.org/2015/1182.pdf
*/

// H holds keys for an instance of chaskey
type H struct {
k [4]uint32
k1 [4]uint32
k2 [4]uint32
r int
// The size of an chaskey checksum in bytes.
const Size = 16

// The blocksize of chaskey in bytes.
const BlockSize = 16

const KeySize = 16

type KeySizeError int

func (k KeySizeError) Error() string {
return fmt.Sprintf("go-hash/chaskey: invalid key size %d", int(k))
}

// digest represents the partial evaluation of a checksum.
type digest struct {
s [4]uint32
k1 [4]uint32
k2 [4]uint32
r int
x [BlockSize]byte
nx int
len uint64
}

// New returns a new hash.Hash computing the chaskey checksum
// New returns a new 8-round chaskey hasher.
func New(k [4]uint32) *H { return newH(k, 8) }
func New(key []byte) (hash.Hash, error) {
return newDigest(key, 8)
}

// New12 returns a new 12-round chaskey hasher.
func New12(k [4]uint32) *H { return newH(k, 12) }

func newH(k [4]uint32, rounds int) *H {
func New12(key []byte) (hash.Hash, error) {
return newDigest(key, 12)
}

h := H{
k: k,
r: rounds,
func newDigest(key []byte, rounds int) (hash.Hash, error) {
l := len(key)
if l != KeySize {
return nil, KeySizeError(l)
}

timestwo(h.k1[:], k[:])
timestwo(h.k2[:], h.k1[:])
var k [4]uint32

k[0] = binary.LittleEndian.Uint32(key[0:])
k[1] = binary.LittleEndian.Uint32(key[4:])
k[2] = binary.LittleEndian.Uint32(key[8:])
k[3] = binary.LittleEndian.Uint32(key[12:])

d := new(digest)
d.Reset()

return &h
d.s = k
d.r = rounds

timestwo(d.k1[:], k[:])
timestwo(d.k2[:], d.k1[:])

return d, nil
}

// MAC computes the chaskey MAC of a message m. The returned byte slice will be a subslice of tag, if provided.
func (h *H) MAC(m, tag []byte) []byte {
func (d *digest) Reset() {
d.s = [4]uint32{}
d.k1 = [4]uint32{}
d.k2 = [4]uint32{}
d.x = [BlockSize]byte{}
d.nx = 0
d.len = 0
}

if len(tag) < 16 {
tag = make([]byte, 16)
func (d *digest) Size() int {
return Size
}

func (d *digest) BlockSize() int {
return BlockSize
}

func (d *digest) Write(p []byte) (nn int, err error) {
nn = len(p)

d.len += uint64(nn)
if d.nx > 0 {
n := copy(d.x[d.nx:], p)
d.nx += n
if d.nx == BlockSize {
block(d, d.x[:])
d.nx = 0
}

p = p[n:]
}

for ; len(p) > BlockSize; p = p[BlockSize:] {
block(d, p)
d.nx = 0
}

if len(p) > 0 {
d.nx = copy(d.x[:], p)
}

chaskeyCore(h, m, tag)
return
}

return tag[:16]
func (d *digest) Sum(in []byte) []byte {
// Make a copy of d so that caller can keep writing and summing.
d0 := *d
hash := d0.checkSum()
return append(in, hash[:]...)
}

func timestwo(out []uint32, in []uint32) {
var C = [2]uint32{0x00, 0x87}
out[0] = (in[0] << 1) ^ C[in[3]>>31]
out[1] = (in[1] << 1) | (in[0] >> 31)
out[2] = (in[2] << 1) | (in[1] >> 31)
out[3] = (in[3] << 1) | (in[2] >> 31)
func (d *digest) checkSum() [Size]byte {
lastblock(d)

if d.nx != 0 {
panic("d.nx != 0")
}

var digest [Size]byte
binary.LittleEndian.PutUint32(digest[0:], d.s[0])
binary.LittleEndian.PutUint32(digest[4:], d.s[1])
binary.LittleEndian.PutUint32(digest[8:], d.s[2])
binary.LittleEndian.PutUint32(digest[12:], d.s[3])
return digest
}
38 changes: 10 additions & 28 deletions chaskey/chaskey_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,17 +147,23 @@ func testVectors(t *testing.T, rounds int, vectors *[64][4]uint32) {
var m [64]byte
k := [4]uint32{0x833D3433, 0x009F389F, 0x2398E64F, 0x417ACF39}

var tag [16]byte
var key [16]byte
binary.LittleEndian.PutUint32(key[0:], k[0])
binary.LittleEndian.PutUint32(key[4:], k[1])
binary.LittleEndian.PutUint32(key[8:], k[2])
binary.LittleEndian.PutUint32(key[12:], k[3])

h := newH(k, rounds)
var tag []byte

for i := 0; i < 64; i++ {
m[i] = byte(i)

h.MAC(m[:i], tag[:])
h, _ := newDigest(key[:], rounds)
h.Write(m[:i])
tag = h.Sum(nil)

t32 := [4]uint32{
binary.LittleEndian.Uint32(tag[:]),
binary.LittleEndian.Uint32(tag[0:]),
binary.LittleEndian.Uint32(tag[4:]),
binary.LittleEndian.Uint32(tag[8:]),
binary.LittleEndian.Uint32(tag[12:]),
Expand All @@ -168,27 +174,3 @@ func testVectors(t *testing.T, rounds int, vectors *[64][4]uint32) {
}
}
}

func benchmarkChaskey(b *testing.B, size int) {

buf := make([]byte, size)

var k H

k.r = 8

b.SetBytes(int64(size))

var t [16]byte

for i := 0; i < b.N; i++ {
k.MAC(buf, t[:])
}
}

func BenchmarkChaskey16(b *testing.B) { benchmarkChaskey(b, 16) }
func BenchmarkChaskey32(b *testing.B) { benchmarkChaskey(b, 32) }
func BenchmarkChaskey64(b *testing.B) { benchmarkChaskey(b, 64) }
func BenchmarkChaskey512(b *testing.B) { benchmarkChaskey(b, 512) }
func BenchmarkChaskey1024(b *testing.B) { benchmarkChaskey(b, 1024) }
func BenchmarkChaskey2048(b *testing.B) { benchmarkChaskey(b, 2048) }
104 changes: 0 additions & 104 deletions chaskey/core.go

This file was deleted.

Loading

0 comments on commit 4b1f6a7

Please sign in to comment.