Pier Angelo Vendrame pushed to branch main at The Tor Project / Applications / tor-browser-build

Commits:

1 changed file:

Changes:

  • projects/kcp-go/remove-crypt-fec.patch deleted
    1
    -From 0b9d0759f979a5d828b747ea51771f307c53d221 Mon Sep 17 00:00:00 2001
    
    2
    -From: David Fifield <david@bamsoftware.com>
    
    3
    -Date: Thu, 9 Apr 2020 11:27:44 -0600
    
    4
    -Subject: [PATCH] Remove crypt and FEC dependencies.
    
    5
    -
    
    6
    ----
    
    7
    - crypt.go   | 618 -----------------------------------------------------
    
    8
    - fec.go     | 337 -----------------------------
    
    9
    - removed.go |  29 +++
    
    10
    - 3 files changed, 29 insertions(+), 955 deletions(-)
    
    11
    - delete mode 100644 crypt.go
    
    12
    - delete mode 100644 fec.go
    
    13
    - create mode 100644 removed.go
    
    14
    -
    
    15
    -diff --git a/crypt.go b/crypt.go
    
    16
    -deleted file mode 100644
    
    17
    -index d882852..0000000
    
    18
    ---- a/crypt.go
    
    19
    -+++ /dev/null
    
    20
    -@@ -1,618 +0,0 @@
    
    21
    --package kcp
    
    22
    --
    
    23
    --import (
    
    24
    --	"crypto/aes"
    
    25
    --	"crypto/cipher"
    
    26
    --	"crypto/des"
    
    27
    --	"crypto/sha1"
    
    28
    --	"unsafe"
    
    29
    --
    
    30
    --	xor "github.com/templexxx/xorsimd"
    
    31
    --	"github.com/tjfoc/gmsm/sm4"
    
    32
    --
    
    33
    --	"golang.org/x/crypto/blowfish"
    
    34
    --	"golang.org/x/crypto/cast5"
    
    35
    --	"golang.org/x/crypto/pbkdf2"
    
    36
    --	"golang.org/x/crypto/salsa20"
    
    37
    --	"golang.org/x/crypto/tea"
    
    38
    --	"golang.org/x/crypto/twofish"
    
    39
    --	"golang.org/x/crypto/xtea"
    
    40
    --)
    
    41
    --
    
    42
    --var (
    
    43
    --	initialVector = []byte{167, 115, 79, 156, 18, 172, 27, 1, 164, 21, 242, 193, 252, 120, 230, 107}
    
    44
    --	saltxor       = `sH3CIVoF#rWLtJo6`
    
    45
    --)
    
    46
    --
    
    47
    --// BlockCrypt defines encryption/decryption methods for a given byte slice.
    
    48
    --// Notes on implementing: the data to be encrypted contains a builtin
    
    49
    --// nonce at the first 16 bytes
    
    50
    --type BlockCrypt interface {
    
    51
    --	// Encrypt encrypts the whole block in src into dst.
    
    52
    --	// Dst and src may point at the same memory.
    
    53
    --	Encrypt(dst, src []byte)
    
    54
    --
    
    55
    --	// Decrypt decrypts the whole block in src into dst.
    
    56
    --	// Dst and src may point at the same memory.
    
    57
    --	Decrypt(dst, src []byte)
    
    58
    --}
    
    59
    --
    
    60
    --type salsa20BlockCrypt struct {
    
    61
    --	key [32]byte
    
    62
    --}
    
    63
    --
    
    64
    --// NewSalsa20BlockCrypt https://en.wikipedia.org/wiki/Salsa20
    
    65
    --func NewSalsa20BlockCrypt(key []byte) (BlockCrypt, error) {
    
    66
    --	c := new(salsa20BlockCrypt)
    
    67
    --	copy(c.key[:], key)
    
    68
    --	return c, nil
    
    69
    --}
    
    70
    --
    
    71
    --func (c *salsa20BlockCrypt) Encrypt(dst, src []byte) {
    
    72
    --	salsa20.XORKeyStream(dst[8:], src[8:], src[:8], &c.key)
    
    73
    --	copy(dst[:8], src[:8])
    
    74
    --}
    
    75
    --func (c *salsa20BlockCrypt) Decrypt(dst, src []byte) {
    
    76
    --	salsa20.XORKeyStream(dst[8:], src[8:], src[:8], &c.key)
    
    77
    --	copy(dst[:8], src[:8])
    
    78
    --}
    
    79
    --
    
    80
    --type sm4BlockCrypt struct {
    
    81
    --	encbuf [sm4.BlockSize]byte // 64bit alignment enc/dec buffer
    
    82
    --	decbuf [2 * sm4.BlockSize]byte
    
    83
    --	block  cipher.Block
    
    84
    --}
    
    85
    --
    
    86
    --// NewSM4BlockCrypt https://github.com/tjfoc/gmsm/tree/master/sm4
    
    87
    --func NewSM4BlockCrypt(key []byte) (BlockCrypt, error) {
    
    88
    --	c := new(sm4BlockCrypt)
    
    89
    --	block, err := sm4.NewCipher(key)
    
    90
    --	if err != nil {
    
    91
    --		return nil, err
    
    92
    --	}
    
    93
    --	c.block = block
    
    94
    --	return c, nil
    
    95
    --}
    
    96
    --
    
    97
    --func (c *sm4BlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf[:]) }
    
    98
    --func (c *sm4BlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf[:]) }
    
    99
    --
    
    100
    --type twofishBlockCrypt struct {
    
    101
    --	encbuf [twofish.BlockSize]byte
    
    102
    --	decbuf [2 * twofish.BlockSize]byte
    
    103
    --	block  cipher.Block
    
    104
    --}
    
    105
    --
    
    106
    --// NewTwofishBlockCrypt https://en.wikipedia.org/wiki/Twofish
    
    107
    --func NewTwofishBlockCrypt(key []byte) (BlockCrypt, error) {
    
    108
    --	c := new(twofishBlockCrypt)
    
    109
    --	block, err := twofish.NewCipher(key)
    
    110
    --	if err != nil {
    
    111
    --		return nil, err
    
    112
    --	}
    
    113
    --	c.block = block
    
    114
    --	return c, nil
    
    115
    --}
    
    116
    --
    
    117
    --func (c *twofishBlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf[:]) }
    
    118
    --func (c *twofishBlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf[:]) }
    
    119
    --
    
    120
    --type tripleDESBlockCrypt struct {
    
    121
    --	encbuf [des.BlockSize]byte
    
    122
    --	decbuf [2 * des.BlockSize]byte
    
    123
    --	block  cipher.Block
    
    124
    --}
    
    125
    --
    
    126
    --// NewTripleDESBlockCrypt https://en.wikipedia.org/wiki/Triple_DES
    
    127
    --func NewTripleDESBlockCrypt(key []byte) (BlockCrypt, error) {
    
    128
    --	c := new(tripleDESBlockCrypt)
    
    129
    --	block, err := des.NewTripleDESCipher(key)
    
    130
    --	if err != nil {
    
    131
    --		return nil, err
    
    132
    --	}
    
    133
    --	c.block = block
    
    134
    --	return c, nil
    
    135
    --}
    
    136
    --
    
    137
    --func (c *tripleDESBlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf[:]) }
    
    138
    --func (c *tripleDESBlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf[:]) }
    
    139
    --
    
    140
    --type cast5BlockCrypt struct {
    
    141
    --	encbuf [cast5.BlockSize]byte
    
    142
    --	decbuf [2 * cast5.BlockSize]byte
    
    143
    --	block  cipher.Block
    
    144
    --}
    
    145
    --
    
    146
    --// NewCast5BlockCrypt https://en.wikipedia.org/wiki/CAST-128
    
    147
    --func NewCast5BlockCrypt(key []byte) (BlockCrypt, error) {
    
    148
    --	c := new(cast5BlockCrypt)
    
    149
    --	block, err := cast5.NewCipher(key)
    
    150
    --	if err != nil {
    
    151
    --		return nil, err
    
    152
    --	}
    
    153
    --	c.block = block
    
    154
    --	return c, nil
    
    155
    --}
    
    156
    --
    
    157
    --func (c *cast5BlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf[:]) }
    
    158
    --func (c *cast5BlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf[:]) }
    
    159
    --
    
    160
    --type blowfishBlockCrypt struct {
    
    161
    --	encbuf [blowfish.BlockSize]byte
    
    162
    --	decbuf [2 * blowfish.BlockSize]byte
    
    163
    --	block  cipher.Block
    
    164
    --}
    
    165
    --
    
    166
    --// NewBlowfishBlockCrypt https://en.wikipedia.org/wiki/Blowfish_(cipher)
    
    167
    --func NewBlowfishBlockCrypt(key []byte) (BlockCrypt, error) {
    
    168
    --	c := new(blowfishBlockCrypt)
    
    169
    --	block, err := blowfish.NewCipher(key)
    
    170
    --	if err != nil {
    
    171
    --		return nil, err
    
    172
    --	}
    
    173
    --	c.block = block
    
    174
    --	return c, nil
    
    175
    --}
    
    176
    --
    
    177
    --func (c *blowfishBlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf[:]) }
    
    178
    --func (c *blowfishBlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf[:]) }
    
    179
    --
    
    180
    --type aesBlockCrypt struct {
    
    181
    --	encbuf [aes.BlockSize]byte
    
    182
    --	decbuf [2 * aes.BlockSize]byte
    
    183
    --	block  cipher.Block
    
    184
    --}
    
    185
    --
    
    186
    --// NewAESBlockCrypt https://en.wikipedia.org/wiki/Advanced_Encryption_Standard
    
    187
    --func NewAESBlockCrypt(key []byte) (BlockCrypt, error) {
    
    188
    --	c := new(aesBlockCrypt)
    
    189
    --	block, err := aes.NewCipher(key)
    
    190
    --	if err != nil {
    
    191
    --		return nil, err
    
    192
    --	}
    
    193
    --	c.block = block
    
    194
    --	return c, nil
    
    195
    --}
    
    196
    --
    
    197
    --func (c *aesBlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf[:]) }
    
    198
    --func (c *aesBlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf[:]) }
    
    199
    --
    
    200
    --type teaBlockCrypt struct {
    
    201
    --	encbuf [tea.BlockSize]byte
    
    202
    --	decbuf [2 * tea.BlockSize]byte
    
    203
    --	block  cipher.Block
    
    204
    --}
    
    205
    --
    
    206
    --// NewTEABlockCrypt https://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm
    
    207
    --func NewTEABlockCrypt(key []byte) (BlockCrypt, error) {
    
    208
    --	c := new(teaBlockCrypt)
    
    209
    --	block, err := tea.NewCipherWithRounds(key, 16)
    
    210
    --	if err != nil {
    
    211
    --		return nil, err
    
    212
    --	}
    
    213
    --	c.block = block
    
    214
    --	return c, nil
    
    215
    --}
    
    216
    --
    
    217
    --func (c *teaBlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf[:]) }
    
    218
    --func (c *teaBlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf[:]) }
    
    219
    --
    
    220
    --type xteaBlockCrypt struct {
    
    221
    --	encbuf [xtea.BlockSize]byte
    
    222
    --	decbuf [2 * xtea.BlockSize]byte
    
    223
    --	block  cipher.Block
    
    224
    --}
    
    225
    --
    
    226
    --// NewXTEABlockCrypt https://en.wikipedia.org/wiki/XTEA
    
    227
    --func NewXTEABlockCrypt(key []byte) (BlockCrypt, error) {
    
    228
    --	c := new(xteaBlockCrypt)
    
    229
    --	block, err := xtea.NewCipher(key)
    
    230
    --	if err != nil {
    
    231
    --		return nil, err
    
    232
    --	}
    
    233
    --	c.block = block
    
    234
    --	return c, nil
    
    235
    --}
    
    236
    --
    
    237
    --func (c *xteaBlockCrypt) Encrypt(dst, src []byte) { encrypt(c.block, dst, src, c.encbuf[:]) }
    
    238
    --func (c *xteaBlockCrypt) Decrypt(dst, src []byte) { decrypt(c.block, dst, src, c.decbuf[:]) }
    
    239
    --
    
    240
    --type simpleXORBlockCrypt struct {
    
    241
    --	xortbl []byte
    
    242
    --}
    
    243
    --
    
    244
    --// NewSimpleXORBlockCrypt simple xor with key expanding
    
    245
    --func NewSimpleXORBlockCrypt(key []byte) (BlockCrypt, error) {
    
    246
    --	c := new(simpleXORBlockCrypt)
    
    247
    --	c.xortbl = pbkdf2.Key(key, []byte(saltxor), 32, mtuLimit, sha1.New)
    
    248
    --	return c, nil
    
    249
    --}
    
    250
    --
    
    251
    --func (c *simpleXORBlockCrypt) Encrypt(dst, src []byte) { xor.Bytes(dst, src, c.xortbl) }
    
    252
    --func (c *simpleXORBlockCrypt) Decrypt(dst, src []byte) { xor.Bytes(dst, src, c.xortbl) }
    
    253
    --
    
    254
    --type noneBlockCrypt struct{}
    
    255
    --
    
    256
    --// NewNoneBlockCrypt does nothing but copying
    
    257
    --func NewNoneBlockCrypt(key []byte) (BlockCrypt, error) {
    
    258
    --	return new(noneBlockCrypt), nil
    
    259
    --}
    
    260
    --
    
    261
    --func (c *noneBlockCrypt) Encrypt(dst, src []byte) { copy(dst, src) }
    
    262
    --func (c *noneBlockCrypt) Decrypt(dst, src []byte) { copy(dst, src) }
    
    263
    --
    
    264
    --// packet encryption with local CFB mode
    
    265
    --func encrypt(block cipher.Block, dst, src, buf []byte) {
    
    266
    --	switch block.BlockSize() {
    
    267
    --	case 8:
    
    268
    --		encrypt8(block, dst, src, buf)
    
    269
    --	case 16:
    
    270
    --		encrypt16(block, dst, src, buf)
    
    271
    --	default:
    
    272
    --		panic("unsupported cipher block size")
    
    273
    --	}
    
    274
    --}
    
    275
    --
    
    276
    --// optimized encryption for the ciphers which works in 8-bytes
    
    277
    --func encrypt8(block cipher.Block, dst, src, buf []byte) {
    
    278
    --	tbl := buf[:8]
    
    279
    --	block.Encrypt(tbl, initialVector)
    
    280
    --	n := len(src) / 8
    
    281
    --	base := 0
    
    282
    --	repeat := n / 8
    
    283
    --	left := n % 8
    
    284
    --	ptr_tbl := (*uint64)(unsafe.Pointer(&tbl[0]))
    
    285
    --
    
    286
    --	for i := 0; i < repeat; i++ {
    
    287
    --		s := src[base:][0:64]
    
    288
    --		d := dst[base:][0:64]
    
    289
    --		// 1
    
    290
    --		*(*uint64)(unsafe.Pointer(&d[0])) = *(*uint64)(unsafe.Pointer(&s[0])) ^ *ptr_tbl
    
    291
    --		block.Encrypt(tbl, d[0:8])
    
    292
    --		// 2
    
    293
    --		*(*uint64)(unsafe.Pointer(&d[8])) = *(*uint64)(unsafe.Pointer(&s[8])) ^ *ptr_tbl
    
    294
    --		block.Encrypt(tbl, d[8:16])
    
    295
    --		// 3
    
    296
    --		*(*uint64)(unsafe.Pointer(&d[16])) = *(*uint64)(unsafe.Pointer(&s[16])) ^ *ptr_tbl
    
    297
    --		block.Encrypt(tbl, d[16:24])
    
    298
    --		// 4
    
    299
    --		*(*uint64)(unsafe.Pointer(&d[24])) = *(*uint64)(unsafe.Pointer(&s[24])) ^ *ptr_tbl
    
    300
    --		block.Encrypt(tbl, d[24:32])
    
    301
    --		// 5
    
    302
    --		*(*uint64)(unsafe.Pointer(&d[32])) = *(*uint64)(unsafe.Pointer(&s[32])) ^ *ptr_tbl
    
    303
    --		block.Encrypt(tbl, d[32:40])
    
    304
    --		// 6
    
    305
    --		*(*uint64)(unsafe.Pointer(&d[40])) = *(*uint64)(unsafe.Pointer(&s[40])) ^ *ptr_tbl
    
    306
    --		block.Encrypt(tbl, d[40:48])
    
    307
    --		// 7
    
    308
    --		*(*uint64)(unsafe.Pointer(&d[48])) = *(*uint64)(unsafe.Pointer(&s[48])) ^ *ptr_tbl
    
    309
    --		block.Encrypt(tbl, d[48:56])
    
    310
    --		// 8
    
    311
    --		*(*uint64)(unsafe.Pointer(&d[56])) = *(*uint64)(unsafe.Pointer(&s[56])) ^ *ptr_tbl
    
    312
    --		block.Encrypt(tbl, d[56:64])
    
    313
    --		base += 64
    
    314
    --	}
    
    315
    --
    
    316
    --	switch left {
    
    317
    --	case 7:
    
    318
    --		*(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *ptr_tbl
    
    319
    --		block.Encrypt(tbl, dst[base:])
    
    320
    --		base += 8
    
    321
    --		fallthrough
    
    322
    --	case 6:
    
    323
    --		*(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *ptr_tbl
    
    324
    --		block.Encrypt(tbl, dst[base:])
    
    325
    --		base += 8
    
    326
    --		fallthrough
    
    327
    --	case 5:
    
    328
    --		*(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *ptr_tbl
    
    329
    --		block.Encrypt(tbl, dst[base:])
    
    330
    --		base += 8
    
    331
    --		fallthrough
    
    332
    --	case 4:
    
    333
    --		*(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *ptr_tbl
    
    334
    --		block.Encrypt(tbl, dst[base:])
    
    335
    --		base += 8
    
    336
    --		fallthrough
    
    337
    --	case 3:
    
    338
    --		*(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *ptr_tbl
    
    339
    --		block.Encrypt(tbl, dst[base:])
    
    340
    --		base += 8
    
    341
    --		fallthrough
    
    342
    --	case 2:
    
    343
    --		*(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *ptr_tbl
    
    344
    --		block.Encrypt(tbl, dst[base:])
    
    345
    --		base += 8
    
    346
    --		fallthrough
    
    347
    --	case 1:
    
    348
    --		*(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *ptr_tbl
    
    349
    --		block.Encrypt(tbl, dst[base:])
    
    350
    --		base += 8
    
    351
    --		fallthrough
    
    352
    --	case 0:
    
    353
    --		xorBytes(dst[base:], src[base:], tbl)
    
    354
    --	}
    
    355
    --}
    
    356
    --
    
    357
    --// optimized encryption for the ciphers which works in 16-bytes
    
    358
    --func encrypt16(block cipher.Block, dst, src, buf []byte) {
    
    359
    --	tbl := buf[:16]
    
    360
    --	block.Encrypt(tbl, initialVector)
    
    361
    --	n := len(src) / 16
    
    362
    --	base := 0
    
    363
    --	repeat := n / 8
    
    364
    --	left := n % 8
    
    365
    --	for i := 0; i < repeat; i++ {
    
    366
    --		s := src[base:][0:128]
    
    367
    --		d := dst[base:][0:128]
    
    368
    --		// 1
    
    369
    --		xor.Bytes16Align(d[0:16], s[0:16], tbl)
    
    370
    --		block.Encrypt(tbl, d[0:16])
    
    371
    --		// 2
    
    372
    --		xor.Bytes16Align(d[16:32], s[16:32], tbl)
    
    373
    --		block.Encrypt(tbl, d[16:32])
    
    374
    --		// 3
    
    375
    --		xor.Bytes16Align(d[32:48], s[32:48], tbl)
    
    376
    --		block.Encrypt(tbl, d[32:48])
    
    377
    --		// 4
    
    378
    --		xor.Bytes16Align(d[48:64], s[48:64], tbl)
    
    379
    --		block.Encrypt(tbl, d[48:64])
    
    380
    --		// 5
    
    381
    --		xor.Bytes16Align(d[64:80], s[64:80], tbl)
    
    382
    --		block.Encrypt(tbl, d[64:80])
    
    383
    --		// 6
    
    384
    --		xor.Bytes16Align(d[80:96], s[80:96], tbl)
    
    385
    --		block.Encrypt(tbl, d[80:96])
    
    386
    --		// 7
    
    387
    --		xor.Bytes16Align(d[96:112], s[96:112], tbl)
    
    388
    --		block.Encrypt(tbl, d[96:112])
    
    389
    --		// 8
    
    390
    --		xor.Bytes16Align(d[112:128], s[112:128], tbl)
    
    391
    --		block.Encrypt(tbl, d[112:128])
    
    392
    --		base += 128
    
    393
    --	}
    
    394
    --
    
    395
    --	switch left {
    
    396
    --	case 7:
    
    397
    --		xor.Bytes16Align(dst[base:], src[base:], tbl)
    
    398
    --		block.Encrypt(tbl, dst[base:])
    
    399
    --		base += 16
    
    400
    --		fallthrough
    
    401
    --	case 6:
    
    402
    --		xor.Bytes16Align(dst[base:], src[base:], tbl)
    
    403
    --		block.Encrypt(tbl, dst[base:])
    
    404
    --		base += 16
    
    405
    --		fallthrough
    
    406
    --	case 5:
    
    407
    --		xor.Bytes16Align(dst[base:], src[base:], tbl)
    
    408
    --		block.Encrypt(tbl, dst[base:])
    
    409
    --		base += 16
    
    410
    --		fallthrough
    
    411
    --	case 4:
    
    412
    --		xor.Bytes16Align(dst[base:], src[base:], tbl)
    
    413
    --		block.Encrypt(tbl, dst[base:])
    
    414
    --		base += 16
    
    415
    --		fallthrough
    
    416
    --	case 3:
    
    417
    --		xor.Bytes16Align(dst[base:], src[base:], tbl)
    
    418
    --		block.Encrypt(tbl, dst[base:])
    
    419
    --		base += 16
    
    420
    --		fallthrough
    
    421
    --	case 2:
    
    422
    --		xor.Bytes16Align(dst[base:], src[base:], tbl)
    
    423
    --		block.Encrypt(tbl, dst[base:])
    
    424
    --		base += 16
    
    425
    --		fallthrough
    
    426
    --	case 1:
    
    427
    --		xor.Bytes16Align(dst[base:], src[base:], tbl)
    
    428
    --		block.Encrypt(tbl, dst[base:])
    
    429
    --		base += 16
    
    430
    --		fallthrough
    
    431
    --	case 0:
    
    432
    --		xorBytes(dst[base:], src[base:], tbl)
    
    433
    --	}
    
    434
    --}
    
    435
    --
    
    436
    --// decryption
    
    437
    --func decrypt(block cipher.Block, dst, src, buf []byte) {
    
    438
    --	switch block.BlockSize() {
    
    439
    --	case 8:
    
    440
    --		decrypt8(block, dst, src, buf)
    
    441
    --	case 16:
    
    442
    --		decrypt16(block, dst, src, buf)
    
    443
    --	default:
    
    444
    --		panic("unsupported cipher block size")
    
    445
    --	}
    
    446
    --}
    
    447
    --
    
    448
    --// decrypt 8 bytes block, all byte slices are supposed to be 64bit aligned
    
    449
    --func decrypt8(block cipher.Block, dst, src, buf []byte) {
    
    450
    --	tbl := buf[0:8]
    
    451
    --	next := buf[8:16]
    
    452
    --	block.Encrypt(tbl, initialVector)
    
    453
    --	n := len(src) / 8
    
    454
    --	base := 0
    
    455
    --	repeat := n / 8
    
    456
    --	left := n % 8
    
    457
    --	ptr_tbl := (*uint64)(unsafe.Pointer(&tbl[0]))
    
    458
    --	ptr_next := (*uint64)(unsafe.Pointer(&next[0]))
    
    459
    --
    
    460
    --	for i := 0; i < repeat; i++ {
    
    461
    --		s := src[base:][0:64]
    
    462
    --		d := dst[base:][0:64]
    
    463
    --		// 1
    
    464
    --		block.Encrypt(next, s[0:8])
    
    465
    --		*(*uint64)(unsafe.Pointer(&d[0])) = *(*uint64)(unsafe.Pointer(&s[0])) ^ *ptr_tbl
    
    466
    --		// 2
    
    467
    --		block.Encrypt(tbl, s[8:16])
    
    468
    --		*(*uint64)(unsafe.Pointer(&d[8])) = *(*uint64)(unsafe.Pointer(&s[8])) ^ *ptr_next
    
    469
    --		// 3
    
    470
    --		block.Encrypt(next, s[16:24])
    
    471
    --		*(*uint64)(unsafe.Pointer(&d[16])) = *(*uint64)(unsafe.Pointer(&s[16])) ^ *ptr_tbl
    
    472
    --		// 4
    
    473
    --		block.Encrypt(tbl, s[24:32])
    
    474
    --		*(*uint64)(unsafe.Pointer(&d[24])) = *(*uint64)(unsafe.Pointer(&s[24])) ^ *ptr_next
    
    475
    --		// 5
    
    476
    --		block.Encrypt(next, s[32:40])
    
    477
    --		*(*uint64)(unsafe.Pointer(&d[32])) = *(*uint64)(unsafe.Pointer(&s[32])) ^ *ptr_tbl
    
    478
    --		// 6
    
    479
    --		block.Encrypt(tbl, s[40:48])
    
    480
    --		*(*uint64)(unsafe.Pointer(&d[40])) = *(*uint64)(unsafe.Pointer(&s[40])) ^ *ptr_next
    
    481
    --		// 7
    
    482
    --		block.Encrypt(next, s[48:56])
    
    483
    --		*(*uint64)(unsafe.Pointer(&d[48])) = *(*uint64)(unsafe.Pointer(&s[48])) ^ *ptr_tbl
    
    484
    --		// 8
    
    485
    --		block.Encrypt(tbl, s[56:64])
    
    486
    --		*(*uint64)(unsafe.Pointer(&d[56])) = *(*uint64)(unsafe.Pointer(&s[56])) ^ *ptr_next
    
    487
    --		base += 64
    
    488
    --	}
    
    489
    --
    
    490
    --	switch left {
    
    491
    --	case 7:
    
    492
    --		block.Encrypt(next, src[base:])
    
    493
    --		*(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *(*uint64)(unsafe.Pointer(&tbl[0]))
    
    494
    --		tbl, next = next, tbl
    
    495
    --		base += 8
    
    496
    --		fallthrough
    
    497
    --	case 6:
    
    498
    --		block.Encrypt(next, src[base:])
    
    499
    --		*(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *(*uint64)(unsafe.Pointer(&tbl[0]))
    
    500
    --		tbl, next = next, tbl
    
    501
    --		base += 8
    
    502
    --		fallthrough
    
    503
    --	case 5:
    
    504
    --		block.Encrypt(next, src[base:])
    
    505
    --		*(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *(*uint64)(unsafe.Pointer(&tbl[0]))
    
    506
    --		tbl, next = next, tbl
    
    507
    --		base += 8
    
    508
    --		fallthrough
    
    509
    --	case 4:
    
    510
    --		block.Encrypt(next, src[base:])
    
    511
    --		*(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *(*uint64)(unsafe.Pointer(&tbl[0]))
    
    512
    --		tbl, next = next, tbl
    
    513
    --		base += 8
    
    514
    --		fallthrough
    
    515
    --	case 3:
    
    516
    --		block.Encrypt(next, src[base:])
    
    517
    --		*(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *(*uint64)(unsafe.Pointer(&tbl[0]))
    
    518
    --		tbl, next = next, tbl
    
    519
    --		base += 8
    
    520
    --		fallthrough
    
    521
    --	case 2:
    
    522
    --		block.Encrypt(next, src[base:])
    
    523
    --		*(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *(*uint64)(unsafe.Pointer(&tbl[0]))
    
    524
    --		tbl, next = next, tbl
    
    525
    --		base += 8
    
    526
    --		fallthrough
    
    527
    --	case 1:
    
    528
    --		block.Encrypt(next, src[base:])
    
    529
    --		*(*uint64)(unsafe.Pointer(&dst[base])) = *(*uint64)(unsafe.Pointer(&src[base])) ^ *(*uint64)(unsafe.Pointer(&tbl[0]))
    
    530
    --		tbl, next = next, tbl
    
    531
    --		base += 8
    
    532
    --		fallthrough
    
    533
    --	case 0:
    
    534
    --		xorBytes(dst[base:], src[base:], tbl)
    
    535
    --	}
    
    536
    --}
    
    537
    --
    
    538
    --func decrypt16(block cipher.Block, dst, src, buf []byte) {
    
    539
    --	tbl := buf[0:16]
    
    540
    --	next := buf[16:32]
    
    541
    --	block.Encrypt(tbl, initialVector)
    
    542
    --	n := len(src) / 16
    
    543
    --	base := 0
    
    544
    --	repeat := n / 8
    
    545
    --	left := n % 8
    
    546
    --	for i := 0; i < repeat; i++ {
    
    547
    --		s := src[base:][0:128]
    
    548
    --		d := dst[base:][0:128]
    
    549
    --		// 1
    
    550
    --		block.Encrypt(next, s[0:16])
    
    551
    --		xor.Bytes16Align(d[0:16], s[0:16], tbl)
    
    552
    --		// 2
    
    553
    --		block.Encrypt(tbl, s[16:32])
    
    554
    --		xor.Bytes16Align(d[16:32], s[16:32], next)
    
    555
    --		// 3
    
    556
    --		block.Encrypt(next, s[32:48])
    
    557
    --		xor.Bytes16Align(d[32:48], s[32:48], tbl)
    
    558
    --		// 4
    
    559
    --		block.Encrypt(tbl, s[48:64])
    
    560
    --		xor.Bytes16Align(d[48:64], s[48:64], next)
    
    561
    --		// 5
    
    562
    --		block.Encrypt(next, s[64:80])
    
    563
    --		xor.Bytes16Align(d[64:80], s[64:80], tbl)
    
    564
    --		// 6
    
    565
    --		block.Encrypt(tbl, s[80:96])
    
    566
    --		xor.Bytes16Align(d[80:96], s[80:96], next)
    
    567
    --		// 7
    
    568
    --		block.Encrypt(next, s[96:112])
    
    569
    --		xor.Bytes16Align(d[96:112], s[96:112], tbl)
    
    570
    --		// 8
    
    571
    --		block.Encrypt(tbl, s[112:128])
    
    572
    --		xor.Bytes16Align(d[112:128], s[112:128], next)
    
    573
    --		base += 128
    
    574
    --	}
    
    575
    --
    
    576
    --	switch left {
    
    577
    --	case 7:
    
    578
    --		block.Encrypt(next, src[base:])
    
    579
    --		xor.Bytes16Align(dst[base:], src[base:], tbl)
    
    580
    --		tbl, next = next, tbl
    
    581
    --		base += 16
    
    582
    --		fallthrough
    
    583
    --	case 6:
    
    584
    --		block.Encrypt(next, src[base:])
    
    585
    --		xor.Bytes16Align(dst[base:], src[base:], tbl)
    
    586
    --		tbl, next = next, tbl
    
    587
    --		base += 16
    
    588
    --		fallthrough
    
    589
    --	case 5:
    
    590
    --		block.Encrypt(next, src[base:])
    
    591
    --		xor.Bytes16Align(dst[base:], src[base:], tbl)
    
    592
    --		tbl, next = next, tbl
    
    593
    --		base += 16
    
    594
    --		fallthrough
    
    595
    --	case 4:
    
    596
    --		block.Encrypt(next, src[base:])
    
    597
    --		xor.Bytes16Align(dst[base:], src[base:], tbl)
    
    598
    --		tbl, next = next, tbl
    
    599
    --		base += 16
    
    600
    --		fallthrough
    
    601
    --	case 3:
    
    602
    --		block.Encrypt(next, src[base:])
    
    603
    --		xor.Bytes16Align(dst[base:], src[base:], tbl)
    
    604
    --		tbl, next = next, tbl
    
    605
    --		base += 16
    
    606
    --		fallthrough
    
    607
    --	case 2:
    
    608
    --		block.Encrypt(next, src[base:])
    
    609
    --		xor.Bytes16Align(dst[base:], src[base:], tbl)
    
    610
    --		tbl, next = next, tbl
    
    611
    --		base += 16
    
    612
    --		fallthrough
    
    613
    --	case 1:
    
    614
    --		block.Encrypt(next, src[base:])
    
    615
    --		xor.Bytes16Align(dst[base:], src[base:], tbl)
    
    616
    --		tbl, next = next, tbl
    
    617
    --		base += 16
    
    618
    --		fallthrough
    
    619
    --	case 0:
    
    620
    --		xorBytes(dst[base:], src[base:], tbl)
    
    621
    --	}
    
    622
    --}
    
    623
    --
    
    624
    --// per bytes xors
    
    625
    --func xorBytes(dst, a, b []byte) int {
    
    626
    --	n := len(a)
    
    627
    --	if len(b) < n {
    
    628
    --		n = len(b)
    
    629
    --	}
    
    630
    --	if n == 0 {
    
    631
    --		return 0
    
    632
    --	}
    
    633
    --
    
    634
    --	for i := 0; i < n; i++ {
    
    635
    --		dst[i] = a[i] ^ b[i]
    
    636
    --	}
    
    637
    --	return n
    
    638
    --}
    
    639
    -diff --git a/fec.go b/fec.go
    
    640
    -deleted file mode 100644
    
    641
    -index 97cd40b..0000000
    
    642
    ---- a/fec.go
    
    643
    -+++ /dev/null
    
    644
    -@@ -1,337 +0,0 @@
    
    645
    --package kcp
    
    646
    --
    
    647
    --import (
    
    648
    --	"encoding/binary"
    
    649
    --	"sync/atomic"
    
    650
    --
    
    651
    --	"github.com/klauspost/reedsolomon"
    
    652
    --)
    
    653
    --
    
    654
    --const (
    
    655
    --	fecHeaderSize      = 6
    
    656
    --	fecHeaderSizePlus2 = fecHeaderSize + 2 // plus 2B data size
    
    657
    --	typeData           = 0xf1
    
    658
    --	typeParity         = 0xf2
    
    659
    --	fecExpire          = 60000
    
    660
    --)
    
    661
    --
    
    662
    --// fecPacket is a decoded FEC packet
    
    663
    --type fecPacket []byte
    
    664
    --
    
    665
    --func (bts fecPacket) seqid() uint32 { return binary.LittleEndian.Uint32(bts) }
    
    666
    --func (bts fecPacket) flag() uint16  { return binary.LittleEndian.Uint16(bts[4:]) }
    
    667
    --func (bts fecPacket) data() []byte  { return bts[6:] }
    
    668
    --
    
    669
    --// fecElement has auxcilliary time field
    
    670
    --type fecElement struct {
    
    671
    --	fecPacket
    
    672
    --	ts uint32
    
    673
    --}
    
    674
    --
    
    675
    --// fecDecoder for decoding incoming packets
    
    676
    --type fecDecoder struct {
    
    677
    --	rxlimit      int // queue size limit
    
    678
    --	dataShards   int
    
    679
    --	parityShards int
    
    680
    --	shardSize    int
    
    681
    --	rx           []fecElement // ordered receive queue
    
    682
    --
    
    683
    --	// caches
    
    684
    --	decodeCache [][]byte
    
    685
    --	flagCache   []bool
    
    686
    --
    
    687
    --	// zeros
    
    688
    --	zeros []byte
    
    689
    --
    
    690
    --	// RS decoder
    
    691
    --	codec reedsolomon.Encoder
    
    692
    --}
    
    693
    --
    
    694
    --func newFECDecoder(rxlimit, dataShards, parityShards int) *fecDecoder {
    
    695
    --	if dataShards <= 0 || parityShards <= 0 {
    
    696
    --		return nil
    
    697
    --	}
    
    698
    --	if rxlimit < dataShards+parityShards {
    
    699
    --		return nil
    
    700
    --	}
    
    701
    --
    
    702
    --	dec := new(fecDecoder)
    
    703
    --	dec.rxlimit = rxlimit
    
    704
    --	dec.dataShards = dataShards
    
    705
    --	dec.parityShards = parityShards
    
    706
    --	dec.shardSize = dataShards + parityShards
    
    707
    --	codec, err := reedsolomon.New(dataShards, parityShards)
    
    708
    --	if err != nil {
    
    709
    --		return nil
    
    710
    --	}
    
    711
    --	dec.codec = codec
    
    712
    --	dec.decodeCache = make([][]byte, dec.shardSize)
    
    713
    --	dec.flagCache = make([]bool, dec.shardSize)
    
    714
    --	dec.zeros = make([]byte, mtuLimit)
    
    715
    --	return dec
    
    716
    --}
    
    717
    --
    
    718
    --// decode a fec packet
    
    719
    --func (dec *fecDecoder) decode(in fecPacket) (recovered [][]byte) {
    
    720
    --	// insertion
    
    721
    --	n := len(dec.rx) - 1
    
    722
    --	insertIdx := 0
    
    723
    --	for i := n; i >= 0; i-- {
    
    724
    --		if in.seqid() == dec.rx[i].seqid() { // de-duplicate
    
    725
    --			return nil
    
    726
    --		} else if _itimediff(in.seqid(), dec.rx[i].seqid()) > 0 { // insertion
    
    727
    --			insertIdx = i + 1
    
    728
    --			break
    
    729
    --		}
    
    730
    --	}
    
    731
    --
    
    732
    --	// make a copy
    
    733
    --	pkt := fecPacket(xmitBuf.Get().([]byte)[:len(in)])
    
    734
    --	copy(pkt, in)
    
    735
    --	elem := fecElement{pkt, currentMs()}
    
    736
    --
    
    737
    --	// insert into ordered rx queue
    
    738
    --	if insertIdx == n+1 {
    
    739
    --		dec.rx = append(dec.rx, elem)
    
    740
    --	} else {
    
    741
    --		dec.rx = append(dec.rx, fecElement{})
    
    742
    --		copy(dec.rx[insertIdx+1:], dec.rx[insertIdx:]) // shift right
    
    743
    --		dec.rx[insertIdx] = elem
    
    744
    --	}
    
    745
    --
    
    746
    --	// shard range for current packet
    
    747
    --	shardBegin := pkt.seqid() - pkt.seqid()%uint32(dec.shardSize)
    
    748
    --	shardEnd := shardBegin + uint32(dec.shardSize) - 1
    
    749
    --
    
    750
    --	// max search range in ordered queue for current shard
    
    751
    --	searchBegin := insertIdx - int(pkt.seqid()%uint32(dec.shardSize))
    
    752
    --	if searchBegin < 0 {
    
    753
    --		searchBegin = 0
    
    754
    --	}
    
    755
    --	searchEnd := searchBegin + dec.shardSize - 1
    
    756
    --	if searchEnd >= len(dec.rx) {
    
    757
    --		searchEnd = len(dec.rx) - 1
    
    758
    --	}
    
    759
    --
    
    760
    --	// re-construct datashards
    
    761
    --	if searchEnd-searchBegin+1 >= dec.dataShards {
    
    762
    --		var numshard, numDataShard, first, maxlen int
    
    763
    --
    
    764
    --		// zero caches
    
    765
    --		shards := dec.decodeCache
    
    766
    --		shardsflag := dec.flagCache
    
    767
    --		for k := range dec.decodeCache {
    
    768
    --			shards[k] = nil
    
    769
    --			shardsflag[k] = false
    
    770
    --		}
    
    771
    --
    
    772
    --		// shard assembly
    
    773
    --		for i := searchBegin; i <= searchEnd; i++ {
    
    774
    --			seqid := dec.rx[i].seqid()
    
    775
    --			if _itimediff(seqid, shardEnd) > 0 {
    
    776
    --				break
    
    777
    --			} else if _itimediff(seqid, shardBegin) >= 0 {
    
    778
    --				shards[seqid%uint32(dec.shardSize)] = dec.rx[i].data()
    
    779
    --				shardsflag[seqid%uint32(dec.shardSize)] = true
    
    780
    --				numshard++
    
    781
    --				if dec.rx[i].flag() == typeData {
    
    782
    --					numDataShard++
    
    783
    --				}
    
    784
    --				if numshard == 1 {
    
    785
    --					first = i
    
    786
    --				}
    
    787
    --				if len(dec.rx[i].data()) > maxlen {
    
    788
    --					maxlen = len(dec.rx[i].data())
    
    789
    --				}
    
    790
    --			}
    
    791
    --		}
    
    792
    --
    
    793
    --		if numDataShard == dec.dataShards {
    
    794
    --			// case 1: no loss on data shards
    
    795
    --			dec.rx = dec.freeRange(first, numshard, dec.rx)
    
    796
    --		} else if numshard >= dec.dataShards {
    
    797
    --			// case 2: loss on data shards, but it's recoverable from parity shards
    
    798
    --			for k := range shards {
    
    799
    --				if shards[k] != nil {
    
    800
    --					dlen := len(shards[k])
    
    801
    --					shards[k] = shards[k][:maxlen]
    
    802
    --					copy(shards[k][dlen:], dec.zeros)
    
    803
    --				} else if k < dec.dataShards {
    
    804
    --					shards[k] = xmitBuf.Get().([]byte)[:0]
    
    805
    --				}
    
    806
    --			}
    
    807
    --			if err := dec.codec.ReconstructData(shards); err == nil {
    
    808
    --				for k := range shards[:dec.dataShards] {
    
    809
    --					if !shardsflag[k] {
    
    810
    --						// recovered data should be recycled
    
    811
    --						recovered = append(recovered, shards[k])
    
    812
    --					}
    
    813
    --				}
    
    814
    --			}
    
    815
    --			dec.rx = dec.freeRange(first, numshard, dec.rx)
    
    816
    --		}
    
    817
    --	}
    
    818
    --
    
    819
    --	// keep rxlimit
    
    820
    --	if len(dec.rx) > dec.rxlimit {
    
    821
    --		if dec.rx[0].flag() == typeData { // track the unrecoverable data
    
    822
    --			atomic.AddUint64(&DefaultSnmp.FECShortShards, 1)
    
    823
    --		}
    
    824
    --		dec.rx = dec.freeRange(0, 1, dec.rx)
    
    825
    --	}
    
    826
    --
    
    827
    --	// timeout policy
    
    828
    --	current := currentMs()
    
    829
    --	numExpired := 0
    
    830
    --	for k := range dec.rx {
    
    831
    --		if _itimediff(current, dec.rx[k].ts) > fecExpire {
    
    832
    --			numExpired++
    
    833
    --			continue
    
    834
    --		}
    
    835
    --		break
    
    836
    --	}
    
    837
    --	if numExpired > 0 {
    
    838
    --		dec.rx = dec.freeRange(0, numExpired, dec.rx)
    
    839
    --	}
    
    840
    --	return
    
    841
    --}
    
    842
    --
    
    843
    --// free a range of fecPacket
    
    844
    --func (dec *fecDecoder) freeRange(first, n int, q []fecElement) []fecElement {
    
    845
    --	for i := first; i < first+n; i++ { // recycle buffer
    
    846
    --		xmitBuf.Put([]byte(q[i].fecPacket))
    
    847
    --	}
    
    848
    --
    
    849
    --	if first == 0 && n < cap(q)/2 {
    
    850
    --		return q[n:]
    
    851
    --	}
    
    852
    --	copy(q[first:], q[first+n:])
    
    853
    --	return q[:len(q)-n]
    
    854
    --}
    
    855
    --
    
    856
    --// release all segments back to xmitBuf
    
    857
    --func (dec *fecDecoder) release() {
    
    858
    --	if n := len(dec.rx); n > 0 {
    
    859
    --		dec.rx = dec.freeRange(0, n, dec.rx)
    
    860
    --	}
    
    861
    --}
    
    862
    --
    
    863
    --type (
    
    864
    --	// fecEncoder for encoding outgoing packets
    
    865
    --	fecEncoder struct {
    
    866
    --		dataShards   int
    
    867
    --		parityShards int
    
    868
    --		shardSize    int
    
    869
    --		paws         uint32 // Protect Against Wrapped Sequence numbers
    
    870
    --		next         uint32 // next seqid
    
    871
    --
    
    872
    --		shardCount int // count the number of datashards collected
    
    873
    --		maxSize    int // track maximum data length in datashard
    
    874
    --
    
    875
    --		headerOffset  int // FEC header offset
    
    876
    --		payloadOffset int // FEC payload offset
    
    877
    --
    
    878
    --		// caches
    
    879
    --		shardCache  [][]byte
    
    880
    --		encodeCache [][]byte
    
    881
    --
    
    882
    --		// zeros
    
    883
    --		zeros []byte
    
    884
    --
    
    885
    --		// RS encoder
    
    886
    --		codec reedsolomon.Encoder
    
    887
    --	}
    
    888
    --)
    
    889
    --
    
    890
    --func newFECEncoder(dataShards, parityShards, offset int) *fecEncoder {
    
    891
    --	if dataShards <= 0 || parityShards <= 0 {
    
    892
    --		return nil
    
    893
    --	}
    
    894
    --	enc := new(fecEncoder)
    
    895
    --	enc.dataShards = dataShards
    
    896
    --	enc.parityShards = parityShards
    
    897
    --	enc.shardSize = dataShards + parityShards
    
    898
    --	enc.paws = 0xffffffff / uint32(enc.shardSize) * uint32(enc.shardSize)
    
    899
    --	enc.headerOffset = offset
    
    900
    --	enc.payloadOffset = enc.headerOffset + fecHeaderSize
    
    901
    --
    
    902
    --	codec, err := reedsolomon.New(dataShards, parityShards)
    
    903
    --	if err != nil {
    
    904
    --		return nil
    
    905
    --	}
    
    906
    --	enc.codec = codec
    
    907
    --
    
    908
    --	// caches
    
    909
    --	enc.encodeCache = make([][]byte, enc.shardSize)
    
    910
    --	enc.shardCache = make([][]byte, enc.shardSize)
    
    911
    --	for k := range enc.shardCache {
    
    912
    --		enc.shardCache[k] = make([]byte, mtuLimit)
    
    913
    --	}
    
    914
    --	enc.zeros = make([]byte, mtuLimit)
    
    915
    --	return enc
    
    916
    --}
    
    917
    --
    
    918
    --// encodes the packet, outputs parity shards if we have collected quorum datashards
    
    919
    --// notice: the contents of 'ps' will be re-written in successive calling
    
    920
    --func (enc *fecEncoder) encode(b []byte) (ps [][]byte) {
    
    921
    --	// The header format:
    
    922
    --	// | FEC SEQID(4B) | FEC TYPE(2B) | SIZE (2B) | PAYLOAD(SIZE-2) |
    
    923
    --	// |<-headerOffset                |<-payloadOffset
    
    924
    --	enc.markData(b[enc.headerOffset:])
    
    925
    --	binary.LittleEndian.PutUint16(b[enc.payloadOffset:], uint16(len(b[enc.payloadOffset:])))
    
    926
    --
    
    927
    --	// copy data from payloadOffset to fec shard cache
    
    928
    --	sz := len(b)
    
    929
    --	enc.shardCache[enc.shardCount] = enc.shardCache[enc.shardCount][:sz]
    
    930
    --	copy(enc.shardCache[enc.shardCount][enc.payloadOffset:], b[enc.payloadOffset:])
    
    931
    --	enc.shardCount++
    
    932
    --
    
    933
    --	// track max datashard length
    
    934
    --	if sz > enc.maxSize {
    
    935
    --		enc.maxSize = sz
    
    936
    --	}
    
    937
    --
    
    938
    --	//  Generation of Reed-Solomon Erasure Code
    
    939
    --	if enc.shardCount == enc.dataShards {
    
    940
    --		// fill '0' into the tail of each datashard
    
    941
    --		for i := 0; i < enc.dataShards; i++ {
    
    942
    --			shard := enc.shardCache[i]
    
    943
    --			slen := len(shard)
    
    944
    --			copy(shard[slen:enc.maxSize], enc.zeros)
    
    945
    --		}
    
    946
    --
    
    947
    --		// construct equal-sized slice with stripped header
    
    948
    --		cache := enc.encodeCache
    
    949
    --		for k := range cache {
    
    950
    --			cache[k] = enc.shardCache[k][enc.payloadOffset:enc.maxSize]
    
    951
    --		}
    
    952
    --
    
    953
    --		// encoding
    
    954
    --		if err := enc.codec.Encode(cache); err == nil {
    
    955
    --			ps = enc.shardCache[enc.dataShards:]
    
    956
    --			for k := range ps {
    
    957
    --				enc.markParity(ps[k][enc.headerOffset:])
    
    958
    --				ps[k] = ps[k][:enc.maxSize]
    
    959
    --			}
    
    960
    --		}
    
    961
    --
    
    962
    --		// counters resetting
    
    963
    --		enc.shardCount = 0
    
    964
    --		enc.maxSize = 0
    
    965
    --	}
    
    966
    --
    
    967
    --	return
    
    968
    --}
    
    969
    --
    
    970
    --func (enc *fecEncoder) markData(data []byte) {
    
    971
    --	binary.LittleEndian.PutUint32(data, enc.next)
    
    972
    --	binary.LittleEndian.PutUint16(data[4:], typeData)
    
    973
    --	enc.next++
    
    974
    --}
    
    975
    --
    
    976
    --func (enc *fecEncoder) markParity(data []byte) {
    
    977
    --	binary.LittleEndian.PutUint32(data, enc.next)
    
    978
    --	binary.LittleEndian.PutUint16(data[4:], typeParity)
    
    979
    --	// sequence wrap will only happen at parity shard
    
    980
    --	enc.next = (enc.next + 1) % enc.paws
    
    981
    --}
    
    982
    -diff --git a/removed.go b/removed.go
    
    983
    -new file mode 100644
    
    984
    -index 0000000..5ecf446
    
    985
    ---- /dev/null
    
    986
    -+++ b/removed.go
    
    987
    -@@ -0,0 +1,29 @@
    
    988
    -+package kcp
    
    989
    -+
    
    990
    -+// Dummy implementations for types from crypt.go and fec.go, removed to reduce
    
    991
    -+// dependencies.
    
    992
    -+
    
    993
    -+const (
    
    994
    -+	fecHeaderSize      = 6
    
    995
    -+	fecHeaderSizePlus2 = fecHeaderSize + 2
    
    996
    -+	typeData           = 0xf1
    
    997
    -+	typeParity         = 0xf2
    
    998
    -+)
    
    999
    -+
    
    1000
    -+type (
    
    1001
    -+	BlockCrypt interface {
    
    1002
    -+		Encrypt(_, _ []byte)
    
    1003
    -+		Decrypt(_, _ []byte)
    
    1004
    -+	}
    
    1005
    -+	fecDecoder struct{}
    
    1006
    -+	fecEncoder struct{}
    
    1007
    -+	fecPacket  []byte
    
    1008
    -+)
    
    1009
    -+
    
    1010
    -+func newFECDecoder(rxlimit, dataShards, parityShards int) *fecDecoder { return nil }
    
    1011
    -+func newFECEncoder(dataShards, parityShards, offset int) *fecEncoder  { return nil }
    
    1012
    -+
    
    1013
    -+func (_ *fecDecoder) decode(in fecPacket) [][]byte { panic("disabled") }
    
    1014
    -+func (_ *fecDecoder) release()                     { panic("disabled") }
    
    1015
    -+func (_ *fecEncoder) encode(b []byte) [][]byte     { panic("disabled") }
    
    1016
    -+func (_ fecPacket) flag() uint16                   { panic("disabled") }
    
    1017
    --- 
    
    1018
    -2.20.1
    
    1019
    -