From f0776751dd1d3bb9ec91a7c946f51678e4afb683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BA=90=E6=96=87=E9=9B=A8?= <41315874+fumiama@users.noreply.github.com> Date: Sat, 1 Feb 2025 15:46:45 +0800 Subject: [PATCH] feat(crypto): use new xor version --- gold/link/crypto.go | 60 ++++++++++++++-------------------------- gold/link/crypto_test.go | 7 +++-- 2 files changed, 26 insertions(+), 41 deletions(-) diff --git a/gold/link/crypto.go b/gold/link/crypto.go index 5228aec..6f677da 100644 --- a/gold/link/crypto.go +++ b/gold/link/crypto.go @@ -125,61 +125,43 @@ func (m *Me) xorenc(data []byte, seq uint32) []byte { batchsz := len(data) / 8 remain := len(data) % 8 sum := m.mask - newdat := helper.MakeBytes(len(data) + 8) + newdat := helper.MakeBytes(8 + batchsz*8 + 8) // seqrand dat tail binary.LittleEndian.PutUint32(newdat[:4], seq) - _, _ = rand.Read(newdat[4:8]) - if remain > 0 { - var buf [8]byte - p := batchsz * 8 - copy(buf[:], data[p:]) - sum ^= binary.LittleEndian.Uint64(buf[:]) - binary.LittleEndian.PutUint64(buf[:], sum) - copy(newdat[8+p:], buf[:]) - } - for i := batchsz - 1; i >= 0; i-- { + _, _ = rand.Read(newdat[4:8]) // seqrand + sum ^= binary.LittleEndian.Uint64(newdat[:8]) // init from seqrand + binary.LittleEndian.PutUint64(newdat[:8], sum) + for i := 0; i < batchsz; i++ { // range on batch data a := i * 8 b := (i + 1) * 8 sum ^= binary.LittleEndian.Uint64(data[a:b]) binary.LittleEndian.PutUint64(newdat[a+8:b+8], sum) } - sum ^= binary.LittleEndian.Uint64(newdat[:8]) - binary.LittleEndian.PutUint64(newdat[:8], sum) + p := batchsz * 8 + copy(newdat[8+p:], data[p:]) + newdat[len(newdat)-1] = byte(remain) + sum ^= binary.LittleEndian.Uint64(newdat[8+p:]) + binary.LittleEndian.PutUint64(newdat[8+p:], sum) return newdat } // xordec 按 8 字节, 以初始 m.mask 循环异或解码 data func (m *Me) xordec(data []byte) (uint32, []byte) { - if len(data) <= 8 { + if len(data) < 16 || len(data)%8 != 0 { return 0, nil } batchsz := len(data) / 8 - remain := len(data) % 8 - this := uint64(0) - next := uint64(0) - if len(data) >= 8 { - next = binary.LittleEndian.Uint64(data[:8]) - } - for i := 0; i < batchsz-1; i++ { + sum := m.mask + for i := 0; i < batchsz; i++ { a := i * 8 b := (i + 1) * 8 - this = next - next = binary.LittleEndian.Uint64(data[a+8 : b+8]) - binary.LittleEndian.PutUint64(data[a:b], this^next) + x := binary.LittleEndian.Uint64(data[a:b]) + sum ^= x + binary.LittleEndian.PutUint64(data[a:b], sum) + sum = x } - if remain > 0 { - var buf [8]byte - a := (batchsz - 1) * 8 - b := batchsz * 8 - copy(buf[:], data[b:]) - this = next - next = binary.LittleEndian.Uint64(buf[:]) | (m.mask & (uint64(0xffffffff_ffffffff) << (uint64(remain) * 8))) - if batchsz > 0 { - binary.LittleEndian.PutUint64(data[a:b], this^next) - } - binary.LittleEndian.PutUint64(buf[:], next^m.mask) - copy(data[b:], buf[:]) - } else { - binary.LittleEndian.PutUint64(data[len(data)-8:], next^m.mask) + remain := data[len(data)-1] + if remain >= 8 { + return 0, nil } - return binary.LittleEndian.Uint32(data[:4]), data[8:] + return binary.LittleEndian.Uint32(data[:4]), data[8 : len(data)-8+int(remain)] } diff --git a/gold/link/crypto_test.go b/gold/link/crypto_test.go index cbb2b51..cc85732 100644 --- a/gold/link/crypto_test.go +++ b/gold/link/crypto_test.go @@ -17,7 +17,7 @@ func TestXOR(t *testing.T) { } buf := make([]byte, 4096) buf2 := make([]byte, 4096) - for i := 1; i < 4096; i++ { + for i := 0; i < 4096; i++ { data := buf[:i] orgdata := buf2[:i] r1 := bytes.NewBuffer(data[:0]) @@ -28,7 +28,10 @@ func TestXOR(t *testing.T) { t.Fatal(err) } seq, dec := m.xordec(m.xorenc(r1.Bytes(), uint32(i))) - if !bytes.Equal(dec, r2.Bytes()) || seq != uint32(i) { + if !bytes.Equal(dec, r2.Bytes()) { + t.Fatal("unexpected xor at", i, "except", hex.EncodeToString(r2.Bytes()), "got", hex.EncodeToString(dec)) + } + if seq != uint32(i) { t.Fatal("unexpected xor at", i, "seq", seq) } }