maskGo applies the WebSocket masking algorithm to p with the given key. See https://tools.ietf.org/html/rfc6455#section-5.3 The returned value is the correctly rotated key to to continue to mask/unmask the message. It is optimized for LittleEndian and expects the key to be in little endian. See h
(b []byte, key uint32)
| 17 | // |
| 18 | // See https://github.com/golang/go/issues/31586 |
| 19 | func maskGo(b []byte, key uint32) uint32 { |
| 20 | if len(b) >= 8 { |
| 21 | key64 := uint64(key)<<32 | uint64(key) |
| 22 | |
| 23 | // At some point in the future we can clean these unrolled loops up. |
| 24 | // See https://github.com/golang/go/issues/31586#issuecomment-487436401 |
| 25 | |
| 26 | // Then we xor until b is less than 128 bytes. |
| 27 | for len(b) >= 128 { |
| 28 | v := binary.LittleEndian.Uint64(b) |
| 29 | binary.LittleEndian.PutUint64(b, v^key64) |
| 30 | v = binary.LittleEndian.Uint64(b[8:16]) |
| 31 | binary.LittleEndian.PutUint64(b[8:16], v^key64) |
| 32 | v = binary.LittleEndian.Uint64(b[16:24]) |
| 33 | binary.LittleEndian.PutUint64(b[16:24], v^key64) |
| 34 | v = binary.LittleEndian.Uint64(b[24:32]) |
| 35 | binary.LittleEndian.PutUint64(b[24:32], v^key64) |
| 36 | v = binary.LittleEndian.Uint64(b[32:40]) |
| 37 | binary.LittleEndian.PutUint64(b[32:40], v^key64) |
| 38 | v = binary.LittleEndian.Uint64(b[40:48]) |
| 39 | binary.LittleEndian.PutUint64(b[40:48], v^key64) |
| 40 | v = binary.LittleEndian.Uint64(b[48:56]) |
| 41 | binary.LittleEndian.PutUint64(b[48:56], v^key64) |
| 42 | v = binary.LittleEndian.Uint64(b[56:64]) |
| 43 | binary.LittleEndian.PutUint64(b[56:64], v^key64) |
| 44 | v = binary.LittleEndian.Uint64(b[64:72]) |
| 45 | binary.LittleEndian.PutUint64(b[64:72], v^key64) |
| 46 | v = binary.LittleEndian.Uint64(b[72:80]) |
| 47 | binary.LittleEndian.PutUint64(b[72:80], v^key64) |
| 48 | v = binary.LittleEndian.Uint64(b[80:88]) |
| 49 | binary.LittleEndian.PutUint64(b[80:88], v^key64) |
| 50 | v = binary.LittleEndian.Uint64(b[88:96]) |
| 51 | binary.LittleEndian.PutUint64(b[88:96], v^key64) |
| 52 | v = binary.LittleEndian.Uint64(b[96:104]) |
| 53 | binary.LittleEndian.PutUint64(b[96:104], v^key64) |
| 54 | v = binary.LittleEndian.Uint64(b[104:112]) |
| 55 | binary.LittleEndian.PutUint64(b[104:112], v^key64) |
| 56 | v = binary.LittleEndian.Uint64(b[112:120]) |
| 57 | binary.LittleEndian.PutUint64(b[112:120], v^key64) |
| 58 | v = binary.LittleEndian.Uint64(b[120:128]) |
| 59 | binary.LittleEndian.PutUint64(b[120:128], v^key64) |
| 60 | b = b[128:] |
| 61 | } |
| 62 | |
| 63 | // Then we xor until b is less than 64 bytes. |
| 64 | for len(b) >= 64 { |
| 65 | v := binary.LittleEndian.Uint64(b) |
| 66 | binary.LittleEndian.PutUint64(b, v^key64) |
| 67 | v = binary.LittleEndian.Uint64(b[8:16]) |
| 68 | binary.LittleEndian.PutUint64(b[8:16], v^key64) |
| 69 | v = binary.LittleEndian.Uint64(b[16:24]) |
| 70 | binary.LittleEndian.PutUint64(b[16:24], v^key64) |
| 71 | v = binary.LittleEndian.Uint64(b[24:32]) |
| 72 | binary.LittleEndian.PutUint64(b[24:32], v^key64) |
| 73 | v = binary.LittleEndian.Uint64(b[32:40]) |
| 74 | binary.LittleEndian.PutUint64(b[32:40], v^key64) |
| 75 | v = binary.LittleEndian.Uint64(b[40:48]) |
| 76 | binary.LittleEndian.PutUint64(b[40:48], v^key64) |