@@ -13,10 +13,10 @@ import (
1313// to be used for masking in the key. This is so that
1414// unmasking can be performed without the entire frame.
1515func fastXOR (key [4 ]byte , keyPos int , b []byte ) int {
16- // If the payload is greater than 16 bytes, then it's worth
16+ // If the payload is greater than or equal to 16 bytes, then it's worth
1717 // masking 8 bytes at a time.
1818 // Optimization from https://github.com/golang/go/issues/31586#issuecomment-485530859
19- if len (b ) > 16 {
19+ if len (b ) >= 16 {
2020 // We first create a key that is 8 bytes long
2121 // and is aligned on the position correctly.
2222 var alignedKey [8 ]byte
@@ -25,6 +25,86 @@ func fastXOR(key [4]byte, keyPos int, b []byte) int {
2525 }
2626 k := binary .LittleEndian .Uint64 (alignedKey [:])
2727
28+ // Then we xor until b is less than 128 bytes.
29+ for len (b ) >= 128 {
30+ v := binary .LittleEndian .Uint64 (b )
31+ binary .LittleEndian .PutUint64 (b , v ^ k )
32+ v = binary .LittleEndian .Uint64 (b [8 :])
33+ binary .LittleEndian .PutUint64 (b [8 :], v ^ k )
34+ v = binary .LittleEndian .Uint64 (b [16 :])
35+ binary .LittleEndian .PutUint64 (b [16 :], v ^ k )
36+ v = binary .LittleEndian .Uint64 (b [24 :])
37+ binary .LittleEndian .PutUint64 (b [24 :], v ^ k )
38+ v = binary .LittleEndian .Uint64 (b [32 :])
39+ binary .LittleEndian .PutUint64 (b [32 :], v ^ k )
40+ v = binary .LittleEndian .Uint64 (b [40 :])
41+ binary .LittleEndian .PutUint64 (b [40 :], v ^ k )
42+ v = binary .LittleEndian .Uint64 (b [48 :])
43+ binary .LittleEndian .PutUint64 (b [48 :], v ^ k )
44+ v = binary .LittleEndian .Uint64 (b [56 :])
45+ binary .LittleEndian .PutUint64 (b [56 :], v ^ k )
46+ v = binary .LittleEndian .Uint64 (b [64 :])
47+ binary .LittleEndian .PutUint64 (b [64 :], v ^ k )
48+ v = binary .LittleEndian .Uint64 (b [72 :])
49+ binary .LittleEndian .PutUint64 (b [72 :], v ^ k )
50+ v = binary .LittleEndian .Uint64 (b [80 :])
51+ binary .LittleEndian .PutUint64 (b [80 :], v ^ k )
52+ v = binary .LittleEndian .Uint64 (b [88 :])
53+ binary .LittleEndian .PutUint64 (b [88 :], v ^ k )
54+ v = binary .LittleEndian .Uint64 (b [96 :])
55+ binary .LittleEndian .PutUint64 (b [96 :], v ^ k )
56+ v = binary .LittleEndian .Uint64 (b [104 :])
57+ binary .LittleEndian .PutUint64 (b [104 :], v ^ k )
58+ v = binary .LittleEndian .Uint64 (b [112 :])
59+ binary .LittleEndian .PutUint64 (b [112 :], v ^ k )
60+ v = binary .LittleEndian .Uint64 (b [120 :])
61+ binary .LittleEndian .PutUint64 (b [120 :], v ^ k )
62+ b = b [128 :]
63+ }
64+
65+ // Then we xor until b is less than 64 bytes.
66+ for len (b ) >= 64 {
67+ v := binary .LittleEndian .Uint64 (b )
68+ binary .LittleEndian .PutUint64 (b , v ^ k )
69+ v = binary .LittleEndian .Uint64 (b [8 :])
70+ binary .LittleEndian .PutUint64 (b [8 :], v ^ k )
71+ v = binary .LittleEndian .Uint64 (b [16 :])
72+ binary .LittleEndian .PutUint64 (b [16 :], v ^ k )
73+ v = binary .LittleEndian .Uint64 (b [24 :])
74+ binary .LittleEndian .PutUint64 (b [24 :], v ^ k )
75+ v = binary .LittleEndian .Uint64 (b [32 :])
76+ binary .LittleEndian .PutUint64 (b [32 :], v ^ k )
77+ v = binary .LittleEndian .Uint64 (b [40 :])
78+ binary .LittleEndian .PutUint64 (b [40 :], v ^ k )
79+ v = binary .LittleEndian .Uint64 (b [48 :])
80+ binary .LittleEndian .PutUint64 (b [48 :], v ^ k )
81+ v = binary .LittleEndian .Uint64 (b [56 :])
82+ binary .LittleEndian .PutUint64 (b [56 :], v ^ k )
83+ b = b [64 :]
84+ }
85+
86+ // Then we xor until b is less than 32 bytes.
87+ for len (b ) >= 32 {
88+ v := binary .LittleEndian .Uint64 (b )
89+ binary .LittleEndian .PutUint64 (b , v ^ k )
90+ v = binary .LittleEndian .Uint64 (b [8 :])
91+ binary .LittleEndian .PutUint64 (b [8 :], v ^ k )
92+ v = binary .LittleEndian .Uint64 (b [16 :])
93+ binary .LittleEndian .PutUint64 (b [16 :], v ^ k )
94+ v = binary .LittleEndian .Uint64 (b [24 :])
95+ binary .LittleEndian .PutUint64 (b [24 :], v ^ k )
96+ b = b [32 :]
97+ }
98+
99+ // Then we xor until b is less than 16 bytes.
100+ for len (b ) >= 16 {
101+ v := binary .LittleEndian .Uint64 (b )
102+ binary .LittleEndian .PutUint64 (b , v ^ k )
103+ v = binary .LittleEndian .Uint64 (b [8 :])
104+ binary .LittleEndian .PutUint64 (b [8 :], v ^ k )
105+ b = b [16 :]
106+ }
107+
28108 // Then we xor until b is less than 8 bytes.
29109 for len (b ) >= 8 {
30110 v := binary .LittleEndian .Uint64 (b )
0 commit comments