Этот коммит содержится в:
Christopher Speller
2016-11-16 19:28:52 -05:00
коммит произвёл GitHub
родитель 0b296dd8c2
Коммит 0135904f7d
445 изменённых файлов: 38624 добавлений и 14161 удалений

2
vendor/golang.org/x/crypto/acme/acme.go сгенерированный поставляемый
Просмотреть файл

@@ -406,9 +406,11 @@ func (c *Client) GetAuthorization(ctx context.Context, url string) (*Authorizati
func (c *Client) RevokeAuthorization(ctx context.Context, url string) error {
req := struct {
Resource string `json:"resource"`
Status string `json:"status"`
Delete bool `json:"delete"`
}{
Resource: "authz",
Status: "deactivated",
Delete: true,
}
res, err := postJWS(ctx, c.HTTPClient, c.Key, url, req)

4
vendor/golang.org/x/crypto/acme/acme_test.go сгенерированный поставляемый
Просмотреть файл

@@ -562,12 +562,16 @@ func TestRevokeAuthorization(t *testing.T) {
case "/1":
var req struct {
Resource string
Status string
Delete bool
}
decodeJWSRequest(t, &req, r)
if req.Resource != "authz" {
t.Errorf("req.Resource = %q; want authz", req.Resource)
}
if req.Status != "deactivated" {
t.Errorf("req.Status = %q; want deactivated", req.Status)
}
if !req.Delete {
t.Errorf("req.Delete is false")
}

188
vendor/golang.org/x/crypto/blake2b/blake2b.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,188 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package blake2b implements the BLAKE2b hash algorithm as
// defined in RFC 7693.
package blake2b
import (
"encoding/binary"
"errors"
"hash"
)
const (
// The blocksize of BLAKE2b in bytes.
BlockSize = 128
// The hash size of BLAKE2b-512 in bytes.
Size = 64
// The hash size of BLAKE2b-384 in bytes.
Size384 = 48
// The hash size of BLAKE2b-256 in bytes.
Size256 = 32
)
var errKeySize = errors.New("blake2b: invalid key size")
var iv = [8]uint64{
0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
}
// Sum512 returns the BLAKE2b-512 checksum of the data.
func Sum512(data []byte) [Size]byte {
var sum [Size]byte
checkSum(&sum, Size, data)
return sum
}
// Sum384 returns the BLAKE2b-384 checksum of the data.
func Sum384(data []byte) [Size384]byte {
var sum [Size]byte
var sum384 [Size384]byte
checkSum(&sum, Size384, data)
copy(sum384[:], sum[:Size384])
return sum384
}
// Sum256 returns the BLAKE2b-256 checksum of the data.
func Sum256(data []byte) [Size256]byte {
var sum [Size]byte
var sum256 [Size256]byte
checkSum(&sum, Size256, data)
copy(sum256[:], sum[:Size256])
return sum256
}
// New512 returns a new hash.Hash computing the BLAKE2b-512 checksum. A non-nil
// key turns the hash into a MAC. The key must between zero and 64 bytes long.
func New512(key []byte) (hash.Hash, error) { return newDigest(Size, key) }
// New384 returns a new hash.Hash computing the BLAKE2b-384 checksum. A non-nil
// key turns the hash into a MAC. The key must between zero and 64 bytes long.
func New384(key []byte) (hash.Hash, error) { return newDigest(Size384, key) }
// New256 returns a new hash.Hash computing the BLAKE2b-256 checksum. A non-nil
// key turns the hash into a MAC. The key must between zero and 64 bytes long.
func New256(key []byte) (hash.Hash, error) { return newDigest(Size256, key) }
func newDigest(hashSize int, key []byte) (*digest, error) {
if len(key) > Size {
return nil, errKeySize
}
d := &digest{
size: hashSize,
keyLen: len(key),
}
copy(d.key[:], key)
d.Reset()
return d, nil
}
func checkSum(sum *[Size]byte, hashSize int, data []byte) {
h := iv
h[0] ^= uint64(hashSize) | (1 << 16) | (1 << 24)
var c [2]uint64
if length := len(data); length > BlockSize {
n := length &^ (BlockSize - 1)
if length == n {
n -= BlockSize
}
hashBlocks(&h, &c, 0, data[:n])
data = data[n:]
}
var block [BlockSize]byte
offset := copy(block[:], data)
remaining := uint64(BlockSize - offset)
if c[0] < remaining {
c[1]--
}
c[0] -= remaining
hashBlocks(&h, &c, 0xFFFFFFFFFFFFFFFF, block[:])
for i, v := range h[:(hashSize+7)/8] {
binary.LittleEndian.PutUint64(sum[8*i:], v)
}
}
type digest struct {
h [8]uint64
c [2]uint64
size int
block [BlockSize]byte
offset int
key [BlockSize]byte
keyLen int
}
func (d *digest) BlockSize() int { return BlockSize }
func (d *digest) Size() int { return d.size }
func (d *digest) Reset() {
d.h = iv
d.h[0] ^= uint64(d.size) | (uint64(d.keyLen) << 8) | (1 << 16) | (1 << 24)
d.offset, d.c[0], d.c[1] = 0, 0, 0
if d.keyLen > 0 {
d.block = d.key
d.offset = BlockSize
}
}
func (d *digest) Write(p []byte) (n int, err error) {
n = len(p)
if d.offset > 0 {
remaining := BlockSize - d.offset
if n <= remaining {
d.offset += copy(d.block[d.offset:], p)
return
}
copy(d.block[d.offset:], p[:remaining])
hashBlocks(&d.h, &d.c, 0, d.block[:])
d.offset = 0
p = p[remaining:]
}
if length := len(p); length > BlockSize {
nn := length &^ (BlockSize - 1)
if length == nn {
nn -= BlockSize
}
hashBlocks(&d.h, &d.c, 0, p[:nn])
p = p[nn:]
}
if len(p) > 0 {
d.offset += copy(d.block[:], p)
}
return
}
func (d *digest) Sum(b []byte) []byte {
var block [BlockSize]byte
copy(block[:], d.block[:d.offset])
remaining := uint64(BlockSize - d.offset)
c := d.c
if c[0] < remaining {
c[1]--
}
c[0] -= remaining
h := d.h
hashBlocks(&h, &c, 0xFFFFFFFFFFFFFFFF, block[:])
var sum [Size]byte
for i, v := range h[:(d.size+7)/8] {
binary.LittleEndian.PutUint64(sum[8*i:], v)
}
return append(b, sum[:d.size]...)
}

32
vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,32 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.7,amd64,!gccgo,!appengine
package blake2b
var useAVX2 = supportAVX2()
var useSSE4 = supportSSE4()
//go:noescape
func supportSSE4() bool
//go:noescape
func supportAVX2() bool
//go:noescape
func hashBlocksAVX2(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
//go:noescape
func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
if useAVX2 {
hashBlocksAVX2(h, c, flag, blocks)
} else if useSSE4 {
hashBlocksSSE4(h, c, flag, blocks)
} else {
hashBlocksGeneric(h, c, flag, blocks)
}
}

196
vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,196 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.7,amd64,!gccgo,!appengine
#include "textflag.h"
DATA ·AVX_iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908
DATA ·AVX_iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b
DATA ·AVX_iv0<>+0x10(SB)/8, $0x3c6ef372fe94f82b
DATA ·AVX_iv0<>+0x18(SB)/8, $0xa54ff53a5f1d36f1
GLOBL ·AVX_iv0<>(SB), (NOPTR+RODATA), $32
DATA ·AVX_iv1<>+0x00(SB)/8, $0x510e527fade682d1
DATA ·AVX_iv1<>+0x08(SB)/8, $0x9b05688c2b3e6c1f
DATA ·AVX_iv1<>+0x10(SB)/8, $0x1f83d9abfb41bd6b
DATA ·AVX_iv1<>+0x18(SB)/8, $0x5be0cd19137e2179
GLOBL ·AVX_iv1<>(SB), (NOPTR+RODATA), $32
DATA ·AVX_c40<>+0x00(SB)/8, $0x0201000706050403
DATA ·AVX_c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b
DATA ·AVX_c40<>+0x10(SB)/8, $0x0201000706050403
DATA ·AVX_c40<>+0x18(SB)/8, $0x0a09080f0e0d0c0b
GLOBL ·AVX_c40<>(SB), (NOPTR+RODATA), $32
DATA ·AVX_c48<>+0x00(SB)/8, $0x0100070605040302
DATA ·AVX_c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a
DATA ·AVX_c48<>+0x10(SB)/8, $0x0100070605040302
DATA ·AVX_c48<>+0x18(SB)/8, $0x09080f0e0d0c0b0a
GLOBL ·AVX_c48<>(SB), (NOPTR+RODATA), $32
// unfortunately the BYTE representation of VPERMQ must be used
#define ROUND(m0, m1, m2, m3, t, c40, c48) \
VPADDQ m0, Y0, Y0; \
VPADDQ Y1, Y0, Y0; \
VPXOR Y0, Y3, Y3; \
VPSHUFD $-79, Y3, Y3; \
VPADDQ Y3, Y2, Y2; \
VPXOR Y2, Y1, Y1; \
VPSHUFB c40, Y1, Y1; \
VPADDQ m1, Y0, Y0; \
VPADDQ Y1, Y0, Y0; \
VPXOR Y0, Y3, Y3; \
VPSHUFB c48, Y3, Y3; \
VPADDQ Y3, Y2, Y2; \
VPXOR Y2, Y1, Y1; \
VPADDQ Y1, Y1, t; \
VPSRLQ $63, Y1, Y1; \
VPXOR t, Y1, Y1; \
BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xc9; BYTE $0x39 \ // VPERMQ 0x39, Y1, Y1
BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xd2; BYTE $0x4e \ // VPERMQ 0x4e, Y2, Y2
BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xdb; BYTE $0x93 \ // VPERMQ 0x93, Y3, Y3
VPADDQ m2, Y0, Y0; \
VPADDQ Y1, Y0, Y0; \
VPXOR Y0, Y3, Y3; \
VPSHUFD $-79, Y3, Y3; \
VPADDQ Y3, Y2, Y2; \
VPXOR Y2, Y1, Y1; \
VPSHUFB c40, Y1, Y1; \
VPADDQ m3, Y0, Y0; \
VPADDQ Y1, Y0, Y0; \
VPXOR Y0, Y3, Y3; \
VPSHUFB c48, Y3, Y3; \
VPADDQ Y3, Y2, Y2; \
VPXOR Y2, Y1, Y1; \
VPADDQ Y1, Y1, t; \
VPSRLQ $63, Y1, Y1; \
VPXOR t, Y1, Y1; \
BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xdb; BYTE $0x39 \ // VPERMQ 0x39, Y3, Y3
BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xd2; BYTE $0x4e \ // VPERMQ 0x4e, Y2, Y2
BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xc9; BYTE $0x93 \ // VPERMQ 0x93, Y1, Y1
// load msg into Y12, Y13, Y14, Y15
#define LOAD_MSG(src, i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15) \
MOVQ i0*8(src), X12; \
PINSRQ $1, i1*8(src), X12; \
MOVQ i2*8(src), X11; \
PINSRQ $1, i3*8(src), X11; \
VINSERTI128 $1, X11, Y12, Y12; \
MOVQ i4*8(src), X13; \
PINSRQ $1, i5*8(src), X13; \
MOVQ i6*8(src), X11; \
PINSRQ $1, i7*8(src), X11; \
VINSERTI128 $1, X11, Y13, Y13; \
MOVQ i8*8(src), X14; \
PINSRQ $1, i9*8(src), X14; \
MOVQ i10*8(src), X11; \
PINSRQ $1, i11*8(src), X11; \
VINSERTI128 $1, X11, Y14, Y14; \
MOVQ i12*8(src), X15; \
PINSRQ $1, i13*8(src), X15; \
MOVQ i14*8(src), X11; \
PINSRQ $1, i15*8(src), X11; \
VINSERTI128 $1, X11, Y15, Y15
// func hashBlocksAVX2(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
TEXT ·hashBlocksAVX2(SB), 4, $320-48 // frame size = 288 + 32 byte alignment
MOVQ h+0(FP), AX
MOVQ c+8(FP), BX
MOVQ flag+16(FP), CX
MOVQ blocks_base+24(FP), SI
MOVQ blocks_len+32(FP), DI
MOVQ SP, DX
MOVQ SP, R9
ADDQ $31, R9
ANDQ $~31, R9
MOVQ R9, SP
MOVQ CX, 16(SP)
XORQ CX, CX
MOVQ CX, 24(SP)
VMOVDQU ·AVX_c40<>(SB), Y4
VMOVDQU ·AVX_c48<>(SB), Y5
VMOVDQU 0(AX), Y8
VMOVDQU 32(AX), Y9
VMOVDQU ·AVX_iv0<>(SB), Y6
VMOVDQU ·AVX_iv1<>(SB), Y7
MOVQ 0(BX), R8
MOVQ 8(BX), R9
MOVQ R9, 8(SP)
loop:
ADDQ $128, R8
MOVQ R8, 0(SP)
CMPQ R8, $128
JGE noinc
INCQ R9
MOVQ R9, 8(SP)
noinc:
VMOVDQA Y8, Y0
VMOVDQA Y9, Y1
VMOVDQU Y6, Y2
VPXOR 0(SP), Y7, Y3
LOAD_MSG(SI, 0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15)
VMOVDQA Y12, 32(SP)
VMOVDQA Y13, 64(SP)
VMOVDQA Y14, 96(SP)
VMOVDQA Y15, 128(SP)
ROUND(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
LOAD_MSG(SI, 14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3)
VMOVDQA Y12, 160(SP)
VMOVDQA Y13, 192(SP)
VMOVDQA Y14, 224(SP)
VMOVDQA Y15, 256(SP)
ROUND(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
LOAD_MSG(SI, 11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4)
ROUND(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
LOAD_MSG(SI, 7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8)
ROUND(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
LOAD_MSG(SI, 9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13)
ROUND(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
LOAD_MSG(SI, 2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9)
ROUND(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
LOAD_MSG(SI, 12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11)
ROUND(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
LOAD_MSG(SI, 13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10)
ROUND(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
LOAD_MSG(SI, 6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5)
ROUND(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
LOAD_MSG(SI, 10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0)
ROUND(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
ROUND(32(SP), 64(SP), 96(SP), 128(SP), Y10, Y4, Y5)
ROUND(160(SP), 192(SP), 224(SP), 256(SP), Y10, Y4, Y5)
VPXOR Y0, Y8, Y8
VPXOR Y1, Y9, Y9
VPXOR Y2, Y8, Y8
VPXOR Y3, Y9, Y9
LEAQ 128(SI), SI
SUBQ $128, DI
JNE loop
MOVQ R8, 0(BX)
MOVQ R9, 8(BX)
VMOVDQU Y8, 0(AX)
VMOVDQU Y9, 32(AX)
MOVQ DX, SP
RET
// func supportAVX2() bool
TEXT ·supportAVX2(SB), 4, $0-1
MOVQ runtime·support_avx2(SB), AX
MOVB AX, ret+0(FP)
RET

24
vendor/golang.org/x/crypto/blake2b/blake2b_amd64.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,24 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !go1.7,amd64,!gccgo,!appengine
package blake2b
var useAVX2 = false
var useSSE4 = supportSSE4()
//go:noescape
func supportSSE4() bool
//go:noescape
func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
if useSSE4 {
hashBlocksSSE4(h, c, flag, blocks)
} else {
hashBlocksGeneric(h, c, flag, blocks)
}
}

275
vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,275 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build amd64,!gccgo,!appengine
#include "textflag.h"
DATA ·iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908
DATA ·iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b
GLOBL ·iv0<>(SB), (NOPTR+RODATA), $16
DATA ·iv1<>+0x00(SB)/8, $0x3c6ef372fe94f82b
DATA ·iv1<>+0x08(SB)/8, $0xa54ff53a5f1d36f1
GLOBL ·iv1<>(SB), (NOPTR+RODATA), $16
DATA ·iv2<>+0x00(SB)/8, $0x510e527fade682d1
DATA ·iv2<>+0x08(SB)/8, $0x9b05688c2b3e6c1f
GLOBL ·iv2<>(SB), (NOPTR+RODATA), $16
DATA ·iv3<>+0x00(SB)/8, $0x1f83d9abfb41bd6b
DATA ·iv3<>+0x08(SB)/8, $0x5be0cd19137e2179
GLOBL ·iv3<>(SB), (NOPTR+RODATA), $32
DATA ·c40<>+0x00(SB)/8, $0x0201000706050403
DATA ·c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b
GLOBL ·c40<>(SB), (NOPTR+RODATA), $16
DATA ·c48<>+0x00(SB)/8, $0x0100070605040302
DATA ·c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a
GLOBL ·c48<>(SB), (NOPTR+RODATA), $16
#define SHUFFLE(v2, v3, v4, v5, v6, v7, t0, t1, t2) \
MOVO v4, t0; \
MOVO v5, v4; \
MOVO t0, v5; \
MOVO v6, t0; \
PUNPCKLQDQ v6, t2; \
PUNPCKHQDQ v7, v6; \
PUNPCKHQDQ t2, v6; \
PUNPCKLQDQ v7, t2; \
MOVO t0, v7; \
MOVO v2, t1; \
PUNPCKHQDQ t2, v7; \
PUNPCKLQDQ v3, t2; \
PUNPCKHQDQ t2, v2; \
PUNPCKLQDQ t1, t2; \
PUNPCKHQDQ t2, v3
#define SHUFFLE_INV(v2, v3, v4, v5, v6, v7, t0, t1, t2) \
MOVO v4, t0; \
MOVO v5, v4; \
MOVO t0, v5; \
MOVO v2, t0; \
PUNPCKLQDQ v2, t2; \
PUNPCKHQDQ v3, v2; \
PUNPCKHQDQ t2, v2; \
PUNPCKLQDQ v3, t2; \
MOVO t0, v3; \
MOVO v6, t1; \
PUNPCKHQDQ t2, v3; \
PUNPCKLQDQ v7, t2; \
PUNPCKHQDQ t2, v6; \
PUNPCKLQDQ t1, t2; \
PUNPCKHQDQ t2, v7
#define HALF_ROUND(v0, v1, v2, v3, v4, v5, v6, v7, m0, m1, m2, m3, t0, t1, t2, c40, c48) \
PADDQ m0, v0; \
PADDQ m1, v1; \
PADDQ v2, v0; \
PADDQ v3, v1; \
PXOR v0, v6; \
PXOR v1, v7; \
PSHUFD $0xB1, v6, v6; \
PSHUFD $0xB1, v7, v7; \
PADDQ v6, v4; \
PADDQ v7, v5; \
PXOR v4, v2; \
PXOR v5, v3; \
PSHUFB c40, v2; \
PSHUFB c40, v3; \
PADDQ m2, v0; \
PADDQ m3, v1; \
PADDQ v2, v0; \
PADDQ v3, v1; \
PXOR v0, v6; \
PXOR v1, v7; \
PSHUFB c48, v6; \
PSHUFB c48, v7; \
PADDQ v6, v4; \
PADDQ v7, v5; \
PXOR v4, v2; \
PXOR v5, v3; \
MOVOU v2, t2; \
PADDQ v2, t2; \
PSRLQ $63, v2; \
PXOR t2, v2; \
MOVOU v3, t2; \
PADDQ v3, t2; \
PSRLQ $63, v3; \
PXOR t2, v3
#define LOAD_MSG(m0, m1, m2, m3, src, i0, i1, i2, i3, i4, i5, i6, i7) \
MOVQ i0*8(src), m0; \
PINSRQ $1, i1*8(src), m0; \
MOVQ i2*8(src), m1; \
PINSRQ $1, i3*8(src), m1; \
MOVQ i4*8(src), m2; \
PINSRQ $1, i5*8(src), m2; \
MOVQ i6*8(src), m3; \
PINSRQ $1, i7*8(src), m3
// func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
TEXT ·hashBlocksSSE4(SB), 4, $32-48 // frame size = 16 + 16 byte alignment
MOVQ h+0(FP), AX
MOVQ c+8(FP), BX
MOVQ flag+16(FP), CX
MOVQ blocks_base+24(FP), SI
MOVQ blocks_len+32(FP), DI
MOVQ SP, BP
MOVQ SP, R9
ADDQ $15, R9
ANDQ $~15, R9
MOVQ R9, SP
MOVOU ·iv3<>(SB), X0
MOVO X0, 0(SP)
XORQ CX, 0(SP) // 0(SP) = ·iv3 ^ (CX || 0)
MOVOU ·c40<>(SB), X13
MOVOU ·c48<>(SB), X14
MOVQ 0(BX), R8
MOVQ 8(BX), R9
loop:
ADDQ $128, R8
CMPQ R8, $128
JGE noinc
INCQ R9
noinc:
MOVQ R8, X15
PINSRQ $1, R9, X15
MOVOU 0(AX), X0
MOVOU 16(AX), X1
MOVOU 32(AX), X2
MOVOU 48(AX), X3
MOVOU ·iv0<>(SB), X4
MOVOU ·iv1<>(SB), X5
MOVOU ·iv2<>(SB), X6
PXOR X15, X6
MOVO 0(SP), X7
LOAD_MSG(X8, X9, X10, X11, SI, 0, 2, 4, 6, 1, 3, 5, 7)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 8, 10, 12, 14, 9, 11, 13, 15)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 14, 4, 9, 13, 10, 8, 15, 6)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 1, 0, 11, 5, 12, 2, 7, 3)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 11, 12, 5, 15, 8, 0, 2, 13)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 10, 3, 7, 9, 14, 6, 1, 4)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 7, 3, 13, 11, 9, 1, 12, 14)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 2, 5, 4, 15, 6, 10, 0, 8)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 9, 5, 2, 10, 0, 7, 4, 15)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 14, 11, 6, 3, 1, 12, 8, 13)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 2, 6, 0, 8, 12, 10, 11, 3)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 4, 7, 15, 1, 13, 5, 14, 9)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 12, 1, 14, 4, 5, 15, 13, 10)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 0, 6, 9, 8, 7, 3, 2, 11)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 13, 7, 12, 3, 11, 14, 1, 9)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 5, 15, 8, 2, 0, 4, 6, 10)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 6, 14, 11, 0, 15, 9, 3, 8)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 12, 13, 1, 10, 2, 7, 4, 5)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 10, 8, 7, 1, 2, 4, 6, 5)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 15, 9, 3, 13, 11, 14, 12, 0)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 0, 2, 4, 6, 1, 3, 5, 7)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 8, 10, 12, 14, 9, 11, 13, 15)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 14, 4, 9, 13, 10, 8, 15, 6)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9, X10)
LOAD_MSG(X8, X9, X10, X11, SI, 1, 0, 11, 5, 12, 2, 7, 3)
HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X8, X9, X12, X13, X14)
SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9, X10)
MOVOU 0(AX), X8
MOVOU 16(AX), X9
MOVOU 32(AX), X10
MOVOU 48(AX), X11
PXOR X0, X8
PXOR X1, X9
PXOR X2, X10
PXOR X3, X11
PXOR X4, X8
PXOR X5, X9
PXOR X6, X10
PXOR X7, X11
MOVOU X8, 0(AX)
MOVOU X9, 16(AX)
MOVOU X10, 32(AX)
MOVOU X11, 48(AX)
LEAQ 128(SI), SI
SUBQ $128, DI
JNE loop
MOVOU X15, 0(BX)
MOVQ BP, SP
RET
// func supportSSE4() bool
TEXT ·supportSSE4(SB), 4, $0-1
MOVL $1, AX
CPUID
SHRL $15, CX // Bit 15 indicates SSE4 support
ANDL $1, CX // CX != 0 if support SSE4
MOVB CX, ret+0(FP)
RET

179
vendor/golang.org/x/crypto/blake2b/blake2b_generic.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,179 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package blake2b
import "encoding/binary"
// the precomputed values for BLAKE2b
// there are 12 16-byte arrays - one for each round
// the entries are calculated from the sigma constants.
var precomputed = [12][16]byte{
{0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15},
{14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3},
{11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4},
{7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8},
{9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13},
{2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9},
{12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11},
{13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10},
{6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5},
{10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0},
{0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15}, // equal to the first
{14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3}, // equal to the second
}
func hashBlocksGeneric(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
var m [16]uint64
c0, c1 := c[0], c[1]
for i := 0; i < len(blocks); {
c0 += BlockSize
if c0 < BlockSize {
c1++
}
v0, v1, v2, v3, v4, v5, v6, v7 := h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]
v8, v9, v10, v11, v12, v13, v14, v15 := iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]
v12 ^= c0
v13 ^= c1
v14 ^= flag
for j := range m {
m[j] = binary.LittleEndian.Uint64(blocks[i:])
i += 8
}
for j := range precomputed {
s := &(precomputed[j])
v0 += m[s[0]]
v0 += v4
v12 ^= v0
v12 = v12<<(64-32) | v12>>32
v8 += v12
v4 ^= v8
v4 = v4<<(64-24) | v4>>24
v1 += m[s[1]]
v1 += v5
v13 ^= v1
v13 = v13<<(64-32) | v13>>32
v9 += v13
v5 ^= v9
v5 = v5<<(64-24) | v5>>24
v2 += m[s[2]]
v2 += v6
v14 ^= v2
v14 = v14<<(64-32) | v14>>32
v10 += v14
v6 ^= v10
v6 = v6<<(64-24) | v6>>24
v3 += m[s[3]]
v3 += v7
v15 ^= v3
v15 = v15<<(64-32) | v15>>32
v11 += v15
v7 ^= v11
v7 = v7<<(64-24) | v7>>24
v0 += m[s[4]]
v0 += v4
v12 ^= v0
v12 = v12<<(64-16) | v12>>16
v8 += v12
v4 ^= v8
v4 = v4<<(64-63) | v4>>63
v1 += m[s[5]]
v1 += v5
v13 ^= v1
v13 = v13<<(64-16) | v13>>16
v9 += v13
v5 ^= v9
v5 = v5<<(64-63) | v5>>63
v2 += m[s[6]]
v2 += v6
v14 ^= v2
v14 = v14<<(64-16) | v14>>16
v10 += v14
v6 ^= v10
v6 = v6<<(64-63) | v6>>63
v3 += m[s[7]]
v3 += v7
v15 ^= v3
v15 = v15<<(64-16) | v15>>16
v11 += v15
v7 ^= v11
v7 = v7<<(64-63) | v7>>63
v0 += m[s[8]]
v0 += v5
v15 ^= v0
v15 = v15<<(64-32) | v15>>32
v10 += v15
v5 ^= v10
v5 = v5<<(64-24) | v5>>24
v1 += m[s[9]]
v1 += v6
v12 ^= v1
v12 = v12<<(64-32) | v12>>32
v11 += v12
v6 ^= v11
v6 = v6<<(64-24) | v6>>24
v2 += m[s[10]]
v2 += v7
v13 ^= v2
v13 = v13<<(64-32) | v13>>32
v8 += v13
v7 ^= v8
v7 = v7<<(64-24) | v7>>24
v3 += m[s[11]]
v3 += v4
v14 ^= v3
v14 = v14<<(64-32) | v14>>32
v9 += v14
v4 ^= v9
v4 = v4<<(64-24) | v4>>24
v0 += m[s[12]]
v0 += v5
v15 ^= v0
v15 = v15<<(64-16) | v15>>16
v10 += v15
v5 ^= v10
v5 = v5<<(64-63) | v5>>63
v1 += m[s[13]]
v1 += v6
v12 ^= v1
v12 = v12<<(64-16) | v12>>16
v11 += v12
v6 ^= v11
v6 = v6<<(64-63) | v6>>63
v2 += m[s[14]]
v2 += v7
v13 ^= v2
v13 = v13<<(64-16) | v13>>16
v8 += v13
v7 ^= v8
v7 = v7<<(64-63) | v7>>63
v3 += m[s[15]]
v3 += v4
v14 ^= v3
v14 = v14<<(64-16) | v14>>16
v9 += v14
v4 ^= v9
v4 = v4<<(64-63) | v4>>63
}
h[0] ^= v0 ^ v8
h[1] ^= v1 ^ v9
h[2] ^= v2 ^ v10
h[3] ^= v3 ^ v11
h[4] ^= v4 ^ v12
h[5] ^= v5 ^ v13
h[6] ^= v6 ^ v14
h[7] ^= v7 ^ v15
}
c[0], c[1] = c0, c1
}

14
vendor/golang.org/x/crypto/blake2b/blake2b_ref.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,14 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !amd64 appengine gccgo
package blake2b
var useAVX2 = false
var useSSE4 = false
func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
hashBlocksGeneric(h, c, flag, blocks)
}

443
vendor/golang.org/x/crypto/blake2b/blake2b_test.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,443 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package blake2b
import (
"bytes"
"encoding/hex"
"fmt"
"hash"
"testing"
)
func fromHex(s string) []byte {
b, err := hex.DecodeString(s)
if err != nil {
panic(err)
}
return b
}
func TestHashes(t *testing.T) {
defer func(sse4, avx2 bool) {
useSSE4, useAVX2 = sse4, avx2
}(useSSE4, useAVX2)
if useAVX2 {
t.Log("AVX2 version")
testHashes(t)
useAVX2 = false
}
if useSSE4 {
t.Log("SSE4 version")
testHashes(t)
useSSE4 = false
}
t.Log("generic version")
testHashes(t)
}
func testHashes(t *testing.T) {
key, _ := hex.DecodeString("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f")
input := make([]byte, 255)
for i := range input {
input[i] = byte(i)
}
for i, expectedHex := range hashes {
h, err := New512(key)
if err != nil {
t.Fatalf("#%d: error from New512: %v", i, err)
}
h.Write(input[:i])
sum := h.Sum(nil)
if gotHex := fmt.Sprintf("%x", sum); gotHex != expectedHex {
t.Fatalf("#%d (single write): got %s, wanted %s", i, gotHex, expectedHex)
}
h.Reset()
for j := 0; j < i; j++ {
h.Write(input[j : j+1])
}
sum = h.Sum(sum[:0])
if gotHex := fmt.Sprintf("%x", sum); gotHex != expectedHex {
t.Fatalf("#%d (byte-by-byte): got %s, wanted %s", i, gotHex, expectedHex)
}
}
}
func generateSequence(out []byte, seed uint32) {
a := 0xDEAD4BAD * seed // prime
b := uint32(1)
for i := range out { // fill the buf
a, b = b, a+b
out[i] = byte(b >> 24)
}
}
func computeMAC(msg []byte, hashSize int, key []byte) (sum []byte) {
var h hash.Hash
switch hashSize {
case Size:
h, _ = New512(key)
case Size384:
h, _ = New384(key)
case Size256:
h, _ = New256(key)
case 20:
h, _ = newDigest(20, key)
default:
panic("unexpected hashSize")
}
h.Write(msg)
return h.Sum(sum)
}
func computeHash(msg []byte, hashSize int) (sum []byte) {
switch hashSize {
case Size:
hash := Sum512(msg)
return hash[:]
case Size384:
hash := Sum384(msg)
return hash[:]
case Size256:
hash := Sum256(msg)
return hash[:]
case 20:
var hash [64]byte
checkSum(&hash, 20, msg)
return hash[:20]
default:
panic("unexpected hashSize")
}
}
// Test function from RFC 7693.
func TestSelfTest(t *testing.T) {
hashLens := [4]int{20, 32, 48, 64}
msgLens := [6]int{0, 3, 128, 129, 255, 1024}
msg := make([]byte, 1024)
key := make([]byte, 64)
h, _ := New256(nil)
for _, hashSize := range hashLens {
for _, msgLength := range msgLens {
generateSequence(msg[:msgLength], uint32(msgLength)) // unkeyed hash
md := computeHash(msg[:msgLength], hashSize)
h.Write(md)
generateSequence(key[:], uint32(hashSize)) // keyed hash
md = computeMAC(msg[:msgLength], hashSize, key[:hashSize])
h.Write(md)
}
}
sum := h.Sum(nil)
expected := [32]byte{
0xc2, 0x3a, 0x78, 0x00, 0xd9, 0x81, 0x23, 0xbd,
0x10, 0xf5, 0x06, 0xc6, 0x1e, 0x29, 0xda, 0x56,
0x03, 0xd7, 0x63, 0xb8, 0xbb, 0xad, 0x2e, 0x73,
0x7f, 0x5e, 0x76, 0x5a, 0x7b, 0xcc, 0xd4, 0x75,
}
if !bytes.Equal(sum, expected[:]) {
t.Fatalf("got %x, wanted %x", sum, expected)
}
}
// Benchmarks
func benchmarkSum(b *testing.B, size int) {
data := make([]byte, size)
b.SetBytes(int64(size))
b.ResetTimer()
for i := 0; i < b.N; i++ {
Sum512(data)
}
}
func benchmarkWrite(b *testing.B, size int) {
data := make([]byte, size)
h, _ := New512(nil)
b.SetBytes(int64(size))
b.ResetTimer()
for i := 0; i < b.N; i++ {
h.Write(data)
}
}
func BenchmarkWrite128(b *testing.B) { benchmarkWrite(b, 128) }
func BenchmarkWrite1K(b *testing.B) { benchmarkWrite(b, 1024) }
func BenchmarkSum128(b *testing.B) { benchmarkSum(b, 128) }
func BenchmarkSum1K(b *testing.B) { benchmarkSum(b, 1024) }
// These values were taken from https://blake2.net/blake2b-test.txt.
var hashes = []string{
"10ebb67700b1868efb4417987acf4690ae9d972fb7a590c2f02871799aaa4786b5e996e8f0f4eb981fc214b005f42d2ff4233499391653df7aefcbc13fc51568",
"961f6dd1e4dd30f63901690c512e78e4b45e4742ed197c3c5e45c549fd25f2e4187b0bc9fe30492b16b0d0bc4ef9b0f34c7003fac09a5ef1532e69430234cebd",
"da2cfbe2d8409a0f38026113884f84b50156371ae304c4430173d08a99d9fb1b983164a3770706d537f49e0c916d9f32b95cc37a95b99d857436f0232c88a965",
"33d0825dddf7ada99b0e7e307104ad07ca9cfd9692214f1561356315e784f3e5a17e364ae9dbb14cb2036df932b77f4b292761365fb328de7afdc6d8998f5fc1",
"beaa5a3d08f3807143cf621d95cd690514d0b49efff9c91d24b59241ec0eefa5f60196d407048bba8d2146828ebcb0488d8842fd56bb4f6df8e19c4b4daab8ac",
"098084b51fd13deae5f4320de94a688ee07baea2800486689a8636117b46c1f4c1f6af7f74ae7c857600456a58a3af251dc4723a64cc7c0a5ab6d9cac91c20bb",
"6044540d560853eb1c57df0077dd381094781cdb9073e5b1b3d3f6c7829e12066bbaca96d989a690de72ca3133a83652ba284a6d62942b271ffa2620c9e75b1f",
"7a8cfe9b90f75f7ecb3acc053aaed6193112b6f6a4aeeb3f65d3de541942deb9e2228152a3c4bbbe72fc3b12629528cfbb09fe630f0474339f54abf453e2ed52",
"380beaf6ea7cc9365e270ef0e6f3a64fb902acae51dd5512f84259ad2c91f4bc4108db73192a5bbfb0cbcf71e46c3e21aee1c5e860dc96e8eb0b7b8426e6abe9",
"60fe3c4535e1b59d9a61ea8500bfac41a69dffb1ceadd9aca323e9a625b64da5763bad7226da02b9c8c4f1a5de140ac5a6c1124e4f718ce0b28ea47393aa6637",
"4fe181f54ad63a2983feaaf77d1e7235c2beb17fa328b6d9505bda327df19fc37f02c4b6f0368ce23147313a8e5738b5fa2a95b29de1c7f8264eb77b69f585cd",
"f228773ce3f3a42b5f144d63237a72d99693adb8837d0e112a8a0f8ffff2c362857ac49c11ec740d1500749dac9b1f4548108bf3155794dcc9e4082849e2b85b",
"962452a8455cc56c8511317e3b1f3b2c37df75f588e94325fdd77070359cf63a9ae6e930936fdf8e1e08ffca440cfb72c28f06d89a2151d1c46cd5b268ef8563",
"43d44bfa18768c59896bf7ed1765cb2d14af8c260266039099b25a603e4ddc5039d6ef3a91847d1088d401c0c7e847781a8a590d33a3c6cb4df0fab1c2f22355",
"dcffa9d58c2a4ca2cdbb0c7aa4c4c1d45165190089f4e983bb1c2cab4aaeff1fa2b5ee516fecd780540240bf37e56c8bcca7fab980e1e61c9400d8a9a5b14ac6",
"6fbf31b45ab0c0b8dad1c0f5f4061379912dde5aa922099a030b725c73346c524291adef89d2f6fd8dfcda6d07dad811a9314536c2915ed45da34947e83de34e",
"a0c65bddde8adef57282b04b11e7bc8aab105b99231b750c021f4a735cb1bcfab87553bba3abb0c3e64a0b6955285185a0bd35fb8cfde557329bebb1f629ee93",
"f99d815550558e81eca2f96718aed10d86f3f1cfb675cce06b0eff02f617c5a42c5aa760270f2679da2677c5aeb94f1142277f21c7f79f3c4f0cce4ed8ee62b1",
"95391da8fc7b917a2044b3d6f5374e1ca072b41454d572c7356c05fd4bc1e0f40b8bb8b4a9f6bce9be2c4623c399b0dca0dab05cb7281b71a21b0ebcd9e55670",
"04b9cd3d20d221c09ac86913d3dc63041989a9a1e694f1e639a3ba7e451840f750c2fc191d56ad61f2e7936bc0ac8e094b60caeed878c18799045402d61ceaf9",
"ec0e0ef707e4ed6c0c66f9e089e4954b058030d2dd86398fe84059631f9ee591d9d77375355149178c0cf8f8e7c49ed2a5e4f95488a2247067c208510fadc44c",
"9a37cce273b79c09913677510eaf7688e89b3314d3532fd2764c39de022a2945b5710d13517af8ddc0316624e73bec1ce67df15228302036f330ab0cb4d218dd",
"4cf9bb8fb3d4de8b38b2f262d3c40f46dfe747e8fc0a414c193d9fcf753106ce47a18f172f12e8a2f1c26726545358e5ee28c9e2213a8787aafbc516d2343152",
"64e0c63af9c808fd893137129867fd91939d53f2af04be4fa268006100069b2d69daa5c5d8ed7fddcb2a70eeecdf2b105dd46a1e3b7311728f639ab489326bc9",
"5e9c93158d659b2def06b0c3c7565045542662d6eee8a96a89b78ade09fe8b3dcc096d4fe48815d88d8f82620156602af541955e1f6ca30dce14e254c326b88f",
"7775dff889458dd11aef417276853e21335eb88e4dec9cfb4e9edb49820088551a2ca60339f12066101169f0dfe84b098fddb148d9da6b3d613df263889ad64b",
"f0d2805afbb91f743951351a6d024f9353a23c7ce1fc2b051b3a8b968c233f46f50f806ecb1568ffaa0b60661e334b21dde04f8fa155ac740eeb42e20b60d764",
"86a2af316e7d7754201b942e275364ac12ea8962ab5bd8d7fb276dc5fbffc8f9a28cae4e4867df6780d9b72524160927c855da5b6078e0b554aa91e31cb9ca1d",
"10bdf0caa0802705e706369baf8a3f79d72c0a03a80675a7bbb00be3a45e516424d1ee88efb56f6d5777545ae6e27765c3a8f5e493fc308915638933a1dfee55",
"b01781092b1748459e2e4ec178696627bf4ebafebba774ecf018b79a68aeb84917bf0b84bb79d17b743151144cd66b7b33a4b9e52c76c4e112050ff5385b7f0b",
"c6dbc61dec6eaeac81e3d5f755203c8e220551534a0b2fd105a91889945a638550204f44093dd998c076205dffad703a0e5cd3c7f438a7e634cd59fededb539e",
"eba51acffb4cea31db4b8d87e9bf7dd48fe97b0253ae67aa580f9ac4a9d941f2bea518ee286818cc9f633f2a3b9fb68e594b48cdd6d515bf1d52ba6c85a203a7",
"86221f3ada52037b72224f105d7999231c5e5534d03da9d9c0a12acb68460cd375daf8e24386286f9668f72326dbf99ba094392437d398e95bb8161d717f8991",
"5595e05c13a7ec4dc8f41fb70cb50a71bce17c024ff6de7af618d0cc4e9c32d9570d6d3ea45b86525491030c0d8f2b1836d5778c1ce735c17707df364d054347",
"ce0f4f6aca89590a37fe034dd74dd5fa65eb1cbd0a41508aaddc09351a3cea6d18cb2189c54b700c009f4cbf0521c7ea01be61c5ae09cb54f27bc1b44d658c82",
"7ee80b06a215a3bca970c77cda8761822bc103d44fa4b33f4d07dcb997e36d55298bceae12241b3fa07fa63be5576068da387b8d5859aeab701369848b176d42",
"940a84b6a84d109aab208c024c6ce9647676ba0aaa11f86dbb7018f9fd2220a6d901a9027f9abcf935372727cbf09ebd61a2a2eeb87653e8ecad1bab85dc8327",
"2020b78264a82d9f4151141adba8d44bf20c5ec062eee9b595a11f9e84901bf148f298e0c9f8777dcdbc7cc4670aac356cc2ad8ccb1629f16f6a76bcefbee760",
"d1b897b0e075ba68ab572adf9d9c436663e43eb3d8e62d92fc49c9be214e6f27873fe215a65170e6bea902408a25b49506f47babd07cecf7113ec10c5dd31252",
"b14d0c62abfa469a357177e594c10c194243ed2025ab8aa5ad2fa41ad318e0ff48cd5e60bec07b13634a711d2326e488a985f31e31153399e73088efc86a5c55",
"4169c5cc808d2697dc2a82430dc23e3cd356dc70a94566810502b8d655b39abf9e7f902fe717e0389219859e1945df1af6ada42e4ccda55a197b7100a30c30a1",
"258a4edb113d66c839c8b1c91f15f35ade609f11cd7f8681a4045b9fef7b0b24c82cda06a5f2067b368825e3914e53d6948ede92efd6e8387fa2e537239b5bee",
"79d2d8696d30f30fb34657761171a11e6c3f1e64cbe7bebee159cb95bfaf812b4f411e2f26d9c421dc2c284a3342d823ec293849e42d1e46b0a4ac1e3c86abaa",
"8b9436010dc5dee992ae38aea97f2cd63b946d94fedd2ec9671dcde3bd4ce9564d555c66c15bb2b900df72edb6b891ebcadfeff63c9ea4036a998be7973981e7",
"c8f68e696ed28242bf997f5b3b34959508e42d613810f1e2a435c96ed2ff560c7022f361a9234b9837feee90bf47922ee0fd5f8ddf823718d86d1e16c6090071",
"b02d3eee4860d5868b2c39ce39bfe81011290564dd678c85e8783f29302dfc1399ba95b6b53cd9ebbf400cca1db0ab67e19a325f2d115812d25d00978ad1bca4",
"7693ea73af3ac4dad21ca0d8da85b3118a7d1c6024cfaf557699868217bc0c2f44a199bc6c0edd519798ba05bd5b1b4484346a47c2cadf6bf30b785cc88b2baf",
"a0e5c1c0031c02e48b7f09a5e896ee9aef2f17fc9e18e997d7f6cac7ae316422c2b1e77984e5f3a73cb45deed5d3f84600105e6ee38f2d090c7d0442ea34c46d",
"41daa6adcfdb69f1440c37b596440165c15ada596813e2e22f060fcd551f24dee8e04ba6890387886ceec4a7a0d7fc6b44506392ec3822c0d8c1acfc7d5aebe8",
"14d4d40d5984d84c5cf7523b7798b254e275a3a8cc0a1bd06ebc0bee726856acc3cbf516ff667cda2058ad5c3412254460a82c92187041363cc77a4dc215e487",
"d0e7a1e2b9a447fee83e2277e9ff8010c2f375ae12fa7aaa8ca5a6317868a26a367a0b69fbc1cf32a55d34eb370663016f3d2110230eba754028a56f54acf57c",
"e771aa8db5a3e043e8178f39a0857ba04a3f18e4aa05743cf8d222b0b095825350ba422f63382a23d92e4149074e816a36c1cd28284d146267940b31f8818ea2",
"feb4fd6f9e87a56bef398b3284d2bda5b5b0e166583a66b61e538457ff0584872c21a32962b9928ffab58de4af2edd4e15d8b35570523207ff4e2a5aa7754caa",
"462f17bf005fb1c1b9e671779f665209ec2873e3e411f98dabf240a1d5ec3f95ce6796b6fc23fe171903b502023467dec7273ff74879b92967a2a43a5a183d33",
"d3338193b64553dbd38d144bea71c5915bb110e2d88180dbc5db364fd6171df317fc7268831b5aef75e4342b2fad8797ba39eddcef80e6ec08159350b1ad696d",
"e1590d585a3d39f7cb599abd479070966409a6846d4377acf4471d065d5db94129cc9be92573b05ed226be1e9b7cb0cabe87918589f80dadd4ef5ef25a93d28e",
"f8f3726ac5a26cc80132493a6fedcb0e60760c09cfc84cad178175986819665e76842d7b9fedf76dddebf5d3f56faaad4477587af21606d396ae570d8e719af2",
"30186055c07949948183c850e9a756cc09937e247d9d928e869e20bafc3cd9721719d34e04a0899b92c736084550186886efba2e790d8be6ebf040b209c439a4",
"f3c4276cb863637712c241c444c5cc1e3554e0fddb174d035819dd83eb700b4ce88df3ab3841ba02085e1a99b4e17310c5341075c0458ba376c95a6818fbb3e2",
"0aa007c4dd9d5832393040a1583c930bca7dc5e77ea53add7e2b3f7c8e231368043520d4a3ef53c969b6bbfd025946f632bd7f765d53c21003b8f983f75e2a6a",
"08e9464720533b23a04ec24f7ae8c103145f765387d738777d3d343477fd1c58db052142cab754ea674378e18766c53542f71970171cc4f81694246b717d7564",
"d37ff7ad297993e7ec21e0f1b4b5ae719cdc83c5db687527f27516cbffa822888a6810ee5c1ca7bfe3321119be1ab7bfa0a502671c8329494df7ad6f522d440f",
"dd9042f6e464dcf86b1262f6accfafbd8cfd902ed3ed89abf78ffa482dbdeeb6969842394c9a1168ae3d481a017842f660002d42447c6b22f7b72f21aae021c9",
"bd965bf31e87d70327536f2a341cebc4768eca275fa05ef98f7f1b71a0351298de006fba73fe6733ed01d75801b4a928e54231b38e38c562b2e33ea1284992fa",
"65676d800617972fbd87e4b9514e1c67402b7a331096d3bfac22f1abb95374abc942f16e9ab0ead33b87c91968a6e509e119ff07787b3ef483e1dcdccf6e3022",
"939fa189699c5d2c81ddd1ffc1fa207c970b6a3685bb29ce1d3e99d42f2f7442da53e95a72907314f4588399a3ff5b0a92beb3f6be2694f9f86ecf2952d5b41c",
"c516541701863f91005f314108ceece3c643e04fc8c42fd2ff556220e616aaa6a48aeb97a84bad74782e8dff96a1a2fa949339d722edcaa32b57067041df88cc",
"987fd6e0d6857c553eaebb3d34970a2c2f6e89a3548f492521722b80a1c21a153892346d2cba6444212d56da9a26e324dccbc0dcde85d4d2ee4399eec5a64e8f",
"ae56deb1c2328d9c4017706bce6e99d41349053ba9d336d677c4c27d9fd50ae6aee17e853154e1f4fe7672346da2eaa31eea53fcf24a22804f11d03da6abfc2b",
"49d6a608c9bde4491870498572ac31aac3fa40938b38a7818f72383eb040ad39532bc06571e13d767e6945ab77c0bdc3b0284253343f9f6c1244ebf2ff0df866",
"da582ad8c5370b4469af862aa6467a2293b2b28bd80ae0e91f425ad3d47249fdf98825cc86f14028c3308c9804c78bfeeeee461444ce243687e1a50522456a1d",
"d5266aa3331194aef852eed86d7b5b2633a0af1c735906f2e13279f14931a9fc3b0eac5ce9245273bd1aa92905abe16278ef7efd47694789a7283b77da3c70f8",
"2962734c28252186a9a1111c732ad4de4506d4b4480916303eb7991d659ccda07a9911914bc75c418ab7a4541757ad054796e26797feaf36e9f6ad43f14b35a4",
"e8b79ec5d06e111bdfafd71e9f5760f00ac8ac5d8bf768f9ff6f08b8f026096b1cc3a4c973333019f1e3553e77da3f98cb9f542e0a90e5f8a940cc58e59844b3",
"dfb320c44f9d41d1efdcc015f08dd5539e526e39c87d509ae6812a969e5431bf4fa7d91ffd03b981e0d544cf72d7b1c0374f8801482e6dea2ef903877eba675e",
"d88675118fdb55a5fb365ac2af1d217bf526ce1ee9c94b2f0090b2c58a06ca58187d7fe57c7bed9d26fca067b4110eefcd9a0a345de872abe20de368001b0745",
"b893f2fc41f7b0dd6e2f6aa2e0370c0cff7df09e3acfcc0e920b6e6fad0ef747c40668417d342b80d2351e8c175f20897a062e9765e6c67b539b6ba8b9170545",
"6c67ec5697accd235c59b486d7b70baeedcbd4aa64ebd4eef3c7eac189561a726250aec4d48cadcafbbe2ce3c16ce2d691a8cce06e8879556d4483ed7165c063",
"f1aa2b044f8f0c638a3f362e677b5d891d6fd2ab0765f6ee1e4987de057ead357883d9b405b9d609eea1b869d97fb16d9b51017c553f3b93c0a1e0f1296fedcd",
"cbaa259572d4aebfc1917acddc582b9f8dfaa928a198ca7acd0f2aa76a134a90252e6298a65b08186a350d5b7626699f8cb721a3ea5921b753ae3a2dce24ba3a",
"fa1549c9796cd4d303dcf452c1fbd5744fd9b9b47003d920b92de34839d07ef2a29ded68f6fc9e6c45e071a2e48bd50c5084e96b657dd0404045a1ddefe282ed",
"5cf2ac897ab444dcb5c8d87c495dbdb34e1838b6b629427caa51702ad0f9688525f13bec503a3c3a2c80a65e0b5715e8afab00ffa56ec455a49a1ad30aa24fcd",
"9aaf80207bace17bb7ab145757d5696bde32406ef22b44292ef65d4519c3bb2ad41a59b62cc3e94b6fa96d32a7faadae28af7d35097219aa3fd8cda31e40c275",
"af88b163402c86745cb650c2988fb95211b94b03ef290eed9662034241fd51cf398f8073e369354c43eae1052f9b63b08191caa138aa54fea889cc7024236897",
"48fa7d64e1ceee27b9864db5ada4b53d00c9bc7626555813d3cd6730ab3cc06ff342d727905e33171bde6e8476e77fb1720861e94b73a2c538d254746285f430",
"0e6fd97a85e904f87bfe85bbeb34f69e1f18105cf4ed4f87aec36c6e8b5f68bd2a6f3dc8a9ecb2b61db4eedb6b2ea10bf9cb0251fb0f8b344abf7f366b6de5ab",
"06622da5787176287fdc8fed440bad187d830099c94e6d04c8e9c954cda70c8bb9e1fc4a6d0baa831b9b78ef6648681a4867a11da93ee36e5e6a37d87fc63f6f",
"1da6772b58fabf9c61f68d412c82f182c0236d7d575ef0b58dd22458d643cd1dfc93b03871c316d8430d312995d4197f0874c99172ba004a01ee295abac24e46",
"3cd2d9320b7b1d5fb9aab951a76023fa667be14a9124e394513918a3f44096ae4904ba0ffc150b63bc7ab1eeb9a6e257e5c8f000a70394a5afd842715de15f29",
"04cdc14f7434e0b4be70cb41db4c779a88eaef6accebcb41f2d42fffe7f32a8e281b5c103a27021d0d08362250753cdf70292195a53a48728ceb5844c2d98bab",
"9071b7a8a075d0095b8fb3ae5113785735ab98e2b52faf91d5b89e44aac5b5d4ebbf91223b0ff4c71905da55342e64655d6ef8c89a4768c3f93a6dc0366b5bc8",
"ebb30240dd96c7bc8d0abe49aa4edcbb4afdc51ff9aaf720d3f9e7fbb0f9c6d6571350501769fc4ebd0b2141247ff400d4fd4be414edf37757bb90a32ac5c65a",
"8532c58bf3c8015d9d1cbe00eef1f5082f8f3632fbe9f1ed4f9dfb1fa79e8283066d77c44c4af943d76b300364aecbd0648c8a8939bd204123f4b56260422dec",
"fe9846d64f7c7708696f840e2d76cb4408b6595c2f81ec6a28a7f2f20cb88cfe6ac0b9e9b8244f08bd7095c350c1d0842f64fb01bb7f532dfcd47371b0aeeb79",
"28f17ea6fb6c42092dc264257e29746321fb5bdaea9873c2a7fa9d8f53818e899e161bc77dfe8090afd82bf2266c5c1bc930a8d1547624439e662ef695f26f24",
"ec6b7d7f030d4850acae3cb615c21dd25206d63e84d1db8d957370737ba0e98467ea0ce274c66199901eaec18a08525715f53bfdb0aacb613d342ebdceeddc3b",
"b403d3691c03b0d3418df327d5860d34bbfcc4519bfbce36bf33b208385fadb9186bc78a76c489d89fd57e7dc75412d23bcd1dae8470ce9274754bb8585b13c5",
"31fc79738b8772b3f55cd8178813b3b52d0db5a419d30ba9495c4b9da0219fac6df8e7c23a811551a62b827f256ecdb8124ac8a6792ccfecc3b3012722e94463",
"bb2039ec287091bcc9642fc90049e73732e02e577e2862b32216ae9bedcd730c4c284ef3968c368b7d37584f97bd4b4dc6ef6127acfe2e6ae2509124e66c8af4",
"f53d68d13f45edfcb9bd415e2831e938350d5380d3432278fc1c0c381fcb7c65c82dafe051d8c8b0d44e0974a0e59ec7bf7ed0459f86e96f329fc79752510fd3",
"8d568c7984f0ecdf7640fbc483b5d8c9f86634f6f43291841b309a350ab9c1137d24066b09da9944bac54d5bb6580d836047aac74ab724b887ebf93d4b32eca9",
"c0b65ce5a96ff774c456cac3b5f2c4cd359b4ff53ef93a3da0778be4900d1e8da1601e769e8f1b02d2a2f8c5b9fa10b44f1c186985468feeb008730283a6657d",
"4900bba6f5fb103ece8ec96ada13a5c3c85488e05551da6b6b33d988e611ec0fe2e3c2aa48ea6ae8986a3a231b223c5d27cec2eadde91ce07981ee652862d1e4",
"c7f5c37c7285f927f76443414d4357ff789647d7a005a5a787e03c346b57f49f21b64fa9cf4b7e45573e23049017567121a9c3d4b2b73ec5e9413577525db45a",
"ec7096330736fdb2d64b5653e7475da746c23a4613a82687a28062d3236364284ac01720ffb406cfe265c0df626a188c9e5963ace5d3d5bb363e32c38c2190a6",
"82e744c75f4649ec52b80771a77d475a3bc091989556960e276a5f9ead92a03f718742cdcfeaee5cb85c44af198adc43a4a428f5f0c2ddb0be36059f06d7df73",
"2834b7a7170f1f5b68559ab78c1050ec21c919740b784a9072f6e5d69f828d70c919c5039fb148e39e2c8a52118378b064ca8d5001cd10a5478387b966715ed6",
"16b4ada883f72f853bb7ef253efcab0c3e2161687ad61543a0d2824f91c1f81347d86be709b16996e17f2dd486927b0288ad38d13063c4a9672c39397d3789b6",
"78d048f3a69d8b54ae0ed63a573ae350d89f7c6cf1f3688930de899afa037697629b314e5cd303aa62feea72a25bf42b304b6c6bcb27fae21c16d925e1fbdac3",
"0f746a48749287ada77a82961f05a4da4abdb7d77b1220f836d09ec814359c0ec0239b8c7b9ff9e02f569d1b301ef67c4612d1de4f730f81c12c40cc063c5caa",
"f0fc859d3bd195fbdc2d591e4cdac15179ec0f1dc821c11df1f0c1d26e6260aaa65b79fafacafd7d3ad61e600f250905f5878c87452897647a35b995bcadc3a3",
"2620f687e8625f6a412460b42e2cef67634208ce10a0cbd4dff7044a41b7880077e9f8dc3b8d1216d3376a21e015b58fb279b521d83f9388c7382c8505590b9b",
"227e3aed8d2cb10b918fcb04f9de3e6d0a57e08476d93759cd7b2ed54a1cbf0239c528fb04bbf288253e601d3bc38b21794afef90b17094a182cac557745e75f",
"1a929901b09c25f27d6b35be7b2f1c4745131fdebca7f3e2451926720434e0db6e74fd693ad29b777dc3355c592a361c4873b01133a57c2e3b7075cbdb86f4fc",
"5fd7968bc2fe34f220b5e3dc5af9571742d73b7d60819f2888b629072b96a9d8ab2d91b82d0a9aaba61bbd39958132fcc4257023d1eca591b3054e2dc81c8200",
"dfcce8cf32870cc6a503eadafc87fd6f78918b9b4d0737db6810be996b5497e7e5cc80e312f61e71ff3e9624436073156403f735f56b0b01845c18f6caf772e6",
"02f7ef3a9ce0fff960f67032b296efca3061f4934d690749f2d01c35c81c14f39a67fa350bc8a0359bf1724bffc3bca6d7c7bba4791fd522a3ad353c02ec5aa8",
"64be5c6aba65d594844ae78bb022e5bebe127fd6b6ffa5a13703855ab63b624dcd1a363f99203f632ec386f3ea767fc992e8ed9686586aa27555a8599d5b808f",
"f78585505c4eaa54a8b5be70a61e735e0ff97af944ddb3001e35d86c4e2199d976104b6ae31750a36a726ed285064f5981b503889fef822fcdc2898dddb7889a",
"e4b5566033869572edfd87479a5bb73c80e8759b91232879d96b1dda36c012076ee5a2ed7ae2de63ef8406a06aea82c188031b560beafb583fb3de9e57952a7e",
"e1b3e7ed867f6c9484a2a97f7715f25e25294e992e41f6a7c161ffc2adc6daaeb7113102d5e6090287fe6ad94ce5d6b739c6ca240b05c76fb73f25dd024bf935",
"85fd085fdc12a080983df07bd7012b0d402a0f4043fcb2775adf0bad174f9b08d1676e476985785c0a5dcc41dbff6d95ef4d66a3fbdc4a74b82ba52da0512b74",
"aed8fa764b0fbff821e05233d2f7b0900ec44d826f95e93c343c1bc3ba5a24374b1d616e7e7aba453a0ada5e4fab5382409e0d42ce9c2bc7fb39a99c340c20f0",
"7ba3b2e297233522eeb343bd3ebcfd835a04007735e87f0ca300cbee6d416565162171581e4020ff4cf176450f1291ea2285cb9ebffe4c56660627685145051c",
"de748bcf89ec88084721e16b85f30adb1a6134d664b5843569babc5bbd1a15ca9b61803c901a4fef32965a1749c9f3a4e243e173939dc5a8dc495c671ab52145",
"aaf4d2bdf200a919706d9842dce16c98140d34bc433df320aba9bd429e549aa7a3397652a4d768277786cf993cde2338673ed2e6b66c961fefb82cd20c93338f",
"c408218968b788bf864f0997e6bc4c3dba68b276e2125a4843296052ff93bf5767b8cdce7131f0876430c1165fec6c4f47adaa4fd8bcfacef463b5d3d0fa61a0",
"76d2d819c92bce55fa8e092ab1bf9b9eab237a25267986cacf2b8ee14d214d730dc9a5aa2d7b596e86a1fd8fa0804c77402d2fcd45083688b218b1cdfa0dcbcb",
"72065ee4dd91c2d8509fa1fc28a37c7fc9fa7d5b3f8ad3d0d7a25626b57b1b44788d4caf806290425f9890a3a2a35a905ab4b37acfd0da6e4517b2525c9651e4",
"64475dfe7600d7171bea0b394e27c9b00d8e74dd1e416a79473682ad3dfdbb706631558055cfc8a40e07bd015a4540dcdea15883cbbf31412df1de1cd4152b91",
"12cd1674a4488a5d7c2b3160d2e2c4b58371bedad793418d6f19c6ee385d70b3e06739369d4df910edb0b0a54cbff43d54544cd37ab3a06cfa0a3ddac8b66c89",
"60756966479dedc6dd4bcff8ea7d1d4ce4d4af2e7b097e32e3763518441147cc12b3c0ee6d2ecabf1198cec92e86a3616fba4f4e872f5825330adbb4c1dee444",
"a7803bcb71bc1d0f4383dde1e0612e04f872b715ad30815c2249cf34abb8b024915cb2fc9f4e7cc4c8cfd45be2d5a91eab0941c7d270e2da4ca4a9f7ac68663a",
"b84ef6a7229a34a750d9a98ee2529871816b87fbe3bc45b45fa5ae82d5141540211165c3c5d7a7476ba5a4aa06d66476f0d9dc49a3f1ee72c3acabd498967414",
"fae4b6d8efc3f8c8e64d001dabec3a21f544e82714745251b2b4b393f2f43e0da3d403c64db95a2cb6e23ebb7b9e94cdd5ddac54f07c4a61bd3cb10aa6f93b49",
"34f7286605a122369540141ded79b8957255da2d4155abbf5a8dbb89c8eb7ede8eeef1daa46dc29d751d045dc3b1d658bb64b80ff8589eddb3824b13da235a6b",
"3b3b48434be27b9eababba43bf6b35f14b30f6a88dc2e750c358470d6b3aa3c18e47db4017fa55106d8252f016371a00f5f8b070b74ba5f23cffc5511c9f09f0",
"ba289ebd6562c48c3e10a8ad6ce02e73433d1e93d7c9279d4d60a7e879ee11f441a000f48ed9f7c4ed87a45136d7dccdca482109c78a51062b3ba4044ada2469",
"022939e2386c5a37049856c850a2bb10a13dfea4212b4c732a8840a9ffa5faf54875c5448816b2785a007da8a8d2bc7d71a54e4e6571f10b600cbdb25d13ede3",
"e6fec19d89ce8717b1a087024670fe026f6c7cbda11caef959bb2d351bf856f8055d1c0ebdaaa9d1b17886fc2c562b5e99642fc064710c0d3488a02b5ed7f6fd",
"94c96f02a8f576aca32ba61c2b206f907285d9299b83ac175c209a8d43d53bfe683dd1d83e7549cb906c28f59ab7c46f8751366a28c39dd5fe2693c9019666c8",
"31a0cd215ebd2cb61de5b9edc91e6195e31c59a5648d5c9f737e125b2605708f2e325ab3381c8dce1a3e958886f1ecdc60318f882cfe20a24191352e617b0f21",
"91ab504a522dce78779f4c6c6ba2e6b6db5565c76d3e7e7c920caf7f757ef9db7c8fcf10e57f03379ea9bf75eb59895d96e149800b6aae01db778bb90afbc989",
"d85cabc6bd5b1a01a5afd8c6734740da9fd1c1acc6db29bfc8a2e5b668b028b6b3154bfb8703fa3180251d589ad38040ceb707c4bad1b5343cb426b61eaa49c1",
"d62efbec2ca9c1f8bd66ce8b3f6a898cb3f7566ba6568c618ad1feb2b65b76c3ce1dd20f7395372faf28427f61c9278049cf0140df434f5633048c86b81e0399",
"7c8fdc6175439e2c3db15bafa7fb06143a6a23bc90f449e79deef73c3d492a671715c193b6fea9f036050b946069856b897e08c00768f5ee5ddcf70b7cd6d0e0",
"58602ee7468e6bc9df21bd51b23c005f72d6cb013f0a1b48cbec5eca299299f97f09f54a9a01483eaeb315a6478bad37ba47ca1347c7c8fc9e6695592c91d723",
"27f5b79ed256b050993d793496edf4807c1d85a7b0a67c9c4fa99860750b0ae66989670a8ffd7856d7ce411599e58c4d77b232a62bef64d15275be46a68235ff",
"3957a976b9f1887bf004a8dca942c92d2b37ea52600f25e0c9bc5707d0279c00c6e85a839b0d2d8eb59c51d94788ebe62474a791cadf52cccf20f5070b6573fc",
"eaa2376d55380bf772ecca9cb0aa4668c95c707162fa86d518c8ce0ca9bf7362b9f2a0adc3ff59922df921b94567e81e452f6c1a07fc817cebe99604b3505d38",
"c1e2c78b6b2734e2480ec550434cb5d613111adcc21d475545c3b1b7e6ff12444476e5c055132e2229dc0f807044bb919b1a5662dd38a9ee65e243a3911aed1a",
"8ab48713389dd0fcf9f965d3ce66b1e559a1f8c58741d67683cd971354f452e62d0207a65e436c5d5d8f8ee71c6abfe50e669004c302b31a7ea8311d4a916051",
"24ce0addaa4c65038bd1b1c0f1452a0b128777aabc94a29df2fd6c7e2f85f8ab9ac7eff516b0e0a825c84a24cfe492eaad0a6308e46dd42fe8333ab971bb30ca",
"5154f929ee03045b6b0c0004fa778edee1d139893267cc84825ad7b36c63de32798e4a166d24686561354f63b00709a1364b3c241de3febf0754045897467cd4",
"e74e907920fd87bd5ad636dd11085e50ee70459c443e1ce5809af2bc2eba39f9e6d7128e0e3712c316da06f4705d78a4838e28121d4344a2c79c5e0db307a677",
"bf91a22334bac20f3fd80663b3cd06c4e8802f30e6b59f90d3035cc9798a217ed5a31abbda7fa6842827bdf2a7a1c21f6fcfccbb54c6c52926f32da816269be1",
"d9d5c74be5121b0bd742f26bffb8c89f89171f3f934913492b0903c271bbe2b3395ef259669bef43b57f7fcc3027db01823f6baee66e4f9fead4d6726c741fce",
"50c8b8cf34cd879f80e2faab3230b0c0e1cc3e9dcadeb1b9d97ab923415dd9a1fe38addd5c11756c67990b256e95ad6d8f9fedce10bf1c90679cde0ecf1be347",
"0a386e7cd5dd9b77a035e09fe6fee2c8ce61b5383c87ea43205059c5e4cd4f4408319bb0a82360f6a58e6c9ce3f487c446063bf813bc6ba535e17fc1826cfc91",
"1f1459cb6b61cbac5f0efe8fc487538f42548987fcd56221cfa7beb22504769e792c45adfb1d6b3d60d7b749c8a75b0bdf14e8ea721b95dca538ca6e25711209",
"e58b3836b7d8fedbb50ca5725c6571e74c0785e97821dab8b6298c10e4c079d4a6cdf22f0fedb55032925c16748115f01a105e77e00cee3d07924dc0d8f90659",
"b929cc6505f020158672deda56d0db081a2ee34c00c1100029bdf8ea98034fa4bf3e8655ec697fe36f40553c5bb46801644a627d3342f4fc92b61f03290fb381",
"72d353994b49d3e03153929a1e4d4f188ee58ab9e72ee8e512f29bc773913819ce057ddd7002c0433ee0a16114e3d156dd2c4a7e80ee53378b8670f23e33ef56",
"c70ef9bfd775d408176737a0736d68517ce1aaad7e81a93c8c1ed967ea214f56c8a377b1763e676615b60f3988241eae6eab9685a5124929d28188f29eab06f7",
"c230f0802679cb33822ef8b3b21bf7a9a28942092901d7dac3760300831026cf354c9232df3e084d9903130c601f63c1f4a4a4b8106e468cd443bbe5a734f45f",
"6f43094cafb5ebf1f7a4937ec50f56a4c9da303cbb55ac1f27f1f1976cd96beda9464f0e7b9c54620b8a9fba983164b8be3578425a024f5fe199c36356b88972",
"3745273f4c38225db2337381871a0c6aafd3af9b018c88aa02025850a5dc3a42a1a3e03e56cbf1b0876d63a441f1d2856a39b8801eb5af325201c415d65e97fe",
"c50c44cca3ec3edaae779a7e179450ebdda2f97067c690aa6c5a4ac7c30139bb27c0df4db3220e63cb110d64f37ffe078db72653e2daacf93ae3f0a2d1a7eb2e",
"8aef263e385cbc61e19b28914243262af5afe8726af3ce39a79c27028cf3ecd3f8d2dfd9cfc9ad91b58f6f20778fd5f02894a3d91c7d57d1e4b866a7f364b6be",
"28696141de6e2d9bcb3235578a66166c1448d3e905a1b482d423be4bc5369bc8c74dae0acc9cc123e1d8ddce9f97917e8c019c552da32d39d2219b9abf0fa8c8",
"2fb9eb2085830181903a9dafe3db428ee15be7662224efd643371fb25646aee716e531eca69b2bdc8233f1a8081fa43da1500302975a77f42fa592136710e9dc",
"66f9a7143f7a3314a669bf2e24bbb35014261d639f495b6c9c1f104fe8e320aca60d4550d69d52edbd5a3cdeb4014ae65b1d87aa770b69ae5c15f4330b0b0ad8",
"f4c4dd1d594c3565e3e25ca43dad82f62abea4835ed4cd811bcd975e46279828d44d4c62c3679f1b7f7b9dd4571d7b49557347b8c5460cbdc1bef690fb2a08c0",
"8f1dc9649c3a84551f8f6e91cac68242a43b1f8f328ee92280257387fa7559aa6db12e4aeadc2d26099178749c6864b357f3f83b2fb3efa8d2a8db056bed6bcc",
"3139c1a7f97afd1675d460ebbc07f2728aa150df849624511ee04b743ba0a833092f18c12dc91b4dd243f333402f59fe28abdbbbae301e7b659c7a26d5c0f979",
"06f94a2996158a819fe34c40de3cf0379fd9fb85b3e363ba3926a0e7d960e3f4c2e0c70c7ce0ccb2a64fc29869f6e7ab12bd4d3f14fce943279027e785fb5c29",
"c29c399ef3eee8961e87565c1ce263925fc3d0ce267d13e48dd9e732ee67b0f69fad56401b0f10fcaac119201046cca28c5b14abdea3212ae65562f7f138db3d",
"4cec4c9df52eef05c3f6faaa9791bc7445937183224ecc37a1e58d0132d35617531d7e795f52af7b1eb9d147de1292d345fe341823f8e6bc1e5badca5c656108",
"898bfbae93b3e18d00697eab7d9704fa36ec339d076131cefdf30edbe8d9cc81c3a80b129659b163a323bab9793d4feed92d54dae966c77529764a09be88db45",
"ee9bd0469d3aaf4f14035be48a2c3b84d9b4b1fff1d945e1f1c1d38980a951be197b25fe22c731f20aeacc930ba9c4a1f4762227617ad350fdabb4e80273a0f4",
"3d4d3113300581cd96acbf091c3d0f3c310138cd6979e6026cde623e2dd1b24d4a8638bed1073344783ad0649cc6305ccec04beb49f31c633088a99b65130267",
"95c0591ad91f921ac7be6d9ce37e0663ed8011c1cfd6d0162a5572e94368bac02024485e6a39854aa46fe38e97d6c6b1947cd272d86b06bb5b2f78b9b68d559d",
"227b79ded368153bf46c0a3ca978bfdbef31f3024a5665842468490b0ff748ae04e7832ed4c9f49de9b1706709d623e5c8c15e3caecae8d5e433430ff72f20eb",
"5d34f3952f0105eef88ae8b64c6ce95ebfade0e02c69b08762a8712d2e4911ad3f941fc4034dc9b2e479fdbcd279b902faf5d838bb2e0c6495d372b5b7029813",
"7f939bf8353abce49e77f14f3750af20b7b03902e1a1e7fb6aaf76d0259cd401a83190f15640e74f3e6c5a90e839c7821f6474757f75c7bf9002084ddc7a62dc",
"062b61a2f9a33a71d7d0a06119644c70b0716a504de7e5e1be49bd7b86e7ed6817714f9f0fc313d06129597e9a2235ec8521de36f7290a90ccfc1ffa6d0aee29",
"f29e01eeae64311eb7f1c6422f946bf7bea36379523e7b2bbaba7d1d34a22d5ea5f1c5a09d5ce1fe682cced9a4798d1a05b46cd72dff5c1b355440b2a2d476bc",
"ec38cd3bbab3ef35d7cb6d5c914298351d8a9dc97fcee051a8a02f58e3ed6184d0b7810a5615411ab1b95209c3c810114fdeb22452084e77f3f847c6dbaafe16",
"c2aef5e0ca43e82641565b8cb943aa8ba53550caef793b6532fafad94b816082f0113a3ea2f63608ab40437ecc0f0229cb8fa224dcf1c478a67d9b64162b92d1",
"15f534efff7105cd1c254d074e27d5898b89313b7d366dc2d7d87113fa7d53aae13f6dba487ad8103d5e854c91fdb6e1e74b2ef6d1431769c30767dde067a35c",
"89acbca0b169897a0a2714c2df8c95b5b79cb69390142b7d6018bb3e3076b099b79a964152a9d912b1b86412b7e372e9cecad7f25d4cbab8a317be36492a67d7",
"e3c0739190ed849c9c962fd9dbb55e207e624fcac1eb417691515499eea8d8267b7e8f1287a63633af5011fde8c4ddf55bfdf722edf88831414f2cfaed59cb9a",
"8d6cf87c08380d2d1506eee46fd4222d21d8c04e585fbfd08269c98f702833a156326a0724656400ee09351d57b440175e2a5de93cc5f80db6daf83576cf75fa",
"da24bede383666d563eeed37f6319baf20d5c75d1635a6ba5ef4cfa1ac95487e96f8c08af600aab87c986ebad49fc70a58b4890b9c876e091016daf49e1d322e",
"f9d1d1b1e87ea7ae753a029750cc1cf3d0157d41805e245c5617bb934e732f0ae3180b78e05bfe76c7c3051e3e3ac78b9b50c05142657e1e03215d6ec7bfd0fc",
"11b7bc1668032048aa43343de476395e814bbbc223678db951a1b03a021efac948cfbe215f97fe9a72a2f6bc039e3956bfa417c1a9f10d6d7ba5d3d32ff323e5",
"b8d9000e4fc2b066edb91afee8e7eb0f24e3a201db8b6793c0608581e628ed0bcc4e5aa6787992a4bcc44e288093e63ee83abd0bc3ec6d0934a674a4da13838a",
"ce325e294f9b6719d6b61278276ae06a2564c03bb0b783fafe785bdf89c7d5acd83e78756d301b445699024eaeb77b54d477336ec2a4f332f2b3f88765ddb0c3",
"29acc30e9603ae2fccf90bf97e6cc463ebe28c1b2f9b4b765e70537c25c702a29dcbfbf14c99c54345ba2b51f17b77b5f15db92bbad8fa95c471f5d070a137cc",
"3379cbaae562a87b4c0425550ffdd6bfe1203f0d666cc7ea095be407a5dfe61ee91441cd5154b3e53b4f5fb31ad4c7a9ad5c7af4ae679aa51a54003a54ca6b2d",
"3095a349d245708c7cf550118703d7302c27b60af5d4e67fc978f8a4e60953c7a04f92fcf41aee64321ccb707a895851552b1e37b00bc5e6b72fa5bcef9e3fff",
"07262d738b09321f4dbccec4bb26f48cb0f0ed246ce0b31b9a6e7bc683049f1f3e5545f28ce932dd985c5ab0f43bd6de0770560af329065ed2e49d34624c2cbb",
"b6405eca8ee3316c87061cc6ec18dba53e6c250c63ba1f3bae9e55dd3498036af08cd272aa24d713c6020d77ab2f3919af1a32f307420618ab97e73953994fb4",
"7ee682f63148ee45f6e5315da81e5c6e557c2c34641fc509c7a5701088c38a74756168e2cd8d351e88fd1a451f360a01f5b2580f9b5a2e8cfc138f3dd59a3ffc",
"1d263c179d6b268f6fa016f3a4f29e943891125ed8593c81256059f5a7b44af2dcb2030d175c00e62ecaf7ee96682aa07ab20a611024a28532b1c25b86657902",
"106d132cbdb4cd2597812846e2bc1bf732fec5f0a5f65dbb39ec4e6dc64ab2ce6d24630d0f15a805c3540025d84afa98e36703c3dbee713e72dde8465bc1be7e",
"0e79968226650667a8d862ea8da4891af56a4e3a8b6d1750e394f0dea76d640d85077bcec2cc86886e506751b4f6a5838f7f0b5fef765d9dc90dcdcbaf079f08",
"521156a82ab0c4e566e5844d5e31ad9aaf144bbd5a464fdca34dbd5717e8ff711d3ffebbfa085d67fe996a34f6d3e4e60b1396bf4b1610c263bdbb834d560816",
"1aba88befc55bc25efbce02db8b9933e46f57661baeabeb21cc2574d2a518a3cba5dc5a38e49713440b25f9c744e75f6b85c9d8f4681f676160f6105357b8406",
"5a9949fcb2c473cda968ac1b5d08566dc2d816d960f57e63b898fa701cf8ebd3f59b124d95bfbbedc5f1cf0e17d5eaed0c02c50b69d8a402cabcca4433b51fd4",
"b0cead09807c672af2eb2b0f06dde46cf5370e15a4096b1a7d7cbb36ec31c205fbefca00b7a4162fa89fb4fb3eb78d79770c23f44e7206664ce3cd931c291e5d",
"bb6664931ec97044e45b2ae420ae1c551a8874bc937d08e969399c3964ebdba8346cdd5d09caafe4c28ba7ec788191ceca65ddd6f95f18583e040d0f30d0364d",
"65bc770a5faa3792369803683e844b0be7ee96f29f6d6a35568006bd5590f9a4ef639b7a8061c7b0424b66b60ac34af3119905f33a9d8c3ae18382ca9b689900",
"ea9b4dca333336aaf839a45c6eaa48b8cb4c7ddabffea4f643d6357ea6628a480a5b45f2b052c1b07d1fedca918b6f1139d80f74c24510dcbaa4be70eacc1b06",
"e6342fb4a780ad975d0e24bce149989b91d360557e87994f6b457b895575cc02d0c15bad3ce7577f4c63927ff13f3e381ff7e72bdbe745324844a9d27e3f1c01",
"3e209c9b33e8e461178ab46b1c64b49a07fb745f1c8bc95fbfb94c6b87c69516651b264ef980937fad41238b91ddc011a5dd777c7efd4494b4b6ecd3a9c22ac0",
"fd6a3d5b1875d80486d6e69694a56dbb04a99a4d051f15db2689776ba1c4882e6d462a603b7015dc9f4b7450f05394303b8652cfb404a266962c41bae6e18a94",
"951e27517e6bad9e4195fc8671dee3e7e9be69cee1422cb9fecfce0dba875f7b310b93ee3a3d558f941f635f668ff832d2c1d033c5e2f0997e4c66f147344e02",
"8eba2f874f1ae84041903c7c4253c82292530fc8509550bfdc34c95c7e2889d5650b0ad8cb988e5c4894cb87fbfbb19612ea93ccc4c5cad17158b9763464b492",
"16f712eaa1b7c6354719a8e7dbdfaf55e4063a4d277d947550019b38dfb564830911057d50506136e2394c3b28945cc964967d54e3000c2181626cfb9b73efd2",
"c39639e7d5c7fb8cdd0fd3e6a52096039437122f21c78f1679cea9d78a734c56ecbeb28654b4f18e342c331f6f7229ec4b4bc281b2d80a6eb50043f31796c88c",
"72d081af99f8a173dcc9a0ac4eb3557405639a29084b54a40172912a2f8a395129d5536f0918e902f9e8fa6000995f4168ddc5f893011be6a0dbc9b8a1a3f5bb",
"c11aa81e5efd24d5fc27ee586cfd8847fbb0e27601ccece5ecca0198e3c7765393bb74457c7e7a27eb9170350e1fb53857177506be3e762cc0f14d8c3afe9077",
"c28f2150b452e6c0c424bcde6f8d72007f9310fed7f2f87de0dbb64f4479d6c1441ba66f44b2accee61609177ed340128b407ecec7c64bbe50d63d22d8627727",
"f63d88122877ec30b8c8b00d22e89000a966426112bd44166e2f525b769ccbe9b286d437a0129130dde1a86c43e04bedb594e671d98283afe64ce331de9828fd",
"348b0532880b88a6614a8d7408c3f913357fbb60e995c60205be9139e74998aede7f4581e42f6b52698f7fa1219708c14498067fd1e09502de83a77dd281150c",
"5133dc8bef725359dff59792d85eaf75b7e1dcd1978b01c35b1b85fcebc63388ad99a17b6346a217dc1a9622ebd122ecf6913c4d31a6b52a695b86af00d741a0",
"2753c4c0e98ecad806e88780ec27fccd0f5c1ab547f9e4bf1659d192c23aa2cc971b58b6802580baef8adc3b776ef7086b2545c2987f348ee3719cdef258c403",
"b1663573ce4b9d8caefc865012f3e39714b9898a5da6ce17c25a6a47931a9ddb9bbe98adaa553beed436e89578455416c2a52a525cf2862b8d1d49a2531b7391",
"64f58bd6bfc856f5e873b2a2956ea0eda0d6db0da39c8c7fc67c9f9feefcff3072cdf9e6ea37f69a44f0c61aa0da3693c2db5b54960c0281a088151db42b11e8",
"0764c7be28125d9065c4b98a69d60aede703547c66a12e17e1c618994132f5ef82482c1e3fe3146cc65376cc109f0138ed9a80e49f1f3c7d610d2f2432f20605",
"f748784398a2ff03ebeb07e155e66116a839741a336e32da71ec696001f0ad1b25cd48c69cfca7265eca1dd71904a0ce748ac4124f3571076dfa7116a9cf00e9",
"3f0dbc0186bceb6b785ba78d2a2a013c910be157bdaffae81bb6663b1a73722f7f1228795f3ecada87cf6ef0078474af73f31eca0cc200ed975b6893f761cb6d",
"d4762cd4599876ca75b2b8fe249944dbd27ace741fdab93616cbc6e425460feb51d4e7adcc38180e7fc47c89024a7f56191adb878dfde4ead62223f5a2610efe",
"cd36b3d5b4c91b90fcbba79513cfee1907d8645a162afd0cd4cf4192d4a5f4c892183a8eacdb2b6b6a9d9aa8c11ac1b261b380dbee24ca468f1bfd043c58eefe",
"98593452281661a53c48a9d8cd790826c1a1ce567738053d0bee4a91a3d5bd92eefdbabebe3204f2031ca5f781bda99ef5d8ae56e5b04a9e1ecd21b0eb05d3e1",
"771f57dd2775ccdab55921d3e8e30ccf484d61fe1c1b9c2ae819d0fb2a12fab9be70c4a7a138da84e8280435daade5bbe66af0836a154f817fb17f3397e725a3",
"c60897c6f828e21f16fbb5f15b323f87b6c8955eabf1d38061f707f608abdd993fac3070633e286cf8339ce295dd352df4b4b40b2f29da1dd50b3a05d079e6bb",
"8210cd2c2d3b135c2cf07fa0d1433cd771f325d075c6469d9c7f1ba0943cd4ab09808cabf4acb9ce5bb88b498929b4b847f681ad2c490d042db2aec94214b06b",
"1d4edfffd8fd80f7e4107840fa3aa31e32598491e4af7013c197a65b7f36dd3ac4b478456111cd4309d9243510782fa31b7c4c95fa951520d020eb7e5c36e4ef",
"af8e6e91fab46ce4873e1a50a8ef448cc29121f7f74deef34a71ef89cc00d9274bc6c2454bbb3230d8b2ec94c62b1dec85f3593bfa30ea6f7a44d7c09465a253",
"29fd384ed4906f2d13aa9fe7af905990938bed807f1832454a372ab412eea1f5625a1fcc9ac8343b7c67c5aba6e0b1cc4644654913692c6b39eb9187ceacd3ec",
"a268c7885d9874a51c44dffed8ea53e94f78456e0b2ed99ff5a3924760813826d960a15edbedbb5de5226ba4b074e71b05c55b9756bb79e55c02754c2c7b6c8a",
"0cf8545488d56a86817cd7ecb10f7116b7ea530a45b6ea497b6c72c997e09e3d0da8698f46bb006fc977c2cd3d1177463ac9057fdd1662c85d0c126443c10473",
"b39614268fdd8781515e2cfebf89b4d5402bab10c226e6344e6b9ae000fb0d6c79cb2f3ec80e80eaeb1980d2f8698916bd2e9f747236655116649cd3ca23a837",
"74bef092fc6f1e5dba3663a3fb003b2a5ba257496536d99f62b9d73f8f9eb3ce9ff3eec709eb883655ec9eb896b9128f2afc89cf7d1ab58a72f4a3bf034d2b4a",
"3a988d38d75611f3ef38b8774980b33e573b6c57bee0469ba5eed9b44f29945e7347967fba2c162e1c3be7f310f2f75ee2381e7bfd6b3f0baea8d95dfb1dafb1",
"58aedfce6f67ddc85a28c992f1c0bd0969f041e66f1ee88020a125cbfcfebcd61709c9c4eba192c15e69f020d462486019fa8dea0cd7a42921a19d2fe546d43d",
"9347bd291473e6b4e368437b8e561e065f649a6d8ada479ad09b1999a8f26b91cf6120fd3bfe014e83f23acfa4c0ad7b3712b2c3c0733270663112ccd9285cd9",
"b32163e7c5dbb5f51fdc11d2eac875efbbcb7e7699090a7e7ff8a8d50795af5d74d9ff98543ef8cdf89ac13d0485278756e0ef00c817745661e1d59fe38e7537",
"1085d78307b1c4b008c57a2e7e5b234658a0a82e4ff1e4aaac72b312fda0fe27d233bc5b10e9cc17fdc7697b540c7d95eb215a19a1a0e20e1abfa126efd568c7",
"4e5c734c7dde011d83eac2b7347b373594f92d7091b9ca34cb9c6f39bdf5a8d2f134379e16d822f6522170ccf2ddd55c84b9e6c64fc927ac4cf8dfb2a17701f2",
"695d83bd990a1117b3d0ce06cc888027d12a054c2677fd82f0d4fbfc93575523e7991a5e35a3752e9b70ce62992e268a877744cdd435f5f130869c9a2074b338",
"a6213743568e3b3158b9184301f3690847554c68457cb40fc9a4b8cfd8d4a118c301a07737aeda0f929c68913c5f51c80394f53bff1c3e83b2e40ca97eba9e15",
"d444bfa2362a96df213d070e33fa841f51334e4e76866b8139e8af3bb3398be2dfaddcbc56b9146de9f68118dc5829e74b0c28d7711907b121f9161cb92b69a9",
"142709d62e28fcccd0af97fad0f8465b971e82201dc51070faa0372aa43e92484be1c1e73ba10906d5d1853db6a4106e0a7bf9800d373d6dee2d46d62ef2a461",
}

160
vendor/golang.org/x/crypto/blake2s/blake2s.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,160 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package blake2s implements the BLAKE2s hash algorithm as
// defined in RFC 7693.
package blake2s
import (
"encoding/binary"
"errors"
"hash"
)
const (
// The blocksize of BLAKE2s in bytes.
BlockSize = 64
// The hash size of BLAKE2s-256 in bytes.
Size = 32
)
var errKeySize = errors.New("blake2s: invalid key size")
var iv = [8]uint32{
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
}
// Sum256 returns the BLAKE2s-256 checksum of the data.
func Sum256(data []byte) [Size]byte {
var sum [Size]byte
checkSum(&sum, Size, data)
return sum
}
// New256 returns a new hash.Hash computing the BLAKE2s-256 checksum. A non-nil
// key turns the hash into a MAC. The key must between zero and 32 bytes long.
func New256(key []byte) (hash.Hash, error) { return newDigest(Size, key) }
func newDigest(hashSize int, key []byte) (*digest, error) {
if len(key) > Size {
return nil, errKeySize
}
d := &digest{
size: hashSize,
keyLen: len(key),
}
copy(d.key[:], key)
d.Reset()
return d, nil
}
func checkSum(sum *[Size]byte, hashSize int, data []byte) {
var (
h [8]uint32
c [2]uint32
)
h = iv
h[0] ^= uint32(hashSize) | (1 << 16) | (1 << 24)
if length := len(data); length > BlockSize {
n := length &^ (BlockSize - 1)
if length == n {
n -= BlockSize
}
hashBlocks(&h, &c, 0, data[:n])
data = data[n:]
}
var block [BlockSize]byte
offset := copy(block[:], data)
remaining := uint32(BlockSize - offset)
if c[0] < remaining {
c[1]--
}
c[0] -= remaining
hashBlocks(&h, &c, 0xFFFFFFFF, block[:])
for i, v := range h {
binary.LittleEndian.PutUint32(sum[4*i:], v)
}
}
type digest struct {
h [8]uint32
c [2]uint32
size int
block [BlockSize]byte
offset int
key [BlockSize]byte
keyLen int
}
func (d *digest) BlockSize() int { return BlockSize }
func (d *digest) Size() int { return d.size }
func (d *digest) Reset() {
d.h = iv
d.h[0] ^= uint32(d.size) | (uint32(d.keyLen) << 8) | (1 << 16) | (1 << 24)
d.offset, d.c[0], d.c[1] = 0, 0, 0
if d.keyLen > 0 {
d.block = d.key
d.offset = BlockSize
}
}
func (d *digest) Write(p []byte) (n int, err error) {
n = len(p)
if d.offset > 0 {
remaining := BlockSize - d.offset
if n <= remaining {
d.offset += copy(d.block[d.offset:], p)
return
}
copy(d.block[d.offset:], p[:remaining])
hashBlocks(&d.h, &d.c, 0, d.block[:])
d.offset = 0
p = p[remaining:]
}
if length := len(p); length > BlockSize {
nn := length &^ (BlockSize - 1)
if length == nn {
nn -= BlockSize
}
hashBlocks(&d.h, &d.c, 0, p[:nn])
p = p[nn:]
}
d.offset += copy(d.block[:], p)
return
}
func (d *digest) Sum(b []byte) []byte {
var block [BlockSize]byte
h := d.h
c := d.c
copy(block[:], d.block[:d.offset])
remaining := uint32(BlockSize - d.offset)
if c[0] < remaining {
c[1]--
}
c[0] -= remaining
hashBlocks(&h, &c, 0xFFFFFFFF, block[:])
var sum [Size]byte
for i, v := range h {
binary.LittleEndian.PutUint32(sum[4*i:], v)
}
return append(b, sum[:d.size]...)
}

36
vendor/golang.org/x/crypto/blake2s/blake2s_386.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,36 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build 386,!gccgo,!appengine
package blake2s
var (
useSSE4 = false
useSSSE3 = supportSSSE3()
useSSE2 = supportSSE2()
useGeneric = true
)
//go:noescape
func supportSSE2() bool
//go:noescape
func supportSSSE3() bool
//go:noescape
func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
//go:noescape
func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
if useSSSE3 {
hashBlocksSSSE3(h, c, flag, blocks)
} else if useSSE2 {
hashBlocksSSE2(h, c, flag, blocks)
} else {
hashBlocksGeneric(h, c, flag, blocks)
}
}

460
vendor/golang.org/x/crypto/blake2s/blake2s_386.s сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,460 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build 386,!gccgo,!appengine
#include "textflag.h"
DATA iv0<>+0x00(SB)/4, $0x6a09e667
DATA iv0<>+0x04(SB)/4, $0xbb67ae85
DATA iv0<>+0x08(SB)/4, $0x3c6ef372
DATA iv0<>+0x0c(SB)/4, $0xa54ff53a
GLOBL iv0<>(SB), (NOPTR+RODATA), $16
DATA iv1<>+0x00(SB)/4, $0x510e527f
DATA iv1<>+0x04(SB)/4, $0x9b05688c
DATA iv1<>+0x08(SB)/4, $0x1f83d9ab
DATA iv1<>+0x0c(SB)/4, $0x5be0cd19
GLOBL iv1<>(SB), (NOPTR+RODATA), $16
DATA rol16<>+0x00(SB)/8, $0x0504070601000302
DATA rol16<>+0x08(SB)/8, $0x0D0C0F0E09080B0A
GLOBL rol16<>(SB), (NOPTR+RODATA), $16
DATA rol8<>+0x00(SB)/8, $0x0407060500030201
DATA rol8<>+0x08(SB)/8, $0x0C0F0E0D080B0A09
GLOBL rol8<>(SB), (NOPTR+RODATA), $16
DATA counter<>+0x00(SB)/8, $0x40
DATA counter<>+0x08(SB)/8, $0x0
GLOBL counter<>(SB), (NOPTR+RODATA), $16
#define ROTL_SSE2(n, t, v) \
MOVO v, t; \
PSLLL $n, t; \
PSRLL $(32-n), v; \
PXOR t, v
#define ROTL_SSSE3(c, v) \
PSHUFB c, v
#define ROUND_SSE2(v0, v1, v2, v3, m0, m1, m2, m3, t) \
PADDL m0, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSE2(16, t, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(20, t, v1); \
PADDL m1, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSE2(24, t, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(25, t, v1); \
PSHUFL $0x39, v1, v1; \
PSHUFL $0x4E, v2, v2; \
PSHUFL $0x93, v3, v3; \
PADDL m2, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSE2(16, t, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(20, t, v1); \
PADDL m3, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSE2(24, t, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(25, t, v1); \
PSHUFL $0x39, v3, v3; \
PSHUFL $0x4E, v2, v2; \
PSHUFL $0x93, v1, v1
#define ROUND_SSSE3(v0, v1, v2, v3, m0, m1, m2, m3, t, c16, c8) \
PADDL m0, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSSE3(c16, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(20, t, v1); \
PADDL m1, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSSE3(c8, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(25, t, v1); \
PSHUFL $0x39, v1, v1; \
PSHUFL $0x4E, v2, v2; \
PSHUFL $0x93, v3, v3; \
PADDL m2, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSSE3(c16, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(20, t, v1); \
PADDL m3, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSSE3(c8, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(25, t, v1); \
PSHUFL $0x39, v3, v3; \
PSHUFL $0x4E, v2, v2; \
PSHUFL $0x93, v1, v1
#define PRECOMPUTE(dst, off, src, t) \
MOVL 0*4(src), t; \
MOVL t, 0*4+off+0(dst); \
MOVL t, 9*4+off+64(dst); \
MOVL t, 5*4+off+128(dst); \
MOVL t, 14*4+off+192(dst); \
MOVL t, 4*4+off+256(dst); \
MOVL t, 2*4+off+320(dst); \
MOVL t, 8*4+off+384(dst); \
MOVL t, 12*4+off+448(dst); \
MOVL t, 3*4+off+512(dst); \
MOVL t, 15*4+off+576(dst); \
MOVL 1*4(src), t; \
MOVL t, 4*4+off+0(dst); \
MOVL t, 8*4+off+64(dst); \
MOVL t, 14*4+off+128(dst); \
MOVL t, 5*4+off+192(dst); \
MOVL t, 12*4+off+256(dst); \
MOVL t, 11*4+off+320(dst); \
MOVL t, 1*4+off+384(dst); \
MOVL t, 6*4+off+448(dst); \
MOVL t, 10*4+off+512(dst); \
MOVL t, 3*4+off+576(dst); \
MOVL 2*4(src), t; \
MOVL t, 1*4+off+0(dst); \
MOVL t, 13*4+off+64(dst); \
MOVL t, 6*4+off+128(dst); \
MOVL t, 8*4+off+192(dst); \
MOVL t, 2*4+off+256(dst); \
MOVL t, 0*4+off+320(dst); \
MOVL t, 14*4+off+384(dst); \
MOVL t, 11*4+off+448(dst); \
MOVL t, 12*4+off+512(dst); \
MOVL t, 4*4+off+576(dst); \
MOVL 3*4(src), t; \
MOVL t, 5*4+off+0(dst); \
MOVL t, 15*4+off+64(dst); \
MOVL t, 9*4+off+128(dst); \
MOVL t, 1*4+off+192(dst); \
MOVL t, 11*4+off+256(dst); \
MOVL t, 7*4+off+320(dst); \
MOVL t, 13*4+off+384(dst); \
MOVL t, 3*4+off+448(dst); \
MOVL t, 6*4+off+512(dst); \
MOVL t, 10*4+off+576(dst); \
MOVL 4*4(src), t; \
MOVL t, 2*4+off+0(dst); \
MOVL t, 1*4+off+64(dst); \
MOVL t, 15*4+off+128(dst); \
MOVL t, 10*4+off+192(dst); \
MOVL t, 6*4+off+256(dst); \
MOVL t, 8*4+off+320(dst); \
MOVL t, 3*4+off+384(dst); \
MOVL t, 13*4+off+448(dst); \
MOVL t, 14*4+off+512(dst); \
MOVL t, 5*4+off+576(dst); \
MOVL 5*4(src), t; \
MOVL t, 6*4+off+0(dst); \
MOVL t, 11*4+off+64(dst); \
MOVL t, 2*4+off+128(dst); \
MOVL t, 9*4+off+192(dst); \
MOVL t, 1*4+off+256(dst); \
MOVL t, 13*4+off+320(dst); \
MOVL t, 4*4+off+384(dst); \
MOVL t, 8*4+off+448(dst); \
MOVL t, 15*4+off+512(dst); \
MOVL t, 7*4+off+576(dst); \
MOVL 6*4(src), t; \
MOVL t, 3*4+off+0(dst); \
MOVL t, 7*4+off+64(dst); \
MOVL t, 13*4+off+128(dst); \
MOVL t, 12*4+off+192(dst); \
MOVL t, 10*4+off+256(dst); \
MOVL t, 1*4+off+320(dst); \
MOVL t, 9*4+off+384(dst); \
MOVL t, 14*4+off+448(dst); \
MOVL t, 0*4+off+512(dst); \
MOVL t, 6*4+off+576(dst); \
MOVL 7*4(src), t; \
MOVL t, 7*4+off+0(dst); \
MOVL t, 14*4+off+64(dst); \
MOVL t, 10*4+off+128(dst); \
MOVL t, 0*4+off+192(dst); \
MOVL t, 5*4+off+256(dst); \
MOVL t, 9*4+off+320(dst); \
MOVL t, 12*4+off+384(dst); \
MOVL t, 1*4+off+448(dst); \
MOVL t, 13*4+off+512(dst); \
MOVL t, 2*4+off+576(dst); \
MOVL 8*4(src), t; \
MOVL t, 8*4+off+0(dst); \
MOVL t, 5*4+off+64(dst); \
MOVL t, 4*4+off+128(dst); \
MOVL t, 15*4+off+192(dst); \
MOVL t, 14*4+off+256(dst); \
MOVL t, 3*4+off+320(dst); \
MOVL t, 11*4+off+384(dst); \
MOVL t, 10*4+off+448(dst); \
MOVL t, 7*4+off+512(dst); \
MOVL t, 1*4+off+576(dst); \
MOVL 9*4(src), t; \
MOVL t, 12*4+off+0(dst); \
MOVL t, 2*4+off+64(dst); \
MOVL t, 11*4+off+128(dst); \
MOVL t, 4*4+off+192(dst); \
MOVL t, 0*4+off+256(dst); \
MOVL t, 15*4+off+320(dst); \
MOVL t, 10*4+off+384(dst); \
MOVL t, 7*4+off+448(dst); \
MOVL t, 5*4+off+512(dst); \
MOVL t, 9*4+off+576(dst); \
MOVL 10*4(src), t; \
MOVL t, 9*4+off+0(dst); \
MOVL t, 4*4+off+64(dst); \
MOVL t, 8*4+off+128(dst); \
MOVL t, 13*4+off+192(dst); \
MOVL t, 3*4+off+256(dst); \
MOVL t, 5*4+off+320(dst); \
MOVL t, 7*4+off+384(dst); \
MOVL t, 15*4+off+448(dst); \
MOVL t, 11*4+off+512(dst); \
MOVL t, 0*4+off+576(dst); \
MOVL 11*4(src), t; \
MOVL t, 13*4+off+0(dst); \
MOVL t, 10*4+off+64(dst); \
MOVL t, 0*4+off+128(dst); \
MOVL t, 3*4+off+192(dst); \
MOVL t, 9*4+off+256(dst); \
MOVL t, 6*4+off+320(dst); \
MOVL t, 15*4+off+384(dst); \
MOVL t, 4*4+off+448(dst); \
MOVL t, 2*4+off+512(dst); \
MOVL t, 12*4+off+576(dst); \
MOVL 12*4(src), t; \
MOVL t, 10*4+off+0(dst); \
MOVL t, 12*4+off+64(dst); \
MOVL t, 1*4+off+128(dst); \
MOVL t, 6*4+off+192(dst); \
MOVL t, 13*4+off+256(dst); \
MOVL t, 4*4+off+320(dst); \
MOVL t, 0*4+off+384(dst); \
MOVL t, 2*4+off+448(dst); \
MOVL t, 8*4+off+512(dst); \
MOVL t, 14*4+off+576(dst); \
MOVL 13*4(src), t; \
MOVL t, 14*4+off+0(dst); \
MOVL t, 3*4+off+64(dst); \
MOVL t, 7*4+off+128(dst); \
MOVL t, 2*4+off+192(dst); \
MOVL t, 15*4+off+256(dst); \
MOVL t, 12*4+off+320(dst); \
MOVL t, 6*4+off+384(dst); \
MOVL t, 0*4+off+448(dst); \
MOVL t, 9*4+off+512(dst); \
MOVL t, 11*4+off+576(dst); \
MOVL 14*4(src), t; \
MOVL t, 11*4+off+0(dst); \
MOVL t, 0*4+off+64(dst); \
MOVL t, 12*4+off+128(dst); \
MOVL t, 7*4+off+192(dst); \
MOVL t, 8*4+off+256(dst); \
MOVL t, 14*4+off+320(dst); \
MOVL t, 2*4+off+384(dst); \
MOVL t, 5*4+off+448(dst); \
MOVL t, 1*4+off+512(dst); \
MOVL t, 13*4+off+576(dst); \
MOVL 15*4(src), t; \
MOVL t, 15*4+off+0(dst); \
MOVL t, 6*4+off+64(dst); \
MOVL t, 3*4+off+128(dst); \
MOVL t, 11*4+off+192(dst); \
MOVL t, 7*4+off+256(dst); \
MOVL t, 10*4+off+320(dst); \
MOVL t, 5*4+off+384(dst); \
MOVL t, 9*4+off+448(dst); \
MOVL t, 4*4+off+512(dst); \
MOVL t, 8*4+off+576(dst)
// func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
TEXT ·hashBlocksSSE2(SB), 0, $672-24 // frame = 656 + 16 byte alignment
MOVL h+0(FP), AX
MOVL c+4(FP), BX
MOVL flag+8(FP), CX
MOVL blocks_base+12(FP), SI
MOVL blocks_len+16(FP), DX
MOVL SP, BP
MOVL SP, DI
ADDL $15, DI
ANDL $~15, DI
MOVL DI, SP
MOVL CX, 8(SP)
MOVL 0(BX), CX
MOVL CX, 0(SP)
MOVL 4(BX), CX
MOVL CX, 4(SP)
XORL CX, CX
MOVL CX, 12(SP)
MOVOU 0(AX), X0
MOVOU 16(AX), X1
MOVOU counter<>(SB), X2
loop:
MOVO X0, X4
MOVO X1, X5
MOVOU iv0<>(SB), X6
MOVOU iv1<>(SB), X7
MOVO 0(SP), X3
PADDQ X2, X3
PXOR X3, X7
MOVO X3, 0(SP)
PRECOMPUTE(SP, 16, SI, CX)
ROUND_SSE2(X4, X5, X6, X7, 16(SP), 32(SP), 48(SP), 64(SP), X3)
ROUND_SSE2(X4, X5, X6, X7, 16+64(SP), 32+64(SP), 48+64(SP), 64+64(SP), X3)
ROUND_SSE2(X4, X5, X6, X7, 16+128(SP), 32+128(SP), 48+128(SP), 64+128(SP), X3)
ROUND_SSE2(X4, X5, X6, X7, 16+192(SP), 32+192(SP), 48+192(SP), 64+192(SP), X3)
ROUND_SSE2(X4, X5, X6, X7, 16+256(SP), 32+256(SP), 48+256(SP), 64+256(SP), X3)
ROUND_SSE2(X4, X5, X6, X7, 16+320(SP), 32+320(SP), 48+320(SP), 64+320(SP), X3)
ROUND_SSE2(X4, X5, X6, X7, 16+384(SP), 32+384(SP), 48+384(SP), 64+384(SP), X3)
ROUND_SSE2(X4, X5, X6, X7, 16+448(SP), 32+448(SP), 48+448(SP), 64+448(SP), X3)
ROUND_SSE2(X4, X5, X6, X7, 16+512(SP), 32+512(SP), 48+512(SP), 64+512(SP), X3)
ROUND_SSE2(X4, X5, X6, X7, 16+576(SP), 32+576(SP), 48+576(SP), 64+576(SP), X3)
PXOR X4, X0
PXOR X5, X1
PXOR X6, X0
PXOR X7, X1
LEAL 64(SI), SI
SUBL $64, DX
JNE loop
MOVL 0(SP), CX
MOVL CX, 0(BX)
MOVL 4(SP), CX
MOVL CX, 4(BX)
MOVOU X0, 0(AX)
MOVOU X1, 16(AX)
MOVL BP, SP
RET
// func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
TEXT ·hashBlocksSSSE3(SB), 0, $704-24 // frame = 688 + 16 byte alignment
MOVL h+0(FP), AX
MOVL c+4(FP), BX
MOVL flag+8(FP), CX
MOVL blocks_base+12(FP), SI
MOVL blocks_len+16(FP), DX
MOVL SP, BP
MOVL SP, DI
ADDL $15, DI
ANDL $~15, DI
MOVL DI, SP
MOVL CX, 8(SP)
MOVL 0(BX), CX
MOVL CX, 0(SP)
MOVL 4(BX), CX
MOVL CX, 4(SP)
XORL CX, CX
MOVL CX, 12(SP)
MOVOU 0(AX), X0
MOVOU 16(AX), X1
MOVOU counter<>(SB), X2
loop:
MOVO X0, 656(SP)
MOVO X1, 672(SP)
MOVO X0, X4
MOVO X1, X5
MOVOU iv0<>(SB), X6
MOVOU iv1<>(SB), X7
MOVO 0(SP), X3
PADDQ X2, X3
PXOR X3, X7
MOVO X3, 0(SP)
MOVOU rol16<>(SB), X0
MOVOU rol8<>(SB), X1
PRECOMPUTE(SP, 16, SI, CX)
ROUND_SSSE3(X4, X5, X6, X7, 16(SP), 32(SP), 48(SP), 64(SP), X3, X0, X1)
ROUND_SSSE3(X4, X5, X6, X7, 16+64(SP), 32+64(SP), 48+64(SP), 64+64(SP), X3, X0, X1)
ROUND_SSSE3(X4, X5, X6, X7, 16+128(SP), 32+128(SP), 48+128(SP), 64+128(SP), X3, X0, X1)
ROUND_SSSE3(X4, X5, X6, X7, 16+192(SP), 32+192(SP), 48+192(SP), 64+192(SP), X3, X0, X1)
ROUND_SSSE3(X4, X5, X6, X7, 16+256(SP), 32+256(SP), 48+256(SP), 64+256(SP), X3, X0, X1)
ROUND_SSSE3(X4, X5, X6, X7, 16+320(SP), 32+320(SP), 48+320(SP), 64+320(SP), X3, X0, X1)
ROUND_SSSE3(X4, X5, X6, X7, 16+384(SP), 32+384(SP), 48+384(SP), 64+384(SP), X3, X0, X1)
ROUND_SSSE3(X4, X5, X6, X7, 16+448(SP), 32+448(SP), 48+448(SP), 64+448(SP), X3, X0, X1)
ROUND_SSSE3(X4, X5, X6, X7, 16+512(SP), 32+512(SP), 48+512(SP), 64+512(SP), X3, X0, X1)
ROUND_SSSE3(X4, X5, X6, X7, 16+576(SP), 32+576(SP), 48+576(SP), 64+576(SP), X3, X0, X1)
MOVO 656(SP), X0
MOVO 672(SP), X1
PXOR X4, X0
PXOR X5, X1
PXOR X6, X0
PXOR X7, X1
LEAL 64(SI), SI
SUBL $64, DX
JNE loop
MOVL 0(SP), CX
MOVL CX, 0(BX)
MOVL 4(SP), CX
MOVL CX, 4(BX)
MOVOU X0, 0(AX)
MOVOU X1, 16(AX)
MOVL BP, SP
RET
// func supportSSSE3() bool
TEXT ·supportSSSE3(SB), 4, $0-1
MOVL $1, AX
CPUID
MOVL CX, BX
ANDL $0x1, BX // supports SSE3
JZ FALSE
ANDL $0x200, CX // supports SSSE3
JZ FALSE
MOVB $1, ret+0(FP)
RET
FALSE:
MOVB $0, ret+0(FP)
RET
// func supportSSE2() bool
TEXT ·supportSSE2(SB), 4, $0-1
MOVL $1, AX
CPUID
SHRL $26, DX
ANDL $1, DX // DX != 0 if support SSE2
MOVB DX, ret+0(FP)
RET

39
vendor/golang.org/x/crypto/blake2s/blake2s_amd64.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,39 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build amd64,!gccgo,!appengine
package blake2s
var (
useSSE4 = supportSSE4()
useSSSE3 = supportSSSE3()
useSSE2 = true // Always available on amd64
useGeneric = false
)
//go:noescape
func supportSSSE3() bool
//go:noescape
func supportSSE4() bool
//go:noescape
func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
//go:noescape
func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
//go:noescape
func hashBlocksSSE4(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
if useSSE4 {
hashBlocksSSE4(h, c, flag, blocks)
} else if useSSSE3 {
hashBlocksSSSE3(h, c, flag, blocks)
} else {
hashBlocksSSE2(h, c, flag, blocks)
}
}

463
vendor/golang.org/x/crypto/blake2s/blake2s_amd64.s сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,463 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build amd64,!gccgo,!appengine
#include "textflag.h"
DATA iv0<>+0x00(SB)/4, $0x6a09e667
DATA iv0<>+0x04(SB)/4, $0xbb67ae85
DATA iv0<>+0x08(SB)/4, $0x3c6ef372
DATA iv0<>+0x0c(SB)/4, $0xa54ff53a
GLOBL iv0<>(SB), (NOPTR+RODATA), $16
DATA iv1<>+0x00(SB)/4, $0x510e527f
DATA iv1<>+0x04(SB)/4, $0x9b05688c
DATA iv1<>+0x08(SB)/4, $0x1f83d9ab
DATA iv1<>+0x0c(SB)/4, $0x5be0cd19
GLOBL iv1<>(SB), (NOPTR+RODATA), $16
DATA rol16<>+0x00(SB)/8, $0x0504070601000302
DATA rol16<>+0x08(SB)/8, $0x0D0C0F0E09080B0A
GLOBL rol16<>(SB), (NOPTR+RODATA), $16
DATA rol8<>+0x00(SB)/8, $0x0407060500030201
DATA rol8<>+0x08(SB)/8, $0x0C0F0E0D080B0A09
GLOBL rol8<>(SB), (NOPTR+RODATA), $16
DATA counter<>+0x00(SB)/8, $0x40
DATA counter<>+0x08(SB)/8, $0x0
GLOBL counter<>(SB), (NOPTR+RODATA), $16
#define ROTL_SSE2(n, t, v) \
MOVO v, t; \
PSLLL $n, t; \
PSRLL $(32-n), v; \
PXOR t, v
#define ROTL_SSSE3(c, v) \
PSHUFB c, v
#define ROUND_SSE2(v0, v1, v2, v3, m0, m1, m2, m3, t) \
PADDL m0, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSE2(16, t, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(20, t, v1); \
PADDL m1, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSE2(24, t, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(25, t, v1); \
PSHUFL $0x39, v1, v1; \
PSHUFL $0x4E, v2, v2; \
PSHUFL $0x93, v3, v3; \
PADDL m2, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSE2(16, t, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(20, t, v1); \
PADDL m3, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSE2(24, t, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(25, t, v1); \
PSHUFL $0x39, v3, v3; \
PSHUFL $0x4E, v2, v2; \
PSHUFL $0x93, v1, v1
#define ROUND_SSSE3(v0, v1, v2, v3, m0, m1, m2, m3, t, c16, c8) \
PADDL m0, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSSE3(c16, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(20, t, v1); \
PADDL m1, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSSE3(c8, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(25, t, v1); \
PSHUFL $0x39, v1, v1; \
PSHUFL $0x4E, v2, v2; \
PSHUFL $0x93, v3, v3; \
PADDL m2, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSSE3(c16, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(20, t, v1); \
PADDL m3, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSSE3(c8, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(25, t, v1); \
PSHUFL $0x39, v3, v3; \
PSHUFL $0x4E, v2, v2; \
PSHUFL $0x93, v1, v1
#define LOAD_MSG_SSE4(m0, m1, m2, m3, src, i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15) \
MOVL i0*4(src), m0; \
PINSRD $1, i1*4(src), m0; \
PINSRD $2, i2*4(src), m0; \
PINSRD $3, i3*4(src), m0; \
MOVL i4*4(src), m1; \
PINSRD $1, i5*4(src), m1; \
PINSRD $2, i6*4(src), m1; \
PINSRD $3, i7*4(src), m1; \
MOVL i8*4(src), m2; \
PINSRD $1, i9*4(src), m2; \
PINSRD $2, i10*4(src), m2; \
PINSRD $3, i11*4(src), m2; \
MOVL i12*4(src), m3; \
PINSRD $1, i13*4(src), m3; \
PINSRD $2, i14*4(src), m3; \
PINSRD $3, i15*4(src), m3
#define PRECOMPUTE_MSG(dst, off, src, R8, R9, R10, R11, R12, R13, R14, R15) \
MOVQ 0*4(src), R8; \
MOVQ 2*4(src), R9; \
MOVQ 4*4(src), R10; \
MOVQ 6*4(src), R11; \
MOVQ 8*4(src), R12; \
MOVQ 10*4(src), R13; \
MOVQ 12*4(src), R14; \
MOVQ 14*4(src), R15; \
\
MOVL R8, 0*4+off+0(dst); \
MOVL R8, 9*4+off+64(dst); \
MOVL R8, 5*4+off+128(dst); \
MOVL R8, 14*4+off+192(dst); \
MOVL R8, 4*4+off+256(dst); \
MOVL R8, 2*4+off+320(dst); \
MOVL R8, 8*4+off+384(dst); \
MOVL R8, 12*4+off+448(dst); \
MOVL R8, 3*4+off+512(dst); \
MOVL R8, 15*4+off+576(dst); \
SHRQ $32, R8; \
MOVL R8, 4*4+off+0(dst); \
MOVL R8, 8*4+off+64(dst); \
MOVL R8, 14*4+off+128(dst); \
MOVL R8, 5*4+off+192(dst); \
MOVL R8, 12*4+off+256(dst); \
MOVL R8, 11*4+off+320(dst); \
MOVL R8, 1*4+off+384(dst); \
MOVL R8, 6*4+off+448(dst); \
MOVL R8, 10*4+off+512(dst); \
MOVL R8, 3*4+off+576(dst); \
\
MOVL R9, 1*4+off+0(dst); \
MOVL R9, 13*4+off+64(dst); \
MOVL R9, 6*4+off+128(dst); \
MOVL R9, 8*4+off+192(dst); \
MOVL R9, 2*4+off+256(dst); \
MOVL R9, 0*4+off+320(dst); \
MOVL R9, 14*4+off+384(dst); \
MOVL R9, 11*4+off+448(dst); \
MOVL R9, 12*4+off+512(dst); \
MOVL R9, 4*4+off+576(dst); \
SHRQ $32, R9; \
MOVL R9, 5*4+off+0(dst); \
MOVL R9, 15*4+off+64(dst); \
MOVL R9, 9*4+off+128(dst); \
MOVL R9, 1*4+off+192(dst); \
MOVL R9, 11*4+off+256(dst); \
MOVL R9, 7*4+off+320(dst); \
MOVL R9, 13*4+off+384(dst); \
MOVL R9, 3*4+off+448(dst); \
MOVL R9, 6*4+off+512(dst); \
MOVL R9, 10*4+off+576(dst); \
\
MOVL R10, 2*4+off+0(dst); \
MOVL R10, 1*4+off+64(dst); \
MOVL R10, 15*4+off+128(dst); \
MOVL R10, 10*4+off+192(dst); \
MOVL R10, 6*4+off+256(dst); \
MOVL R10, 8*4+off+320(dst); \
MOVL R10, 3*4+off+384(dst); \
MOVL R10, 13*4+off+448(dst); \
MOVL R10, 14*4+off+512(dst); \
MOVL R10, 5*4+off+576(dst); \
SHRQ $32, R10; \
MOVL R10, 6*4+off+0(dst); \
MOVL R10, 11*4+off+64(dst); \
MOVL R10, 2*4+off+128(dst); \
MOVL R10, 9*4+off+192(dst); \
MOVL R10, 1*4+off+256(dst); \
MOVL R10, 13*4+off+320(dst); \
MOVL R10, 4*4+off+384(dst); \
MOVL R10, 8*4+off+448(dst); \
MOVL R10, 15*4+off+512(dst); \
MOVL R10, 7*4+off+576(dst); \
\
MOVL R11, 3*4+off+0(dst); \
MOVL R11, 7*4+off+64(dst); \
MOVL R11, 13*4+off+128(dst); \
MOVL R11, 12*4+off+192(dst); \
MOVL R11, 10*4+off+256(dst); \
MOVL R11, 1*4+off+320(dst); \
MOVL R11, 9*4+off+384(dst); \
MOVL R11, 14*4+off+448(dst); \
MOVL R11, 0*4+off+512(dst); \
MOVL R11, 6*4+off+576(dst); \
SHRQ $32, R11; \
MOVL R11, 7*4+off+0(dst); \
MOVL R11, 14*4+off+64(dst); \
MOVL R11, 10*4+off+128(dst); \
MOVL R11, 0*4+off+192(dst); \
MOVL R11, 5*4+off+256(dst); \
MOVL R11, 9*4+off+320(dst); \
MOVL R11, 12*4+off+384(dst); \
MOVL R11, 1*4+off+448(dst); \
MOVL R11, 13*4+off+512(dst); \
MOVL R11, 2*4+off+576(dst); \
\
MOVL R12, 8*4+off+0(dst); \
MOVL R12, 5*4+off+64(dst); \
MOVL R12, 4*4+off+128(dst); \
MOVL R12, 15*4+off+192(dst); \
MOVL R12, 14*4+off+256(dst); \
MOVL R12, 3*4+off+320(dst); \
MOVL R12, 11*4+off+384(dst); \
MOVL R12, 10*4+off+448(dst); \
MOVL R12, 7*4+off+512(dst); \
MOVL R12, 1*4+off+576(dst); \
SHRQ $32, R12; \
MOVL R12, 12*4+off+0(dst); \
MOVL R12, 2*4+off+64(dst); \
MOVL R12, 11*4+off+128(dst); \
MOVL R12, 4*4+off+192(dst); \
MOVL R12, 0*4+off+256(dst); \
MOVL R12, 15*4+off+320(dst); \
MOVL R12, 10*4+off+384(dst); \
MOVL R12, 7*4+off+448(dst); \
MOVL R12, 5*4+off+512(dst); \
MOVL R12, 9*4+off+576(dst); \
\
MOVL R13, 9*4+off+0(dst); \
MOVL R13, 4*4+off+64(dst); \
MOVL R13, 8*4+off+128(dst); \
MOVL R13, 13*4+off+192(dst); \
MOVL R13, 3*4+off+256(dst); \
MOVL R13, 5*4+off+320(dst); \
MOVL R13, 7*4+off+384(dst); \
MOVL R13, 15*4+off+448(dst); \
MOVL R13, 11*4+off+512(dst); \
MOVL R13, 0*4+off+576(dst); \
SHRQ $32, R13; \
MOVL R13, 13*4+off+0(dst); \
MOVL R13, 10*4+off+64(dst); \
MOVL R13, 0*4+off+128(dst); \
MOVL R13, 3*4+off+192(dst); \
MOVL R13, 9*4+off+256(dst); \
MOVL R13, 6*4+off+320(dst); \
MOVL R13, 15*4+off+384(dst); \
MOVL R13, 4*4+off+448(dst); \
MOVL R13, 2*4+off+512(dst); \
MOVL R13, 12*4+off+576(dst); \
\
MOVL R14, 10*4+off+0(dst); \
MOVL R14, 12*4+off+64(dst); \
MOVL R14, 1*4+off+128(dst); \
MOVL R14, 6*4+off+192(dst); \
MOVL R14, 13*4+off+256(dst); \
MOVL R14, 4*4+off+320(dst); \
MOVL R14, 0*4+off+384(dst); \
MOVL R14, 2*4+off+448(dst); \
MOVL R14, 8*4+off+512(dst); \
MOVL R14, 14*4+off+576(dst); \
SHRQ $32, R14; \
MOVL R14, 14*4+off+0(dst); \
MOVL R14, 3*4+off+64(dst); \
MOVL R14, 7*4+off+128(dst); \
MOVL R14, 2*4+off+192(dst); \
MOVL R14, 15*4+off+256(dst); \
MOVL R14, 12*4+off+320(dst); \
MOVL R14, 6*4+off+384(dst); \
MOVL R14, 0*4+off+448(dst); \
MOVL R14, 9*4+off+512(dst); \
MOVL R14, 11*4+off+576(dst); \
\
MOVL R15, 11*4+off+0(dst); \
MOVL R15, 0*4+off+64(dst); \
MOVL R15, 12*4+off+128(dst); \
MOVL R15, 7*4+off+192(dst); \
MOVL R15, 8*4+off+256(dst); \
MOVL R15, 14*4+off+320(dst); \
MOVL R15, 2*4+off+384(dst); \
MOVL R15, 5*4+off+448(dst); \
MOVL R15, 1*4+off+512(dst); \
MOVL R15, 13*4+off+576(dst); \
SHRQ $32, R15; \
MOVL R15, 15*4+off+0(dst); \
MOVL R15, 6*4+off+64(dst); \
MOVL R15, 3*4+off+128(dst); \
MOVL R15, 11*4+off+192(dst); \
MOVL R15, 7*4+off+256(dst); \
MOVL R15, 10*4+off+320(dst); \
MOVL R15, 5*4+off+384(dst); \
MOVL R15, 9*4+off+448(dst); \
MOVL R15, 4*4+off+512(dst); \
MOVL R15, 8*4+off+576(dst)
#define BLAKE2s_SSE2() \
PRECOMPUTE_MSG(SP, 16, SI, R8, R9, R10, R11, R12, R13, R14, R15); \
ROUND_SSE2(X4, X5, X6, X7, 16(SP), 32(SP), 48(SP), 64(SP), X8); \
ROUND_SSE2(X4, X5, X6, X7, 16+64(SP), 32+64(SP), 48+64(SP), 64+64(SP), X8); \
ROUND_SSE2(X4, X5, X6, X7, 16+128(SP), 32+128(SP), 48+128(SP), 64+128(SP), X8); \
ROUND_SSE2(X4, X5, X6, X7, 16+192(SP), 32+192(SP), 48+192(SP), 64+192(SP), X8); \
ROUND_SSE2(X4, X5, X6, X7, 16+256(SP), 32+256(SP), 48+256(SP), 64+256(SP), X8); \
ROUND_SSE2(X4, X5, X6, X7, 16+320(SP), 32+320(SP), 48+320(SP), 64+320(SP), X8); \
ROUND_SSE2(X4, X5, X6, X7, 16+384(SP), 32+384(SP), 48+384(SP), 64+384(SP), X8); \
ROUND_SSE2(X4, X5, X6, X7, 16+448(SP), 32+448(SP), 48+448(SP), 64+448(SP), X8); \
ROUND_SSE2(X4, X5, X6, X7, 16+512(SP), 32+512(SP), 48+512(SP), 64+512(SP), X8); \
ROUND_SSE2(X4, X5, X6, X7, 16+576(SP), 32+576(SP), 48+576(SP), 64+576(SP), X8)
#define BLAKE2s_SSSE3() \
PRECOMPUTE_MSG(SP, 16, SI, R8, R9, R10, R11, R12, R13, R14, R15); \
ROUND_SSSE3(X4, X5, X6, X7, 16(SP), 32(SP), 48(SP), 64(SP), X8, X13, X14); \
ROUND_SSSE3(X4, X5, X6, X7, 16+64(SP), 32+64(SP), 48+64(SP), 64+64(SP), X8, X13, X14); \
ROUND_SSSE3(X4, X5, X6, X7, 16+128(SP), 32+128(SP), 48+128(SP), 64+128(SP), X8, X13, X14); \
ROUND_SSSE3(X4, X5, X6, X7, 16+192(SP), 32+192(SP), 48+192(SP), 64+192(SP), X8, X13, X14); \
ROUND_SSSE3(X4, X5, X6, X7, 16+256(SP), 32+256(SP), 48+256(SP), 64+256(SP), X8, X13, X14); \
ROUND_SSSE3(X4, X5, X6, X7, 16+320(SP), 32+320(SP), 48+320(SP), 64+320(SP), X8, X13, X14); \
ROUND_SSSE3(X4, X5, X6, X7, 16+384(SP), 32+384(SP), 48+384(SP), 64+384(SP), X8, X13, X14); \
ROUND_SSSE3(X4, X5, X6, X7, 16+448(SP), 32+448(SP), 48+448(SP), 64+448(SP), X8, X13, X14); \
ROUND_SSSE3(X4, X5, X6, X7, 16+512(SP), 32+512(SP), 48+512(SP), 64+512(SP), X8, X13, X14); \
ROUND_SSSE3(X4, X5, X6, X7, 16+576(SP), 32+576(SP), 48+576(SP), 64+576(SP), X8, X13, X14)
#define BLAKE2s_SSE4() \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14)
#define HASH_BLOCKS(h, c, flag, blocks_base, blocks_len, BLAKE2s_FUNC) \
MOVQ h, AX; \
MOVQ c, BX; \
MOVL flag, CX; \
MOVQ blocks_base, SI; \
MOVQ blocks_len, DX; \
\
MOVQ SP, BP; \
MOVQ SP, R9; \
ADDQ $15, R9; \
ANDQ $~15, R9; \
MOVQ R9, SP; \
\
MOVQ 0(BX), R9; \
MOVQ R9, 0(SP); \
XORQ R9, R9; \
MOVQ R9, 8(SP); \
MOVL CX, 8(SP); \
\
MOVOU 0(AX), X0; \
MOVOU 16(AX), X1; \
MOVOU iv0<>(SB), X2; \
MOVOU iv1<>(SB), X3 \
\
MOVOU counter<>(SB), X12; \
MOVOU rol16<>(SB), X13; \
MOVOU rol8<>(SB), X14; \
MOVO 0(SP), X15; \
\
loop: \
MOVO X0, X4; \
MOVO X1, X5; \
MOVO X2, X6; \
MOVO X3, X7; \
\
PADDQ X12, X15; \
PXOR X15, X7; \
\
BLAKE2s_FUNC(); \
\
PXOR X4, X0; \
PXOR X5, X1; \
PXOR X6, X0; \
PXOR X7, X1; \
\
LEAQ 64(SI), SI; \
SUBQ $64, DX; \
JNE loop; \
\
MOVO X15, 0(SP); \
MOVQ 0(SP), R9; \
MOVQ R9, 0(BX); \
\
MOVOU X0, 0(AX); \
MOVOU X1, 16(AX); \
\
MOVQ BP, SP
// func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
TEXT ·hashBlocksSSE2(SB), 0, $672-48 // frame = 656 + 16 byte alignment
HASH_BLOCKS(h+0(FP), c+8(FP), flag+16(FP), blocks_base+24(FP), blocks_len+32(FP), BLAKE2s_SSE2)
RET
// func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
TEXT ·hashBlocksSSSE3(SB), 0, $672-48 // frame = 656 + 16 byte alignment
HASH_BLOCKS(h+0(FP), c+8(FP), flag+16(FP), blocks_base+24(FP), blocks_len+32(FP), BLAKE2s_SSSE3)
RET
// func hashBlocksSSE4(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
TEXT ·hashBlocksSSE4(SB), 0, $32-48 // frame = 16 + 16 byte alignment
HASH_BLOCKS(h+0(FP), c+8(FP), flag+16(FP), blocks_base+24(FP), blocks_len+32(FP), BLAKE2s_SSE4)
RET
// func supportSSE4() bool
TEXT ·supportSSE4(SB), 4, $0-1
MOVL $1, AX
CPUID
SHRL $19, CX // Bit 19 indicates SSE4.1.
ANDL $1, CX
MOVB CX, ret+0(FP)
RET
// func supportSSSE3() bool
TEXT ·supportSSSE3(SB), 4, $0-1
MOVL $1, AX
CPUID
MOVL CX, BX
ANDL $0x1, BX // Bit zero indicates SSE3 support.
JZ FALSE
ANDL $0x200, CX // Bit nine indicates SSSE3 support.
JZ FALSE
MOVB $1, ret+0(FP)
RET
FALSE:
MOVB $0, ret+0(FP)
RET

174
vendor/golang.org/x/crypto/blake2s/blake2s_generic.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,174 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package blake2s
// the precomputed values for BLAKE2s
// there are 10 16-byte arrays - one for each round
// the entries are calculated from the sigma constants.
var precomputed = [10][16]byte{
{0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15},
{14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3},
{11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4},
{7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8},
{9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13},
{2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9},
{12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11},
{13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10},
{6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5},
{10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0},
}
func hashBlocksGeneric(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
var m [16]uint32
c0, c1 := c[0], c[1]
for i := 0; i < len(blocks); {
c0 += BlockSize
if c0 < BlockSize {
c1++
}
v0, v1, v2, v3, v4, v5, v6, v7 := h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]
v8, v9, v10, v11, v12, v13, v14, v15 := iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]
v12 ^= c0
v13 ^= c1
v14 ^= flag
for j := range m {
m[j] = uint32(blocks[i]) | uint32(blocks[i+1])<<8 | uint32(blocks[i+2])<<16 | uint32(blocks[i+3])<<24
i += 4
}
for k := range precomputed {
s := &(precomputed[k])
v0 += m[s[0]]
v0 += v4
v12 ^= v0
v12 = v12<<(32-16) | v12>>16
v8 += v12
v4 ^= v8
v4 = v4<<(32-12) | v4>>12
v1 += m[s[1]]
v1 += v5
v13 ^= v1
v13 = v13<<(32-16) | v13>>16
v9 += v13
v5 ^= v9
v5 = v5<<(32-12) | v5>>12
v2 += m[s[2]]
v2 += v6
v14 ^= v2
v14 = v14<<(32-16) | v14>>16
v10 += v14
v6 ^= v10
v6 = v6<<(32-12) | v6>>12
v3 += m[s[3]]
v3 += v7
v15 ^= v3
v15 = v15<<(32-16) | v15>>16
v11 += v15
v7 ^= v11
v7 = v7<<(32-12) | v7>>12
v0 += m[s[4]]
v0 += v4
v12 ^= v0
v12 = v12<<(32-8) | v12>>8
v8 += v12
v4 ^= v8
v4 = v4<<(32-7) | v4>>7
v1 += m[s[5]]
v1 += v5
v13 ^= v1
v13 = v13<<(32-8) | v13>>8
v9 += v13
v5 ^= v9
v5 = v5<<(32-7) | v5>>7
v2 += m[s[6]]
v2 += v6
v14 ^= v2
v14 = v14<<(32-8) | v14>>8
v10 += v14
v6 ^= v10
v6 = v6<<(32-7) | v6>>7
v3 += m[s[7]]
v3 += v7
v15 ^= v3
v15 = v15<<(32-8) | v15>>8
v11 += v15
v7 ^= v11
v7 = v7<<(32-7) | v7>>7
v0 += m[s[8]]
v0 += v5
v15 ^= v0
v15 = v15<<(32-16) | v15>>16
v10 += v15
v5 ^= v10
v5 = v5<<(32-12) | v5>>12
v1 += m[s[9]]
v1 += v6
v12 ^= v1
v12 = v12<<(32-16) | v12>>16
v11 += v12
v6 ^= v11
v6 = v6<<(32-12) | v6>>12
v2 += m[s[10]]
v2 += v7
v13 ^= v2
v13 = v13<<(32-16) | v13>>16
v8 += v13
v7 ^= v8
v7 = v7<<(32-12) | v7>>12
v3 += m[s[11]]
v3 += v4
v14 ^= v3
v14 = v14<<(32-16) | v14>>16
v9 += v14
v4 ^= v9
v4 = v4<<(32-12) | v4>>12
v0 += m[s[12]]
v0 += v5
v15 ^= v0
v15 = v15<<(32-8) | v15>>8
v10 += v15
v5 ^= v10
v5 = v5<<(32-7) | v5>>7
v1 += m[s[13]]
v1 += v6
v12 ^= v1
v12 = v12<<(32-8) | v12>>8
v11 += v12
v6 ^= v11
v6 = v6<<(32-7) | v6>>7
v2 += m[s[14]]
v2 += v7
v13 ^= v2
v13 = v13<<(32-8) | v13>>8
v8 += v13
v7 ^= v8
v7 = v7<<(32-7) | v7>>7
v3 += m[s[15]]
v3 += v4
v14 ^= v3
v14 = v14<<(32-8) | v14>>8
v9 += v14
v4 ^= v9
v4 = v4<<(32-7) | v4>>7
}
h[0] ^= v0 ^ v8
h[1] ^= v1 ^ v9
h[2] ^= v2 ^ v10
h[3] ^= v3 ^ v11
h[4] ^= v4 ^ v12
h[5] ^= v5 ^ v13
h[6] ^= v6 ^ v14
h[7] ^= v7 ^ v15
}
c[0], c[1] = c0, c1
}

18
vendor/golang.org/x/crypto/blake2s/blake2s_ref.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,18 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !amd64,!386 gccgo appengine
package blake2s
var (
useSSE4 = false
useSSSE3 = false
useSSE2 = false
useGeneric = true
)
func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
hashBlocksGeneric(h, c, flag, blocks)
}

357
vendor/golang.org/x/crypto/blake2s/blake2s_test.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,357 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package blake2s
import (
"encoding/hex"
"fmt"
"testing"
)
func TestHashes(t *testing.T) {
defer func(sse2, ssse3, sse4 bool) {
useSSE2, useSSSE3, useSSE4 = sse2, ssse3, sse4
}(useSSE2, useSSSE3, useSSE4)
if useSSE4 {
t.Log("SSE4 version")
testHashes(t)
useSSE4 = false
}
if useSSSE3 {
t.Log("SSSE3 version")
testHashes(t)
useSSSE3 = false
}
if useSSE2 {
t.Log("SSE2 version")
testHashes(t)
useSSE2 = false
}
if useGeneric {
t.Log("generic version")
testHashes(t)
}
}
func testHashes(t *testing.T) {
key, _ := hex.DecodeString("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
input := make([]byte, 255)
for i := range input {
input[i] = byte(i)
}
for i, expectedHex := range hashes {
h, err := New256(key)
if err != nil {
t.Fatalf("#%d: error from New256: %v", i, err)
}
h.Write(input[:i])
sum := h.Sum(nil)
if gotHex := fmt.Sprintf("%x", sum); gotHex != expectedHex {
t.Fatalf("#%d (single write): got %s, wanted %s", i, gotHex, expectedHex)
}
h.Reset()
for j := 0; j < i; j++ {
h.Write(input[j : j+1])
}
sum = h.Sum(sum[:0])
if gotHex := fmt.Sprintf("%x", sum); gotHex != expectedHex {
t.Fatalf("#%d (byte-by-byte): got %s, wanted %s", i, gotHex, expectedHex)
}
}
}
// Benchmarks
func benchmarkSum(b *testing.B, size int) {
data := make([]byte, size)
b.SetBytes(int64(size))
b.ResetTimer()
for i := 0; i < b.N; i++ {
Sum256(data)
}
}
func benchmarkWrite(b *testing.B, size int) {
data := make([]byte, size)
h, _ := New256(nil)
b.SetBytes(int64(size))
b.ResetTimer()
for i := 0; i < b.N; i++ {
h.Write(data)
}
}
func BenchmarkWrite64(b *testing.B) { benchmarkWrite(b, 64) }
func BenchmarkWrite1K(b *testing.B) { benchmarkWrite(b, 1024) }
func BenchmarkSum64(b *testing.B) { benchmarkSum(b, 64) }
func BenchmarkSum1K(b *testing.B) { benchmarkSum(b, 1024) }
// hashes is taken from https://blake2.net/blake2s-test.txt
var hashes = []string{
"48a8997da407876b3d79c0d92325ad3b89cbb754d86ab71aee047ad345fd2c49",
"40d15fee7c328830166ac3f918650f807e7e01e177258cdc0a39b11f598066f1",
"6bb71300644cd3991b26ccd4d274acd1adeab8b1d7914546c1198bbe9fc9d803",
"1d220dbe2ee134661fdf6d9e74b41704710556f2f6e5a091b227697445dbea6b",
"f6c3fbadb4cc687a0064a5be6e791bec63b868ad62fba61b3757ef9ca52e05b2",
"49c1f21188dfd769aea0e911dd6b41f14dab109d2b85977aa3088b5c707e8598",
"fdd8993dcd43f696d44f3cea0ff35345234ec8ee083eb3cada017c7f78c17143",
"e6c8125637438d0905b749f46560ac89fd471cf8692e28fab982f73f019b83a9",
"19fc8ca6979d60e6edd3b4541e2f967ced740df6ec1eaebbfe813832e96b2974",
"a6ad777ce881b52bb5a4421ab6cdd2dfba13e963652d4d6d122aee46548c14a7",
"f5c4b2ba1a00781b13aba0425242c69cb1552f3f71a9a3bb22b4a6b4277b46dd",
"e33c4c9bd0cc7e45c80e65c77fa5997fec7002738541509e68a9423891e822a3",
"fba16169b2c3ee105be6e1e650e5cbf40746b6753d036ab55179014ad7ef6651",
"f5c4bec6d62fc608bf41cc115f16d61c7efd3ff6c65692bbe0afffb1fede7475",
"a4862e76db847f05ba17ede5da4e7f91b5925cf1ad4ba12732c3995742a5cd6e",
"65f4b860cd15b38ef814a1a804314a55be953caa65fd758ad989ff34a41c1eea",
"19ba234f0a4f38637d1839f9d9f76ad91c8522307143c97d5f93f69274cec9a7",
"1a67186ca4a5cb8e65fca0e2ecbc5ddc14ae381bb8bffeb9e0a103449e3ef03c",
"afbea317b5a2e89c0bd90ccf5d7fd0ed57fe585e4be3271b0a6bf0f5786b0f26",
"f1b01558ce541262f5ec34299d6fb4090009e3434be2f49105cf46af4d2d4124",
"13a0a0c86335635eaa74ca2d5d488c797bbb4f47dc07105015ed6a1f3309efce",
"1580afeebebb346f94d59fe62da0b79237ead7b1491f5667a90e45edf6ca8b03",
"20be1a875b38c573dd7faaa0de489d655c11efb6a552698e07a2d331b5f655c3",
"be1fe3c4c04018c54c4a0f6b9a2ed3c53abe3a9f76b4d26de56fc9ae95059a99",
"e3e3ace537eb3edd8463d9ad3582e13cf86533ffde43d668dd2e93bbdbd7195a",
"110c50c0bf2c6e7aeb7e435d92d132ab6655168e78a2decdec3330777684d9c1",
"e9ba8f505c9c80c08666a701f3367e6cc665f34b22e73c3c0417eb1c2206082f",
"26cd66fca02379c76df12317052bcafd6cd8c3a7b890d805f36c49989782433a",
"213f3596d6e3a5d0e9932cd2159146015e2abc949f4729ee2632fe1edb78d337",
"1015d70108e03be1c702fe97253607d14aee591f2413ea6787427b6459ff219a",
"3ca989de10cfe609909472c8d35610805b2f977734cf652cc64b3bfc882d5d89",
"b6156f72d380ee9ea6acd190464f2307a5c179ef01fd71f99f2d0f7a57360aea",
"c03bc642b20959cbe133a0303e0c1abff3e31ec8e1a328ec8565c36decff5265",
"2c3e08176f760c6264c3a2cd66fec6c3d78de43fc192457b2a4a660a1e0eb22b",
"f738c02f3c1b190c512b1a32deabf353728e0e9ab034490e3c3409946a97aeec",
"8b1880df301cc963418811088964839287ff7fe31c49ea6ebd9e48bdeee497c5",
"1e75cb21c60989020375f1a7a242839f0b0b68973a4c2a05cf7555ed5aaec4c1",
"62bf8a9c32a5bccf290b6c474d75b2a2a4093f1a9e27139433a8f2b3bce7b8d7",
"166c8350d3173b5e702b783dfd33c66ee0432742e9b92b997fd23c60dc6756ca",
"044a14d822a90cacf2f5a101428adc8f4109386ccb158bf905c8618b8ee24ec3",
"387d397ea43a994be84d2d544afbe481a2000f55252696bba2c50c8ebd101347",
"56f8ccf1f86409b46ce36166ae9165138441577589db08cbc5f66ca29743b9fd",
"9706c092b04d91f53dff91fa37b7493d28b576b5d710469df79401662236fc03",
"877968686c068ce2f7e2adcff68bf8748edf3cf862cfb4d3947a3106958054e3",
"8817e5719879acf7024787eccdb271035566cfa333e049407c0178ccc57a5b9f",
"8938249e4b50cadaccdf5b18621326cbb15253e33a20f5636e995d72478de472",
"f164abba4963a44d107257e3232d90aca5e66a1408248c51741e991db5227756",
"d05563e2b1cba0c4a2a1e8bde3a1a0d9f5b40c85a070d6f5fb21066ead5d0601",
"03fbb16384f0a3866f4c3117877666efbf124597564b293d4aab0d269fabddfa",
"5fa8486ac0e52964d1881bbe338eb54be2f719549224892057b4da04ba8b3475",
"cdfabcee46911111236a31708b2539d71fc211d9b09c0d8530a11e1dbf6eed01",
"4f82de03b9504793b82a07a0bdcdff314d759e7b62d26b784946b0d36f916f52",
"259ec7f173bcc76a0994c967b4f5f024c56057fb79c965c4fae41875f06a0e4c",
"193cc8e7c3e08bb30f5437aa27ade1f142369b246a675b2383e6da9b49a9809e",
"5c10896f0e2856b2a2eee0fe4a2c1633565d18f0e93e1fab26c373e8f829654d",
"f16012d93f28851a1eb989f5d0b43f3f39ca73c9a62d5181bff237536bd348c3",
"2966b3cfae1e44ea996dc5d686cf25fa053fb6f67201b9e46eade85d0ad6b806",
"ddb8782485e900bc60bcf4c33a6fd585680cc683d516efa03eb9985fad8715fb",
"4c4d6e71aea05786413148fc7a786b0ecaf582cff1209f5a809fba8504ce662c",
"fb4c5e86d7b2229b99b8ba6d94c247ef964aa3a2bae8edc77569f28dbbff2d4e",
"e94f526de9019633ecd54ac6120f23958d7718f1e7717bf329211a4faeed4e6d",
"cbd6660a10db3f23f7a03d4b9d4044c7932b2801ac89d60bc9eb92d65a46c2a0",
"8818bbd3db4dc123b25cbba5f54c2bc4b3fcf9bf7d7a7709f4ae588b267c4ece",
"c65382513f07460da39833cb666c5ed82e61b9e998f4b0c4287cee56c3cc9bcd",
"8975b0577fd35566d750b362b0897a26c399136df07bababbde6203ff2954ed4",
"21fe0ceb0052be7fb0f004187cacd7de67fa6eb0938d927677f2398c132317a8",
"2ef73f3c26f12d93889f3c78b6a66c1d52b649dc9e856e2c172ea7c58ac2b5e3",
"388a3cd56d73867abb5f8401492b6e2681eb69851e767fd84210a56076fb3dd3",
"af533e022fc9439e4e3cb838ecd18692232adf6fe9839526d3c3dd1b71910b1a",
"751c09d41a9343882a81cd13ee40818d12eb44c6c7f40df16e4aea8fab91972a",
"5b73ddb68d9d2b0aa265a07988d6b88ae9aac582af83032f8a9b21a2e1b7bf18",
"3da29126c7c5d7f43e64242a79feaa4ef3459cdeccc898ed59a97f6ec93b9dab",
"566dc920293da5cb4fe0aa8abda8bbf56f552313bff19046641e3615c1e3ed3f",
"4115bea02f73f97f629e5c5590720c01e7e449ae2a6697d4d2783321303692f9",
"4ce08f4762468a7670012164878d68340c52a35e66c1884d5c864889abc96677",
"81ea0b7804124e0c22ea5fc71104a2afcb52a1fa816f3ecb7dcb5d9dea1786d0",
"fe362733b05f6bedaf9379d7f7936ede209b1f8323c3922549d9e73681b5db7b",
"eff37d30dfd20359be4e73fdf40d27734b3df90a97a55ed745297294ca85d09f",
"172ffc67153d12e0ca76a8b6cd5d4731885b39ce0cac93a8972a18006c8b8baf",
"c47957f1cc88e83ef9445839709a480a036bed5f88ac0fcc8e1e703ffaac132c",
"30f3548370cfdceda5c37b569b6175e799eef1a62aaa943245ae7669c227a7b5",
"c95dcb3cf1f27d0eef2f25d2413870904a877c4a56c2de1e83e2bc2ae2e46821",
"d5d0b5d705434cd46b185749f66bfb5836dcdf6ee549a2b7a4aee7f58007caaf",
"bbc124a712f15d07c300e05b668389a439c91777f721f8320c1c9078066d2c7e",
"a451b48c35a6c7854cfaae60262e76990816382ac0667e5a5c9e1b46c4342ddf",
"b0d150fb55e778d01147f0b5d89d99ecb20ff07e5e6760d6b645eb5b654c622b",
"34f737c0ab219951eee89a9f8dac299c9d4c38f33fa494c5c6eefc92b6db08bc",
"1a62cc3a00800dcbd99891080c1e098458193a8cc9f970ea99fbeff00318c289",
"cfce55ebafc840d7ae48281c7fd57ec8b482d4b704437495495ac414cf4a374b",
"6746facf71146d999dabd05d093ae586648d1ee28e72617b99d0f0086e1e45bf",
"571ced283b3f23b4e750bf12a2caf1781847bd890e43603cdc5976102b7bb11b",
"cfcb765b048e35022c5d089d26e85a36b005a2b80493d03a144e09f409b6afd1",
"4050c7a27705bb27f42089b299f3cbe5054ead68727e8ef9318ce6f25cd6f31d",
"184070bd5d265fbdc142cd1c5cd0d7e414e70369a266d627c8fba84fa5e84c34",
"9edda9a4443902a9588c0d0ccc62b930218479a6841e6fe7d43003f04b1fd643",
"e412feef7908324a6da1841629f35d3d358642019310ec57c614836b63d30763",
"1a2b8edff3f9acc1554fcbae3cf1d6298c6462e22e5eb0259684f835012bd13f",
"288c4ad9b9409762ea07c24a41f04f69a7d74bee2d95435374bde946d7241c7b",
"805691bb286748cfb591d3aebe7e6f4e4dc6e2808c65143cc004e4eb6fd09d43",
"d4ac8d3a0afc6cfa7b460ae3001baeb36dadb37da07d2e8ac91822df348aed3d",
"c376617014d20158bced3d3ba552b6eccf84e62aa3eb650e90029c84d13eea69",
"c41f09f43cecae7293d6007ca0a357087d5ae59be500c1cd5b289ee810c7b082",
"03d1ced1fba5c39155c44b7765cb760c78708dcfc80b0bd8ade3a56da8830b29",
"09bde6f152218dc92c41d7f45387e63e5869d807ec70b821405dbd884b7fcf4b",
"71c9036e18179b90b37d39e9f05eb89cc5fc341fd7c477d0d7493285faca08a4",
"5916833ebb05cd919ca7fe83b692d3205bef72392b2cf6bb0a6d43f994f95f11",
"f63aab3ec641b3b024964c2b437c04f6043c4c7e0279239995401958f86bbe54",
"f172b180bfb09740493120b6326cbdc561e477def9bbcfd28cc8c1c5e3379a31",
"cb9b89cc18381dd9141ade588654d4e6a231d5bf49d4d59ac27d869cbe100cf3",
"7bd8815046fdd810a923e1984aaebdcdf84d87c8992d68b5eeb460f93eb3c8d7",
"607be66862fd08ee5b19facac09dfdbcd40c312101d66e6ebd2b841f1b9a9325",
"9fe03bbe69ab1834f5219b0da88a08b30a66c5913f0151963c360560db0387b3",
"90a83585717b75f0e9b725e055eeeeb9e7a028ea7e6cbc07b20917ec0363e38c",
"336ea0530f4a7469126e0218587ebbde3358a0b31c29d200f7dc7eb15c6aadd8",
"a79e76dc0abca4396f0747cd7b748df913007626b1d659da0c1f78b9303d01a3",
"44e78a773756e0951519504d7038d28d0213a37e0ce375371757bc996311e3b8",
"77ac012a3f754dcfeab5eb996be9cd2d1f96111b6e49f3994df181f28569d825",
"ce5a10db6fccdaf140aaa4ded6250a9c06e9222bc9f9f3658a4aff935f2b9f3a",
"ecc203a7fe2be4abd55bb53e6e673572e0078da8cd375ef430cc97f9f80083af",
"14a5186de9d7a18b0412b8563e51cc5433840b4a129a8ff963b33a3c4afe8ebb",
"13f8ef95cb86e6a638931c8e107673eb76ba10d7c2cd70b9d9920bbeed929409",
"0b338f4ee12f2dfcb78713377941e0b0632152581d1332516e4a2cab1942cca4",
"eaab0ec37b3b8ab796e9f57238de14a264a076f3887d86e29bb5906db5a00e02",
"23cb68b8c0e6dc26dc27766ddc0a13a99438fd55617aa4095d8f969720c872df",
"091d8ee30d6f2968d46b687dd65292665742de0bb83dcc0004c72ce10007a549",
"7f507abc6d19ba00c065a876ec5657868882d18a221bc46c7a6912541f5bc7ba",
"a0607c24e14e8c223db0d70b4d30ee88014d603f437e9e02aa7dafa3cdfbad94",
"ddbfea75cc467882eb3483ce5e2e756a4f4701b76b445519e89f22d60fa86e06",
"0c311f38c35a4fb90d651c289d486856cd1413df9b0677f53ece2cd9e477c60a",
"46a73a8dd3e70f59d3942c01df599def783c9da82fd83222cd662b53dce7dbdf",
"ad038ff9b14de84a801e4e621ce5df029dd93520d0c2fa38bff176a8b1d1698c",
"ab70c5dfbd1ea817fed0cd067293abf319e5d7901c2141d5d99b23f03a38e748",
"1fffda67932b73c8ecaf009a3491a026953babfe1f663b0697c3c4ae8b2e7dcb",
"b0d2cc19472dd57f2b17efc03c8d58c2283dbb19da572f7755855aa9794317a0",
"a0d19a6ee33979c325510e276622df41f71583d07501b87071129a0ad94732a5",
"724642a7032d1062b89e52bea34b75df7d8fe772d9fe3c93ddf3c4545ab5a99b",
"ade5eaa7e61f672d587ea03dae7d7b55229c01d06bc0a5701436cbd18366a626",
"013b31ebd228fcdda51fabb03bb02d60ac20ca215aafa83bdd855e3755a35f0b",
"332ed40bb10dde3c954a75d7b8999d4b26a1c063c1dc6e32c1d91bab7bbb7d16",
"c7a197b3a05b566bcc9facd20e441d6f6c2860ac9651cd51d6b9d2cdeeea0390",
"bd9cf64ea8953c037108e6f654914f3958b68e29c16700dc184d94a21708ff60",
"8835b0ac021151df716474ce27ce4d3c15f0b2dab48003cf3f3efd0945106b9a",
"3bfefa3301aa55c080190cffda8eae51d9af488b4c1f24c3d9a75242fd8ea01d",
"08284d14993cd47d53ebaecf0df0478cc182c89c00e1859c84851686ddf2c1b7",
"1ed7ef9f04c2ac8db6a864db131087f27065098e69c3fe78718d9b947f4a39d0",
"c161f2dcd57e9c1439b31a9dd43d8f3d7dd8f0eb7cfac6fb25a0f28e306f0661",
"c01969ad34c52caf3dc4d80d19735c29731ac6e7a92085ab9250c48dea48a3fc",
"1720b3655619d2a52b3521ae0e49e345cb3389ebd6208acaf9f13fdacca8be49",
"756288361c83e24c617cf95c905b22d017cdc86f0bf1d658f4756c7379873b7f",
"e7d0eda3452693b752abcda1b55e276f82698f5f1605403eff830bea0071a394",
"2c82ecaa6b84803e044af63118afe544687cb6e6c7df49ed762dfd7c8693a1bc",
"6136cbf4b441056fa1e2722498125d6ded45e17b52143959c7f4d4e395218ac2",
"721d3245aafef27f6a624f47954b6c255079526ffa25e9ff77e5dcff473b1597",
"9dd2fbd8cef16c353c0ac21191d509eb28dd9e3e0d8cea5d26ca839393851c3a",
"b2394ceacdebf21bf9df2ced98e58f1c3a4bbbff660dd900f62202d6785cc46e",
"57089f222749ad7871765f062b114f43ba20ec56422a8b1e3f87192c0ea718c6",
"e49a9459961cd33cdf4aae1b1078a5dea7c040e0fea340c93a724872fc4af806",
"ede67f720effd2ca9c88994152d0201dee6b0a2d2c077aca6dae29f73f8b6309",
"e0f434bf22e3088039c21f719ffc67f0f2cb5e98a7a0194c76e96bf4e8e17e61",
"277c04e2853484a4eba910ad336d01b477b67cc200c59f3c8d77eef8494f29cd",
"156d5747d0c99c7f27097d7b7e002b2e185cb72d8dd7eb424a0321528161219f",
"20ddd1ed9b1ca803946d64a83ae4659da67fba7a1a3eddb1e103c0f5e03e3a2c",
"f0af604d3dabbf9a0f2a7d3dda6bd38bba72c6d09be494fcef713ff10189b6e6",
"9802bb87def4cc10c4a5fd49aa58dfe2f3fddb46b4708814ead81d23ba95139b",
"4f8ce1e51d2fe7f24043a904d898ebfc91975418753413aa099b795ecb35cedb",
"bddc6514d7ee6ace0a4ac1d0e068112288cbcf560454642705630177cba608bd",
"d635994f6291517b0281ffdd496afa862712e5b3c4e52e4cd5fdae8c0e72fb08",
"878d9ca600cf87e769cc305c1b35255186615a73a0da613b5f1c98dbf81283ea",
"a64ebe5dc185de9fdde7607b6998702eb23456184957307d2fa72e87a47702d6",
"ce50eab7b5eb52bdc9ad8e5a480ab780ca9320e44360b1fe37e03f2f7ad7de01",
"eeddb7c0db6e30abe66d79e327511e61fcebbc29f159b40a86b046ecf0513823",
"787fc93440c1ec96b5ad01c16cf77916a1405f9426356ec921d8dff3ea63b7e0",
"7f0d5eab47eefda696c0bf0fbf86ab216fce461e9303aba6ac374120e890e8df",
"b68004b42f14ad029f4c2e03b1d5eb76d57160e26476d21131bef20ada7d27f4",
"b0c4eb18ae250b51a41382ead92d0dc7455f9379fc9884428e4770608db0faec",
"f92b7a870c059f4d46464c824ec96355140bdce681322cc3a992ff103e3fea52",
"5364312614813398cc525d4c4e146edeb371265fba19133a2c3d2159298a1742",
"f6620e68d37fb2af5000fc28e23b832297ecd8bce99e8be4d04e85309e3d3374",
"5316a27969d7fe04ff27b283961bffc3bf5dfb32fb6a89d101c6c3b1937c2871",
"81d1664fdf3cb33c24eebac0bd64244b77c4abea90bbe8b5ee0b2aafcf2d6a53",
"345782f295b0880352e924a0467b5fbc3e8f3bfbc3c7e48b67091fb5e80a9442",
"794111ea6cd65e311f74ee41d476cb632ce1e4b051dc1d9e9d061a19e1d0bb49",
"2a85daf6138816b99bf8d08ba2114b7ab07975a78420c1a3b06a777c22dd8bcb",
"89b0d5f289ec16401a069a960d0b093e625da3cf41ee29b59b930c5820145455",
"d0fdcb543943fc27d20864f52181471b942cc77ca675bcb30df31d358ef7b1eb",
"b17ea8d77063c709d4dc6b879413c343e3790e9e62ca85b7900b086f6b75c672",
"e71a3e2c274db842d92114f217e2c0eac8b45093fdfd9df4ca7162394862d501",
"c0476759ab7aa333234f6b44f5fd858390ec23694c622cb986e769c78edd733e",
"9ab8eabb1416434d85391341d56993c55458167d4418b19a0f2ad8b79a83a75b",
"7992d0bbb15e23826f443e00505d68d3ed7372995a5c3e498654102fbcd0964e",
"c021b30085151435df33b007ccecc69df1269f39ba25092bed59d932ac0fdc28",
"91a25ec0ec0d9a567f89c4bfe1a65a0e432d07064b4190e27dfb81901fd3139b",
"5950d39a23e1545f301270aa1a12f2e6c453776e4d6355de425cc153f9818867",
"d79f14720c610af179a3765d4b7c0968f977962dbf655b521272b6f1e194488e",
"e9531bfc8b02995aeaa75ba27031fadbcbf4a0dab8961d9296cd7e84d25d6006",
"34e9c26a01d7f16181b454a9d1623c233cb99d31c694656e9413aca3e918692f",
"d9d7422f437bd439ddd4d883dae2a08350173414be78155133fff1964c3d7972",
"4aee0c7aaf075414ff1793ead7eaca601775c615dbd60b640b0a9f0ce505d435",
"6bfdd15459c83b99f096bfb49ee87b063d69c1974c6928acfcfb4099f8c4ef67",
"9fd1c408fd75c336193a2a14d94f6af5adf050b80387b4b010fb29f4cc72707c",
"13c88480a5d00d6c8c7ad2110d76a82d9b70f4fa6696d4e5dd42a066dcaf9920",
"820e725ee25fe8fd3a8d5abe4c46c3ba889de6fa9191aa22ba67d5705421542b",
"32d93a0eb02f42fbbcaf2bad0085b282e46046a4df7ad10657c9d6476375b93e",
"adc5187905b1669cd8ec9c721e1953786b9d89a9bae30780f1e1eab24a00523c",
"e90756ff7f9ad810b239a10ced2cf9b2284354c1f8c7e0accc2461dc796d6e89",
"1251f76e56978481875359801db589a0b22f86d8d634dc04506f322ed78f17e8",
"3afa899fd980e73ecb7f4d8b8f291dc9af796bc65d27f974c6f193c9191a09fd",
"aa305be26e5deddc3c1010cbc213f95f051c785c5b431e6a7cd048f161787528",
"8ea1884ff32e9d10f039b407d0d44e7e670abd884aeee0fb757ae94eaa97373d",
"d482b2155d4dec6b4736a1f1617b53aaa37310277d3fef0c37ad41768fc235b4",
"4d413971387e7a8898a8dc2a27500778539ea214a2dfe9b3d7e8ebdce5cf3db3",
"696e5d46e6c57e8796e4735d08916e0b7929b3cf298c296d22e9d3019653371c",
"1f5647c1d3b088228885865c8940908bf40d1a8272821973b160008e7a3ce2eb",
"b6e76c330f021a5bda65875010b0edf09126c0f510ea849048192003aef4c61c",
"3cd952a0beada41abb424ce47f94b42be64e1ffb0fd0782276807946d0d0bc55",
"98d92677439b41b7bb513312afb92bcc8ee968b2e3b238cecb9b0f34c9bb63d0",
"ecbca2cf08ae57d517ad16158a32bfa7dc0382eaeda128e91886734c24a0b29d",
"942cc7c0b52e2b16a4b89fa4fc7e0bf609e29a08c1a8543452b77c7bfd11bb28",
"8a065d8b61a0dffb170d5627735a76b0e9506037808cba16c345007c9f79cf8f",
"1b9fa19714659c78ff413871849215361029ac802b1cbcd54e408bd87287f81f",
"8dab071bcd6c7292a9ef727b4ae0d86713301da8618d9a48adce55f303a869a1",
"8253e3e7c7b684b9cb2beb014ce330ff3d99d17abbdbabe4f4d674ded53ffc6b",
"f195f321e9e3d6bd7d074504dd2ab0e6241f92e784b1aa271ff648b1cab6d7f6",
"27e4cc72090f241266476a7c09495f2db153d5bcbd761903ef79275ec56b2ed8",
"899c2405788e25b99a1846355e646d77cf400083415f7dc5afe69d6e17c00023",
"a59b78c4905744076bfee894de707d4f120b5c6893ea0400297d0bb834727632",
"59dc78b105649707a2bb4419c48f005400d3973de3736610230435b10424b24f",
"c0149d1d7e7a6353a6d906efe728f2f329fe14a4149a3ea77609bc42b975ddfa",
"a32f241474a6c16932e9243be0cf09bcdc7e0ca0e7a6a1b9b1a0f01e41502377",
"b239b2e4f81841361c1339f68e2c359f929af9ad9f34e01aab4631ad6d5500b0",
"85fb419c7002a3e0b4b6ea093b4c1ac6936645b65dac5ac15a8528b7b94c1754",
"9619720625f190b93a3fad186ab314189633c0d3a01e6f9bc8c4a8f82f383dbf",
"7d620d90fe69fa469a6538388970a1aa09bb48a2d59b347b97e8ce71f48c7f46",
"294383568596fb37c75bbacd979c5ff6f20a556bf8879cc72924855df9b8240e",
"16b18ab314359c2b833c1c6986d48c55a9fc97cde9a3c1f10a3177140f73f738",
"8cbbdd14bc33f04cf45813e4a153a273d36adad5ce71f499eeb87fb8ac63b729",
"69c9a498db174ecaefcc5a3ac9fdedf0f813a5bec727f1e775babdec7718816e",
"b462c3be40448f1d4f80626254e535b08bc9cdcff599a768578d4b2881a8e3f0",
"553e9d9c5f360ac0b74a7d44e5a391dad4ced03e0c24183b7e8ecabdf1715a64",
"7a7c55a56fa9ae51e655e01975d8a6ff4ae9e4b486fcbe4eac044588f245ebea",
"2afdf3c82abc4867f5de111286c2b3be7d6e48657ba923cfbf101a6dfcf9db9a",
"41037d2edcdce0c49b7fb4a6aa0999ca66976c7483afe631d4eda283144f6dfc",
"c4466f8497ca2eeb4583a0b08e9d9ac74395709fda109d24f2e4462196779c5d",
"75f609338aa67d969a2ae2a2362b2da9d77c695dfd1df7224a6901db932c3364",
"68606ceb989d5488fc7cf649f3d7c272ef055da1a93faecd55fe06f6967098ca",
"44346bdeb7e052f6255048f0d9b42c425bab9c3dd24168212c3ecf1ebf34e6ae",
"8e9cf6e1f366471f2ac7d2ee9b5e6266fda71f8f2e4109f2237ed5f8813fc718",
"84bbeb8406d250951f8c1b3e86a7c010082921833dfd9555a2f909b1086eb4b8",
"ee666f3eef0f7e2a9c222958c97eaf35f51ced393d714485ab09a069340fdf88",
"c153d34a65c47b4a62c5cacf24010975d0356b2f32c8f5da530d338816ad5de6",
"9fc5450109e1b779f6c7ae79d56c27635c8dd426c5a9d54e2578db989b8c3b4e",
"d12bf3732ef4af5c22fa90356af8fc50fcb40f8f2ea5c8594737a3b3d5abdbd7",
"11030b9289bba5af65260672ab6fee88b87420acef4a1789a2073b7ec2f2a09e",
"69cb192b8444005c8c0ceb12c846860768188cda0aec27a9c8a55cdee2123632",
"db444c15597b5f1a03d1f9edd16e4a9f43a667cc275175dfa2b704e3bb1a9b83",
"3fb735061abc519dfe979e54c1ee5bfad0a9d858b3315bad34bde999efd724dd",
}

83
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,83 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package chacha20poly1305 implements the ChaCha20-Poly1305 AEAD as specified in RFC 7539.
package chacha20poly1305
import (
"crypto/cipher"
"errors"
)
const (
// KeySize is the size of the key used by this AEAD, in bytes.
KeySize = 32
// NonceSize is the size of the nonce used with this AEAD, in bytes.
NonceSize = 12
)
type chacha20poly1305 struct {
key [32]byte
}
// New returns a ChaCha20-Poly1305 AEAD that uses the given, 256-bit key.
func New(key []byte) (cipher.AEAD, error) {
if len(key) != KeySize {
return nil, errors.New("chacha20poly1305: bad key length")
}
ret := new(chacha20poly1305)
copy(ret.key[:], key)
return ret, nil
}
func (c *chacha20poly1305) NonceSize() int {
return NonceSize
}
func (c *chacha20poly1305) Overhead() int {
return 16
}
func (c *chacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
if len(nonce) != NonceSize {
panic("chacha20poly1305: bad nonce length passed to Seal")
}
if uint64(len(plaintext)) > (1<<38)-64 {
panic("chacha20poly1305: plaintext too large")
}
return c.seal(dst, nonce, plaintext, additionalData)
}
var errOpen = errors.New("chacha20poly1305: message authentication failed")
func (c *chacha20poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
if len(nonce) != NonceSize {
panic("chacha20poly1305: bad nonce length passed to Open")
}
if len(ciphertext) < 16 {
return nil, errOpen
}
if uint64(len(ciphertext)) > (1<<38)-48 {
panic("chacha20poly1305: ciphertext too large")
}
return c.open(dst, nonce, ciphertext, additionalData)
}
// sliceForAppend takes a slice and a requested number of bytes. It returns a
// slice with the contents of the given slice followed by that many bytes and a
// second slice that aliases into it and contains only the extra bytes. If the
// original slice has sufficient capacity then no allocation is performed.
func sliceForAppend(in []byte, n int) (head, tail []byte) {
if total := len(in) + n; cap(in) >= total {
head = in[:total]
} else {
head = make([]byte, total)
copy(head, in)
}
tail = head[len(in):]
return
}

80
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,80 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.7,amd64,!gccgo,!appengine
package chacha20poly1305
import "encoding/binary"
//go:noescape
func chacha20Poly1305Open(dst []byte, key []uint32, src, ad []byte) bool
//go:noescape
func chacha20Poly1305Seal(dst []byte, key []uint32, src, ad []byte)
//go:noescape
func haveSSSE3() bool
var canUseASM bool
func init() {
canUseASM = haveSSSE3()
}
// setupState writes a ChaCha20 input matrix to state. See
// https://tools.ietf.org/html/rfc7539#section-2.3.
func setupState(state *[16]uint32, key *[32]byte, nonce []byte) {
state[0] = 0x61707865
state[1] = 0x3320646e
state[2] = 0x79622d32
state[3] = 0x6b206574
state[4] = binary.LittleEndian.Uint32(key[:4])
state[5] = binary.LittleEndian.Uint32(key[4:8])
state[6] = binary.LittleEndian.Uint32(key[8:12])
state[7] = binary.LittleEndian.Uint32(key[12:16])
state[8] = binary.LittleEndian.Uint32(key[16:20])
state[9] = binary.LittleEndian.Uint32(key[20:24])
state[10] = binary.LittleEndian.Uint32(key[24:28])
state[11] = binary.LittleEndian.Uint32(key[28:32])
state[12] = 0
state[13] = binary.LittleEndian.Uint32(nonce[:4])
state[14] = binary.LittleEndian.Uint32(nonce[4:8])
state[15] = binary.LittleEndian.Uint32(nonce[8:12])
}
func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []byte {
if !canUseASM {
return c.sealGeneric(dst, nonce, plaintext, additionalData)
}
var state [16]uint32
setupState(&state, &c.key, nonce)
ret, out := sliceForAppend(dst, len(plaintext)+16)
chacha20Poly1305Seal(out[:], state[:], plaintext, additionalData)
return ret
}
func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
if !canUseASM {
return c.openGeneric(dst, nonce, ciphertext, additionalData)
}
var state [16]uint32
setupState(&state, &c.key, nonce)
ciphertext = ciphertext[:len(ciphertext)-16]
ret, out := sliceForAppend(dst, len(ciphertext))
if !chacha20Poly1305Open(out, state[:], ciphertext, additionalData) {
for i := range out {
out[i] = 0
}
return nil, errOpen
}
return ret, nil
}

2707
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s сгенерированный поставляемый Обычный файл

Разница между файлами не показана из-за своего большого размера Загрузить разницу

70
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,70 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package chacha20poly1305
import (
"encoding/binary"
"golang.org/x/crypto/chacha20poly1305/internal/chacha20"
"golang.org/x/crypto/poly1305"
)
func roundTo16(n int) int {
return 16 * ((n + 15) / 16)
}
func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []byte) []byte {
var counter [16]byte
copy(counter[4:], nonce)
var polyKey [32]byte
chacha20.XORKeyStream(polyKey[:], polyKey[:], &counter, &c.key)
ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize)
counter[0] = 1
chacha20.XORKeyStream(out, plaintext, &counter, &c.key)
polyInput := make([]byte, roundTo16(len(additionalData))+roundTo16(len(plaintext))+8+8)
copy(polyInput, additionalData)
copy(polyInput[roundTo16(len(additionalData)):], out[:len(plaintext)])
binary.LittleEndian.PutUint64(polyInput[len(polyInput)-16:], uint64(len(additionalData)))
binary.LittleEndian.PutUint64(polyInput[len(polyInput)-8:], uint64(len(plaintext)))
var tag [poly1305.TagSize]byte
poly1305.Sum(&tag, polyInput, &polyKey)
copy(out[len(plaintext):], tag[:])
return ret
}
func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
var tag [poly1305.TagSize]byte
copy(tag[:], ciphertext[len(ciphertext)-16:])
ciphertext = ciphertext[:len(ciphertext)-16]
var counter [16]byte
copy(counter[4:], nonce)
var polyKey [32]byte
chacha20.XORKeyStream(polyKey[:], polyKey[:], &counter, &c.key)
polyInput := make([]byte, roundTo16(len(additionalData))+roundTo16(len(ciphertext))+8+8)
copy(polyInput, additionalData)
copy(polyInput[roundTo16(len(additionalData)):], ciphertext)
binary.LittleEndian.PutUint64(polyInput[len(polyInput)-16:], uint64(len(additionalData)))
binary.LittleEndian.PutUint64(polyInput[len(polyInput)-8:], uint64(len(ciphertext)))
ret, out := sliceForAppend(dst, len(ciphertext))
if !poly1305.Verify(&tag, polyInput, &polyKey) {
for i := range out {
out[i] = 0
}
return nil, errOpen
}
counter[0] = 1
chacha20.XORKeyStream(out, ciphertext, &counter, &c.key)
return ret, nil
}

15
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,15 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !amd64 !go1.7 gccgo appengine
package chacha20poly1305
func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []byte {
return c.sealGeneric(dst, nonce, plaintext, additionalData)
}
func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
return c.openGeneric(dst, nonce, ciphertext, additionalData)
}

182
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_test.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,182 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package chacha20poly1305
import (
"bytes"
cr "crypto/rand"
"encoding/hex"
mr "math/rand"
"testing"
)
func TestVectors(t *testing.T) {
for i, test := range chacha20Poly1305Tests {
key, _ := hex.DecodeString(test.key)
nonce, _ := hex.DecodeString(test.nonce)
ad, _ := hex.DecodeString(test.aad)
plaintext, _ := hex.DecodeString(test.plaintext)
aead, err := New(key)
if err != nil {
t.Fatal(err)
}
ct := aead.Seal(nil, nonce, plaintext, ad)
if ctHex := hex.EncodeToString(ct); ctHex != test.out {
t.Errorf("#%d: got %s, want %s", i, ctHex, test.out)
continue
}
plaintext2, err := aead.Open(nil, nonce, ct, ad)
if err != nil {
t.Errorf("#%d: Open failed", i)
continue
}
if !bytes.Equal(plaintext, plaintext2) {
t.Errorf("#%d: plaintext's don't match: got %x vs %x", i, plaintext2, plaintext)
continue
}
if len(ad) > 0 {
alterAdIdx := mr.Intn(len(ad))
ad[alterAdIdx] ^= 0x80
if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
t.Errorf("#%d: Open was successful after altering additional data", i)
}
ad[alterAdIdx] ^= 0x80
}
alterNonceIdx := mr.Intn(aead.NonceSize())
nonce[alterNonceIdx] ^= 0x80
if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
t.Errorf("#%d: Open was successful after altering nonce", i)
}
nonce[alterNonceIdx] ^= 0x80
alterCtIdx := mr.Intn(len(ct))
ct[alterCtIdx] ^= 0x80
if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
t.Errorf("#%d: Open was successful after altering ciphertext", i)
}
ct[alterCtIdx] ^= 0x80
}
}
func TestRandom(t *testing.T) {
// Some random tests to verify Open(Seal) == Plaintext
for i := 0; i < 256; i++ {
var nonce [12]byte
var key [32]byte
al := mr.Intn(128)
pl := mr.Intn(16384)
ad := make([]byte, al)
plaintext := make([]byte, pl)
cr.Read(key[:])
cr.Read(nonce[:])
cr.Read(ad)
cr.Read(plaintext)
aead, err := New(key[:])
if err != nil {
t.Fatal(err)
}
ct := aead.Seal(nil, nonce[:], plaintext, ad)
plaintext2, err := aead.Open(nil, nonce[:], ct, ad)
if err != nil {
t.Errorf("Random #%d: Open failed", i)
continue
}
if !bytes.Equal(plaintext, plaintext2) {
t.Errorf("Random #%d: plaintext's don't match: got %x vs %x", i, plaintext2, plaintext)
continue
}
if len(ad) > 0 {
alterAdIdx := mr.Intn(len(ad))
ad[alterAdIdx] ^= 0x80
if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
t.Errorf("Random #%d: Open was successful after altering additional data", i)
}
ad[alterAdIdx] ^= 0x80
}
alterNonceIdx := mr.Intn(aead.NonceSize())
nonce[alterNonceIdx] ^= 0x80
if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
t.Errorf("Random #%d: Open was successful after altering nonce", i)
}
nonce[alterNonceIdx] ^= 0x80
alterCtIdx := mr.Intn(len(ct))
ct[alterCtIdx] ^= 0x80
if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
t.Errorf("Random #%d: Open was successful after altering ciphertext", i)
}
ct[alterCtIdx] ^= 0x80
}
}
func benchamarkChaCha20Poly1305Seal(b *testing.B, buf []byte) {
b.SetBytes(int64(len(buf)))
var key [32]byte
var nonce [12]byte
var ad [13]byte
var out []byte
aead, _ := New(key[:])
b.ResetTimer()
for i := 0; i < b.N; i++ {
out = aead.Seal(out[:0], nonce[:], buf[:], ad[:])
}
}
func benchamarkChaCha20Poly1305Open(b *testing.B, buf []byte) {
b.SetBytes(int64(len(buf)))
var key [32]byte
var nonce [12]byte
var ad [13]byte
var ct []byte
var out []byte
aead, _ := New(key[:])
ct = aead.Seal(ct[:0], nonce[:], buf[:], ad[:])
b.ResetTimer()
for i := 0; i < b.N; i++ {
out, _ = aead.Open(out[:0], nonce[:], ct[:], ad[:])
}
}
func BenchmarkChacha20Poly1305Open_64(b *testing.B) {
benchamarkChaCha20Poly1305Open(b, make([]byte, 64))
}
func BenchmarkChacha20Poly1305Seal_64(b *testing.B) {
benchamarkChaCha20Poly1305Seal(b, make([]byte, 64))
}
func BenchmarkChacha20Poly1305Open_1350(b *testing.B) {
benchamarkChaCha20Poly1305Open(b, make([]byte, 1350))
}
func BenchmarkChacha20Poly1305Seal_1350(b *testing.B) {
benchamarkChaCha20Poly1305Seal(b, make([]byte, 1350))
}
func BenchmarkChacha20Poly1305Open_8K(b *testing.B) {
benchamarkChaCha20Poly1305Open(b, make([]byte, 8*1024))
}
func BenchmarkChacha20Poly1305Seal_8K(b *testing.B) {
benchamarkChaCha20Poly1305Seal(b, make([]byte, 8*1024))
}

332
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_test_vectors.go сгенерированный поставляемый Обычный файл

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

199
vendor/golang.org/x/crypto/chacha20poly1305/internal/chacha20/chacha_generic.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,199 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package ChaCha20 implements the core ChaCha20 function as specified in https://tools.ietf.org/html/rfc7539#section-2.3.
package chacha20
import "encoding/binary"
const rounds = 20
// core applies the ChaCha20 core function to 16-byte input in, 32-byte key k,
// and 16-byte constant c, and puts the result into 64-byte array out.
func core(out *[64]byte, in *[16]byte, k *[32]byte) {
j0 := uint32(0x61707865)
j1 := uint32(0x3320646e)
j2 := uint32(0x79622d32)
j3 := uint32(0x6b206574)
j4 := binary.LittleEndian.Uint32(k[0:4])
j5 := binary.LittleEndian.Uint32(k[4:8])
j6 := binary.LittleEndian.Uint32(k[8:12])
j7 := binary.LittleEndian.Uint32(k[12:16])
j8 := binary.LittleEndian.Uint32(k[16:20])
j9 := binary.LittleEndian.Uint32(k[20:24])
j10 := binary.LittleEndian.Uint32(k[24:28])
j11 := binary.LittleEndian.Uint32(k[28:32])
j12 := binary.LittleEndian.Uint32(in[0:4])
j13 := binary.LittleEndian.Uint32(in[4:8])
j14 := binary.LittleEndian.Uint32(in[8:12])
j15 := binary.LittleEndian.Uint32(in[12:16])
x0, x1, x2, x3, x4, x5, x6, x7 := j0, j1, j2, j3, j4, j5, j6, j7
x8, x9, x10, x11, x12, x13, x14, x15 := j8, j9, j10, j11, j12, j13, j14, j15
for i := 0; i < rounds; i += 2 {
x0 += x4
x12 ^= x0
x12 = (x12 << 16) | (x12 >> (16))
x8 += x12
x4 ^= x8
x4 = (x4 << 12) | (x4 >> (20))
x0 += x4
x12 ^= x0
x12 = (x12 << 8) | (x12 >> (24))
x8 += x12
x4 ^= x8
x4 = (x4 << 7) | (x4 >> (25))
x1 += x5
x13 ^= x1
x13 = (x13 << 16) | (x13 >> 16)
x9 += x13
x5 ^= x9
x5 = (x5 << 12) | (x5 >> 20)
x1 += x5
x13 ^= x1
x13 = (x13 << 8) | (x13 >> 24)
x9 += x13
x5 ^= x9
x5 = (x5 << 7) | (x5 >> 25)
x2 += x6
x14 ^= x2
x14 = (x14 << 16) | (x14 >> 16)
x10 += x14
x6 ^= x10
x6 = (x6 << 12) | (x6 >> 20)
x2 += x6
x14 ^= x2
x14 = (x14 << 8) | (x14 >> 24)
x10 += x14
x6 ^= x10
x6 = (x6 << 7) | (x6 >> 25)
x3 += x7
x15 ^= x3
x15 = (x15 << 16) | (x15 >> 16)
x11 += x15
x7 ^= x11
x7 = (x7 << 12) | (x7 >> 20)
x3 += x7
x15 ^= x3
x15 = (x15 << 8) | (x15 >> 24)
x11 += x15
x7 ^= x11
x7 = (x7 << 7) | (x7 >> 25)
x0 += x5
x15 ^= x0
x15 = (x15 << 16) | (x15 >> 16)
x10 += x15
x5 ^= x10
x5 = (x5 << 12) | (x5 >> 20)
x0 += x5
x15 ^= x0
x15 = (x15 << 8) | (x15 >> 24)
x10 += x15
x5 ^= x10
x5 = (x5 << 7) | (x5 >> 25)
x1 += x6
x12 ^= x1
x12 = (x12 << 16) | (x12 >> 16)
x11 += x12
x6 ^= x11
x6 = (x6 << 12) | (x6 >> 20)
x1 += x6
x12 ^= x1
x12 = (x12 << 8) | (x12 >> 24)
x11 += x12
x6 ^= x11
x6 = (x6 << 7) | (x6 >> 25)
x2 += x7
x13 ^= x2
x13 = (x13 << 16) | (x13 >> 16)
x8 += x13
x7 ^= x8
x7 = (x7 << 12) | (x7 >> 20)
x2 += x7
x13 ^= x2
x13 = (x13 << 8) | (x13 >> 24)
x8 += x13
x7 ^= x8
x7 = (x7 << 7) | (x7 >> 25)
x3 += x4
x14 ^= x3
x14 = (x14 << 16) | (x14 >> 16)
x9 += x14
x4 ^= x9
x4 = (x4 << 12) | (x4 >> 20)
x3 += x4
x14 ^= x3
x14 = (x14 << 8) | (x14 >> 24)
x9 += x14
x4 ^= x9
x4 = (x4 << 7) | (x4 >> 25)
}
x0 += j0
x1 += j1
x2 += j2
x3 += j3
x4 += j4
x5 += j5
x6 += j6
x7 += j7
x8 += j8
x9 += j9
x10 += j10
x11 += j11
x12 += j12
x13 += j13
x14 += j14
x15 += j15
binary.LittleEndian.PutUint32(out[0:4], x0)
binary.LittleEndian.PutUint32(out[4:8], x1)
binary.LittleEndian.PutUint32(out[8:12], x2)
binary.LittleEndian.PutUint32(out[12:16], x3)
binary.LittleEndian.PutUint32(out[16:20], x4)
binary.LittleEndian.PutUint32(out[20:24], x5)
binary.LittleEndian.PutUint32(out[24:28], x6)
binary.LittleEndian.PutUint32(out[28:32], x7)
binary.LittleEndian.PutUint32(out[32:36], x8)
binary.LittleEndian.PutUint32(out[36:40], x9)
binary.LittleEndian.PutUint32(out[40:44], x10)
binary.LittleEndian.PutUint32(out[44:48], x11)
binary.LittleEndian.PutUint32(out[48:52], x12)
binary.LittleEndian.PutUint32(out[52:56], x13)
binary.LittleEndian.PutUint32(out[56:60], x14)
binary.LittleEndian.PutUint32(out[60:64], x15)
}
// XORKeyStream crypts bytes from in to out using the given key and counters.
// In and out may be the same slice but otherwise should not overlap. Counter
// contains the raw ChaCha20 counter bytes (i.e. block counter followed by
// nonce).
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
var block [64]byte
var counterCopy [16]byte
copy(counterCopy[:], counter[:])
for len(in) >= 64 {
core(&block, &counterCopy, key)
for i, x := range block {
out[i] = in[i] ^ x
}
u := uint32(1)
for i := 0; i < 4; i++ {
u += uint32(counterCopy[i])
counterCopy[i] = byte(u)
u >>= 8
}
in = in[64:]
out = out[64:]
}
if len(in) > 0 {
core(&block, &counterCopy, key)
for i, v := range in {
out[i] = v ^ block[i]
}
}
}

29
vendor/golang.org/x/crypto/chacha20poly1305/internal/chacha20/chacha_test.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,29 @@
package chacha20
import (
"encoding/hex"
"testing"
)
func TestCore(t *testing.T) {
// This is just a smoke test that checks the example from
// https://tools.ietf.org/html/rfc7539#section-2.3.2. The
// chacha20poly1305 package contains much more extensive tests of this
// code.
var key [32]byte
for i := range key {
key[i] = byte(i)
}
var input [16]byte
input[0] = 1
input[7] = 9
input[11] = 0x4a
var out [64]byte
XORKeyStream(out[:], out[:], &input, &key)
const expected = "10f1e7e4d13b5915500fdd1fa32071c4c7d1f4c733c068030422aa9ac3d46c4ed2826446079faa0914c2d705d98b02a2b5129cd1de164eb9cbd083e8a2503c4e"
if result := hex.EncodeToString(out[:]); result != expected {
t.Errorf("wanted %x but got %x", expected, result)
}
}

25
vendor/golang.org/x/crypto/curve25519/freeze_amd64.s сгенерированный поставляемый
Просмотреть файл

@@ -8,22 +8,9 @@
// +build amd64,!gccgo,!appengine
// func freeze(inout *[5]uint64)
TEXT ·freeze(SB),7,$96-8
TEXT ·freeze(SB),7,$0-8
MOVQ inout+0(FP), DI
MOVQ SP,R11
MOVQ $31,CX
NOTQ CX
ANDQ CX,SP
ADDQ $32,SP
MOVQ R11,0(SP)
MOVQ R12,8(SP)
MOVQ R13,16(SP)
MOVQ R14,24(SP)
MOVQ R15,32(SP)
MOVQ BX,40(SP)
MOVQ BP,48(SP)
MOVQ 0(DI),SI
MOVQ 8(DI),DX
MOVQ 16(DI),CX
@@ -81,14 +68,4 @@ REDUCELOOP:
MOVQ CX,16(DI)
MOVQ R8,24(DI)
MOVQ R9,32(DI)
MOVQ 0(SP),R11
MOVQ 8(SP),R12
MOVQ 16(SP),R13
MOVQ 24(SP),R14
MOVQ 32(SP),R15
MOVQ 40(SP),BX
MOVQ 48(SP),BP
MOVQ R11,SP
MOVQ DI,AX
MOVQ SI,DX
RET

847
vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s сгенерированный поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

40
vendor/golang.org/x/crypto/curve25519/mul_amd64.s сгенерированный поставляемый
Просмотреть файл

@@ -8,35 +8,21 @@
// +build amd64,!gccgo,!appengine
// func mul(dest, a, b *[5]uint64)
TEXT ·mul(SB),0,$128-24
TEXT ·mul(SB),0,$16-24
MOVQ dest+0(FP), DI
MOVQ a+8(FP), SI
MOVQ b+16(FP), DX
MOVQ SP,R11
MOVQ $31,CX
NOTQ CX
ANDQ CX,SP
ADDQ $32,SP
MOVQ R11,0(SP)
MOVQ R12,8(SP)
MOVQ R13,16(SP)
MOVQ R14,24(SP)
MOVQ R15,32(SP)
MOVQ BX,40(SP)
MOVQ BP,48(SP)
MOVQ DI,56(SP)
MOVQ DX,CX
MOVQ 24(SI),DX
IMUL3Q $19,DX,AX
MOVQ AX,64(SP)
MOVQ AX,0(SP)
MULQ 16(CX)
MOVQ AX,R8
MOVQ DX,R9
MOVQ 32(SI),DX
IMUL3Q $19,DX,AX
MOVQ AX,72(SP)
MOVQ AX,8(SP)
MULQ 8(CX)
ADDQ AX,R8
ADCQ DX,R9
@@ -111,11 +97,11 @@ TEXT ·mul(SB),0,$128-24
MULQ 8(CX)
ADDQ AX,BX
ADCQ DX,BP
MOVQ 64(SP),AX
MOVQ 0(SP),AX
MULQ 24(CX)
ADDQ AX,R10
ADCQ DX,R11
MOVQ 64(SP),AX
MOVQ 0(SP),AX
MULQ 32(CX)
ADDQ AX,R12
ADCQ DX,R13
@@ -123,15 +109,15 @@ TEXT ·mul(SB),0,$128-24
MULQ 0(CX)
ADDQ AX,BX
ADCQ DX,BP
MOVQ 72(SP),AX
MOVQ 8(SP),AX
MULQ 16(CX)
ADDQ AX,R10
ADCQ DX,R11
MOVQ 72(SP),AX
MOVQ 8(SP),AX
MULQ 24(CX)
ADDQ AX,R12
ADCQ DX,R13
MOVQ 72(SP),AX
MOVQ 8(SP),AX
MULQ 32(CX)
ADDQ AX,R14
ADCQ DX,R15
@@ -178,14 +164,4 @@ TEXT ·mul(SB),0,$128-24
MOVQ R9,16(DI)
MOVQ AX,24(DI)
MOVQ R10,32(DI)
MOVQ 0(SP),R11
MOVQ 8(SP),R12
MOVQ 16(SP),R13
MOVQ 24(SP),R14
MOVQ 32(SP),R15
MOVQ 40(SP),BX
MOVQ 48(SP),BP
MOVQ R11,SP
MOVQ DI,AX
MOVQ SI,DX
RET

25
vendor/golang.org/x/crypto/curve25519/square_amd64.s сгенерированный поставляемый
Просмотреть файл

@@ -8,23 +8,10 @@
// +build amd64,!gccgo,!appengine
// func square(out, in *[5]uint64)
TEXT ·square(SB),7,$96-16
TEXT ·square(SB),7,$0-16
MOVQ out+0(FP), DI
MOVQ in+8(FP), SI
MOVQ SP,R11
MOVQ $31,CX
NOTQ CX
ANDQ CX,SP
ADDQ $32, SP
MOVQ R11,0(SP)
MOVQ R12,8(SP)
MOVQ R13,16(SP)
MOVQ R14,24(SP)
MOVQ R15,32(SP)
MOVQ BX,40(SP)
MOVQ BP,48(SP)
MOVQ 0(SI),AX
MULQ 0(SI)
MOVQ AX,CX
@@ -140,14 +127,4 @@ TEXT ·square(SB),7,$96-16
MOVQ R9,16(DI)
MOVQ AX,24(DI)
MOVQ R10,32(DI)
MOVQ 0(SP),R11
MOVQ 8(SP),R12
MOVQ 16(SP),R13
MOVQ 24(SP),R14
MOVQ 32(SP),R15
MOVQ 40(SP),BX
MOVQ 48(SP),BP
MOVQ R11,SP
MOVQ DI,AX
MOVQ SI,DX
RET

85
vendor/golang.org/x/crypto/ocsp/ocsp.go сгенерированный поставляемый
Просмотреть файл

@@ -266,6 +266,15 @@ func getHashAlgorithmFromOID(target asn1.ObjectIdentifier) crypto.Hash {
return crypto.Hash(0)
}
func getOIDFromHashAlgorithm(target crypto.Hash) asn1.ObjectIdentifier {
for hash, oid := range hashOIDs {
if hash == target {
return oid
}
}
return nil
}
// This is the exposed reflection of the internal OCSP structures.
// The status values that can be expressed in OCSP. See RFC 6960.
@@ -305,6 +314,32 @@ type Request struct {
SerialNumber *big.Int
}
// Marshal marshals the OCSP request to ASN.1 DER encoded form.
func (req *Request) Marshal() ([]byte, error) {
hashAlg := getOIDFromHashAlgorithm(req.HashAlgorithm)
if hashAlg == nil {
return nil, errors.New("Unknown hash algorithm")
}
return asn1.Marshal(ocspRequest{
tbsRequest{
Version: 0,
RequestList: []request{
{
Cert: certID{
pkix.AlgorithmIdentifier{
Algorithm: hashAlg,
Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */},
},
req.IssuerNameHash,
req.IssuerKeyHash,
req.SerialNumber,
},
},
},
},
})
}
// Response represents an OCSP response containing a single SingleResponse. See
// RFC 6960.
type Response struct {
@@ -402,6 +437,18 @@ func ParseRequest(bytes []byte) (*Request, error) {
// Invalid signatures or parse failures will result in a ParseError. Error
// responses will result in a ResponseError.
func ParseResponse(bytes []byte, issuer *x509.Certificate) (*Response, error) {
return ParseResponseForCert(bytes, nil, issuer)
}
// ParseResponseForCert parses an OCSP response in DER form and searches for a
// Response relating to cert. If such a Response is found and the OCSP response
// contains a certificate then the signature over the response is checked. If
// issuer is not nil then it will be used to validate the signature or embedded
// certificate.
//
// Invalid signatures or parse failures will result in a ParseError. Error
// responses will result in a ResponseError.
func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Response, error) {
var resp responseASN1
rest, err := asn1.Unmarshal(bytes, &resp)
if err != nil {
@@ -429,7 +476,7 @@ func ParseResponse(bytes []byte, issuer *x509.Certificate) (*Response, error) {
return nil, ParseError("OCSP response contains bad number of certificates")
}
if len(basicResp.TBSResponseData.Responses) != 1 {
if n := len(basicResp.TBSResponseData.Responses); n == 0 || cert == nil && n > 1 {
return nil, ParseError("OCSP response contains bad number of responses")
}
@@ -460,7 +507,13 @@ func ParseResponse(bytes []byte, issuer *x509.Certificate) (*Response, error) {
}
}
r := basicResp.TBSResponseData.Responses[0]
var r singleResponse
for _, resp := range basicResp.TBSResponseData.Responses {
if cert == nil || cert.SerialNumber.Cmp(resp.CertID.SerialNumber) == 0 {
r = resp
break
}
}
for _, ext := range r.SingleExtensions {
if ext.Critical {
@@ -512,8 +565,7 @@ func CreateRequest(cert, issuer *x509.Certificate, opts *RequestOptions) ([]byte
// OCSP seems to be the only place where these raw hash identifiers are
// used. I took the following from
// http://msdn.microsoft.com/en-us/library/ff635603.aspx
var hashOID asn1.ObjectIdentifier
hashOID, ok := hashOIDs[hashFunc]
_, ok := hashOIDs[hashFunc]
if !ok {
return nil, x509.ErrUnsupportedAlgorithm
}
@@ -538,24 +590,13 @@ func CreateRequest(cert, issuer *x509.Certificate, opts *RequestOptions) ([]byte
h.Write(issuer.RawSubject)
issuerNameHash := h.Sum(nil)
return asn1.Marshal(ocspRequest{
tbsRequest{
Version: 0,
RequestList: []request{
{
Cert: certID{
pkix.AlgorithmIdentifier{
Algorithm: hashOID,
Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */},
},
issuerNameHash,
issuerKeyHash,
cert.SerialNumber,
},
},
},
},
})
req := &Request{
HashAlgorithm: hashFunc,
IssuerNameHash: issuerNameHash,
IssuerKeyHash: issuerKeyHash,
SerialNumber: cert.SerialNumber,
}
return req.Marshal()
}
// CreateResponse returns a DER-encoded OCSP response with the specified contents.

194
vendor/golang.org/x/crypto/ocsp/ocsp_test.go сгенерированный поставляемый
Просмотреть файл

@@ -159,6 +159,19 @@ func TestOCSPRequest(t *testing.T) {
if got := decodedRequest.SerialNumber; got.Cmp(cert.SerialNumber) != 0 {
t.Errorf("request.SerialNumber: got %x, want %x", got, cert.SerialNumber)
}
marshaledRequest, err := decodedRequest.Marshal()
if err != nil {
t.Fatal(err)
}
if bytes.Compare(expectedBytes, marshaledRequest) != 0 {
t.Errorf(
"Marshaled request doesn't match expected: wanted %x, got %x",
expectedBytes,
marshaledRequest,
)
}
}
func TestOCSPResponse(t *testing.T) {
@@ -265,6 +278,24 @@ func TestErrorResponse(t *testing.T) {
}
}
func TestOCSPDecodeMultiResponse(t *testing.T) {
inclCert, _ := hex.DecodeString(ocspMultiResponseCertHex)
cert, err := x509.ParseCertificate(inclCert)
if err != nil {
t.Fatal(err)
}
responseBytes, _ := hex.DecodeString(ocspMultiResponseHex)
resp, err := ParseResponseForCert(responseBytes, cert, nil)
if err != nil {
t.Fatal(err)
}
if resp.SerialNumber.Cmp(cert.SerialNumber) != 0 {
t.Errorf("resp.SerialNumber: got %x, want %x", resp.SerialNumber, cert.SerialNumber)
}
}
// This OCSP response was taken from Thawte's public OCSP responder.
// To recreate:
// $ openssl s_client -tls1 -showcerts -servername www.google.com -connect www.google.com:443
@@ -462,6 +493,169 @@ const ocspResponseWithExtensionHex = "308204fb0a0100a08204f4308204f006092b060105
"e17afa19d6e8ae91ddf33179d16ebb6ac2c69cae8373d408ebf8c55308be6c04d93a2543" +
"9a94299a65a709756c7a3e568be049d5c38839"
const ocspMultiResponseHex = "30820ee60a0100a0820edf30820edb06092b060105050730010104820ecc30820ec83082" +
"0839a216041445ac2ecd75f53f1cf6e4c51d3de0047ad0aa7465180f3230313530363032" +
"3130303033305a3082080c3065303d300906052b0e03021a05000414f7452a0080601527" +
"72e4a135e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f0204" +
"5456656a8000180f32303135303630323039303230375aa011180f323031353036303331" +
"30303033305a3065303d300906052b0e03021a05000414f7452a008060152772e4a135e7" +
"6e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f02045456656b80" +
"00180f32303135303630323039303230375aa011180f3230313530363033313030303330" +
"5a3065303d300906052b0e03021a05000414f7452a008060152772e4a135e76e9e52fde0" +
"f1580414edd8f2ee977252853a330b297a18f5c993853b3f02045456656c8000180f3230" +
"3135303630323039303230375aa011180f32303135303630333130303033305a3065303d" +
"300906052b0e03021a05000414f7452a008060152772e4a135e76e9e52fde0f1580414ed" +
"d8f2ee977252853a330b297a18f5c993853b3f02045456656d8000180f32303135303630" +
"323039303230375aa011180f32303135303630333130303033305a3065303d300906052b" +
"0e03021a05000414f7452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee9772" +
"52853a330b297a18f5c993853b3f02045456656e8000180f323031353036303230393032" +
"30375aa011180f32303135303630333130303033305a3065303d300906052b0e03021a05" +
"000414f7452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee977252853a330b" +
"297a18f5c993853b3f02045456656f8000180f32303135303630323039303230375aa011" +
"180f32303135303630333130303033305a3065303d300906052b0e03021a05000414f745" +
"2a008060152772e4a135e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c9" +
"93853b3f0204545665708000180f32303135303630323039303230375aa011180f323031" +
"35303630333130303033305a3065303d300906052b0e03021a05000414f7452a00806015" +
"2772e4a135e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f02" +
"04545665718000180f32303135303630323039303230375aa011180f3230313530363033" +
"3130303033305a3065303d300906052b0e03021a05000414f7452a008060152772e4a135" +
"e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f020454566572" +
"8000180f32303135303630323039303230375aa011180f32303135303630333130303033" +
"305a3065303d300906052b0e03021a05000414f7452a008060152772e4a135e76e9e52fd" +
"e0f1580414edd8f2ee977252853a330b297a18f5c993853b3f0204545665738000180f32" +
"303135303630323039303230375aa011180f32303135303630333130303033305a306530" +
"3d300906052b0e03021a05000414f7452a008060152772e4a135e76e9e52fde0f1580414" +
"edd8f2ee977252853a330b297a18f5c993853b3f0204545665748000180f323031353036" +
"30323039303230375aa011180f32303135303630333130303033305a3065303d30090605" +
"2b0e03021a05000414f7452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee97" +
"7252853a330b297a18f5c993853b3f0204545665758000180f3230313530363032303930" +
"3230375aa011180f32303135303630333130303033305a3065303d300906052b0e03021a" +
"05000414f7452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee977252853a33" +
"0b297a18f5c993853b3f0204545665768000180f32303135303630323039303230375aa0" +
"11180f32303135303630333130303033305a3065303d300906052b0e03021a05000414f7" +
"452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5" +
"c993853b3f0204545665778000180f32303135303630323039303230375aa011180f3230" +
"3135303630333130303033305a3065303d300906052b0e03021a05000414f7452a008060" +
"152772e4a135e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f" +
"0204545665788000180f32303135303630323039303230375aa011180f32303135303630" +
"333130303033305a3065303d300906052b0e03021a05000414f7452a008060152772e4a1" +
"35e76e9e52fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f0204545665" +
"798000180f32303135303630323039303230375aa011180f323031353036303331303030" +
"33305a3065303d300906052b0e03021a05000414f7452a008060152772e4a135e76e9e52" +
"fde0f1580414edd8f2ee977252853a330b297a18f5c993853b3f02045456657a8000180f" +
"32303135303630323039303230375aa011180f32303135303630333130303033305a3065" +
"303d300906052b0e03021a05000414f7452a008060152772e4a135e76e9e52fde0f15804" +
"14edd8f2ee977252853a330b297a18f5c993853b3f02045456657b8000180f3230313530" +
"3630323039303230375aa011180f32303135303630333130303033305a3065303d300906" +
"052b0e03021a05000414f7452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee" +
"977252853a330b297a18f5c993853b3f02045456657c8000180f32303135303630323039" +
"303230375aa011180f32303135303630333130303033305a3065303d300906052b0e0302" +
"1a05000414f7452a008060152772e4a135e76e9e52fde0f1580414edd8f2ee977252853a" +
"330b297a18f5c993853b3f02045456657d8000180f32303135303630323039303230375a" +
"a011180f32303135303630333130303033305a300d06092a864886f70d01010505000382" +
"01010016b73b92859979f27d15eb018cf069eed39c3d280213565f3026de11ba15bdb94d" +
"764cf2d0fdd204ef926c588d7b183483c8a2b1995079c7ed04dcefcc650c1965be4b6832" +
"a8839e832f7f60f638425eccdf9bc3a81fbe700fda426ddf4f06c29bee431bbbe81effda" +
"a60b7da5b378f199af2f3c8380be7ba6c21c8e27124f8a4d8989926aea19055700848d33" +
"799e833512945fd75364edbd2dd18b783c1e96e332266b17979a0b88c35b43f47c87c493" +
"19155056ad8dbbae5ff2afad3c0e1c69ed111206ffda49875e8e4efc0926264823bc4423" +
"c8a002f34288c4bc22516f98f54fc609943721f590ddd8d24f989457526b599b0eb75cb5" +
"a80da1ad93a621a08205733082056f3082056b30820453a0030201020204545638c4300d" +
"06092a864886f70d01010b0500308182310b300906035504061302555331183016060355" +
"040a130f552e532e20476f7665726e6d656e7431233021060355040b131a446570617274" +
"6d656e74206f662074686520547265617375727931223020060355040b13194365727469" +
"6669636174696f6e20417574686f7269746965733110300e060355040b13074f43494f20" +
"4341301e170d3135303332303131353531335a170d3135303633303034303030305a3081" +
"98310b300906035504061302555331183016060355040a130f552e532e20476f7665726e" +
"6d656e7431233021060355040b131a4465706172746d656e74206f662074686520547265" +
"617375727931223020060355040b131943657274696669636174696f6e20417574686f72" +
"69746965733110300e060355040b13074f43494f204341311430120603550403130b4f43" +
"5350205369676e657230820122300d06092a864886f70d01010105000382010f00308201" +
"0a0282010100c1b6fe1ba1ad50bb98c855811acbd67fe68057f48b8e08d3800e7f2c51b7" +
"9e20551934971fd92b9c9e6c49453097927cba83a94c0b2fea7124ba5ac442b38e37dba6" +
"7303d4962dd7d92b22a04b0e0e182e9ea67620b1c6ce09ee607c19e0e6e3adae81151db1" +
"2bb7f706149349a292e21c1eb28565b6839df055e1a838a772ff34b5a1452618e2c26042" +
"705d53f0af4b57aae6163f58216af12f3887813fe44b0321827b3a0c52b0e47d0aab94a2" +
"f768ab0ba3901d22f8bb263823090b0e37a7f8856db4b0d165c42f3aa7e94f5f6ce1855e" +
"98dc57adea0ae98ad39f67ecdec00b88685566e9e8d69f6cefb6ddced53015d0d3b862bc" +
"be21f3d72251eefcec730203010001a38201cf308201cb300e0603551d0f0101ff040403" +
"020780306b0603551d2004643062300c060a60864801650302010502300c060a60864801" +
"650302010503300c060a60864801650302010504300c060a60864801650302010507300c" +
"060a60864801650302010508300c060a6086480165030201030d300c060a608648016503" +
"020103113081e506082b060105050701010481d83081d5303006082b0601050507300286" +
"24687474703a2f2f706b692e74726561732e676f762f746f63615f65655f6169612e7037" +
"633081a006082b060105050730028681936c6461703a2f2f6c6461702e74726561732e67" +
"6f762f6f753d4f43494f25323043412c6f753d43657274696669636174696f6e25323041" +
"7574686f7269746965732c6f753d4465706172746d656e742532306f6625323074686525" +
"323054726561737572792c6f3d552e532e253230476f7665726e6d656e742c633d55533f" +
"634143657274696669636174653b62696e61727930130603551d25040c300a06082b0601" +
"0505070309300f06092b060105050730010504020500301f0603551d23041830168014a2" +
"13a8e5c607546c243d4eb72b27a2a7711ab5af301d0603551d0e0416041451f98046818a" +
"e46d953ac90c210ccfaa1a06980c300d06092a864886f70d01010b050003820101003a37" +
"0b301d14ffdeb370883639bec5ae6f572dcbddadd672af16ee2a8303316b14e1fbdca8c2" +
"8f4bad9c7b1410250e149c14e9830ca6f17370a8d13151205d956e28c141cc0500379596" +
"c5b9239fcfa3d2de8f1d4f1a2b1bf2d1851bed1c86012ee8135bdc395cd4496ce69fadd0" +
"3b682b90350ca7b4f458190b7a0ab5c33a04cf1347a77d541877a380a4c94988c5658908" +
"44fdc22637a72b9fa410333e2caf969477f9fe07f50e3681c204fb3bf073b9da01cd8d91" +
"8044c40b1159955af12a3263ab1d34119d7f59bfa6cae88ed058addc4e08250263f8f836" +
"2f5bdffd45636fea7474c60a55c535954477b2f286e1b2535f0dd12c162f1b353c370e08" +
"be67"
const ocspMultiResponseCertHex = "308207943082067ca003020102020454566573300d06092a864886f70d01010b05003081" +
"82310b300906035504061302555331183016060355040a130f552e532e20476f7665726e" +
"6d656e7431233021060355040b131a4465706172746d656e74206f662074686520547265" +
"617375727931223020060355040b131943657274696669636174696f6e20417574686f72" +
"69746965733110300e060355040b13074f43494f204341301e170d313530343130313535" +
"3733385a170d3138303431303136323733385a30819d310b300906035504061302555331" +
"183016060355040a130f552e532e20476f7665726e6d656e7431233021060355040b131a" +
"4465706172746d656e74206f662074686520547265617375727931253023060355040b13" +
"1c427572656175206f66207468652046697363616c20536572766963653110300e060355" +
"040b130744657669636573311630140603550403130d706b692e74726561732e676f7630" +
"820122300d06092a864886f70d01010105000382010f003082010a0282010100c7273623" +
"8c49c48bf501515a2490ef6e5ae0c06e0ad2aa9a6bb77f3d0370d846b2571581ebf38fd3" +
"1948daad3dec7a4da095f1dcbe9654e65bcf7acdfd4ee802421dad9b90536c721d2bca58" +
"8413e6bfd739a72470560bb7d64f9a09284f90ff8af1d5a3c5c84d0f95a00f9c6d988dd0" +
"d87f1d0d3344580901c955139f54d09de0acdbd3322b758cb0c58881bf04913243401f44" +
"013fd9f6d8348044cc8bb0a71978ad93366b2a4687a5274b2ee07d0fb40225453eb244ed" +
"b20152251ac77c59455260ff07eeceb3cb3c60fb8121cf92afd3daa2a4650e1942ccb555" +
"de10b3d481feb299838ef05d0fd1810b146753472ae80da65dd34da25ca1f89971f10039" +
"0203010001a38203f3308203ef300e0603551d0f0101ff0404030205a030170603551d20" +
"0410300e300c060a60864801650302010503301106096086480186f84201010404030206" +
"4030130603551d25040c300a06082b060105050703013082010806082b06010505070101" +
"0481fb3081f8303006082b060105050730028624687474703a2f2f706b692e7472656173" +
"2e676f762f746f63615f65655f6169612e7037633081a006082b06010505073002868193" +
"6c6461703a2f2f6c6461702e74726561732e676f762f6f753d4f43494f25323043412c6f" +
"753d43657274696669636174696f6e253230417574686f7269746965732c6f753d446570" +
"6172746d656e742532306f6625323074686525323054726561737572792c6f3d552e532e" +
"253230476f7665726e6d656e742c633d55533f634143657274696669636174653b62696e" +
"617279302106082b060105050730018615687474703a2f2f6f6373702e74726561732e67" +
"6f76307b0603551d1104743072811c6373612d7465616d4066697363616c2e7472656173" +
"7572792e676f768210706b692e74726561737572792e676f768210706b692e64696d632e" +
"6468732e676f76820d706b692e74726561732e676f76811f6563622d686f7374696e6740" +
"66697363616c2e74726561737572792e676f76308201890603551d1f048201803082017c" +
"3027a025a0238621687474703a2f2f706b692e74726561732e676f762f4f43494f5f4341" +
"332e63726c3082014fa082014ba0820147a48197308194310b3009060355040613025553" +
"31183016060355040a130f552e532e20476f7665726e6d656e7431233021060355040b13" +
"1a4465706172746d656e74206f662074686520547265617375727931223020060355040b" +
"131943657274696669636174696f6e20417574686f7269746965733110300e060355040b" +
"13074f43494f2043413110300e0603550403130743524c313430398681aa6c6461703a2f" +
"2f6c6461702e74726561732e676f762f636e3d43524c313430392c6f753d4f43494f2532" +
"3043412c6f753d43657274696669636174696f6e253230417574686f7269746965732c6f" +
"753d4465706172746d656e742532306f6625323074686525323054726561737572792c6f" +
"3d552e532e253230476f7665726e6d656e742c633d55533f636572746966696361746552" +
"65766f636174696f6e4c6973743b62696e617279302b0603551d1004243022800f323031" +
"35303431303135353733385a810f32303138303431303136323733385a301f0603551d23" +
"041830168014a213a8e5c607546c243d4eb72b27a2a7711ab5af301d0603551d0e041604" +
"14b0869c12c293914cd460e33ed43e6c5a26e0d68f301906092a864886f67d074100040c" +
"300a1b0456382e31030203a8300d06092a864886f70d01010b050003820101004968d182" +
"8f9efdc147e747bb5dda15536a42a079b32d3d7f87e619b483aeee70b7e26bda393c6028" +
"7c733ecb468fe8b8b11bf809ff76add6b90eb25ad8d3a1052e43ee281e48a3a1ebe7efb5" +
"9e2c4a48765dedeb23f5346242145786cc988c762d230d28dd33bf4c2405d80cbb2cb1d6" +
"4c8f10ba130d50cb174f6ffb9cfc12808297a2cefba385f4fad170f39b51ebd87c12abf9" +
"3c51fc000af90d8aaba78f48923908804a5eb35f617ccf71d201e3708a559e6d16f9f13e" +
"074361eb9007e28d86bb4e0bfa13aad0e9ddd9124e84519de60e2fc6040b18d9fd602b02" +
"684b4c071c3019fc842197d00c120c41654bcbfbc4a096a1c637b79112b81ce1fa3899f9"
const ocspRequestHex = "3051304f304d304b3049300906052b0e03021a05000414c0fe0278fc99188891b3f212e9" +
"c7e1b21ab7bfc004140dfc1df0a9e0f01ce7f2b213177e6f8d157cd4f60210017f77deb3" +
"bcbb235d44ccc7dba62e72"

20
vendor/golang.org/x/crypto/openpgp/packet/private_key.go сгенерированный поставляемый
Просмотреть файл

@@ -6,6 +6,7 @@ package packet
import (
"bytes"
"crypto"
"crypto/cipher"
"crypto/dsa"
"crypto/ecdsa"
@@ -30,7 +31,7 @@ type PrivateKey struct {
encryptedData []byte
cipher CipherFunction
s2k func(out, in []byte)
PrivateKey interface{} // An *rsa.PrivateKey or *dsa.PrivateKey.
PrivateKey interface{} // An *{rsa|dsa|ecdsa}.PrivateKey or a crypto.Signer.
sha1Checksum bool
iv []byte
}
@@ -63,6 +64,23 @@ func NewECDSAPrivateKey(currentTime time.Time, priv *ecdsa.PrivateKey) *PrivateK
return pk
}
// NewSignerPrivateKey creates a sign-only PrivateKey from a crypto.Signer that
// implements RSA or ECDSA.
func NewSignerPrivateKey(currentTime time.Time, signer crypto.Signer) *PrivateKey {
pk := new(PrivateKey)
switch pubkey := signer.Public().(type) {
case rsa.PublicKey:
pk.PublicKey = *NewRSAPublicKey(currentTime, &pubkey)
pk.PubKeyAlgo = PubKeyAlgoRSASignOnly
case ecdsa.PublicKey:
pk.PublicKey = *NewECDSAPublicKey(currentTime, &pubkey)
default:
panic("openpgp: unknown crypto.Signer type in NewSignerPrivateKey")
}
pk.PrivateKey = signer
return pk
}
func (pk *PrivateKey) parse(r io.Reader) (err error) {
err = (&pk.PublicKey).parse(r)
if err != nil {

144
vendor/golang.org/x/crypto/openpgp/packet/private_key_test.go сгенерированный поставляемый
Просмотреть файл

@@ -10,7 +10,11 @@ import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/hex"
"hash"
"io"
"testing"
"time"
)
@@ -70,6 +74,50 @@ func populateHash(hashFunc crypto.Hash, msg []byte) (hash.Hash, error) {
return h, nil
}
func TestRSAPrivateKey(t *testing.T) {
privKeyDER, _ := hex.DecodeString(pkcs1PrivKeyHex)
rsaPriv, err := x509.ParsePKCS1PrivateKey(privKeyDER)
if err != nil {
t.Fatal(err)
}
var buf bytes.Buffer
if err := NewRSAPrivateKey(time.Now(), rsaPriv).Serialize(&buf); err != nil {
t.Fatal(err)
}
p, err := Read(&buf)
if err != nil {
t.Fatal(err)
}
priv, ok := p.(*PrivateKey)
if !ok {
t.Fatal("didn't parse private key")
}
sig := &Signature{
PubKeyAlgo: PubKeyAlgoRSA,
Hash: crypto.SHA256,
}
msg := []byte("Hello World!")
h, err := populateHash(sig.Hash, msg)
if err != nil {
t.Fatal(err)
}
if err := sig.Sign(h, priv, nil); err != nil {
t.Fatal(err)
}
if h, err = populateHash(sig.Hash, msg); err != nil {
t.Fatal(err)
}
if err := priv.VerifySignature(h, sig); err != nil {
t.Fatal(err)
}
}
func TestECDSAPrivateKey(t *testing.T) {
ecdsaPriv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
@@ -113,6 +161,98 @@ func TestECDSAPrivateKey(t *testing.T) {
}
}
type rsaSigner struct {
priv *rsa.PrivateKey
}
func (s *rsaSigner) Public() crypto.PublicKey {
return s.priv.PublicKey
}
func (s *rsaSigner) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) ([]byte, error) {
return s.priv.Sign(rand, msg, opts)
}
func TestRSASignerPrivateKey(t *testing.T) {
rsaPriv, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
t.Fatal(err)
}
priv := NewSignerPrivateKey(time.Now(), &rsaSigner{rsaPriv})
if priv.PubKeyAlgo != PubKeyAlgoRSASignOnly {
t.Fatal("NewSignerPrivateKey should have made a sign-only RSA private key")
}
sig := &Signature{
PubKeyAlgo: PubKeyAlgoRSASignOnly,
Hash: crypto.SHA256,
}
msg := []byte("Hello World!")
h, err := populateHash(sig.Hash, msg)
if err != nil {
t.Fatal(err)
}
if err := sig.Sign(h, priv, nil); err != nil {
t.Fatal(err)
}
if h, err = populateHash(sig.Hash, msg); err != nil {
t.Fatal(err)
}
if err := priv.VerifySignature(h, sig); err != nil {
t.Fatal(err)
}
}
type ecdsaSigner struct {
priv *ecdsa.PrivateKey
}
func (s *ecdsaSigner) Public() crypto.PublicKey {
return s.priv.PublicKey
}
func (s *ecdsaSigner) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) ([]byte, error) {
return s.priv.Sign(rand, msg, opts)
}
func TestECDSASignerPrivateKey(t *testing.T) {
ecdsaPriv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
t.Fatal(err)
}
priv := NewSignerPrivateKey(time.Now(), &ecdsaSigner{ecdsaPriv})
if priv.PubKeyAlgo != PubKeyAlgoECDSA {
t.Fatal("NewSignerPrivateKey should have made a ECSDA private key")
}
sig := &Signature{
PubKeyAlgo: PubKeyAlgoECDSA,
Hash: crypto.SHA256,
}
msg := []byte("Hello World!")
h, err := populateHash(sig.Hash, msg)
if err != nil {
t.Fatal(err)
}
if err := sig.Sign(h, priv, nil); err != nil {
t.Fatal(err)
}
if h, err = populateHash(sig.Hash, msg); err != nil {
t.Fatal(err)
}
if err := priv.VerifySignature(h, sig); err != nil {
t.Fatal(err)
}
}
func TestIssue11505(t *testing.T) {
// parsing a rsa private key with p or q == 1 used to panic due to a divide by zero
_, _ = Read(readerFromHex("9c3004303030300100000011303030000000000000010130303030303030303030303030303030303030303030303030303030303030303030303030303030303030"))
@@ -124,3 +264,7 @@ const privKeyRSAHex = "9501fe044cc349a8010400b70ca0010e98c090008d45d1ee8f9113bd5
// Generated by `gpg --export-secret-keys` followed by a manual extraction of
// the ElGamal subkey from the packets.
const privKeyElGamalHex = "9d0157044df9ee1a100400eb8e136a58ec39b582629cdadf830bc64e0a94ed8103ca8bb247b27b11b46d1d25297ef4bcc3071785ba0c0bedfe89eabc5287fcc0edf81ab5896c1c8e4b20d27d79813c7aede75320b33eaeeaa586edc00fd1036c10133e6ba0ff277245d0d59d04b2b3421b7244aca5f4a8d870c6f1c1fbff9e1c26699a860b9504f35ca1d700030503fd1ededd3b840795be6d9ccbe3c51ee42e2f39233c432b831ddd9c4e72b7025a819317e47bf94f9ee316d7273b05d5fcf2999c3a681f519b1234bbfa6d359b4752bd9c3f77d6b6456cde152464763414ca130f4e91d91041432f90620fec0e6d6b5116076c2985d5aeaae13be492b9b329efcaf7ee25120159a0a30cd976b42d7afe030302dae7eb80db744d4960c4df930d57e87fe81412eaace9f900e6c839817a614ddb75ba6603b9417c33ea7b6c93967dfa2bcff3fa3c74a5ce2c962db65b03aece14c96cbd0038fc"
// pkcs1PrivKeyHex is a PKCS#1, RSA private key.
// Generated by `openssl genrsa 1024 | openssl rsa -outform DER | xxd -p`
const pkcs1PrivKeyHex = "3082025d02010002818100e98edfa1c3b35884a54d0b36a6a603b0290fa85e49e30fa23fc94fef9c6790bc4849928607aa48d809da326fb42a969d06ad756b98b9c1a90f5d4a2b6d0ac05953c97f4da3120164a21a679793ce181c906dc01d235cc085ddcdf6ea06c389b6ab8885dfd685959e693138856a68a7e5db263337ff82a088d583a897cf2d59e9020301000102818100b6d5c9eb70b02d5369b3ee5b520a14490b5bde8a317d36f7e4c74b7460141311d1e5067735f8f01d6f5908b2b96fbd881f7a1ab9a84d82753e39e19e2d36856be960d05ac9ef8e8782ea1b6d65aee28fdfe1d61451e8cff0adfe84322f12cf455028b581cf60eb9e0e140ba5d21aeba6c2634d7c65318b9a665fc01c3191ca21024100fa5e818da3705b0fa33278bb28d4b6f6050388af2d4b75ec9375dd91ccf2e7d7068086a8b82a8f6282e4fbbdb8a7f2622eb97295249d87acea7f5f816f54d347024100eecf9406d7dc49cdfb95ab1eff4064de84c7a30f64b2798936a0d2018ba9eb52e4b636f82e96c49cc63b80b675e91e40d1b2e4017d4b9adaf33ab3d9cf1c214f024100c173704ace742c082323066226a4655226819a85304c542b9dacbeacbf5d1881ee863485fcf6f59f3a604f9b42289282067447f2b13dfeed3eab7851fc81e0550240741fc41f3fc002b382eed8730e33c5d8de40256e4accee846667f536832f711ab1d4590e7db91a8a116ac5bff3be13d3f9243ff2e976662aa9b395d907f8e9c9024046a5696c9ef882363e06c9fa4e2f5b580906452befba03f4a99d0f873697ef1f851d2226ca7934b30b7c3e80cb634a67172bbbf4781735fe3e09263e2dd723e7"

31
vendor/golang.org/x/crypto/openpgp/packet/signature.go сгенерированный поставляемый
Просмотреть файл

@@ -9,10 +9,11 @@ import (
"crypto"
"crypto/dsa"
"crypto/ecdsa"
"crypto/rsa"
"encoding/asn1"
"encoding/binary"
"hash"
"io"
"math/big"
"strconv"
"time"
@@ -516,7 +517,8 @@ func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err e
switch priv.PubKeyAlgo {
case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
sig.RSASignature.bytes, err = rsa.SignPKCS1v15(config.Random(), priv.PrivateKey.(*rsa.PrivateKey), sig.Hash, digest)
// supports both *rsa.PrivateKey and crypto.Signer
sig.RSASignature.bytes, err = priv.PrivateKey.(crypto.Signer).Sign(config.Random(), digest, sig.Hash)
sig.RSASignature.bitLength = uint16(8 * len(sig.RSASignature.bytes))
case PubKeyAlgoDSA:
dsaPriv := priv.PrivateKey.(*dsa.PrivateKey)
@@ -534,7 +536,17 @@ func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err e
sig.DSASigS.bitLength = uint16(8 * len(sig.DSASigS.bytes))
}
case PubKeyAlgoECDSA:
r, s, err := ecdsa.Sign(config.Random(), priv.PrivateKey.(*ecdsa.PrivateKey), digest)
var r, s *big.Int
if pk, ok := priv.PrivateKey.(*ecdsa.PrivateKey); ok {
// direct support, avoid asn1 wrapping/unwrapping
r, s, err = ecdsa.Sign(config.Random(), pk, digest)
} else {
var b []byte
b, err = priv.PrivateKey.(crypto.Signer).Sign(config.Random(), digest, nil)
if err == nil {
r, s, err = unwrapECDSASig(b)
}
}
if err == nil {
sig.ECDSASigR = fromBig(r)
sig.ECDSASigS = fromBig(s)
@@ -546,6 +558,19 @@ func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err e
return
}
// unwrapECDSASig parses the two integer components of an ASN.1-encoded ECDSA
// signature.
func unwrapECDSASig(b []byte) (r, s *big.Int, err error) {
var ecsdaSig struct {
R, S *big.Int
}
_, err = asn1.Unmarshal(b, &ecsdaSig)
if err != nil {
return
}
return ecsdaSig.R, ecsdaSig.S, nil
}
// SignUserId computes a signature from priv, asserting that pub is a valid
// key for the identity id. On success, the signature is stored in sig. Call
// Serialize to write it out.

2
vendor/golang.org/x/crypto/openpgp/read.go сгенерированный поставляемый
Просмотреть файл

@@ -50,7 +50,7 @@ type MessageDetails struct {
// If IsSigned is true and SignedBy is non-zero then the signature will
// be verified as UnverifiedBody is read. The signature cannot be
// checked until the whole of UnverifiedBody is read so UnverifiedBody
// must be consumed until EOF before the data can trusted. Even if a
// must be consumed until EOF before the data can be trusted. Even if a
// message isn't signed (or the signer is unknown) the data may contain
// an authentication code that is only checked once UnverifiedBody has
// been consumed. Once EOF has been seen, the following fields are

45
vendor/golang.org/x/crypto/poly1305/const_amd64.s сгенерированный поставляемый
Просмотреть файл

@@ -1,45 +0,0 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This code was translated into a form compatible with 6a from the public
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
// +build amd64,!gccgo,!appengine
DATA ·SCALE(SB)/8, $0x37F4000000000000
GLOBL ·SCALE(SB), 8, $8
DATA ·TWO32(SB)/8, $0x41F0000000000000
GLOBL ·TWO32(SB), 8, $8
DATA ·TWO64(SB)/8, $0x43F0000000000000
GLOBL ·TWO64(SB), 8, $8
DATA ·TWO96(SB)/8, $0x45F0000000000000
GLOBL ·TWO96(SB), 8, $8
DATA ·ALPHA32(SB)/8, $0x45E8000000000000
GLOBL ·ALPHA32(SB), 8, $8
DATA ·ALPHA64(SB)/8, $0x47E8000000000000
GLOBL ·ALPHA64(SB), 8, $8
DATA ·ALPHA96(SB)/8, $0x49E8000000000000
GLOBL ·ALPHA96(SB), 8, $8
DATA ·ALPHA130(SB)/8, $0x4C08000000000000
GLOBL ·ALPHA130(SB), 8, $8
DATA ·DOFFSET0(SB)/8, $0x4330000000000000
GLOBL ·DOFFSET0(SB), 8, $8
DATA ·DOFFSET1(SB)/8, $0x4530000000000000
GLOBL ·DOFFSET1(SB), 8, $8
DATA ·DOFFSET2(SB)/8, $0x4730000000000000
GLOBL ·DOFFSET2(SB), 8, $8
DATA ·DOFFSET3(SB)/8, $0x4930000000000000
GLOBL ·DOFFSET3(SB), 8, $8
DATA ·DOFFSET3MINUSTWO128(SB)/8, $0x492FFFFE00000000
GLOBL ·DOFFSET3MINUSTWO128(SB), 8, $8
DATA ·HOFFSET0(SB)/8, $0x43300001FFFFFFFB
GLOBL ·HOFFSET0(SB), 8, $8
DATA ·HOFFSET1(SB)/8, $0x45300001FFFFFFFE
GLOBL ·HOFFSET1(SB), 8, $8
DATA ·HOFFSET2(SB)/8, $0x47300001FFFFFFFE
GLOBL ·HOFFSET2(SB), 8, $8
DATA ·HOFFSET3(SB)/8, $0x49300003FFFFFFFE
GLOBL ·HOFFSET3(SB), 8, $8
DATA ·ROUNDING(SB)/2, $0x137f
GLOBL ·ROUNDING(SB), 8, $2

497
vendor/golang.org/x/crypto/poly1305/poly1305_amd64.s сгенерированный поставляемый
Просмотреть файл

@@ -1,497 +0,0 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This code was translated into a form compatible with 6a from the public
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
// +build amd64,!gccgo,!appengine
// func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]key)
TEXT ·poly1305(SB),0,$224-32
MOVQ out+0(FP),DI
MOVQ m+8(FP),SI
MOVQ mlen+16(FP),DX
MOVQ key+24(FP),CX
MOVQ SP,R11
MOVQ $31,R9
NOTQ R9
ANDQ R9,SP
ADDQ $32,SP
MOVQ R11,32(SP)
MOVQ R12,40(SP)
MOVQ R13,48(SP)
MOVQ R14,56(SP)
MOVQ R15,64(SP)
MOVQ BX,72(SP)
MOVQ BP,80(SP)
FLDCW ·ROUNDING(SB)
MOVL 0(CX),R8
MOVL 4(CX),R9
MOVL 8(CX),AX
MOVL 12(CX),R10
MOVQ DI,88(SP)
MOVQ CX,96(SP)
MOVL $0X43300000,108(SP)
MOVL $0X45300000,116(SP)
MOVL $0X47300000,124(SP)
MOVL $0X49300000,132(SP)
ANDL $0X0FFFFFFF,R8
ANDL $0X0FFFFFFC,R9
ANDL $0X0FFFFFFC,AX
ANDL $0X0FFFFFFC,R10
MOVL R8,104(SP)
MOVL R9,112(SP)
MOVL AX,120(SP)
MOVL R10,128(SP)
FMOVD 104(SP), F0
FSUBD ·DOFFSET0(SB), F0
FMOVD 112(SP), F0
FSUBD ·DOFFSET1(SB), F0
FMOVD 120(SP), F0
FSUBD ·DOFFSET2(SB), F0
FMOVD 128(SP), F0
FSUBD ·DOFFSET3(SB), F0
FXCHD F0, F3
FMOVDP F0, 136(SP)
FXCHD F0, F1
FMOVD F0, 144(SP)
FMULD ·SCALE(SB), F0
FMOVDP F0, 152(SP)
FMOVD F0, 160(SP)
FMULD ·SCALE(SB), F0
FMOVDP F0, 168(SP)
FMOVD F0, 176(SP)
FMULD ·SCALE(SB), F0
FMOVDP F0, 184(SP)
FLDZ
FLDZ
FLDZ
FLDZ
CMPQ DX,$16
JB ADDATMOST15BYTES
INITIALATLEAST16BYTES:
MOVL 12(SI),DI
MOVL 8(SI),CX
MOVL 4(SI),R8
MOVL 0(SI),R9
MOVL DI,128(SP)
MOVL CX,120(SP)
MOVL R8,112(SP)
MOVL R9,104(SP)
ADDQ $16,SI
SUBQ $16,DX
FXCHD F0, F3
FADDD 128(SP), F0
FSUBD ·DOFFSET3MINUSTWO128(SB), F0
FXCHD F0, F1
FADDD 112(SP), F0
FSUBD ·DOFFSET1(SB), F0
FXCHD F0, F2
FADDD 120(SP), F0
FSUBD ·DOFFSET2(SB), F0
FXCHD F0, F3
FADDD 104(SP), F0
FSUBD ·DOFFSET0(SB), F0
CMPQ DX,$16
JB MULTIPLYADDATMOST15BYTES
MULTIPLYADDATLEAST16BYTES:
MOVL 12(SI),DI
MOVL 8(SI),CX
MOVL 4(SI),R8
MOVL 0(SI),R9
MOVL DI,128(SP)
MOVL CX,120(SP)
MOVL R8,112(SP)
MOVL R9,104(SP)
ADDQ $16,SI
SUBQ $16,DX
FMOVD ·ALPHA130(SB), F0
FADDD F2,F0
FSUBD ·ALPHA130(SB), F0
FSUBD F0,F2
FMULD ·SCALE(SB), F0
FMOVD ·ALPHA32(SB), F0
FADDD F2,F0
FSUBD ·ALPHA32(SB), F0
FSUBD F0,F2
FXCHD F0, F2
FADDDP F0,F1
FMOVD ·ALPHA64(SB), F0
FADDD F4,F0
FSUBD ·ALPHA64(SB), F0
FSUBD F0,F4
FMOVD ·ALPHA96(SB), F0
FADDD F6,F0
FSUBD ·ALPHA96(SB), F0
FSUBD F0,F6
FXCHD F0, F6
FADDDP F0,F1
FXCHD F0, F3
FADDDP F0,F5
FXCHD F0, F3
FADDDP F0,F1
FMOVD 176(SP), F0
FMULD F3,F0
FMOVD 160(SP), F0
FMULD F4,F0
FMOVD 144(SP), F0
FMULD F5,F0
FMOVD 136(SP), F0
FMULDP F0,F6
FMOVD 160(SP), F0
FMULD F4,F0
FADDDP F0,F3
FMOVD 144(SP), F0
FMULD F4,F0
FADDDP F0,F2
FMOVD 136(SP), F0
FMULD F4,F0
FADDDP F0,F1
FMOVD 184(SP), F0
FMULDP F0,F4
FXCHD F0, F3
FADDDP F0,F5
FMOVD 144(SP), F0
FMULD F4,F0
FADDDP F0,F2
FMOVD 136(SP), F0
FMULD F4,F0
FADDDP F0,F1
FMOVD 184(SP), F0
FMULD F4,F0
FADDDP F0,F3
FMOVD 168(SP), F0
FMULDP F0,F4
FXCHD F0, F3
FADDDP F0,F4
FMOVD 136(SP), F0
FMULD F5,F0
FADDDP F0,F1
FXCHD F0, F3
FMOVD 184(SP), F0
FMULD F5,F0
FADDDP F0,F3
FXCHD F0, F1
FMOVD 168(SP), F0
FMULD F5,F0
FADDDP F0,F1
FMOVD 152(SP), F0
FMULDP F0,F5
FXCHD F0, F4
FADDDP F0,F1
CMPQ DX,$16
FXCHD F0, F2
FMOVD 128(SP), F0
FSUBD ·DOFFSET3MINUSTWO128(SB), F0
FADDDP F0,F1
FXCHD F0, F1
FMOVD 120(SP), F0
FSUBD ·DOFFSET2(SB), F0
FADDDP F0,F1
FXCHD F0, F3
FMOVD 112(SP), F0
FSUBD ·DOFFSET1(SB), F0
FADDDP F0,F1
FXCHD F0, F2
FMOVD 104(SP), F0
FSUBD ·DOFFSET0(SB), F0
FADDDP F0,F1
JAE MULTIPLYADDATLEAST16BYTES
MULTIPLYADDATMOST15BYTES:
FMOVD ·ALPHA130(SB), F0
FADDD F2,F0
FSUBD ·ALPHA130(SB), F0
FSUBD F0,F2
FMULD ·SCALE(SB), F0
FMOVD ·ALPHA32(SB), F0
FADDD F2,F0
FSUBD ·ALPHA32(SB), F0
FSUBD F0,F2
FMOVD ·ALPHA64(SB), F0
FADDD F5,F0
FSUBD ·ALPHA64(SB), F0
FSUBD F0,F5
FMOVD ·ALPHA96(SB), F0
FADDD F7,F0
FSUBD ·ALPHA96(SB), F0
FSUBD F0,F7
FXCHD F0, F7
FADDDP F0,F1
FXCHD F0, F5
FADDDP F0,F1
FXCHD F0, F3
FADDDP F0,F5
FADDDP F0,F1
FMOVD 176(SP), F0
FMULD F1,F0
FMOVD 160(SP), F0
FMULD F2,F0
FMOVD 144(SP), F0
FMULD F3,F0
FMOVD 136(SP), F0
FMULDP F0,F4
FMOVD 160(SP), F0
FMULD F5,F0
FADDDP F0,F3
FMOVD 144(SP), F0
FMULD F5,F0
FADDDP F0,F2
FMOVD 136(SP), F0
FMULD F5,F0
FADDDP F0,F1
FMOVD 184(SP), F0
FMULDP F0,F5
FXCHD F0, F4
FADDDP F0,F3
FMOVD 144(SP), F0
FMULD F5,F0
FADDDP F0,F2
FMOVD 136(SP), F0
FMULD F5,F0
FADDDP F0,F1
FMOVD 184(SP), F0
FMULD F5,F0
FADDDP F0,F4
FMOVD 168(SP), F0
FMULDP F0,F5
FXCHD F0, F4
FADDDP F0,F2
FMOVD 136(SP), F0
FMULD F5,F0
FADDDP F0,F1
FMOVD 184(SP), F0
FMULD F5,F0
FADDDP F0,F4
FMOVD 168(SP), F0
FMULD F5,F0
FADDDP F0,F3
FMOVD 152(SP), F0
FMULDP F0,F5
FXCHD F0, F4
FADDDP F0,F1
ADDATMOST15BYTES:
CMPQ DX,$0
JE NOMOREBYTES
MOVL $0,0(SP)
MOVL $0, 4 (SP)
MOVL $0, 8 (SP)
MOVL $0, 12 (SP)
LEAQ 0(SP),DI
MOVQ DX,CX
REP; MOVSB
MOVB $1,0(DI)
MOVL 12 (SP),DI
MOVL 8 (SP),SI
MOVL 4 (SP),DX
MOVL 0(SP),CX
MOVL DI,128(SP)
MOVL SI,120(SP)
MOVL DX,112(SP)
MOVL CX,104(SP)
FXCHD F0, F3
FADDD 128(SP), F0
FSUBD ·DOFFSET3(SB), F0
FXCHD F0, F2
FADDD 120(SP), F0
FSUBD ·DOFFSET2(SB), F0
FXCHD F0, F1
FADDD 112(SP), F0
FSUBD ·DOFFSET1(SB), F0
FXCHD F0, F3
FADDD 104(SP), F0
FSUBD ·DOFFSET0(SB), F0
FMOVD ·ALPHA130(SB), F0
FADDD F3,F0
FSUBD ·ALPHA130(SB), F0
FSUBD F0,F3
FMULD ·SCALE(SB), F0
FMOVD ·ALPHA32(SB), F0
FADDD F2,F0
FSUBD ·ALPHA32(SB), F0
FSUBD F0,F2
FMOVD ·ALPHA64(SB), F0
FADDD F6,F0
FSUBD ·ALPHA64(SB), F0
FSUBD F0,F6
FMOVD ·ALPHA96(SB), F0
FADDD F5,F0
FSUBD ·ALPHA96(SB), F0
FSUBD F0,F5
FXCHD F0, F4
FADDDP F0,F3
FXCHD F0, F6
FADDDP F0,F1
FXCHD F0, F3
FADDDP F0,F5
FXCHD F0, F3
FADDDP F0,F1
FMOVD 176(SP), F0
FMULD F3,F0
FMOVD 160(SP), F0
FMULD F4,F0
FMOVD 144(SP), F0
FMULD F5,F0
FMOVD 136(SP), F0
FMULDP F0,F6
FMOVD 160(SP), F0
FMULD F5,F0
FADDDP F0,F3
FMOVD 144(SP), F0
FMULD F5,F0
FADDDP F0,F2
FMOVD 136(SP), F0
FMULD F5,F0
FADDDP F0,F1
FMOVD 184(SP), F0
FMULDP F0,F5
FXCHD F0, F4
FADDDP F0,F5
FMOVD 144(SP), F0
FMULD F6,F0
FADDDP F0,F2
FMOVD 136(SP), F0
FMULD F6,F0
FADDDP F0,F1
FMOVD 184(SP), F0
FMULD F6,F0
FADDDP F0,F4
FMOVD 168(SP), F0
FMULDP F0,F6
FXCHD F0, F5
FADDDP F0,F4
FMOVD 136(SP), F0
FMULD F2,F0
FADDDP F0,F1
FMOVD 184(SP), F0
FMULD F2,F0
FADDDP F0,F5
FMOVD 168(SP), F0
FMULD F2,F0
FADDDP F0,F3
FMOVD 152(SP), F0
FMULDP F0,F2
FXCHD F0, F1
FADDDP F0,F3
FXCHD F0, F3
FXCHD F0, F2
NOMOREBYTES:
MOVL $0,R10
FMOVD ·ALPHA130(SB), F0
FADDD F4,F0
FSUBD ·ALPHA130(SB), F0
FSUBD F0,F4
FMULD ·SCALE(SB), F0
FMOVD ·ALPHA32(SB), F0
FADDD F2,F0
FSUBD ·ALPHA32(SB), F0
FSUBD F0,F2
FMOVD ·ALPHA64(SB), F0
FADDD F4,F0
FSUBD ·ALPHA64(SB), F0
FSUBD F0,F4
FMOVD ·ALPHA96(SB), F0
FADDD F6,F0
FSUBD ·ALPHA96(SB), F0
FXCHD F0, F6
FSUBD F6,F0
FXCHD F0, F4
FADDDP F0,F3
FXCHD F0, F4
FADDDP F0,F1
FXCHD F0, F2
FADDDP F0,F3
FXCHD F0, F4
FADDDP F0,F3
FXCHD F0, F3
FADDD ·HOFFSET0(SB), F0
FXCHD F0, F3
FADDD ·HOFFSET1(SB), F0
FXCHD F0, F1
FADDD ·HOFFSET2(SB), F0
FXCHD F0, F2
FADDD ·HOFFSET3(SB), F0
FXCHD F0, F3
FMOVDP F0, 104(SP)
FMOVDP F0, 112(SP)
FMOVDP F0, 120(SP)
FMOVDP F0, 128(SP)
MOVL 108(SP),DI
ANDL $63,DI
MOVL 116(SP),SI
ANDL $63,SI
MOVL 124(SP),DX
ANDL $63,DX
MOVL 132(SP),CX
ANDL $63,CX
MOVL 112(SP),R8
ADDL DI,R8
MOVQ R8,112(SP)
MOVL 120(SP),DI
ADCL SI,DI
MOVQ DI,120(SP)
MOVL 128(SP),DI
ADCL DX,DI
MOVQ DI,128(SP)
MOVL R10,DI
ADCL CX,DI
MOVQ DI,136(SP)
MOVQ $5,DI
MOVL 104(SP),SI
ADDL SI,DI
MOVQ DI,104(SP)
MOVL R10,DI
MOVQ 112(SP),DX
ADCL DX,DI
MOVQ DI,112(SP)
MOVL R10,DI
MOVQ 120(SP),CX
ADCL CX,DI
MOVQ DI,120(SP)
MOVL R10,DI
MOVQ 128(SP),R8
ADCL R8,DI
MOVQ DI,128(SP)
MOVQ $0XFFFFFFFC,DI
MOVQ 136(SP),R9
ADCL R9,DI
SARL $16,DI
MOVQ DI,R9
XORL $0XFFFFFFFF,R9
ANDQ DI,SI
MOVQ 104(SP),AX
ANDQ R9,AX
ORQ AX,SI
ANDQ DI,DX
MOVQ 112(SP),AX
ANDQ R9,AX
ORQ AX,DX
ANDQ DI,CX
MOVQ 120(SP),AX
ANDQ R9,AX
ORQ AX,CX
ANDQ DI,R8
MOVQ 128(SP),DI
ANDQ R9,DI
ORQ DI,R8
MOVQ 88(SP),DI
MOVQ 96(SP),R9
ADDL 16(R9),SI
ADCL 20(R9),DX
ADCL 24(R9),CX
ADCL 28(R9),R8
MOVL SI,0(DI)
MOVL DX,4(DI)
MOVL CX,8(DI)
MOVL R8,12(DI)
MOVQ 32(SP),R11
MOVQ 40(SP),R12
MOVQ 48(SP),R13
MOVQ 56(SP),R14
MOVQ 64(SP),R15
MOVQ 72(SP),BX
MOVQ 80(SP),BP
MOVQ R11,SP
RET

379
vendor/golang.org/x/crypto/poly1305/poly1305_arm.s сгенерированный поставляемый
Просмотреть файл

@@ -1,379 +0,0 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This code was translated into a form compatible with 5a from the public
// domain source by Andrew Moon: github.com/floodyberry/poly1305-opt/blob/master/app/extensions/poly1305.
// +build arm,!gccgo,!appengine
DATA poly1305_init_constants_armv6<>+0x00(SB)/4, $0x3ffffff
DATA poly1305_init_constants_armv6<>+0x04(SB)/4, $0x3ffff03
DATA poly1305_init_constants_armv6<>+0x08(SB)/4, $0x3ffc0ff
DATA poly1305_init_constants_armv6<>+0x0c(SB)/4, $0x3f03fff
DATA poly1305_init_constants_armv6<>+0x10(SB)/4, $0x00fffff
GLOBL poly1305_init_constants_armv6<>(SB), 8, $20
// Warning: the linker may use R11 to synthesize certain instructions. Please
// take care and verify that no synthetic instructions use it.
TEXT poly1305_init_ext_armv6<>(SB),4,$-4
MOVM.DB.W [R4-R11], (R13)
MOVM.IA.W (R1), [R2-R5]
MOVW $poly1305_init_constants_armv6<>(SB), R7
MOVW R2, R8
MOVW R2>>26, R9
MOVW R3>>20, g
MOVW R4>>14, R11
MOVW R5>>8, R12
ORR R3<<6, R9, R9
ORR R4<<12, g, g
ORR R5<<18, R11, R11
MOVM.IA (R7), [R2-R6]
AND R8, R2, R2
AND R9, R3, R3
AND g, R4, R4
AND R11, R5, R5
AND R12, R6, R6
MOVM.IA.W [R2-R6], (R0)
EOR R2, R2, R2
EOR R3, R3, R3
EOR R4, R4, R4
EOR R5, R5, R5
EOR R6, R6, R6
MOVM.IA.W [R2-R6], (R0)
MOVM.IA.W (R1), [R2-R5]
MOVM.IA [R2-R6], (R0)
MOVM.IA.W (R13), [R4-R11]
RET
#define MOVW_UNALIGNED(Rsrc, Rdst, Rtmp, offset) \
MOVBU (offset+0)(Rsrc), Rtmp; \
MOVBU Rtmp, (offset+0)(Rdst); \
MOVBU (offset+1)(Rsrc), Rtmp; \
MOVBU Rtmp, (offset+1)(Rdst); \
MOVBU (offset+2)(Rsrc), Rtmp; \
MOVBU Rtmp, (offset+2)(Rdst); \
MOVBU (offset+3)(Rsrc), Rtmp; \
MOVBU Rtmp, (offset+3)(Rdst)
TEXT poly1305_blocks_armv6<>(SB),4,$-4
MOVM.DB.W [R4, R5, R6, R7, R8, R9, g, R11, R14], (R13)
SUB $128, R13
MOVW R0, 36(R13)
MOVW R1, 40(R13)
MOVW R2, 44(R13)
MOVW R1, R14
MOVW R2, R12
MOVW 56(R0), R8
WORD $0xe1180008 // TST R8, R8 not working see issue 5921
EOR R6, R6, R6
MOVW.EQ $(1<<24), R6
MOVW R6, 32(R13)
ADD $64, R13, g
MOVM.IA (R0), [R0-R9]
MOVM.IA [R0-R4], (g)
CMP $16, R12
BLO poly1305_blocks_armv6_done
poly1305_blocks_armv6_mainloop:
WORD $0xe31e0003 // TST R14, #3 not working see issue 5921
BEQ poly1305_blocks_armv6_mainloop_aligned
ADD $48, R13, g
MOVW_UNALIGNED(R14, g, R0, 0)
MOVW_UNALIGNED(R14, g, R0, 4)
MOVW_UNALIGNED(R14, g, R0, 8)
MOVW_UNALIGNED(R14, g, R0, 12)
MOVM.IA (g), [R0-R3]
ADD $16, R14
B poly1305_blocks_armv6_mainloop_loaded
poly1305_blocks_armv6_mainloop_aligned:
MOVM.IA.W (R14), [R0-R3]
poly1305_blocks_armv6_mainloop_loaded:
MOVW R0>>26, g
MOVW R1>>20, R11
MOVW R2>>14, R12
MOVW R14, 40(R13)
MOVW R3>>8, R4
ORR R1<<6, g, g
ORR R2<<12, R11, R11
ORR R3<<18, R12, R12
BIC $0xfc000000, R0, R0
BIC $0xfc000000, g, g
MOVW 32(R13), R3
BIC $0xfc000000, R11, R11
BIC $0xfc000000, R12, R12
ADD R0, R5, R5
ADD g, R6, R6
ORR R3, R4, R4
ADD R11, R7, R7
ADD $64, R13, R14
ADD R12, R8, R8
ADD R4, R9, R9
MOVM.IA (R14), [R0-R4]
MULLU R4, R5, (R11, g)
MULLU R3, R5, (R14, R12)
MULALU R3, R6, (R11, g)
MULALU R2, R6, (R14, R12)
MULALU R2, R7, (R11, g)
MULALU R1, R7, (R14, R12)
ADD R4<<2, R4, R4
ADD R3<<2, R3, R3
MULALU R1, R8, (R11, g)
MULALU R0, R8, (R14, R12)
MULALU R0, R9, (R11, g)
MULALU R4, R9, (R14, R12)
MOVW g, 24(R13)
MOVW R11, 28(R13)
MOVW R12, 16(R13)
MOVW R14, 20(R13)
MULLU R2, R5, (R11, g)
MULLU R1, R5, (R14, R12)
MULALU R1, R6, (R11, g)
MULALU R0, R6, (R14, R12)
MULALU R0, R7, (R11, g)
MULALU R4, R7, (R14, R12)
ADD R2<<2, R2, R2
ADD R1<<2, R1, R1
MULALU R4, R8, (R11, g)
MULALU R3, R8, (R14, R12)
MULALU R3, R9, (R11, g)
MULALU R2, R9, (R14, R12)
MOVW g, 8(R13)
MOVW R11, 12(R13)
MOVW R12, 0(R13)
MOVW R14, w+4(SP)
MULLU R0, R5, (R11, g)
MULALU R4, R6, (R11, g)
MULALU R3, R7, (R11, g)
MULALU R2, R8, (R11, g)
MULALU R1, R9, (R11, g)
MOVM.IA (R13), [R0-R7]
MOVW g>>26, R12
MOVW R4>>26, R14
ORR R11<<6, R12, R12
ORR R5<<6, R14, R14
BIC $0xfc000000, g, g
BIC $0xfc000000, R4, R4
ADD.S R12, R0, R0
ADC $0, R1, R1
ADD.S R14, R6, R6
ADC $0, R7, R7
MOVW R0>>26, R12
MOVW R6>>26, R14
ORR R1<<6, R12, R12
ORR R7<<6, R14, R14
BIC $0xfc000000, R0, R0
BIC $0xfc000000, R6, R6
ADD R14<<2, R14, R14
ADD.S R12, R2, R2
ADC $0, R3, R3
ADD R14, g, g
MOVW R2>>26, R12
MOVW g>>26, R14
ORR R3<<6, R12, R12
BIC $0xfc000000, g, R5
BIC $0xfc000000, R2, R7
ADD R12, R4, R4
ADD R14, R0, R0
MOVW R4>>26, R12
BIC $0xfc000000, R4, R8
ADD R12, R6, R9
MOVW w+44(SP), R12
MOVW w+40(SP), R14
MOVW R0, R6
CMP $32, R12
SUB $16, R12, R12
MOVW R12, 44(R13)
BHS poly1305_blocks_armv6_mainloop
poly1305_blocks_armv6_done:
MOVW 36(R13), R12
MOVW R5, 20(R12)
MOVW R6, 24(R12)
MOVW R7, 28(R12)
MOVW R8, 32(R12)
MOVW R9, 36(R12)
ADD $128, R13, R13
MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, g, R11, R14]
RET
#define MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp) \
MOVBU.P 1(Rsrc), Rtmp; \
MOVBU.P Rtmp, 1(Rdst); \
MOVBU.P 1(Rsrc), Rtmp; \
MOVBU.P Rtmp, 1(Rdst)
#define MOVWP_UNALIGNED(Rsrc, Rdst, Rtmp) \
MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp); \
MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp)
TEXT poly1305_finish_ext_armv6<>(SB),4,$-4
MOVM.DB.W [R4, R5, R6, R7, R8, R9, g, R11, R14], (R13)
SUB $16, R13, R13
MOVW R0, R5
MOVW R1, R6
MOVW R2, R7
MOVW R3, R8
AND.S R2, R2, R2
BEQ poly1305_finish_ext_armv6_noremaining
EOR R0, R0
MOVW R13, R9
MOVW R0, 0(R13)
MOVW R0, 4(R13)
MOVW R0, 8(R13)
MOVW R0, 12(R13)
WORD $0xe3110003 // TST R1, #3 not working see issue 5921
BEQ poly1305_finish_ext_armv6_aligned
WORD $0xe3120008 // TST R2, #8 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip8
MOVWP_UNALIGNED(R1, R9, g)
MOVWP_UNALIGNED(R1, R9, g)
poly1305_finish_ext_armv6_skip8:
WORD $0xe3120004 // TST $4, R2 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip4
MOVWP_UNALIGNED(R1, R9, g)
poly1305_finish_ext_armv6_skip4:
WORD $0xe3120002 // TST $2, R2 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip2
MOVHUP_UNALIGNED(R1, R9, g)
B poly1305_finish_ext_armv6_skip2
poly1305_finish_ext_armv6_aligned:
WORD $0xe3120008 // TST R2, #8 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip8_aligned
MOVM.IA.W (R1), [g-R11]
MOVM.IA.W [g-R11], (R9)
poly1305_finish_ext_armv6_skip8_aligned:
WORD $0xe3120004 // TST $4, R2 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip4_aligned
MOVW.P 4(R1), g
MOVW.P g, 4(R9)
poly1305_finish_ext_armv6_skip4_aligned:
WORD $0xe3120002 // TST $2, R2 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip2
MOVHU.P 2(R1), g
MOVH.P g, 2(R9)
poly1305_finish_ext_armv6_skip2:
WORD $0xe3120001 // TST $1, R2 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip1
MOVBU.P 1(R1), g
MOVBU.P g, 1(R9)
poly1305_finish_ext_armv6_skip1:
MOVW $1, R11
MOVBU R11, 0(R9)
MOVW R11, 56(R5)
MOVW R5, R0
MOVW R13, R1
MOVW $16, R2
BL poly1305_blocks_armv6<>(SB)
poly1305_finish_ext_armv6_noremaining:
MOVW 20(R5), R0
MOVW 24(R5), R1
MOVW 28(R5), R2
MOVW 32(R5), R3
MOVW 36(R5), R4
MOVW R4>>26, R12
BIC $0xfc000000, R4, R4
ADD R12<<2, R12, R12
ADD R12, R0, R0
MOVW R0>>26, R12
BIC $0xfc000000, R0, R0
ADD R12, R1, R1
MOVW R1>>26, R12
BIC $0xfc000000, R1, R1
ADD R12, R2, R2
MOVW R2>>26, R12
BIC $0xfc000000, R2, R2
ADD R12, R3, R3
MOVW R3>>26, R12
BIC $0xfc000000, R3, R3
ADD R12, R4, R4
ADD $5, R0, R6
MOVW R6>>26, R12
BIC $0xfc000000, R6, R6
ADD R12, R1, R7
MOVW R7>>26, R12
BIC $0xfc000000, R7, R7
ADD R12, R2, g
MOVW g>>26, R12
BIC $0xfc000000, g, g
ADD R12, R3, R11
MOVW $-(1<<26), R12
ADD R11>>26, R12, R12
BIC $0xfc000000, R11, R11
ADD R12, R4, R14
MOVW R14>>31, R12
SUB $1, R12
AND R12, R6, R6
AND R12, R7, R7
AND R12, g, g
AND R12, R11, R11
AND R12, R14, R14
MVN R12, R12
AND R12, R0, R0
AND R12, R1, R1
AND R12, R2, R2
AND R12, R3, R3
AND R12, R4, R4
ORR R6, R0, R0
ORR R7, R1, R1
ORR g, R2, R2
ORR R11, R3, R3
ORR R14, R4, R4
ORR R1<<26, R0, R0
MOVW R1>>6, R1
ORR R2<<20, R1, R1
MOVW R2>>12, R2
ORR R3<<14, R2, R2
MOVW R3>>18, R3
ORR R4<<8, R3, R3
MOVW 40(R5), R6
MOVW 44(R5), R7
MOVW 48(R5), g
MOVW 52(R5), R11
ADD.S R6, R0, R0
ADC.S R7, R1, R1
ADC.S g, R2, R2
ADC.S R11, R3, R3
MOVM.IA [R0-R3], (R8)
MOVW R5, R12
EOR R0, R0, R0
EOR R1, R1, R1
EOR R2, R2, R2
EOR R3, R3, R3
EOR R4, R4, R4
EOR R5, R5, R5
EOR R6, R6, R6
EOR R7, R7, R7
MOVM.IA.W [R0-R7], (R12)
MOVM.IA [R0-R7], (R12)
ADD $16, R13, R13
MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, g, R11, R14]
RET
// func poly1305_auth_armv6(out *[16]byte, m *byte, mlen uint32, key *[32]key)
TEXT ·poly1305_auth_armv6(SB),0,$280-16
MOVW out+0(FP), R4
MOVW m+4(FP), R5
MOVW mlen+8(FP), R6
MOVW key+12(FP), R7
MOVW R13, R8
BIC $63, R13
SUB $64, R13, R13
MOVW R13, R0
MOVW R7, R1
BL poly1305_init_ext_armv6<>(SB)
BIC.S $15, R6, R2
BEQ poly1305_auth_armv6_noblocks
MOVW R13, R0
MOVW R5, R1
ADD R2, R5, R5
SUB R2, R6, R6
BL poly1305_blocks_armv6<>(SB)
poly1305_auth_armv6_noblocks:
MOVW R13, R0
MOVW R5, R1
MOVW R6, R2
MOVW R4, R3
BL poly1305_finish_ext_armv6<>(SB)
MOVW R8, R13
RET

6
vendor/golang.org/x/crypto/poly1305/poly1305_test.go сгенерированный поставляемый
Просмотреть файл

@@ -33,6 +33,12 @@ var testData = []struct {
make([]byte, 32),
make([]byte, 16),
},
{
// This test triggers an edge-case. See https://go-review.googlesource.com/#/c/30101/.
[]byte{0x81, 0xd8, 0xb2, 0xe4, 0x6a, 0x25, 0x21, 0x3b, 0x58, 0xfe, 0xe4, 0x21, 0x3a, 0x2a, 0x28, 0xe9, 0x21, 0xc1, 0x2a, 0x96, 0x32, 0x51, 0x6d, 0x3b, 0x73, 0x27, 0x27, 0x27, 0xbe, 0xcf, 0x21, 0x29},
[]byte{0x3b, 0x3a, 0x29, 0xe9, 0x3b, 0x21, 0x3a, 0x5c, 0x5c, 0x3b, 0x3b, 0x05, 0x3a, 0x3a, 0x8c, 0x0d},
[]byte{0x6d, 0xc1, 0x8b, 0x8c, 0x34, 0x4c, 0xd7, 0x99, 0x27, 0x11, 0x8b, 0xbe, 0x84, 0xb7, 0xf3, 0x14},
},
}
func testSum(t *testing.T, unaligned bool) {

4
vendor/golang.org/x/crypto/poly1305/sum_amd64.go сгенерированный поставляемый
Просмотреть файл

@@ -6,10 +6,8 @@
package poly1305
// This function is implemented in poly1305_amd64.s
// This function is implemented in sum_amd64.s
//go:noescape
func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]byte)
// Sum generates an authenticator for m using a one-time key and puts the

125
vendor/golang.org/x/crypto/poly1305/sum_amd64.s сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,125 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build amd64,!gccgo,!appengine
#include "textflag.h"
#define POLY1305_ADD(msg, h0, h1, h2) \
ADDQ 0(msg), h0; \
ADCQ 8(msg), h1; \
ADCQ $1, h2; \
LEAQ 16(msg), msg
#define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3) \
MOVQ r0, AX; \
MULQ h0; \
MOVQ AX, t0; \
MOVQ DX, t1; \
MOVQ r0, AX; \
MULQ h1; \
ADDQ AX, t1; \
ADCQ $0, DX; \
MOVQ r0, t2; \
IMULQ h2, t2; \
ADDQ DX, t2; \
\
MOVQ r1, AX; \
MULQ h0; \
ADDQ AX, t1; \
ADCQ $0, DX; \
MOVQ DX, h0; \
MOVQ r1, t3; \
IMULQ h2, t3; \
MOVQ r1, AX; \
MULQ h1; \
ADDQ AX, t2; \
ADCQ DX, t3; \
ADDQ h0, t2; \
ADCQ $0, t3; \
\
MOVQ t0, h0; \
MOVQ t1, h1; \
MOVQ t2, h2; \
ANDQ $3, h2; \
MOVQ t2, t0; \
ANDQ $0xFFFFFFFFFFFFFFFC, t0; \
ADDQ t0, h0; \
ADCQ t3, h1; \
ADCQ $0, h2; \
SHRQ $2, t3, t2; \
SHRQ $2, t3; \
ADDQ t2, h0; \
ADCQ t3, h1; \
ADCQ $0, h2
DATA poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF
DATA poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
GLOBL poly1305Mask<>(SB), RODATA, $16
// func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]key)
TEXT ·poly1305(SB), $0-32
MOVQ out+0(FP), DI
MOVQ m+8(FP), SI
MOVQ mlen+16(FP), R15
MOVQ key+24(FP), AX
MOVQ 0(AX), R11
MOVQ 8(AX), R12
ANDQ poly1305Mask<>(SB), R11 // r0
ANDQ poly1305Mask<>+8(SB), R12 // r1
XORQ R8, R8 // h0
XORQ R9, R9 // h1
XORQ R10, R10 // h2
CMPQ R15, $16
JB bytes_between_0_and_15
loop:
POLY1305_ADD(SI, R8, R9, R10)
multiply:
POLY1305_MUL(R8, R9, R10, R11, R12, BX, CX, R13, R14)
SUBQ $16, R15
CMPQ R15, $16
JAE loop
bytes_between_0_and_15:
TESTQ R15, R15
JZ done
MOVQ $1, BX
XORQ CX, CX
XORQ R13, R13
ADDQ R15, SI
flush_buffer:
SHLQ $8, BX, CX
SHLQ $8, BX
MOVB -1(SI), R13
XORQ R13, BX
DECQ SI
DECQ R15
JNZ flush_buffer
ADDQ BX, R8
ADCQ CX, R9
ADCQ $0, R10
MOVQ $16, R15
JMP multiply
done:
MOVQ R8, AX
MOVQ R9, BX
SUBQ $0xFFFFFFFFFFFFFFFB, AX
SBBQ $0xFFFFFFFFFFFFFFFF, BX
SBBQ $3, R10
CMOVQCS R8, AX
CMOVQCS R9, BX
MOVQ key+24(FP), R8
ADDQ 16(R8), AX
ADCQ 24(R8), BX
MOVQ AX, 0(DI)
MOVQ BX, 8(DI)
RET

6
vendor/golang.org/x/crypto/poly1305/sum_arm.go сгенерированный поставляемый
Просмотреть файл

@@ -2,14 +2,12 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build arm,!gccgo,!appengine
// +build arm,!gccgo,!appengine,!nacl
package poly1305
// This function is implemented in poly1305_arm.s
// This function is implemented in sum_arm.s
//go:noescape
func poly1305_auth_armv6(out *[16]byte, m *byte, mlen uint32, key *[32]byte)
// Sum generates an authenticator for m using a one-time key and puts the

427
vendor/golang.org/x/crypto/poly1305/sum_arm.s сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,427 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build arm,!gccgo,!appengine,!nacl
#include "textflag.h"
// This code was translated into a form compatible with 5a from the public
// domain source by Andrew Moon: github.com/floodyberry/poly1305-opt/blob/master/app/extensions/poly1305.
DATA poly1305_init_constants_armv6<>+0x00(SB)/4, $0x3ffffff
DATA poly1305_init_constants_armv6<>+0x04(SB)/4, $0x3ffff03
DATA poly1305_init_constants_armv6<>+0x08(SB)/4, $0x3ffc0ff
DATA poly1305_init_constants_armv6<>+0x0c(SB)/4, $0x3f03fff
DATA poly1305_init_constants_armv6<>+0x10(SB)/4, $0x00fffff
GLOBL poly1305_init_constants_armv6<>(SB), 8, $20
// Warning: the linker may use R11 to synthesize certain instructions. Please
// take care and verify that no synthetic instructions use it.
TEXT poly1305_init_ext_armv6<>(SB), NOSPLIT, $0
// Needs 16 bytes of stack and 64 bytes of space pointed to by R0. (It
// might look like it's only 60 bytes of space but the final four bytes
// will be written by another function.) We need to skip over four
// bytes of stack because that's saving the value of 'g'.
ADD $4, R13, R8
MOVM.IB [R4-R7], (R8)
MOVM.IA.W (R1), [R2-R5]
MOVW $poly1305_init_constants_armv6<>(SB), R7
MOVW R2, R8
MOVW R2>>26, R9
MOVW R3>>20, g
MOVW R4>>14, R11
MOVW R5>>8, R12
ORR R3<<6, R9, R9
ORR R4<<12, g, g
ORR R5<<18, R11, R11
MOVM.IA (R7), [R2-R6]
AND R8, R2, R2
AND R9, R3, R3
AND g, R4, R4
AND R11, R5, R5
AND R12, R6, R6
MOVM.IA.W [R2-R6], (R0)
EOR R2, R2, R2
EOR R3, R3, R3
EOR R4, R4, R4
EOR R5, R5, R5
EOR R6, R6, R6
MOVM.IA.W [R2-R6], (R0)
MOVM.IA.W (R1), [R2-R5]
MOVM.IA [R2-R6], (R0)
ADD $20, R13, R0
MOVM.DA (R0), [R4-R7]
RET
#define MOVW_UNALIGNED(Rsrc, Rdst, Rtmp, offset) \
MOVBU (offset+0)(Rsrc), Rtmp; \
MOVBU Rtmp, (offset+0)(Rdst); \
MOVBU (offset+1)(Rsrc), Rtmp; \
MOVBU Rtmp, (offset+1)(Rdst); \
MOVBU (offset+2)(Rsrc), Rtmp; \
MOVBU Rtmp, (offset+2)(Rdst); \
MOVBU (offset+3)(Rsrc), Rtmp; \
MOVBU Rtmp, (offset+3)(Rdst)
TEXT poly1305_blocks_armv6<>(SB), NOSPLIT, $0
// Needs 24 bytes of stack for saved registers and then 88 bytes of
// scratch space after that. We assume that 24 bytes at (R13) have
// already been used: four bytes for the link register saved in the
// prelude of poly1305_auth_armv6, four bytes for saving the value of g
// in that function and 16 bytes of scratch space used around
// poly1305_finish_ext_armv6_skip1.
ADD $24, R13, R12
MOVM.IB [R4-R8, R14], (R12)
MOVW R0, 88(R13)
MOVW R1, 92(R13)
MOVW R2, 96(R13)
MOVW R1, R14
MOVW R2, R12
MOVW 56(R0), R8
WORD $0xe1180008 // TST R8, R8 not working see issue 5921
EOR R6, R6, R6
MOVW.EQ $(1<<24), R6
MOVW R6, 84(R13)
ADD $116, R13, g
MOVM.IA (R0), [R0-R9]
MOVM.IA [R0-R4], (g)
CMP $16, R12
BLO poly1305_blocks_armv6_done
poly1305_blocks_armv6_mainloop:
WORD $0xe31e0003 // TST R14, #3 not working see issue 5921
BEQ poly1305_blocks_armv6_mainloop_aligned
ADD $100, R13, g
MOVW_UNALIGNED(R14, g, R0, 0)
MOVW_UNALIGNED(R14, g, R0, 4)
MOVW_UNALIGNED(R14, g, R0, 8)
MOVW_UNALIGNED(R14, g, R0, 12)
MOVM.IA (g), [R0-R3]
ADD $16, R14
B poly1305_blocks_armv6_mainloop_loaded
poly1305_blocks_armv6_mainloop_aligned:
MOVM.IA.W (R14), [R0-R3]
poly1305_blocks_armv6_mainloop_loaded:
MOVW R0>>26, g
MOVW R1>>20, R11
MOVW R2>>14, R12
MOVW R14, 92(R13)
MOVW R3>>8, R4
ORR R1<<6, g, g
ORR R2<<12, R11, R11
ORR R3<<18, R12, R12
BIC $0xfc000000, R0, R0
BIC $0xfc000000, g, g
MOVW 84(R13), R3
BIC $0xfc000000, R11, R11
BIC $0xfc000000, R12, R12
ADD R0, R5, R5
ADD g, R6, R6
ORR R3, R4, R4
ADD R11, R7, R7
ADD $116, R13, R14
ADD R12, R8, R8
ADD R4, R9, R9
MOVM.IA (R14), [R0-R4]
MULLU R4, R5, (R11, g)
MULLU R3, R5, (R14, R12)
MULALU R3, R6, (R11, g)
MULALU R2, R6, (R14, R12)
MULALU R2, R7, (R11, g)
MULALU R1, R7, (R14, R12)
ADD R4<<2, R4, R4
ADD R3<<2, R3, R3
MULALU R1, R8, (R11, g)
MULALU R0, R8, (R14, R12)
MULALU R0, R9, (R11, g)
MULALU R4, R9, (R14, R12)
MOVW g, 76(R13)
MOVW R11, 80(R13)
MOVW R12, 68(R13)
MOVW R14, 72(R13)
MULLU R2, R5, (R11, g)
MULLU R1, R5, (R14, R12)
MULALU R1, R6, (R11, g)
MULALU R0, R6, (R14, R12)
MULALU R0, R7, (R11, g)
MULALU R4, R7, (R14, R12)
ADD R2<<2, R2, R2
ADD R1<<2, R1, R1
MULALU R4, R8, (R11, g)
MULALU R3, R8, (R14, R12)
MULALU R3, R9, (R11, g)
MULALU R2, R9, (R14, R12)
MOVW g, 60(R13)
MOVW R11, 64(R13)
MOVW R12, 52(R13)
MOVW R14, 56(R13)
MULLU R0, R5, (R11, g)
MULALU R4, R6, (R11, g)
MULALU R3, R7, (R11, g)
MULALU R2, R8, (R11, g)
MULALU R1, R9, (R11, g)
ADD $52, R13, R0
MOVM.IA (R0), [R0-R7]
MOVW g>>26, R12
MOVW R4>>26, R14
ORR R11<<6, R12, R12
ORR R5<<6, R14, R14
BIC $0xfc000000, g, g
BIC $0xfc000000, R4, R4
ADD.S R12, R0, R0
ADC $0, R1, R1
ADD.S R14, R6, R6
ADC $0, R7, R7
MOVW R0>>26, R12
MOVW R6>>26, R14
ORR R1<<6, R12, R12
ORR R7<<6, R14, R14
BIC $0xfc000000, R0, R0
BIC $0xfc000000, R6, R6
ADD R14<<2, R14, R14
ADD.S R12, R2, R2
ADC $0, R3, R3
ADD R14, g, g
MOVW R2>>26, R12
MOVW g>>26, R14
ORR R3<<6, R12, R12
BIC $0xfc000000, g, R5
BIC $0xfc000000, R2, R7
ADD R12, R4, R4
ADD R14, R0, R0
MOVW R4>>26, R12
BIC $0xfc000000, R4, R8
ADD R12, R6, R9
MOVW 96(R13), R12
MOVW 92(R13), R14
MOVW R0, R6
CMP $32, R12
SUB $16, R12, R12
MOVW R12, 96(R13)
BHS poly1305_blocks_armv6_mainloop
poly1305_blocks_armv6_done:
MOVW 88(R13), R12
MOVW R5, 20(R12)
MOVW R6, 24(R12)
MOVW R7, 28(R12)
MOVW R8, 32(R12)
MOVW R9, 36(R12)
ADD $48, R13, R0
MOVM.DA (R0), [R4-R8, R14]
RET
#define MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp) \
MOVBU.P 1(Rsrc), Rtmp; \
MOVBU.P Rtmp, 1(Rdst); \
MOVBU.P 1(Rsrc), Rtmp; \
MOVBU.P Rtmp, 1(Rdst)
#define MOVWP_UNALIGNED(Rsrc, Rdst, Rtmp) \
MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp); \
MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp)
// func poly1305_auth_armv6(out *[16]byte, m *byte, mlen uint32, key *[32]key)
TEXT ·poly1305_auth_armv6(SB), $196-16
// The value 196, just above, is the sum of 64 (the size of the context
// structure) and 132 (the amount of stack needed).
//
// At this point, the stack pointer (R13) has been moved down. It
// points to the saved link register and there's 196 bytes of free
// space above it.
//
// The stack for this function looks like:
//
// +---------------------
// |
// | 64 bytes of context structure
// |
// +---------------------
// |
// | 112 bytes for poly1305_blocks_armv6
// |
// +---------------------
// | 16 bytes of final block, constructed at
// | poly1305_finish_ext_armv6_skip8
// +---------------------
// | four bytes of saved 'g'
// +---------------------
// | lr, saved by prelude <- R13 points here
// +---------------------
MOVW g, 4(R13)
MOVW out+0(FP), R4
MOVW m+4(FP), R5
MOVW mlen+8(FP), R6
MOVW key+12(FP), R7
ADD $136, R13, R0 // 136 = 4 + 4 + 16 + 112
MOVW R7, R1
// poly1305_init_ext_armv6 will write to the stack from R13+4, but
// that's ok because none of the other values have been written yet.
BL poly1305_init_ext_armv6<>(SB)
BIC.S $15, R6, R2
BEQ poly1305_auth_armv6_noblocks
ADD $136, R13, R0
MOVW R5, R1
ADD R2, R5, R5
SUB R2, R6, R6
BL poly1305_blocks_armv6<>(SB)
poly1305_auth_armv6_noblocks:
ADD $136, R13, R0
MOVW R5, R1
MOVW R6, R2
MOVW R4, R3
MOVW R0, R5
MOVW R1, R6
MOVW R2, R7
MOVW R3, R8
AND.S R2, R2, R2
BEQ poly1305_finish_ext_armv6_noremaining
EOR R0, R0
ADD $8, R13, R9 // 8 = offset to 16 byte scratch space
MOVW R0, (R9)
MOVW R0, 4(R9)
MOVW R0, 8(R9)
MOVW R0, 12(R9)
WORD $0xe3110003 // TST R1, #3 not working see issue 5921
BEQ poly1305_finish_ext_armv6_aligned
WORD $0xe3120008 // TST R2, #8 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip8
MOVWP_UNALIGNED(R1, R9, g)
MOVWP_UNALIGNED(R1, R9, g)
poly1305_finish_ext_armv6_skip8:
WORD $0xe3120004 // TST $4, R2 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip4
MOVWP_UNALIGNED(R1, R9, g)
poly1305_finish_ext_armv6_skip4:
WORD $0xe3120002 // TST $2, R2 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip2
MOVHUP_UNALIGNED(R1, R9, g)
B poly1305_finish_ext_armv6_skip2
poly1305_finish_ext_armv6_aligned:
WORD $0xe3120008 // TST R2, #8 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip8_aligned
MOVM.IA.W (R1), [g-R11]
MOVM.IA.W [g-R11], (R9)
poly1305_finish_ext_armv6_skip8_aligned:
WORD $0xe3120004 // TST $4, R2 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip4_aligned
MOVW.P 4(R1), g
MOVW.P g, 4(R9)
poly1305_finish_ext_armv6_skip4_aligned:
WORD $0xe3120002 // TST $2, R2 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip2
MOVHU.P 2(R1), g
MOVH.P g, 2(R9)
poly1305_finish_ext_armv6_skip2:
WORD $0xe3120001 // TST $1, R2 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip1
MOVBU.P 1(R1), g
MOVBU.P g, 1(R9)
poly1305_finish_ext_armv6_skip1:
MOVW $1, R11
MOVBU R11, 0(R9)
MOVW R11, 56(R5)
MOVW R5, R0
ADD $8, R13, R1
MOVW $16, R2
BL poly1305_blocks_armv6<>(SB)
poly1305_finish_ext_armv6_noremaining:
MOVW 20(R5), R0
MOVW 24(R5), R1
MOVW 28(R5), R2
MOVW 32(R5), R3
MOVW 36(R5), R4
MOVW R4>>26, R12
BIC $0xfc000000, R4, R4
ADD R12<<2, R12, R12
ADD R12, R0, R0
MOVW R0>>26, R12
BIC $0xfc000000, R0, R0
ADD R12, R1, R1
MOVW R1>>26, R12
BIC $0xfc000000, R1, R1
ADD R12, R2, R2
MOVW R2>>26, R12
BIC $0xfc000000, R2, R2
ADD R12, R3, R3
MOVW R3>>26, R12
BIC $0xfc000000, R3, R3
ADD R12, R4, R4
ADD $5, R0, R6
MOVW R6>>26, R12
BIC $0xfc000000, R6, R6
ADD R12, R1, R7
MOVW R7>>26, R12
BIC $0xfc000000, R7, R7
ADD R12, R2, g
MOVW g>>26, R12
BIC $0xfc000000, g, g
ADD R12, R3, R11
MOVW $-(1<<26), R12
ADD R11>>26, R12, R12
BIC $0xfc000000, R11, R11
ADD R12, R4, R9
MOVW R9>>31, R12
SUB $1, R12
AND R12, R6, R6
AND R12, R7, R7
AND R12, g, g
AND R12, R11, R11
AND R12, R9, R9
MVN R12, R12
AND R12, R0, R0
AND R12, R1, R1
AND R12, R2, R2
AND R12, R3, R3
AND R12, R4, R4
ORR R6, R0, R0
ORR R7, R1, R1
ORR g, R2, R2
ORR R11, R3, R3
ORR R9, R4, R4
ORR R1<<26, R0, R0
MOVW R1>>6, R1
ORR R2<<20, R1, R1
MOVW R2>>12, R2
ORR R3<<14, R2, R2
MOVW R3>>18, R3
ORR R4<<8, R3, R3
MOVW 40(R5), R6
MOVW 44(R5), R7
MOVW 48(R5), g
MOVW 52(R5), R11
ADD.S R6, R0, R0
ADC.S R7, R1, R1
ADC.S g, R2, R2
ADC.S R11, R3, R3
MOVM.IA [R0-R3], (R8)
MOVW R5, R12
EOR R0, R0, R0
EOR R1, R1, R1
EOR R2, R2, R2
EOR R3, R3, R3
EOR R4, R4, R4
EOR R5, R5, R5
EOR R6, R6, R6
EOR R7, R7, R7
MOVM.IA.W [R0-R7], (R12)
MOVM.IA [R0-R7], (R12)
MOVW 4(R13), g
RET

2
vendor/golang.org/x/crypto/poly1305/sum_ref.go сгенерированный поставляемый
Просмотреть файл

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !amd64,!arm gccgo appengine
// +build !amd64,!arm gccgo appengine nacl
package poly1305

43
vendor/golang.org/x/crypto/salsa20/salsa/salsa2020_amd64.s сгенерированный поставляемый
Просмотреть файл

@@ -8,26 +8,20 @@
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
// func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte)
TEXT ·salsa2020XORKeyStream(SB),0,$512-40
// This needs up to 64 bytes at 360(SP); hence the non-obvious frame size.
TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
MOVQ out+0(FP),DI
MOVQ in+8(FP),SI
MOVQ n+16(FP),DX
MOVQ nonce+24(FP),CX
MOVQ key+32(FP),R8
MOVQ SP,R11
MOVQ $31,R9
NOTQ R9
ANDQ R9,SP
ADDQ $32,SP
MOVQ SP,R12
MOVQ SP,R9
ADDQ $31, R9
ANDQ $~31, R9
MOVQ R9, SP
MOVQ R11,352(SP)
MOVQ R12,360(SP)
MOVQ R13,368(SP)
MOVQ R14,376(SP)
MOVQ R15,384(SP)
MOVQ BX,392(SP)
MOVQ BP,400(SP)
MOVQ DX,R9
MOVQ CX,DX
MOVQ R8,R10
@@ -133,7 +127,7 @@ TEXT ·salsa2020XORKeyStream(SB),0,$512-40
SHRQ $32,CX
MOVL DX,16(SP)
MOVL CX, 36 (SP)
MOVQ R9,408(SP)
MOVQ R9,352(SP)
MOVQ $20,DX
MOVOA 64(SP),X0
MOVOA 80(SP),X1
@@ -650,7 +644,7 @@ TEXT ·salsa2020XORKeyStream(SB),0,$512-40
MOVL CX,244(DI)
MOVL R8,248(DI)
MOVL R9,252(DI)
MOVQ 408(SP),R9
MOVQ 352(SP),R9
SUBQ $256,R9
ADDQ $256,SI
ADDQ $256,DI
@@ -662,13 +656,13 @@ TEXT ·salsa2020XORKeyStream(SB),0,$512-40
CMPQ R9,$64
JAE NOCOPY
MOVQ DI,DX
LEAQ 416(SP),DI
LEAQ 360(SP),DI
MOVQ R9,CX
REP; MOVSB
LEAQ 416(SP),DI
LEAQ 416(SP),SI
LEAQ 360(SP),DI
LEAQ 360(SP),SI
NOCOPY:
MOVQ R9,408(SP)
MOVQ R9,352(SP)
MOVOA 48(SP),X0
MOVOA 0(SP),X1
MOVOA 16(SP),X2
@@ -867,7 +861,7 @@ TEXT ·salsa2020XORKeyStream(SB),0,$512-40
MOVL R8,44(DI)
MOVL R9,28(DI)
MOVL AX,12(DI)
MOVQ 408(SP),R9
MOVQ 352(SP),R9
MOVL 16(SP),CX
MOVL 36 (SP),R8
ADDQ $1,CX
@@ -886,14 +880,7 @@ TEXT ·salsa2020XORKeyStream(SB),0,$512-40
REP; MOVSB
BYTESATLEAST64:
DONE:
MOVQ 352(SP),R11
MOVQ 360(SP),R12
MOVQ 368(SP),R13
MOVQ 376(SP),R14
MOVQ 384(SP),R15
MOVQ 392(SP),BX
MOVQ 400(SP),BP
MOVQ R11,SP
MOVQ R12,SP
RET
BYTESATLEAST65:
SUBQ $64,R9

2
vendor/golang.org/x/crypto/sha3/keccakf_amd64.s сгенерированный поставляемый
Просмотреть файл

@@ -322,7 +322,6 @@
// func keccakF1600(state *[25]uint64)
TEXT ·keccakF1600(SB), 0, $200-8
MOVQ state+0(FP), rpState
SUBQ $(8*25), SP
// Convert the user state into an internal state
NOTQ _be(rpState)
@@ -388,5 +387,4 @@ TEXT ·keccakF1600(SB), 0, $200-8
NOTQ _mi(rpState)
NOTQ _sa(rpState)
ADDQ $(8*25), SP
RET

24
vendor/golang.org/x/crypto/ssh/agent/client_test.go сгенерированный поставляемый
Просмотреть файл

@@ -86,6 +86,11 @@ func testAgent(t *testing.T, key interface{}, cert *ssh.Certificate, lifetimeSec
testAgentInterface(t, agent, key, cert, lifetimeSecs)
}
func testKeyring(t *testing.T, key interface{}, cert *ssh.Certificate, lifetimeSecs uint32) {
a := NewKeyring()
testAgentInterface(t, a, key, cert, lifetimeSecs)
}
func testAgentInterface(t *testing.T, agent Agent, key interface{}, cert *ssh.Certificate, lifetimeSecs uint32) {
signer, err := ssh.NewSignerFromKey(key)
if err != nil {
@@ -137,11 +142,25 @@ func testAgentInterface(t *testing.T, agent Agent, key interface{}, cert *ssh.Ce
if err := pubKey.Verify(data, sig); err != nil {
t.Fatalf("Verify(%s): %v", pubKey.Type(), err)
}
// If the key has a lifetime, is it removed when it should be?
if lifetimeSecs > 0 {
time.Sleep(time.Second*time.Duration(lifetimeSecs) + 100*time.Millisecond)
keys, err := agent.List()
if err != nil {
t.Fatalf("List: %v", err)
}
if len(keys) > 0 {
t.Fatalf("key not expired")
}
}
}
func TestAgent(t *testing.T) {
for _, keyType := range []string{"rsa", "dsa", "ecdsa", "ed25519"} {
testAgent(t, testPrivateKeys[keyType], nil, 0)
testKeyring(t, testPrivateKeys[keyType], nil, 1)
}
}
@@ -154,10 +173,7 @@ func TestCert(t *testing.T) {
cert.SignCert(rand.Reader, testSigners["ecdsa"])
testAgent(t, testPrivateKeys["rsa"], cert, 0)
}
func TestConstraints(t *testing.T) {
testAgent(t, testPrivateKeys["rsa"], nil, 3600 /* lifetime in seconds */)
testKeyring(t, testPrivateKeys["rsa"], cert, 1)
}
// netPipe is analogous to net.Pipe, but it uses a real net.Conn, and

53
vendor/golang.org/x/crypto/ssh/agent/keyring.go сгенерированный поставляемый
Просмотреть файл

@@ -11,6 +11,7 @@ import (
"errors"
"fmt"
"sync"
"time"
"golang.org/x/crypto/ssh"
)
@@ -18,6 +19,7 @@ import (
type privKey struct {
signer ssh.Signer
comment string
expire *time.Time
}
type keyring struct {
@@ -48,15 +50,9 @@ func (r *keyring) RemoveAll() error {
return nil
}
// Remove removes all identities with the given public key.
func (r *keyring) Remove(key ssh.PublicKey) error {
r.mu.Lock()
defer r.mu.Unlock()
if r.locked {
return errLocked
}
want := key.Marshal()
// removeLocked does the actual key removal. The caller must already be holding the
// keyring mutex.
func (r *keyring) removeLocked(want []byte) error {
found := false
for i := 0; i < len(r.keys); {
if bytes.Equal(r.keys[i].signer.PublicKey().Marshal(), want) {
@@ -75,7 +71,18 @@ func (r *keyring) Remove(key ssh.PublicKey) error {
return nil
}
// Lock locks the agent. Sign and Remove will fail, and List will empty an empty list.
// Remove removes all identities with the given public key.
func (r *keyring) Remove(key ssh.PublicKey) error {
r.mu.Lock()
defer r.mu.Unlock()
if r.locked {
return errLocked
}
return r.removeLocked(key.Marshal())
}
// Lock locks the agent. Sign and Remove will fail, and List will return an empty list.
func (r *keyring) Lock(passphrase []byte) error {
r.mu.Lock()
defer r.mu.Unlock()
@@ -104,6 +111,17 @@ func (r *keyring) Unlock(passphrase []byte) error {
return nil
}
// expireKeysLocked removes expired keys from the keyring. If a key was added
// with a lifetimesecs contraint and seconds >= lifetimesecs seconds have
// ellapsed, it is removed. The caller *must* be holding the keyring mutex.
func (r *keyring) expireKeysLocked() {
for _, k := range r.keys {
if k.expire != nil && time.Now().After(*k.expire) {
r.removeLocked(k.signer.PublicKey().Marshal())
}
}
}
// List returns the identities known to the agent.
func (r *keyring) List() ([]*Key, error) {
r.mu.Lock()
@@ -113,6 +131,7 @@ func (r *keyring) List() ([]*Key, error) {
return nil, nil
}
r.expireKeysLocked()
var ids []*Key
for _, k := range r.keys {
pub := k.signer.PublicKey()
@@ -146,7 +165,17 @@ func (r *keyring) Add(key AddedKey) error {
}
}
r.keys = append(r.keys, privKey{signer, key.Comment})
p := privKey{
signer: signer,
comment: key.Comment,
}
if key.LifetimeSecs > 0 {
t := time.Now().Add(time.Duration(key.LifetimeSecs) * time.Second)
p.expire = &t
}
r.keys = append(r.keys, p)
return nil
}
@@ -159,6 +188,7 @@ func (r *keyring) Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error) {
return nil, errLocked
}
r.expireKeysLocked()
wanted := key.Marshal()
for _, k := range r.keys {
if bytes.Equal(k.signer.PublicKey().Marshal(), wanted) {
@@ -176,6 +206,7 @@ func (r *keyring) Signers() ([]ssh.Signer, error) {
return nil, errLocked
}
r.expireKeysLocked()
s := make([]ssh.Signer, 0, len(r.keys))
for _, k := range r.keys {
s = append(s, k.signer)

4
vendor/golang.org/x/crypto/ssh/agent/keyring_test.go сгенерированный поставляемый
Просмотреть файл

@@ -4,9 +4,7 @@
package agent
import (
"testing"
)
import "testing"
func addTestKey(t *testing.T, a Agent, keyName string) {
err := a.Add(AddedKey{

2
vendor/golang.org/x/crypto/ssh/client_auth_test.go сгенерированный поставляемый
Просмотреть файл

@@ -464,7 +464,7 @@ func TestClientAuthNone(t *testing.T) {
go NewClientConn(c2, "", clientConfig)
serverConn, err := newServer(c1, serverConfig)
if err != nil {
t.Fatal("newServer: %v", err)
t.Fatalf("newServer: %v", err)
}
if serverConn.User() != user {
t.Fatalf("server: got %q, want %q", serverConn.User(), user)

75
vendor/golang.org/x/crypto/ssh/example_test.go сгенерированный поставляемый
Просмотреть файл

@@ -17,9 +17,29 @@ import (
)
func ExampleNewServerConn() {
// Public key authentication is done by comparing
// the public key of a received connection
// with the entries in the authorized_keys file.
authorizedKeysBytes, err := ioutil.ReadFile("authorized_keys")
if err != nil {
log.Fatalf("Failed to load authorized_keys, err: %v", err)
}
authorizedKeysMap := map[string]bool{}
for len(authorizedKeysBytes) > 0 {
pubKey, _, _, rest, err := ssh.ParseAuthorizedKey(authorizedKeysBytes)
if err != nil {
log.Fatal(err)
}
authorizedKeysMap[string(pubKey.Marshal())] = true
authorizedKeysBytes = rest
}
// An SSH server is represented by a ServerConfig, which holds
// certificate details and handles authentication of ServerConns.
config := &ssh.ServerConfig{
// Remove to disable password auth.
PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
// Should use constant-time compare (or better, salt+hash) in
// a production setting.
@@ -28,16 +48,24 @@ func ExampleNewServerConn() {
}
return nil, fmt.Errorf("password rejected for %q", c.User())
},
// Remove to disable public key auth.
PublicKeyCallback: func(c ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error) {
if authorizedKeysMap[string(pubKey.Marshal())] {
return nil, nil
}
return nil, fmt.Errorf("unknown public key for %q", c.User())
},
}
privateBytes, err := ioutil.ReadFile("id_rsa")
if err != nil {
panic("Failed to load private key")
log.Fatal("Failed to load private key: ", err)
}
private, err := ssh.ParsePrivateKey(privateBytes)
if err != nil {
panic("Failed to parse private key")
log.Fatal("Failed to parse private key: ", err)
}
config.AddHostKey(private)
@@ -46,22 +74,24 @@ func ExampleNewServerConn() {
// accepted.
listener, err := net.Listen("tcp", "0.0.0.0:2022")
if err != nil {
panic("failed to listen for connection")
log.Fatal("failed to listen for connection: ", err)
}
nConn, err := listener.Accept()
if err != nil {
panic("failed to accept incoming connection")
log.Fatal("failed to accept incoming connection: ", err)
}
// Before use, a handshake must be performed on the incoming
// net.Conn.
_, chans, reqs, err := ssh.NewServerConn(nConn, config)
if err != nil {
panic("failed to handshake")
log.Fatal("failed to handshake: ", err)
}
// The incoming Request channel must be serviced.
go ssh.DiscardRequests(reqs)
// Service the incoming Channel channel.
// Service the incoming Channel channel.
for newChannel := range chans {
// Channels have a type, depending on the application level
@@ -74,7 +104,7 @@ func ExampleNewServerConn() {
}
channel, requests, err := newChannel.Accept()
if err != nil {
panic("could not accept channel.")
log.Fatalf("Could not accept channel: %v", err)
}
// Sessions have out-of-band requests such as "shell",
@@ -82,18 +112,7 @@ func ExampleNewServerConn() {
// "shell" request.
go func(in <-chan *ssh.Request) {
for req := range in {
ok := false
switch req.Type {
case "shell":
ok = true
if len(req.Payload) > 0 {
// We don't accept any
// commands, only the
// default shell.
ok = false
}
}
req.Reply(ok, nil)
req.Reply(req.Type == "shell", nil)
}
}(requests)
@@ -125,14 +144,14 @@ func ExampleDial() {
}
client, err := ssh.Dial("tcp", "yourserver.com:22", config)
if err != nil {
panic("Failed to dial: " + err.Error())
log.Fatal("Failed to dial: ", err)
}
// Each ClientConn can support multiple interactive sessions,
// represented by a Session.
session, err := client.NewSession()
if err != nil {
panic("Failed to create session: " + err.Error())
log.Fatal("Failed to create session: ", err)
}
defer session.Close()
@@ -141,7 +160,7 @@ func ExampleDial() {
var b bytes.Buffer
session.Stdout = &b
if err := session.Run("/usr/bin/whoami"); err != nil {
panic("Failed to run: " + err.Error())
log.Fatal("Failed to run: " + err.Error())
}
fmt.Println(b.String())
}
@@ -189,14 +208,14 @@ func ExampleClient_Listen() {
// Dial your ssh server.
conn, err := ssh.Dial("tcp", "localhost:22", config)
if err != nil {
log.Fatalf("unable to connect: %s", err)
log.Fatal("unable to connect: ", err)
}
defer conn.Close()
// Request the remote side to open port 8080 on all interfaces.
l, err := conn.Listen("tcp", "0.0.0.0:8080")
if err != nil {
log.Fatalf("unable to register tcp forward: %v", err)
log.Fatal("unable to register tcp forward: ", err)
}
defer l.Close()
@@ -217,13 +236,13 @@ func ExampleSession_RequestPty() {
// Connect to ssh server
conn, err := ssh.Dial("tcp", "localhost:22", config)
if err != nil {
log.Fatalf("unable to connect: %s", err)
log.Fatal("unable to connect: ", err)
}
defer conn.Close()
// Create a session
session, err := conn.NewSession()
if err != nil {
log.Fatalf("unable to create session: %s", err)
log.Fatal("unable to create session: ", err)
}
defer session.Close()
// Set up terminal modes
@@ -233,11 +252,11 @@ func ExampleSession_RequestPty() {
ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
}
// Request pseudo terminal
if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
log.Fatalf("request for pseudo terminal failed: %s", err)
if err := session.RequestPty("xterm", 40, 80, modes); err != nil {
log.Fatal("request for pseudo terminal failed: ", err)
}
// Start remote shell
if err := session.Shell(); err != nil {
log.Fatalf("failed to start shell: %s", err)
log.Fatal("failed to start shell: ", err)
}
}

30
vendor/golang.org/x/crypto/ssh/kex.go сгенерированный поставляемый
Просмотреть файл

@@ -77,11 +77,11 @@ type kexAlgorithm interface {
// dhGroup is a multiplicative group suitable for implementing Diffie-Hellman key agreement.
type dhGroup struct {
g, p *big.Int
g, p, pMinus1 *big.Int
}
func (group *dhGroup) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int, error) {
if theirPublic.Sign() <= 0 || theirPublic.Cmp(group.p) >= 0 {
if theirPublic.Cmp(bigOne) <= 0 || theirPublic.Cmp(group.pMinus1) >= 0 {
return nil, errors.New("ssh: DH parameter out of bounds")
}
return new(big.Int).Exp(theirPublic, myPrivate, group.p), nil
@@ -90,10 +90,17 @@ func (group *dhGroup) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int,
func (group *dhGroup) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) {
hashFunc := crypto.SHA1
x, err := rand.Int(randSource, group.p)
if err != nil {
return nil, err
var x *big.Int
for {
var err error
if x, err = rand.Int(randSource, group.pMinus1); err != nil {
return nil, err
}
if x.Sign() > 0 {
break
}
}
X := new(big.Int).Exp(group.g, x, group.p)
kexDHInit := kexDHInitMsg{
X: X,
@@ -146,9 +153,14 @@ func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handsha
return
}
y, err := rand.Int(randSource, group.p)
if err != nil {
return
var y *big.Int
for {
if y, err = rand.Int(randSource, group.pMinus1); err != nil {
return
}
if y.Sign() > 0 {
break
}
}
Y := new(big.Int).Exp(group.g, y, group.p)
@@ -373,6 +385,7 @@ func init() {
kexAlgoMap[kexAlgoDH1SHA1] = &dhGroup{
g: new(big.Int).SetInt64(2),
p: p,
pMinus1: new(big.Int).Sub(p, bigOne),
}
// This is the group called diffie-hellman-group14-sha1 in RFC
@@ -382,6 +395,7 @@ func init() {
kexAlgoMap[kexAlgoDH14SHA1] = &dhGroup{
g: new(big.Int).SetInt64(2),
p: p,
pMinus1: new(big.Int).Sub(p, bigOne),
}
kexAlgoMap[kexAlgoECDH521] = &ecdh{elliptic.P521()}

38
vendor/golang.org/x/crypto/ssh/keys.go сгенерированный поставляемый
Просмотреть файл

@@ -281,6 +281,12 @@ type PublicKey interface {
Verify(data []byte, sig *Signature) error
}
// CryptoPublicKey, if implemented by a PublicKey,
// returns the underlying crypto.PublicKey form of the key.
type CryptoPublicKey interface {
CryptoPublicKey() crypto.PublicKey
}
// A Signer can create signatures that verify against a public key.
type Signer interface {
// PublicKey returns an associated PublicKey instance.
@@ -348,6 +354,10 @@ func (r *rsaPublicKey) Verify(data []byte, sig *Signature) error {
return rsa.VerifyPKCS1v15((*rsa.PublicKey)(r), crypto.SHA1, digest, sig.Blob)
}
func (r *rsaPublicKey) CryptoPublicKey() crypto.PublicKey {
return (*rsa.PublicKey)(r)
}
type dsaPublicKey dsa.PublicKey
func (r *dsaPublicKey) Type() string {
@@ -416,6 +426,10 @@ func (k *dsaPublicKey) Verify(data []byte, sig *Signature) error {
return errors.New("ssh: signature did not verify")
}
func (k *dsaPublicKey) CryptoPublicKey() crypto.PublicKey {
return (*dsa.PublicKey)(k)
}
type dsaPrivateKey struct {
*dsa.PrivateKey
}
@@ -509,6 +523,10 @@ func (key ed25519PublicKey) Verify(b []byte, sig *Signature) error {
return nil
}
func (k ed25519PublicKey) CryptoPublicKey() crypto.PublicKey {
return ed25519.PublicKey(k)
}
func supportedEllipticCurve(curve elliptic.Curve) bool {
return curve == elliptic.P256() || curve == elliptic.P384() || curve == elliptic.P521()
}
@@ -604,6 +622,10 @@ func (key *ecdsaPublicKey) Verify(data []byte, sig *Signature) error {
return errors.New("ssh: signature did not verify")
}
func (k *ecdsaPublicKey) CryptoPublicKey() crypto.PublicKey {
return (*ecdsa.PublicKey)(k)
}
// NewSignerFromKey takes an *rsa.PrivateKey, *dsa.PrivateKey,
// *ecdsa.PrivateKey or any other crypto.Signer and returns a corresponding
// Signer instance. ECDSA keys must use P-256, P-384 or P-521.
@@ -700,8 +722,8 @@ func (s *wrappedSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
}
// NewPublicKey takes an *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey,
// ed25519.PublicKey, or any other crypto.Signer and returns a corresponding
// Signer instance. ECDSA keys must use P-256, P-384 or P-521.
// or ed25519.PublicKey returns a corresponding PublicKey instance.
// ECDSA keys must use P-256, P-384 or P-521.
func NewPublicKey(key interface{}) (PublicKey, error) {
switch key := key.(type) {
case *rsa.PublicKey:
@@ -731,6 +753,14 @@ func ParsePrivateKey(pemBytes []byte) (Signer, error) {
return NewSignerFromKey(key)
}
// encryptedBlock tells whether a private key is
// encrypted by examining its Proc-Type header
// for a mention of ENCRYPTED
// according to RFC 1421 Section 4.6.1.1.
func encryptedBlock(block *pem.Block) bool {
return strings.Contains(block.Headers["Proc-Type"], "ENCRYPTED")
}
// ParseRawPrivateKey returns a private key from a PEM encoded private key. It
// supports RSA (PKCS#1), DSA (OpenSSL), and ECDSA private keys.
func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {
@@ -739,6 +769,10 @@ func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {
return nil, errors.New("ssh: no key found")
}
if encryptedBlock(block) {
return nil, errors.New("ssh: cannot decode encrypted private keys")
}
switch block.Type {
case "RSA PRIVATE KEY":
return x509.ParsePKCS1PrivateKey(block.Bytes)

34
vendor/golang.org/x/crypto/ssh/keys_test.go сгенерированный поставляемый
Просмотреть файл

@@ -132,6 +132,22 @@ func TestParseECPrivateKey(t *testing.T) {
}
}
// See Issue https://github.com/golang/go/issues/6650.
func TestParseEncryptedPrivateKeysFails(t *testing.T) {
const wantSubstring = "encrypted"
for i, tt := range testdata.PEMEncryptedKeys {
_, err := ParsePrivateKey(tt.PEMBytes)
if err == nil {
t.Errorf("#%d key %s: ParsePrivateKey successfully parsed, expected an error", i, tt.Name)
continue
}
if !strings.Contains(err.Error(), wantSubstring) {
t.Errorf("#%d key %s: got error %q, want substring %q", i, tt.Name, err, wantSubstring)
}
}
}
func TestParseDSA(t *testing.T) {
// We actually exercise the ParsePrivateKey codepath here, as opposed to
// using the ParseRawPrivateKey+NewSignerFromKey path that testdata_test.go
@@ -309,14 +325,14 @@ func TestInvalidEntry(t *testing.T) {
}
var knownHostsParseTests = []struct {
input string
err string
input string
err string
marker string
comment string
hosts []string
rest string
} {
marker string
comment string
hosts []string
rest string
}{
{
"",
"EOF",
@@ -375,13 +391,13 @@ var knownHostsParseTests = []struct {
"localhost,[host2:123]\tssh-rsa {RSAPUB}\tcomment comment",
"",
"", "comment comment", []string{"localhost","[host2:123]"}, "",
"", "comment comment", []string{"localhost", "[host2:123]"}, "",
},
{
"@marker \tlocalhost,[host2:123]\tssh-rsa {RSAPUB}",
"",
"marker", "", []string{"localhost","[host2:123]"}, "",
"marker", "", []string{"localhost", "[host2:123]"}, "",
},
{
"@marker \tlocalhost,[host2:123]\tssh-rsa aabbccdd",

73
vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,73 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build solaris
package terminal // import "golang.org/x/crypto/ssh/terminal"
import (
"golang.org/x/sys/unix"
"io"
"syscall"
)
// State contains the state of a terminal.
type State struct {
termios syscall.Termios
}
// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd int) bool {
// see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c
var termio unix.Termio
err := unix.IoctlSetTermio(fd, unix.TCGETA, &termio)
return err == nil
}
// ReadPassword reads a line of input from a terminal without local echo. This
// is commonly used for inputting passwords and other sensitive data. The slice
// returned does not include the \n.
func ReadPassword(fd int) ([]byte, error) {
// see also: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libast/common/uwin/getpass.c
val, err := unix.IoctlGetTermios(fd, unix.TCGETS)
if err != nil {
return nil, err
}
oldState := *val
newState := oldState
newState.Lflag &^= syscall.ECHO
newState.Lflag |= syscall.ICANON | syscall.ISIG
newState.Iflag |= syscall.ICRNL
err = unix.IoctlSetTermios(fd, unix.TCSETS, &newState)
if err != nil {
return nil, err
}
defer unix.IoctlSetTermios(fd, unix.TCSETS, &oldState)
var buf [16]byte
var ret []byte
for {
n, err := syscall.Read(fd, buf[:])
if err != nil {
return nil, err
}
if n == 0 {
if len(ret) == 0 {
return nil, io.EOF
}
break
}
if buf[n-1] == '\n' {
n--
}
ret = append(ret, buf[:n]...)
if n < len(buf) {
break
}
}
return ret, nil
}

63
vendor/golang.org/x/crypto/ssh/testdata/keys.go сгенерированный поставляемый
Просмотреть файл

@@ -55,3 +55,66 @@ PLL8IEwvYu2wq+lpXfGQnNMbzYf9gspG0w==
-----END EC PRIVATE KEY-----
`),
}
var PEMEncryptedKeys = []struct {
Name string
EncryptionKey string
PEMBytes []byte
}{
0: {
Name: "rsa-encrypted",
EncryptionKey: "r54-G0pher_t3st$",
PEMBytes: []byte(`-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,3E1714DE130BC5E81327F36564B05462
MqW88sud4fnWk/Jk3fkjh7ydu51ZkHLN5qlQgA4SkAXORPPMj2XvqZOv1v2LOgUV
dUevUn8PZK7a9zbZg4QShUSzwE5k6wdB7XKPyBgI39mJ79GBd2U4W3h6KT6jIdWA
goQpluxkrzr2/X602IaxLEre97FT9mpKC6zxKCLvyFWVIP9n3OSFS47cTTXyFr+l
7PdRhe60nn6jSBgUNk/Q1lAvEQ9fufdPwDYY93F1wyJ6lOr0F1+mzRrMbH67NyKs
rG8J1Fa7cIIre7ueKIAXTIne7OAWqpU9UDgQatDtZTbvA7ciqGsSFgiwwW13N+Rr
hN8MkODKs9cjtONxSKi05s206A3NDU6STtZ3KuPDjFE1gMJODotOuqSM+cxKfyFq
wxpk/CHYCDdMAVBSwxb/vraOHamylL4uCHpJdBHypzf2HABt+lS8Su23uAmL87DR
yvyCS/lmpuNTndef6qHPRkoW2EV3xqD3ovosGf7kgwGJUk2ZpCLVteqmYehKlZDK
r/Jy+J26ooI2jIg9bjvD1PZq+Mv+2dQ1RlDrPG3PB+rEixw6vBaL9x3jatCd4ej7
XG7lb3qO9xFpLsx89tkEcvpGR+broSpUJ6Mu5LBCVmrvqHjvnDhrZVz1brMiQtU9
iMZbgXqDLXHd6ERWygk7OTU03u+l1gs+KGMfmS0h0ZYw6KGVLgMnsoxqd6cFSKNB
8Ohk9ZTZGCiovlXBUepyu8wKat1k8YlHSfIHoRUJRhhcd7DrmojC+bcbMIZBU22T
Pl2ftVRGtcQY23lYd0NNKfebF7ncjuLWQGy+vZW+7cgfI6wPIbfYfP6g7QAutk6W
KQx0AoX5woZ6cNxtpIrymaVjSMRRBkKQrJKmRp3pC/lul5E5P2cueMs1fj4OHTbJ
lAUv88ywr+R+mRgYQlFW/XQ653f6DT4t6+njfO9oBcPrQDASZel3LjXLpjjYG/N5
+BWnVexuJX9ika8HJiFl55oqaKb+WknfNhk5cPY+x7SDV9ywQeMiDZpr0ffeYAEP
LlwwiWRDYpO+uwXHSFF3+JjWwjhs8m8g99iFb7U93yKgBB12dCEPPa2ZeH9wUHMJ
sreYhNuq6f4iWWSXpzN45inQqtTi8jrJhuNLTT543ErW7DtntBO2rWMhff3aiXbn
Uy3qzZM1nPbuCGuBmP9L2dJ3Z5ifDWB4JmOyWY4swTZGt9AVmUxMIKdZpRONx8vz
I9u9nbVPGZBcou50Pa0qTLbkWsSL94MNXrARBxzhHC9Zs6XNEtwN7mOuii7uMkVc
adrxgknBH1J1N+NX/eTKzUwJuPvDtA+Z5ILWNN9wpZT/7ed8zEnKHPNUexyeT5g3
uw9z9jH7ffGxFYlx87oiVPHGOrCXYZYW5uoZE31SCBkbtNuffNRJRKIFeipmpJ3P
7bpAG+kGHMelQH6b+5K1Qgsv4tpuSyKeTKpPFH9Av5nN4P1ZBm9N80tzbNWqjSJm
S7rYdHnuNEVnUGnRmEUMmVuYZnNBEVN/fP2m2SEwXcP3Uh7TiYlcWw10ygaGmOr7
MvMLGkYgQ4Utwnd98mtqa0jr0hK2TcOSFir3AqVvXN3XJj4cVULkrXe4Im1laWgp
-----END RSA PRIVATE KEY-----
`),
},
1: {
Name: "dsa-encrypted",
EncryptionKey: "qG0pher-dsa_t3st$",
PEMBytes: []byte(`-----BEGIN DSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,7CE7A6E4A647DC01AF860210B15ADE3E
hvnBpI99Hceq/55pYRdOzBLntIEis02JFNXuLEydWL+RJBFDn7tA+vXec0ERJd6J
G8JXlSOAhmC2H4uK3q2xR8/Y3yL95n6OIcjvCBiLsV+o3jj1MYJmErxP6zRtq4w3
JjIjGHWmaYFSxPKQ6e8fs74HEqaeMV9ONUoTtB+aISmgaBL15Fcoayg245dkBvVl
h5Kqspe7yvOBmzA3zjRuxmSCqKJmasXM7mqs3vIrMxZE3XPo1/fWKcPuExgpVQoT
HkJZEoIEIIPnPMwT2uYbFJSGgPJVMDT84xz7yvjCdhLmqrsXgs5Qw7Pw0i0c0BUJ
b7fDJ2UhdiwSckWGmIhTLlJZzr8K+JpjCDlP+REYBI5meB7kosBnlvCEHdw2EJkH
0QDc/2F4xlVrHOLbPRFyu1Oi2Gvbeoo9EsM/DThpd1hKAlb0sF5Y0y0d+owv0PnE
R/4X3HWfIdOHsDUvJ8xVWZ4BZk9Zk9qol045DcFCehpr/3hslCrKSZHakLt9GI58
vVQJ4L0aYp5nloLfzhViZtKJXRLkySMKdzYkIlNmW1oVGl7tce5UCNI8Nok4j6yn
IiHM7GBn+0nJoKTXsOGMIBe3ulKlKVxLjEuk9yivh/8=
-----END DSA PRIVATE KEY-----
`),
},
}

25
vendor/golang.org/x/image/tiff/reader.go сгенерированный поставляемый
Просмотреть файл

@@ -118,8 +118,9 @@ func (d *decoder) ifdUint(p []byte) (u []uint, err error) {
}
// parseIFD decides whether the the IFD entry in p is "interesting" and
// stows away the data in the decoder.
func (d *decoder) parseIFD(p []byte) error {
// stows away the data in the decoder. It returns the tag number of the
// entry and an error, if any.
func (d *decoder) parseIFD(p []byte) (int, error) {
tag := d.byteOrder.Uint16(p[0:2])
switch tag {
case tBitsPerSample,
@@ -138,17 +139,17 @@ func (d *decoder) parseIFD(p []byte) error {
tImageWidth:
val, err := d.ifdUint(p)
if err != nil {
return err
return 0, err
}
d.features[int(tag)] = val
case tColorMap:
val, err := d.ifdUint(p)
if err != nil {
return err
return 0, err
}
numcolors := len(val) / 3
if len(val)%3 != 0 || numcolors <= 0 || numcolors > 256 {
return FormatError("bad ColorMap length")
return 0, FormatError("bad ColorMap length")
}
d.palette = make([]color.Color, numcolors)
for i := 0; i < numcolors; i++ {
@@ -166,15 +167,15 @@ func (d *decoder) parseIFD(p []byte) error {
// must terminate the import process gracefully.
val, err := d.ifdUint(p)
if err != nil {
return err
return 0, err
}
for _, v := range val {
if v != 1 {
return UnsupportedError("sample format")
return 0, UnsupportedError("sample format")
}
}
}
return nil
return int(tag), nil
}
// readBits reads n bits from the internal buffer starting at the current offset.
@@ -428,10 +429,16 @@ func newDecoder(r io.Reader) (*decoder, error) {
return nil, err
}
prevTag := -1
for i := 0; i < len(p); i += ifdLen {
if err := d.parseIFD(p[i : i+ifdLen]); err != nil {
tag, err := d.parseIFD(p[i : i+ifdLen])
if err != nil {
return nil, err
}
if tag <= prevTag {
return nil, FormatError("tags are not sorted in ascending order")
}
prevTag = tag
}
d.config.Width = int(d.firstVal(tImageWidth))

18
vendor/golang.org/x/image/tiff/reader_test.go сгенерированный поставляемый
Просмотреть файл

@@ -192,6 +192,24 @@ func TestDecodeLZW(t *testing.T) {
compare(t, img0, img1)
}
// TestDecodeTagOrder tests that a malformed image with unsorted IFD entries is
// correctly rejected.
func TestDecodeTagOrder(t *testing.T) {
data, err := ioutil.ReadFile("../testdata/video-001.tiff")
if err != nil {
t.Fatal(err)
}
// Swap the first two IFD entries.
ifdOffset := int64(binary.LittleEndian.Uint32(data[4:8]))
for i := ifdOffset + 2; i < ifdOffset+14; i++ {
data[i], data[i+12] = data[i+12], data[i]
}
if _, _, err := image.Decode(bytes.NewReader(data)); err == nil {
t.Fatal("got nil error, want non-nil")
}
}
// TestDecompress tests that decoding some TIFF images that use different
// compression formats result in the same pixel data.
func TestDecompress(t *testing.T) {

34
vendor/golang.org/x/image/vector/acc_amd64.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,34 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !appengine
// +build gc
// +build go1.6
// +build !noasm
package vector
func haveSSE4_1() bool
var haveFixedAccumulateSIMD = haveSSE4_1()
const haveFloatingAccumulateSIMD = true
//go:noescape
func fixedAccumulateOpOverSIMD(dst []uint8, src []uint32)
//go:noescape
func fixedAccumulateOpSrcSIMD(dst []uint8, src []uint32)
//go:noescape
func fixedAccumulateMaskSIMD(buf []uint32)
//go:noescape
func floatingAccumulateOpOverSIMD(dst []uint8, src []float32)
//go:noescape
func floatingAccumulateOpSrcSIMD(dst []uint8, src []float32)
//go:noescape
func floatingAccumulateMaskSIMD(dst []uint32, src []float32)

1083
vendor/golang.org/x/image/vector/acc_amd64.s сгенерированный поставляемый Обычный файл

Разница между файлами не показана из-за своего большого размера Загрузить разницу

17
vendor/golang.org/x/image/vector/acc_other.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,17 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !amd64 appengine !gc !go1.6 noasm
package vector
const haveFixedAccumulateSIMD = false
const haveFloatingAccumulateSIMD = false
func fixedAccumulateOpOverSIMD(dst []uint8, src []uint32) {}
func fixedAccumulateOpSrcSIMD(dst []uint8, src []uint32) {}
func fixedAccumulateMaskSIMD(buf []uint32) {}
func floatingAccumulateOpOverSIMD(dst []uint8, src []float32) {}
func floatingAccumulateOpSrcSIMD(dst []uint8, src []float32) {}
func floatingAccumulateMaskSIMD(dst []uint32, src []float32) {}

651
vendor/golang.org/x/image/vector/acc_test.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,651 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package vector
import (
"bytes"
"fmt"
"math/rand"
"testing"
)
// TestDivideByFFFF tests that dividing by 0xffff is equivalent to multiplying
// and then shifting by magic constants. The Go compiler itself issues this
// multiply-and-shift for a division by the constant value 0xffff. This trick
// is used in the asm code as the GOARCH=amd64 SIMD instructions have parallel
// multiply but not parallel divide.
//
// There's undoubtedly a justification somewhere in Hacker's Delight chapter 10
// "Integer Division by Constants", but I don't have a more specific link.
//
// http://www.hackersdelight.org/divcMore.pdf and
// http://www.hackersdelight.org/magic.htm
func TestDivideByFFFF(t *testing.T) {
const mul, shift = 0x80008001, 47
rng := rand.New(rand.NewSource(1))
for i := 0; i < 20000; i++ {
u := rng.Uint32()
got := uint32((uint64(u) * mul) >> shift)
want := u / 0xffff
if got != want {
t.Fatalf("i=%d, u=%#08x: got %#08x, want %#08x", i, u, got, want)
}
}
}
// TestXxxSIMDUnaligned tests that unaligned SIMD loads/stores don't crash.
func TestFixedAccumulateSIMDUnaligned(t *testing.T) {
if !haveFixedAccumulateSIMD {
t.Skip("No SIMD implemention")
}
dst := make([]uint8, 64)
src := make([]uint32, 64)
for d := 0; d < 16; d++ {
for s := 0; s < 16; s++ {
fixedAccumulateOpSrcSIMD(dst[d:d+32], src[s:s+32])
}
}
}
func TestFloatingAccumulateSIMDUnaligned(t *testing.T) {
if !haveFloatingAccumulateSIMD {
t.Skip("No SIMD implemention")
}
dst := make([]uint8, 64)
src := make([]float32, 64)
for d := 0; d < 16; d++ {
for s := 0; s < 16; s++ {
floatingAccumulateOpSrcSIMD(dst[d:d+32], src[s:s+32])
}
}
}
// TestXxxSIMDShortDst tests that the SIMD implementations don't write past the
// end of the dst buffer.
func TestFixedAccumulateSIMDShortDst(t *testing.T) {
if !haveFixedAccumulateSIMD {
t.Skip("No SIMD implemention")
}
const oneQuarter = uint32(int2ϕ(fxOne*fxOne)) / 4
src := []uint32{oneQuarter, oneQuarter, oneQuarter, oneQuarter}
for i := 0; i < 4; i++ {
dst := make([]uint8, 4)
fixedAccumulateOpSrcSIMD(dst[:i], src[:i])
for j := range dst {
if j < i {
if got := dst[j]; got == 0 {
t.Errorf("i=%d, j=%d: got %#02x, want non-zero", i, j, got)
}
} else {
if got := dst[j]; got != 0 {
t.Errorf("i=%d, j=%d: got %#02x, want zero", i, j, got)
}
}
}
}
}
func TestFloatingAccumulateSIMDShortDst(t *testing.T) {
if !haveFloatingAccumulateSIMD {
t.Skip("No SIMD implemention")
}
const oneQuarter = 0.25
src := []float32{oneQuarter, oneQuarter, oneQuarter, oneQuarter}
for i := 0; i < 4; i++ {
dst := make([]uint8, 4)
floatingAccumulateOpSrcSIMD(dst[:i], src[:i])
for j := range dst {
if j < i {
if got := dst[j]; got == 0 {
t.Errorf("i=%d, j=%d: got %#02x, want non-zero", i, j, got)
}
} else {
if got := dst[j]; got != 0 {
t.Errorf("i=%d, j=%d: got %#02x, want zero", i, j, got)
}
}
}
}
}
func TestFixedAccumulateOpOverShort(t *testing.T) { testAcc(t, fxInShort, fxMaskShort, "over") }
func TestFixedAccumulateOpSrcShort(t *testing.T) { testAcc(t, fxInShort, fxMaskShort, "src") }
func TestFixedAccumulateMaskShort(t *testing.T) { testAcc(t, fxInShort, fxMaskShort, "mask") }
func TestFloatingAccumulateOpOverShort(t *testing.T) { testAcc(t, flInShort, flMaskShort, "over") }
func TestFloatingAccumulateOpSrcShort(t *testing.T) { testAcc(t, flInShort, flMaskShort, "src") }
func TestFloatingAccumulateMaskShort(t *testing.T) { testAcc(t, flInShort, flMaskShort, "mask") }
func TestFixedAccumulateOpOver16(t *testing.T) { testAcc(t, fxIn16, fxMask16, "over") }
func TestFixedAccumulateOpSrc16(t *testing.T) { testAcc(t, fxIn16, fxMask16, "src") }
func TestFixedAccumulateMask16(t *testing.T) { testAcc(t, fxIn16, fxMask16, "mask") }
func TestFloatingAccumulateOpOver16(t *testing.T) { testAcc(t, flIn16, flMask16, "over") }
func TestFloatingAccumulateOpSrc16(t *testing.T) { testAcc(t, flIn16, flMask16, "src") }
func TestFloatingAccumulateMask16(t *testing.T) { testAcc(t, flIn16, flMask16, "mask") }
func testAcc(t *testing.T, in interface{}, mask []uint32, op string) {
for _, simd := range []bool{false, true} {
maxN := 0
switch in := in.(type) {
case []uint32:
if simd && !haveFixedAccumulateSIMD {
continue
}
maxN = len(in)
case []float32:
if simd && !haveFloatingAccumulateSIMD {
continue
}
maxN = len(in)
}
for _, n := range []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
33, 55, 79, 96, 120, 165, 256, maxN} {
if n > maxN {
continue
}
var (
got8, want8 []uint8
got32, want32 []uint32
)
switch op {
case "over":
const background = 0x40
got8 = make([]uint8, n)
for i := range got8 {
got8[i] = background
}
want8 = make([]uint8, n)
for i := range want8 {
dstA := uint32(background * 0x101)
maskA := mask[i]
outA := dstA*(0xffff-maskA)/0xffff + maskA
want8[i] = uint8(outA >> 8)
}
case "src":
got8 = make([]uint8, n)
want8 = make([]uint8, n)
for i := range want8 {
want8[i] = uint8(mask[i] >> 8)
}
case "mask":
got32 = make([]uint32, n)
want32 = mask[:n]
}
switch in := in.(type) {
case []uint32:
switch op {
case "over":
if simd {
fixedAccumulateOpOverSIMD(got8, in[:n])
} else {
fixedAccumulateOpOver(got8, in[:n])
}
case "src":
if simd {
fixedAccumulateOpSrcSIMD(got8, in[:n])
} else {
fixedAccumulateOpSrc(got8, in[:n])
}
case "mask":
copy(got32, in[:n])
if simd {
fixedAccumulateMaskSIMD(got32)
} else {
fixedAccumulateMask(got32)
}
}
case []float32:
switch op {
case "over":
if simd {
floatingAccumulateOpOverSIMD(got8, in[:n])
} else {
floatingAccumulateOpOver(got8, in[:n])
}
case "src":
if simd {
floatingAccumulateOpSrcSIMD(got8, in[:n])
} else {
floatingAccumulateOpSrc(got8, in[:n])
}
case "mask":
if simd {
floatingAccumulateMaskSIMD(got32, in[:n])
} else {
floatingAccumulateMask(got32, in[:n])
}
}
}
if op != "mask" {
if !bytes.Equal(got8, want8) {
t.Errorf("simd=%t, n=%d:\ngot: % x\nwant: % x", simd, n, got8, want8)
}
} else {
if !uint32sEqual(got32, want32) {
t.Errorf("simd=%t, n=%d:\ngot: % x\nwant: % x", simd, n, got32, want32)
}
}
}
}
}
func uint32sEqual(xs, ys []uint32) bool {
if len(xs) != len(ys) {
return false
}
for i := range xs {
if xs[i] != ys[i] {
return false
}
}
return true
}
func float32sEqual(xs, ys []float32) bool {
if len(xs) != len(ys) {
return false
}
for i := range xs {
if xs[i] != ys[i] {
return false
}
}
return true
}
func BenchmarkFixedAccumulateOpOver16(b *testing.B) { benchAcc(b, fxIn16, "over", false) }
func BenchmarkFixedAccumulateOpOverSIMD16(b *testing.B) { benchAcc(b, fxIn16, "over", true) }
func BenchmarkFixedAccumulateOpSrc16(b *testing.B) { benchAcc(b, fxIn16, "src", false) }
func BenchmarkFixedAccumulateOpSrcSIMD16(b *testing.B) { benchAcc(b, fxIn16, "src", true) }
func BenchmarkFixedAccumulateMask16(b *testing.B) { benchAcc(b, fxIn16, "mask", false) }
func BenchmarkFixedAccumulateMaskSIMD16(b *testing.B) { benchAcc(b, fxIn16, "mask", true) }
func BenchmarkFloatingAccumulateOpOver16(b *testing.B) { benchAcc(b, flIn16, "over", false) }
func BenchmarkFloatingAccumulateOpOverSIMD16(b *testing.B) { benchAcc(b, flIn16, "over", true) }
func BenchmarkFloatingAccumulateOpSrc16(b *testing.B) { benchAcc(b, flIn16, "src", false) }
func BenchmarkFloatingAccumulateOpSrcSIMD16(b *testing.B) { benchAcc(b, flIn16, "src", true) }
func BenchmarkFloatingAccumulateMask16(b *testing.B) { benchAcc(b, flIn16, "mask", false) }
func BenchmarkFloatingAccumulateMaskSIMD16(b *testing.B) { benchAcc(b, flIn16, "mask", true) }
func BenchmarkFixedAccumulateOpOver64(b *testing.B) { benchAcc(b, fxIn64, "over", false) }
func BenchmarkFixedAccumulateOpOverSIMD64(b *testing.B) { benchAcc(b, fxIn64, "over", true) }
func BenchmarkFixedAccumulateOpSrc64(b *testing.B) { benchAcc(b, fxIn64, "src", false) }
func BenchmarkFixedAccumulateOpSrcSIMD64(b *testing.B) { benchAcc(b, fxIn64, "src", true) }
func BenchmarkFixedAccumulateMask64(b *testing.B) { benchAcc(b, fxIn64, "mask", false) }
func BenchmarkFixedAccumulateMaskSIMD64(b *testing.B) { benchAcc(b, fxIn64, "mask", true) }
func BenchmarkFloatingAccumulateOpOver64(b *testing.B) { benchAcc(b, flIn64, "over", false) }
func BenchmarkFloatingAccumulateOpOverSIMD64(b *testing.B) { benchAcc(b, flIn64, "over", true) }
func BenchmarkFloatingAccumulateOpSrc64(b *testing.B) { benchAcc(b, flIn64, "src", false) }
func BenchmarkFloatingAccumulateOpSrcSIMD64(b *testing.B) { benchAcc(b, flIn64, "src", true) }
func BenchmarkFloatingAccumulateMask64(b *testing.B) { benchAcc(b, flIn64, "mask", false) }
func BenchmarkFloatingAccumulateMaskSIMD64(b *testing.B) { benchAcc(b, flIn64, "mask", true) }
func benchAcc(b *testing.B, in interface{}, op string, simd bool) {
var f func()
switch in := in.(type) {
case []uint32:
if simd && !haveFixedAccumulateSIMD {
b.Skip("No SIMD implemention")
}
switch op {
case "over":
dst := make([]uint8, len(in))
if simd {
f = func() { fixedAccumulateOpOverSIMD(dst, in) }
} else {
f = func() { fixedAccumulateOpOver(dst, in) }
}
case "src":
dst := make([]uint8, len(in))
if simd {
f = func() { fixedAccumulateOpSrcSIMD(dst, in) }
} else {
f = func() { fixedAccumulateOpSrc(dst, in) }
}
case "mask":
buf := make([]uint32, len(in))
copy(buf, in)
if simd {
f = func() { fixedAccumulateMaskSIMD(buf) }
} else {
f = func() { fixedAccumulateMask(buf) }
}
}
case []float32:
if simd && !haveFloatingAccumulateSIMD {
b.Skip("No SIMD implemention")
}
switch op {
case "over":
dst := make([]uint8, len(in))
if simd {
f = func() { floatingAccumulateOpOverSIMD(dst, in) }
} else {
f = func() { floatingAccumulateOpOver(dst, in) }
}
case "src":
dst := make([]uint8, len(in))
if simd {
f = func() { floatingAccumulateOpSrcSIMD(dst, in) }
} else {
f = func() { floatingAccumulateOpSrc(dst, in) }
}
case "mask":
dst := make([]uint32, len(in))
if simd {
f = func() { floatingAccumulateMaskSIMD(dst, in) }
} else {
f = func() { floatingAccumulateMask(dst, in) }
}
}
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
f()
}
}
// itou exists because "uint32(int2ϕ(-1))" doesn't compile: constant -1
// overflows uint32.
func itou(i int2ϕ) uint32 {
return uint32(i)
}
var fxInShort = []uint32{
itou(+0x08000), // +0.125, // Running sum: +0.125
itou(-0x20000), // -0.500, // Running sum: -0.375
itou(+0x10000), // +0.250, // Running sum: -0.125
itou(+0x18000), // +0.375, // Running sum: +0.250
itou(+0x08000), // +0.125, // Running sum: +0.375
itou(+0x00000), // +0.000, // Running sum: +0.375
itou(-0x40000), // -1.000, // Running sum: -0.625
itou(-0x20000), // -0.500, // Running sum: -1.125
itou(+0x10000), // +0.250, // Running sum: -0.875
itou(+0x38000), // +0.875, // Running sum: +0.000
itou(+0x10000), // +0.250, // Running sum: +0.250
itou(+0x30000), // +0.750, // Running sum: +1.000
}
var flInShort = []float32{
+0.125, // Running sum: +0.125
-0.500, // Running sum: -0.375
+0.250, // Running sum: -0.125
+0.375, // Running sum: +0.250
+0.125, // Running sum: +0.375
+0.000, // Running sum: +0.375
-1.000, // Running sum: -0.625
-0.500, // Running sum: -1.125
+0.250, // Running sum: -0.875
+0.875, // Running sum: +0.000
+0.250, // Running sum: +0.250
+0.750, // Running sum: +1.000
}
// It's OK for fxMaskShort and flMaskShort to have slightly different values.
// Both the fixed and floating point implementations already have (different)
// rounding errors in the xxxLineTo methods before we get to accumulation. It's
// OK for 50% coverage (in ideal math) to be approximated by either 0x7fff or
// 0x8000. Both slices do contain checks that 0% and 100% map to 0x0000 and
// 0xffff, as does checkCornersCenter in vector_test.go.
//
// It is important, though, for the SIMD and non-SIMD fixed point
// implementations to give the exact same output, and likewise for the floating
// point implementations.
var fxMaskShort = []uint32{
0x2000,
0x6000,
0x2000,
0x4000,
0x6000,
0x6000,
0xa000,
0xffff,
0xe000,
0x0000,
0x4000,
0xffff,
}
var flMaskShort = []uint32{
0x1fff,
0x5fff,
0x1fff,
0x3fff,
0x5fff,
0x5fff,
0x9fff,
0xffff,
0xdfff,
0x0000,
0x3fff,
0xffff,
}
func TestMakeFxInXxx(t *testing.T) {
dump := func(us []uint32) string {
var b bytes.Buffer
for i, u := range us {
if i%8 == 0 {
b.WriteByte('\n')
}
fmt.Fprintf(&b, "%#08x, ", u)
}
return b.String()
}
if !uint32sEqual(fxIn16, hardCodedFxIn16) {
t.Errorf("height 16: got:%v\nwant:%v", dump(fxIn16), dump(hardCodedFxIn16))
}
}
func TestMakeFlInXxx(t *testing.T) {
dump := func(fs []float32) string {
var b bytes.Buffer
for i, f := range fs {
if i%8 == 0 {
b.WriteByte('\n')
}
fmt.Fprintf(&b, "%v, ", f)
}
return b.String()
}
if !float32sEqual(flIn16, hardCodedFlIn16) {
t.Errorf("height 16: got:%v\nwant:%v", dump(flIn16), dump(hardCodedFlIn16))
}
}
func makeInXxx(height int, useFloatingPointMath bool) *Rasterizer {
width, data := scaledBenchmarkGlyphData(height)
z := NewRasterizer(width, height)
z.setUseFloatingPointMath(useFloatingPointMath)
for _, d := range data {
switch d.n {
case 0:
z.MoveTo(d.px, d.py)
case 1:
z.LineTo(d.px, d.py)
case 2:
z.QuadTo(d.px, d.py, d.qx, d.qy)
}
}
return z
}
func makeFxInXxx(height int) []uint32 {
z := makeInXxx(height, false)
return z.bufU32
}
func makeFlInXxx(height int) []float32 {
z := makeInXxx(height, true)
return z.bufF32
}
// fxInXxx and flInXxx are the z.bufU32 and z.bufF32 inputs to the accumulate
// functions when rasterizing benchmarkGlyphData at a height of Xxx pixels.
//
// fxMaskXxx and flMaskXxx are the corresponding golden outputs of those
// accumulateMask functions.
//
// The hardCodedEtc versions are a sanity check for unexpected changes in the
// rasterization implementations up to but not including accumulation.
var (
fxIn16 = makeFxInXxx(16)
fxIn64 = makeFxInXxx(64)
flIn16 = makeFlInXxx(16)
flIn64 = makeFlInXxx(64)
)
var hardCodedFxIn16 = []uint32{
0x00000000, 0x00000000, 0xffffe91d, 0xfffe7c4a, 0xfffeaa9f, 0xffff4e33, 0xffffc1c5, 0x00007782,
0x00009619, 0x0001a857, 0x000129e9, 0x00000028, 0x00000000, 0x00000000, 0xffff6e70, 0xfffd3199,
0xffff5ff8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00014b29,
0x0002acf3, 0x000007e2, 0xffffca5a, 0xfffcab73, 0xffff8a34, 0x00001b55, 0x0001b334, 0x0001449e,
0x0000434d, 0xffff62ec, 0xfffe1443, 0xffff325d, 0x00000000, 0x0002234a, 0x0001dcb6, 0xfffe2948,
0xfffdd6b8, 0x00000000, 0x00028cc0, 0x00017340, 0x00000000, 0x00000000, 0x00000000, 0xffffd2d6,
0xfffcadd0, 0xffff7f5c, 0x00007400, 0x00038c00, 0xfffe9260, 0xffff2da0, 0x0000023a, 0x0002259b,
0x0000182a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xfffdc600, 0xfffe3a00, 0x00000059,
0x0003a44d, 0x00005b59, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0xfffe33f3, 0xfffdcc0d, 0x00000000, 0x00033c02, 0x0000c3fe, 0x00000000,
0x00000000, 0xffffa13d, 0xfffeeec8, 0xffff8c02, 0xffff8c48, 0xffffc7b5, 0x00000000, 0xffff5b68,
0xffff3498, 0x00000000, 0x00033c00, 0x0000c400, 0xffff9bc4, 0xfffdf4a3, 0xfffe8df3, 0xffffe1a8,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00033c00,
0x000092c7, 0xfffcf373, 0xffff3dc7, 0x00000fcc, 0x00011ae7, 0x000130c3, 0x0000680d, 0x00004a59,
0x00000a20, 0xfffe9dc4, 0xfffe4a3c, 0x00000000, 0x00033c00, 0xfffe87ef, 0xfffe3c11, 0x0000105e,
0x0002b9c4, 0x000135dc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xfffe3600, 0xfffdca00,
0x00000000, 0x00033c00, 0xfffd9000, 0xffff3400, 0x0000e400, 0x00031c00, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0xfffe3600, 0xfffdca00, 0x00000000, 0x00033c00, 0xfffcf9a5,
0xffffca5b, 0x000120e6, 0x0002df1a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0xfffdb195, 0xfffe4e6b, 0x00000000, 0x00033c00, 0xfffd9e00, 0xffff2600, 0x00002f0e, 0x00033ea3,
0x0000924d, 0x00000000, 0x00000000, 0x00000000, 0xfffe83b3, 0xfffd881d, 0xfffff431, 0x00000000,
0x00031f60, 0xffff297a, 0xfffdb726, 0x00000000, 0x000053a7, 0x0001b506, 0x0000a24b, 0xffffa32d,
0xfffead9b, 0xffff0479, 0xffffffc9, 0x00000000, 0x00000000, 0x0002d800, 0x0001249d, 0xfffd67bb,
0xfffe9baa, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000ac03, 0x0001448b,
0xfffe0f70, 0x00000000, 0x000229ea, 0x0001d616, 0xffffff8c, 0xfffebf76, 0xfffe54d9, 0xffff5d9e,
0xffffd3eb, 0x0000c65e, 0x0000fc15, 0x0001d491, 0xffffb566, 0xfffd9433, 0x00000000, 0x0000e4ec,
}
var hardCodedFlIn16 = []float32{
0, 0, -0.022306755, -0.3782405, -0.33334962, -0.1741521, -0.0607556, 0.11660573,
0.14664596, 0.41462868, 0.2907673, 0.0001568835, 0, 0, -0.14239307, -0.7012868,
-0.15632017, 0, 0, 0, 0, 0, 0, 0.3230303,
0.6690931, 0.007876594, -0.05189419, -0.832786, -0.11531975, 0.026225802, 0.42518616, 0.3154636,
0.06598757, -0.15304244, -0.47969276, -0.20012794, 0, 0.5327272, 0.46727282, -0.45950258,
-0.5404974, 0, 0.63484025, 0.36515975, 0, 0, 0, -0.04351709,
-0.8293345, -0.12714837, 0.11087036, 0.88912964, -0.35792422, -0.2053554, 0.0022513224, 0.5374398,
0.023588525, 0, 0, 0, 0, -0.55346966, -0.44653034, 0.0002531938,
0.9088273, 0.090919495, 0, 0, 0, 0, 0, 0,
0, 0, -0.44745448, -0.5525455, 0, 0.80748945, 0.19251058, 0,
0, -0.092476256, -0.2661464, -0.11322958, -0.11298219, -0.055094406, 0, -0.16045958,
-0.1996116, 0, 0.80748653, 0.19251347, -0.09804727, -0.51129663, -0.3610403, -0.029615778,
0, 0, 0, 0, 0, 0, 0, 0.80748653,
0.14411622, -0.76251525, -0.1890875, 0.01527351, 0.27528667, 0.29730347, 0.101477206, 0.07259522,
0.009900213, -0.34395567, -0.42788061, 0, 0.80748653, -0.3648737, -0.44261283, 0.015778137,
0.6826565, 0.30156538, 0, 0, 0, 0, -0.44563293, -0.55436707,
0, 0.80748653, -0.60703933, -0.20044717, 0.22371745, 0.77628255, 0, 0,
0, 0, 0, -0.44563293, -0.55436707, 0, 0.80748653, -0.7550391,
-0.05244744, 0.2797074, 0.72029257, 0, 0, 0, 0, 0,
-0.57440215, -0.42559785, 0, 0.80748653, -0.59273535, -0.21475118, 0.04544862, 0.81148535,
0.14306602, 0, 0, 0, -0.369642, -0.61841226, -0.011945802, 0,
0.7791623, -0.20691396, -0.57224834, 0, 0.08218567, 0.42637306, 0.1586175, -0.089709565,
-0.32935485, -0.24788953, -0.00022224105, 0, 0, 0.7085409, 0.28821066, -0.64765793,
-0.34909368, 0, 0, 0, 0, 0, 0.16679136, 0.31914657,
-0.48593786, 0, 0.537915, 0.462085, -0.00041967133, -0.3120329, -0.41914812, -0.15886839,
-0.042683028, 0.19370951, 0.24624406, 0.45803425, -0.07049577, -0.6091341, 0, 0.22253075,
}
var fxMask16 = []uint32{
0x0000, 0x0000, 0x05b8, 0x66a6, 0xbbfe, 0xe871, 0xf800, 0xda20, 0xb499, 0x4a84, 0x0009, 0x0000, 0x0000,
0x0000, 0x2463, 0xd7fd, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xad35, 0x01f8, 0x0000,
0x0d69, 0xe28c, 0xffff, 0xf92a, 0x8c5d, 0x3b36, 0x2a62, 0x51a7, 0xcc97, 0xffff, 0xffff, 0x772d, 0x0000,
0x75ad, 0xffff, 0xffff, 0x5ccf, 0x0000, 0x0000, 0x0000, 0x0000, 0x0b4a, 0xdfd6, 0xffff, 0xe2ff, 0x0000,
0x5b67, 0x8fff, 0x8f70, 0x060a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8e7f, 0xffff, 0xffe9, 0x16d6,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7303, 0xffff, 0xffff, 0x30ff,
0x0000, 0x0000, 0x0000, 0x17b0, 0x5bfe, 0x78fe, 0x95ec, 0xa3fe, 0xa3fe, 0xcd24, 0xfffe, 0xfffe, 0x30fe,
0x0001, 0x190d, 0x9be5, 0xf868, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0x30fe,
0x0c4c, 0xcf6f, 0xfffe, 0xfc0b, 0xb551, 0x6920, 0x4f1d, 0x3c87, 0x39ff, 0x928e, 0xffff, 0xffff, 0x30ff,
0x8f03, 0xffff, 0xfbe7, 0x4d76, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x727f, 0xffff, 0xffff, 0x30ff,
0xccff, 0xffff, 0xc6ff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x727f, 0xffff, 0xffff, 0x30ff,
0xf296, 0xffff, 0xb7c6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x939a, 0xffff, 0xffff, 0x30ff,
0xc97f, 0xffff, 0xf43c, 0x2493, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f13, 0xfd0c, 0xffff, 0xffff, 0x3827,
0x6dc9, 0xffff, 0xffff, 0xeb16, 0x7dd4, 0x5541, 0x6c76, 0xc10f, 0xfff1, 0xffff, 0xffff, 0xffff, 0x49ff,
0x00d8, 0xa6e9, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xd4fe, 0x83db, 0xffff, 0xffff, 0x7584,
0x0000, 0x001c, 0x503e, 0xbb08, 0xe3a1, 0xeea6, 0xbd0e, 0x7e09, 0x08e5, 0x1b8b, 0xb67f, 0xb67f, 0x7d44,
}
var flMask16 = []uint32{
0x0000, 0x0000, 0x05b5, 0x668a, 0xbbe0, 0xe875, 0xf803, 0xda29, 0xb49f, 0x4a7a, 0x000a, 0x0000, 0x0000,
0x0000, 0x2473, 0xd7fb, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xad4d, 0x0204, 0x0000,
0x0d48, 0xe27a, 0xffff, 0xf949, 0x8c70, 0x3bae, 0x2ac9, 0x51f7, 0xccc4, 0xffff, 0xffff, 0x779f, 0x0000,
0x75a1, 0xffff, 0xffff, 0x5d7b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0b23, 0xdf73, 0xffff, 0xe39d, 0x0000,
0x5ba0, 0x9033, 0x8f9f, 0x0609, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8db0, 0xffff, 0xffef, 0x1746,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x728c, 0xffff, 0xffff, 0x3148,
0x0000, 0x0000, 0x0000, 0x17ac, 0x5bce, 0x78cb, 0x95b7, 0xa3d2, 0xa3d2, 0xcce6, 0xffff, 0xffff, 0x3148,
0x0000, 0x1919, 0x9bfd, 0xf86b, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x3148,
0x0c63, 0xcf97, 0xffff, 0xfc17, 0xb59d, 0x6981, 0x4f87, 0x3cf1, 0x3a68, 0x9276, 0xffff, 0xffff, 0x3148,
0x8eb0, 0xffff, 0xfbf5, 0x4d33, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7214, 0xffff, 0xffff, 0x3148,
0xccaf, 0xffff, 0xc6ba, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7214, 0xffff, 0xffff, 0x3148,
0xf292, 0xffff, 0xb865, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x930c, 0xffff, 0xffff, 0x3148,
0xc906, 0xffff, 0xf45d, 0x249f, 0x0000, 0x0000, 0x0000, 0x0000, 0x5ea0, 0xfcf1, 0xffff, 0xffff, 0x3888,
0x6d81, 0xffff, 0xffff, 0xeaf5, 0x7dcf, 0x5533, 0x6c2b, 0xc07b, 0xfff1, 0xffff, 0xffff, 0xffff, 0x4a9d,
0x00d4, 0xa6a1, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xd54d, 0x8399, 0xffff, 0xffff, 0x764b,
0x0000, 0x001b, 0x4ffc, 0xbb4a, 0xe3f5, 0xeee3, 0xbd4c, 0x7e42, 0x0900, 0x1b0c, 0xb6fc, 0xb6fc, 0x7e04,
}
// TestFixedFloatingCloseness compares the closeness of the fixed point and
// floating point rasterizer.
func TestFixedFloatingCloseness(t *testing.T) {
if len(fxMask16) != len(flMask16) {
t.Fatalf("len(fxMask16) != len(flMask16)")
}
total := uint32(0)
for i := range fxMask16 {
a := fxMask16[i]
b := flMask16[i]
if a > b {
total += a - b
} else {
total += b - a
}
}
n := len(fxMask16)
// This log message is useful when changing the fixed point rasterizer
// implementation, such as by changing ϕ. Assuming that the floating point
// rasterizer is accurate, the average difference is a measure of how
// inaccurate the (faster) fixed point rasterizer is.
//
// Smaller is better.
percent := float64(total*100) / float64(n*65535)
t.Logf("Comparing closeness of the fixed point and floating point rasterizer.\n"+
"Specifically, the elements of fxMask16 and flMask16.\n"+
"Total diff = %d, n = %d, avg = %.5f out of 65535, or %.5f%%.\n",
total, n, float64(total)/float64(n), percent)
const thresholdPercent = 1.0
if percent > thresholdPercent {
t.Errorf("average difference: got %.5f%%, want <= %.5f%%", percent, thresholdPercent)
}
}

447
vendor/golang.org/x/image/vector/gen.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,447 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
package main
import (
"bytes"
"io/ioutil"
"log"
"strings"
"text/template"
)
const (
copyright = "" +
"// Copyright 2016 The Go Authors. All rights reserved.\n" +
"// Use of this source code is governed by a BSD-style\n" +
"// license that can be found in the LICENSE file.\n"
doNotEdit = "// generated by go run gen.go; DO NOT EDIT\n"
dashDashDash = "// --------"
)
func main() {
tmpl, err := ioutil.ReadFile("gen_acc_amd64.s.tmpl")
if err != nil {
log.Fatalf("ReadFile: %v", err)
}
if !bytes.HasPrefix(tmpl, []byte(copyright)) {
log.Fatal("source template did not start with the copyright header")
}
tmpl = tmpl[len(copyright):]
preamble := []byte(nil)
if i := bytes.Index(tmpl, []byte(dashDashDash)); i < 0 {
log.Fatalf("source template did not contain %q", dashDashDash)
} else {
preamble, tmpl = tmpl[:i], tmpl[i:]
}
t, err := template.New("").Parse(string(tmpl))
if err != nil {
log.Fatalf("Parse: %v", err)
}
out := bytes.NewBuffer(nil)
out.WriteString(doNotEdit)
out.Write(preamble)
for i, v := range instances {
if i != 0 {
out.WriteString("\n")
}
if strings.Contains(v.LoadArgs, "{{.ShortName}}") {
v.LoadArgs = strings.Replace(v.LoadArgs, "{{.ShortName}}", v.ShortName, -1)
}
if err := t.Execute(out, v); err != nil {
log.Fatalf("Execute(%q): %v", v.ShortName, err)
}
}
if err := ioutil.WriteFile("acc_amd64.s", out.Bytes(), 0666); err != nil {
log.Fatalf("WriteFile: %v", err)
}
}
var instances = []struct {
LongName string
ShortName string
FrameSize string
ArgsSize string
Args string
DstElemSize1 int
DstElemSize4 int
XMM3 string
XMM4 string
XMM5 string
XMM6 string
XMM8 string
XMM9 string
XMM10 string
LoadArgs string
Setup string
LoadXMMRegs string
Add string
ClampAndScale string
ConvertToInt32 string
Store4 string
Store1 string
}{{
LongName: "fixedAccumulateOpOver",
ShortName: "fxAccOpOver",
FrameSize: fxFrameSize,
ArgsSize: twoArgArgsSize,
Args: "dst []uint8, src []uint32",
DstElemSize1: 1 * sizeOfUint8,
DstElemSize4: 4 * sizeOfUint8,
XMM3: fxXMM3,
XMM4: fxXMM4,
XMM5: fxXMM5,
XMM6: opOverXMM6,
XMM8: opOverXMM8,
XMM9: opOverXMM9,
XMM10: opOverXMM10,
LoadArgs: twoArgLoadArgs,
Setup: fxSetup,
LoadXMMRegs: fxLoadXMMRegs + "\n" + opOverLoadXMMRegs,
Add: fxAdd,
ClampAndScale: fxClampAndScale,
ConvertToInt32: fxConvertToInt32,
Store4: opOverStore4,
Store1: opOverStore1,
}, {
LongName: "fixedAccumulateOpSrc",
ShortName: "fxAccOpSrc",
FrameSize: fxFrameSize,
ArgsSize: twoArgArgsSize,
Args: "dst []uint8, src []uint32",
DstElemSize1: 1 * sizeOfUint8,
DstElemSize4: 4 * sizeOfUint8,
XMM3: fxXMM3,
XMM4: fxXMM4,
XMM5: fxXMM5,
XMM6: opSrcXMM6,
XMM8: opSrcXMM8,
XMM9: opSrcXMM9,
XMM10: opSrcXMM10,
LoadArgs: twoArgLoadArgs,
Setup: fxSetup,
LoadXMMRegs: fxLoadXMMRegs + "\n" + opSrcLoadXMMRegs,
Add: fxAdd,
ClampAndScale: fxClampAndScale,
ConvertToInt32: fxConvertToInt32,
Store4: opSrcStore4,
Store1: opSrcStore1,
}, {
LongName: "fixedAccumulateMask",
ShortName: "fxAccMask",
FrameSize: fxFrameSize,
ArgsSize: oneArgArgsSize,
Args: "buf []uint32",
DstElemSize1: 1 * sizeOfUint32,
DstElemSize4: 4 * sizeOfUint32,
XMM3: fxXMM3,
XMM4: fxXMM4,
XMM5: fxXMM5,
XMM6: maskXMM6,
XMM8: maskXMM8,
XMM9: maskXMM9,
XMM10: maskXMM10,
LoadArgs: oneArgLoadArgs,
Setup: fxSetup,
LoadXMMRegs: fxLoadXMMRegs + "\n" + maskLoadXMMRegs,
Add: fxAdd,
ClampAndScale: fxClampAndScale,
ConvertToInt32: fxConvertToInt32,
Store4: maskStore4,
Store1: maskStore1,
}, {
LongName: "floatingAccumulateOpOver",
ShortName: "flAccOpOver",
FrameSize: flFrameSize,
ArgsSize: twoArgArgsSize,
Args: "dst []uint8, src []float32",
DstElemSize1: 1 * sizeOfUint8,
DstElemSize4: 4 * sizeOfUint8,
XMM3: flXMM3,
XMM4: flXMM4,
XMM5: flXMM5,
XMM6: opOverXMM6,
XMM8: opOverXMM8,
XMM9: opOverXMM9,
XMM10: opOverXMM10,
LoadArgs: twoArgLoadArgs,
Setup: flSetup,
LoadXMMRegs: flLoadXMMRegs + "\n" + opOverLoadXMMRegs,
Add: flAdd,
ClampAndScale: flClampAndScale,
ConvertToInt32: flConvertToInt32,
Store4: opOverStore4,
Store1: opOverStore1,
}, {
LongName: "floatingAccumulateOpSrc",
ShortName: "flAccOpSrc",
FrameSize: flFrameSize,
ArgsSize: twoArgArgsSize,
Args: "dst []uint8, src []float32",
DstElemSize1: 1 * sizeOfUint8,
DstElemSize4: 4 * sizeOfUint8,
XMM3: flXMM3,
XMM4: flXMM4,
XMM5: flXMM5,
XMM6: opSrcXMM6,
XMM8: opSrcXMM8,
XMM9: opSrcXMM9,
XMM10: opSrcXMM10,
LoadArgs: twoArgLoadArgs,
Setup: flSetup,
LoadXMMRegs: flLoadXMMRegs + "\n" + opSrcLoadXMMRegs,
Add: flAdd,
ClampAndScale: flClampAndScale,
ConvertToInt32: flConvertToInt32,
Store4: opSrcStore4,
Store1: opSrcStore1,
}, {
LongName: "floatingAccumulateMask",
ShortName: "flAccMask",
FrameSize: flFrameSize,
ArgsSize: twoArgArgsSize,
Args: "dst []uint32, src []float32",
DstElemSize1: 1 * sizeOfUint32,
DstElemSize4: 4 * sizeOfUint32,
XMM3: flXMM3,
XMM4: flXMM4,
XMM5: flXMM5,
XMM6: maskXMM6,
XMM8: maskXMM8,
XMM9: maskXMM9,
XMM10: maskXMM10,
LoadArgs: twoArgLoadArgs,
Setup: flSetup,
LoadXMMRegs: flLoadXMMRegs + "\n" + maskLoadXMMRegs,
Add: flAdd,
ClampAndScale: flClampAndScale,
ConvertToInt32: flConvertToInt32,
Store4: maskStore4,
Store1: maskStore1,
}}
const (
fxFrameSize = `0`
flFrameSize = `8`
oneArgArgsSize = `24`
twoArgArgsSize = `48`
sizeOfUint8 = 1
sizeOfUint32 = 4
fxXMM3 = `-`
flXMM3 = `flSignMask`
fxXMM4 = `-`
flXMM4 = `flOne`
fxXMM5 = `fxAlmost65536`
flXMM5 = `flAlmost65536`
oneArgLoadArgs = `
MOVQ buf_base+0(FP), DI
MOVQ buf_len+8(FP), BX
MOVQ buf_base+0(FP), SI
MOVQ buf_len+8(FP), R10
`
twoArgLoadArgs = `
MOVQ dst_base+0(FP), DI
MOVQ dst_len+8(FP), BX
MOVQ src_base+24(FP), SI
MOVQ src_len+32(FP), R10
// Sanity check that len(dst) >= len(src).
CMPQ BX, R10
JLT {{.ShortName}}End
`
fxSetup = ``
flSetup = `
// Prepare to set MXCSR bits 13 and 14, so that the CVTPS2PL below is
// "Round To Zero".
STMXCSR mxcsrOrig-8(SP)
MOVL mxcsrOrig-8(SP), AX
ORL $0x6000, AX
MOVL AX, mxcsrNew-4(SP)
`
fxLoadXMMRegs = `
// fxAlmost65536 := XMM(0x0000ffff repeated four times) // Maximum of an uint16.
MOVOU fxAlmost65536<>(SB), X5
`
flLoadXMMRegs = `
// flSignMask := XMM(0x7fffffff repeated four times) // All but the sign bit of a float32.
// flOne := XMM(0x3f800000 repeated four times) // 1 as a float32.
// flAlmost65536 := XMM(0x477fffff repeated four times) // 255.99998 * 256 as a float32.
MOVOU flSignMask<>(SB), X3
MOVOU flOne<>(SB), X4
MOVOU flAlmost65536<>(SB), X5
`
fxAdd = `PADDD`
flAdd = `ADDPS`
fxClampAndScale = `
// y = abs(x)
// y >>= 2 // Shift by 2*ϕ - 16.
// y = min(y, fxAlmost65536)
//
// pabsd %xmm1,%xmm2
// psrld $0x2,%xmm2
// pminud %xmm5,%xmm2
//
// Hopefully we'll get these opcode mnemonics into the assembler for Go
// 1.8. https://golang.org/issue/16007 isn't exactly the same thing, but
// it's similar.
BYTE $0x66; BYTE $0x0f; BYTE $0x38; BYTE $0x1e; BYTE $0xd1
BYTE $0x66; BYTE $0x0f; BYTE $0x72; BYTE $0xd2; BYTE $0x02
BYTE $0x66; BYTE $0x0f; BYTE $0x38; BYTE $0x3b; BYTE $0xd5
`
flClampAndScale = `
// y = x & flSignMask
// y = min(y, flOne)
// y = mul(y, flAlmost65536)
MOVOU X3, X2
ANDPS X1, X2
MINPS X4, X2
MULPS X5, X2
`
fxConvertToInt32 = `
// z = convertToInt32(y)
// No-op.
`
flConvertToInt32 = `
// z = convertToInt32(y)
LDMXCSR mxcsrNew-4(SP)
CVTPS2PL X2, X2
LDMXCSR mxcsrOrig-8(SP)
`
opOverStore4 = `
// Blend over the dst's prior value. SIMD for i in 0..3:
//
// dstA := uint32(dst[i]) * 0x101
// maskA := z@i
// outA := dstA*(0xffff-maskA)/0xffff + maskA
// dst[i] = uint8(outA >> 8)
//
// First, set X0 to dstA*(0xfff-maskA).
MOVL (DI), X0
PSHUFB X8, X0
MOVOU X9, X11
PSUBL X2, X11
PMULLD X11, X0
// We implement uint32 division by 0xffff as multiplication by a magic
// constant (0x800080001) and then a shift by a magic constant (47).
// See TestDivideByFFFF for a justification.
//
// That multiplication widens from uint32 to uint64, so we have to
// duplicate and shift our four uint32s from one XMM register (X0) to
// two XMM registers (X0 and X11).
//
// Move the second and fourth uint32s in X0 to be the first and third
// uint32s in X11.
MOVOU X0, X11
PSRLQ $32, X11
// Multiply by magic, shift by magic.
//
// pmuludq %xmm10,%xmm0
// pmuludq %xmm10,%xmm11
BYTE $0x66; BYTE $0x41; BYTE $0x0f; BYTE $0xf4; BYTE $0xc2
BYTE $0x66; BYTE $0x45; BYTE $0x0f; BYTE $0xf4; BYTE $0xda
PSRLQ $47, X0
PSRLQ $47, X11
// Merge the two registers back to one, X11, and add maskA.
PSLLQ $32, X11
XORPS X0, X11
PADDD X11, X2
// As per opSrcStore4, shuffle and copy the 4 second-lowest bytes.
PSHUFB X6, X2
MOVL X2, (DI)
`
opSrcStore4 = `
// z = shuffleTheSecondLowestBytesOfEach4ByteElement(z)
// copy(dst[:4], low4BytesOf(z))
PSHUFB X6, X2
MOVL X2, (DI)
`
maskStore4 = `
// copy(dst[:4], z)
MOVOU X2, (DI)
`
opOverStore1 = `
// Blend over the dst's prior value.
//
// dstA := uint32(dst[0]) * 0x101
// maskA := z
// outA := dstA*(0xffff-maskA)/0xffff + maskA
// dst[0] = uint8(outA >> 8)
MOVBLZX (DI), R12
IMULL $0x101, R12
MOVL X2, R13
MOVL $0xffff, AX
SUBL R13, AX
MULL R12 // MULL's implicit arg is AX, and the result is stored in DX:AX.
MOVL $0x80008001, BX // Divide by 0xffff is to first multiply by a magic constant...
MULL BX // MULL's implicit arg is AX, and the result is stored in DX:AX.
SHRL $15, DX // ...and then shift by another magic constant (47 - 32 = 15).
ADDL DX, R13
SHRL $8, R13
MOVB R13, (DI)
`
opSrcStore1 = `
// dst[0] = uint8(z>>8)
MOVL X2, BX
SHRL $8, BX
MOVB BX, (DI)
`
maskStore1 = `
// dst[0] = uint32(z)
MOVL X2, (DI)
`
opOverXMM6 = `gather`
opSrcXMM6 = `gather`
maskXMM6 = `-`
opOverXMM8 = `scatterAndMulBy0x101`
opSrcXMM8 = `-`
maskXMM8 = `-`
opOverXMM9 = `fxAlmost65536`
opSrcXMM9 = `-`
maskXMM9 = `-`
opOverXMM10 = `inverseFFFF`
opSrcXMM10 = `-`
maskXMM10 = `-`
opOverLoadXMMRegs = `
// gather := XMM(see above) // PSHUFB shuffle mask.
// scatterAndMulBy0x101 := XMM(see above) // PSHUFB shuffle mask.
// fxAlmost65536 := XMM(0x0000ffff repeated four times) // 0xffff.
// inverseFFFF := XMM(0x80008001 repeated four times) // Magic constant for dividing by 0xffff.
MOVOU gather<>(SB), X6
MOVOU scatterAndMulBy0x101<>(SB), X8
MOVOU fxAlmost65536<>(SB), X9
MOVOU inverseFFFF<>(SB), X10
`
opSrcLoadXMMRegs = `
// gather := XMM(see above) // PSHUFB shuffle mask.
MOVOU gather<>(SB), X6
`
maskLoadXMMRegs = ``
)

171
vendor/golang.org/x/image/vector/gen_acc_amd64.s.tmpl сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,171 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !appengine
// +build gc
// +build go1.6
// +build !noasm
#include "textflag.h"
// fl is short for floating point math. fx is short for fixed point math.
DATA flAlmost65536<>+0x00(SB)/8, $0x477fffff477fffff
DATA flAlmost65536<>+0x08(SB)/8, $0x477fffff477fffff
DATA flOne<>+0x00(SB)/8, $0x3f8000003f800000
DATA flOne<>+0x08(SB)/8, $0x3f8000003f800000
DATA flSignMask<>+0x00(SB)/8, $0x7fffffff7fffffff
DATA flSignMask<>+0x08(SB)/8, $0x7fffffff7fffffff
// scatterAndMulBy0x101 is a PSHUFB mask that brings the low four bytes of an
// XMM register to the low byte of that register's four uint32 values. It
// duplicates those bytes, effectively multiplying each uint32 by 0x101.
//
// It transforms a little-endian 16-byte XMM value from
// ijkl????????????
// to
// ii00jj00kk00ll00
DATA scatterAndMulBy0x101<>+0x00(SB)/8, $0x8080010180800000
DATA scatterAndMulBy0x101<>+0x08(SB)/8, $0x8080030380800202
// gather is a PSHUFB mask that brings the second-lowest byte of the XMM
// register's four uint32 values to the low four bytes of that register.
//
// It transforms a little-endian 16-byte XMM value from
// ?i???j???k???l??
// to
// ijkl000000000000
DATA gather<>+0x00(SB)/8, $0x808080800d090501
DATA gather<>+0x08(SB)/8, $0x8080808080808080
DATA fxAlmost65536<>+0x00(SB)/8, $0x0000ffff0000ffff
DATA fxAlmost65536<>+0x08(SB)/8, $0x0000ffff0000ffff
DATA inverseFFFF<>+0x00(SB)/8, $0x8000800180008001
DATA inverseFFFF<>+0x08(SB)/8, $0x8000800180008001
GLOBL flAlmost65536<>(SB), (NOPTR+RODATA), $16
GLOBL flOne<>(SB), (NOPTR+RODATA), $16
GLOBL flSignMask<>(SB), (NOPTR+RODATA), $16
GLOBL scatterAndMulBy0x101<>(SB), (NOPTR+RODATA), $16
GLOBL gather<>(SB), (NOPTR+RODATA), $16
GLOBL fxAlmost65536<>(SB), (NOPTR+RODATA), $16
GLOBL inverseFFFF<>(SB), (NOPTR+RODATA), $16
// func haveSSE4_1() bool
TEXT ·haveSSE4_1(SB), NOSPLIT, $0
MOVQ $1, AX
CPUID
SHRQ $19, CX
ANDQ $1, CX
MOVB CX, ret+0(FP)
RET
// ----------------------------------------------------------------------------
// func {{.LongName}}SIMD({{.Args}})
//
// XMM registers. Variable names are per
// https://github.com/google/font-rs/blob/master/src/accumulate.c
//
// xmm0 scratch
// xmm1 x
// xmm2 y, z
// xmm3 {{.XMM3}}
// xmm4 {{.XMM4}}
// xmm5 {{.XMM5}}
// xmm6 {{.XMM6}}
// xmm7 offset
// xmm8 {{.XMM8}}
// xmm9 {{.XMM9}}
// xmm10 {{.XMM10}}
TEXT ·{{.LongName}}SIMD(SB), NOSPLIT, ${{.FrameSize}}-{{.ArgsSize}}
{{.LoadArgs}}
// R10 = len(src) &^ 3
// R11 = len(src)
MOVQ R10, R11
ANDQ $-4, R10
{{.Setup}}
{{.LoadXMMRegs}}
// offset := XMM(0x00000000 repeated four times) // Cumulative sum.
XORPS X7, X7
// i := 0
MOVQ $0, R9
{{.ShortName}}Loop4:
// for i < (len(src) &^ 3)
CMPQ R9, R10
JAE {{.ShortName}}Loop1
// x = XMM(s0, s1, s2, s3)
//
// Where s0 is src[i+0], s1 is src[i+1], etc.
MOVOU (SI), X1
// scratch = XMM(0, s0, s1, s2)
// x += scratch // yields x == XMM(s0, s0+s1, s1+s2, s2+s3)
MOVOU X1, X0
PSLLO $4, X0
{{.Add}} X0, X1
// scratch = XMM(0, 0, 0, 0)
// scratch = XMM(scratch@0, scratch@0, x@0, x@1) // yields scratch == XMM(0, 0, s0, s0+s1)
// x += scratch // yields x == XMM(s0, s0+s1, s0+s1+s2, s0+s1+s2+s3)
XORPS X0, X0
SHUFPS $0x40, X1, X0
{{.Add}} X0, X1
// x += offset
{{.Add}} X7, X1
{{.ClampAndScale}}
{{.ConvertToInt32}}
{{.Store4}}
// offset = XMM(x@3, x@3, x@3, x@3)
MOVOU X1, X7
SHUFPS $0xff, X1, X7
// i += 4
// dst = dst[4:]
// src = src[4:]
ADDQ $4, R9
ADDQ ${{.DstElemSize4}}, DI
ADDQ $16, SI
JMP {{.ShortName}}Loop4
{{.ShortName}}Loop1:
// for i < len(src)
CMPQ R9, R11
JAE {{.ShortName}}End
// x = src[i] + offset
MOVL (SI), X1
{{.Add}} X7, X1
{{.ClampAndScale}}
{{.ConvertToInt32}}
{{.Store1}}
// offset = x
MOVOU X1, X7
// i += 1
// dst = dst[1:]
// src = src[1:]
ADDQ $1, R9
ADDQ ${{.DstElemSize1}}, DI
ADDQ $4, SI
JMP {{.ShortName}}Loop1
{{.ShortName}}End:
RET

327
vendor/golang.org/x/image/vector/raster_fixed.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,327 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package vector
// This file contains a fixed point math implementation of the vector
// graphics rasterizer.
const (
// ϕ is the number of binary digits after the fixed point.
//
// For example, if ϕ == 10 (and int1ϕ is based on the int32 type) then we
// are using 22.10 fixed point math.
//
// When changing this number, also change the assembly code (search for ϕ
// in the .s files).
ϕ = 9
fxOne int1ϕ = 1 << ϕ
fxOneAndAHalf int1ϕ = 1<<ϕ + 1<<(ϕ-1)
fxOneMinusIota int1ϕ = 1<<ϕ - 1 // Used for rounding up.
)
// int1ϕ is a signed fixed-point number with 1*ϕ binary digits after the fixed
// point.
type int1ϕ int32
// int2ϕ is a signed fixed-point number with 2*ϕ binary digits after the fixed
// point.
//
// The Rasterizer's bufU32 field, nominally of type []uint32 (since that slice
// is also used by other code), can be thought of as a []int2ϕ during the
// fixedLineTo method. Lines of code that are actually like:
// buf[i] += uint32(etc) // buf has type []uint32.
// can be thought of as
// buf[i] += int2ϕ(etc) // buf has type []int2ϕ.
type int2ϕ int32
func fixedMax(x, y int1ϕ) int1ϕ {
if x > y {
return x
}
return y
}
func fixedMin(x, y int1ϕ) int1ϕ {
if x < y {
return x
}
return y
}
func fixedFloor(x int1ϕ) int32 { return int32(x >> ϕ) }
func fixedCeil(x int1ϕ) int32 { return int32((x + fxOneMinusIota) >> ϕ) }
func (z *Rasterizer) fixedLineTo(bx, by float32) {
ax, ay := z.penX, z.penY
z.penX, z.penY = bx, by
dir := int1ϕ(1)
if ay > by {
dir, ax, ay, bx, by = -1, bx, by, ax, ay
}
// Horizontal line segments yield no change in coverage. Almost horizontal
// segments would yield some change, in ideal math, but the computation
// further below, involving 1 / (by - ay), is unstable in fixed point math,
// so we treat the segment as if it was perfectly horizontal.
if by-ay <= 0.000001 {
return
}
dxdy := (bx - ax) / (by - ay)
ayϕ := int1ϕ(ay * float32(fxOne))
byϕ := int1ϕ(by * float32(fxOne))
x := int1ϕ(ax * float32(fxOne))
y := fixedFloor(ayϕ)
yMax := fixedCeil(byϕ)
if yMax > int32(z.size.Y) {
yMax = int32(z.size.Y)
}
width := int32(z.size.X)
for ; y < yMax; y++ {
dy := fixedMin(int1ϕ(y+1)<<ϕ, byϕ) - fixedMax(int1ϕ(y)<<ϕ, ayϕ)
xNext := x + int1ϕ(float32(dy)*dxdy)
if y < 0 {
x = xNext
continue
}
buf := z.bufU32[y*width:]
d := dy * dir // d ranges up to ±1<<(1*ϕ).
x0, x1 := x, xNext
if x > xNext {
x0, x1 = x1, x0
}
x0i := fixedFloor(x0)
x0Floor := int1ϕ(x0i) << ϕ
x1i := fixedCeil(x1)
x1Ceil := int1ϕ(x1i) << ϕ
if x1i <= x0i+1 {
xmf := (x+xNext)>>1 - x0Floor
if i := clamp(x0i+0, width); i < uint(len(buf)) {
buf[i] += uint32(d * (fxOne - xmf))
}
if i := clamp(x0i+1, width); i < uint(len(buf)) {
buf[i] += uint32(d * xmf)
}
} else {
oneOverS := x1 - x0
twoOverS := 2 * oneOverS
x0f := x0 - x0Floor
oneMinusX0f := fxOne - x0f
oneMinusX0fSquared := oneMinusX0f * oneMinusX0f
x1f := x1 - x1Ceil + fxOne
x1fSquared := x1f * x1f
// These next two variables are unused, as rounding errors are
// minimized when we delay the division by oneOverS for as long as
// possible. These lines of code (and the "In ideal math" comments
// below) are commented out instead of deleted in order to aid the
// comparison with the floating point version of the rasterizer.
//
// a0 := ((oneMinusX0f * oneMinusX0f) >> 1) / oneOverS
// am := ((x1f * x1f) >> 1) / oneOverS
if i := clamp(x0i, width); i < uint(len(buf)) {
// In ideal math: buf[i] += uint32(d * a0)
D := oneMinusX0fSquared // D ranges up to ±1<<(2*ϕ).
D *= d // D ranges up to ±1<<(3*ϕ).
D /= twoOverS
buf[i] += uint32(D)
}
if x1i == x0i+2 {
if i := clamp(x0i+1, width); i < uint(len(buf)) {
// In ideal math: buf[i] += uint32(d * (fxOne - a0 - am))
//
// (x1i == x0i+2) and (twoOverS == 2 * (x1 - x0)) implies
// that twoOverS ranges up to +1<<(1*ϕ+2).
D := twoOverS<<ϕ - oneMinusX0fSquared - x1fSquared // D ranges up to ±1<<(2*ϕ+2).
D *= d // D ranges up to ±1<<(3*ϕ+2).
D /= twoOverS
buf[i] += uint32(D)
}
} else {
// This is commented out for the same reason as a0 and am.
//
// a1 := ((fxOneAndAHalf - x0f) << ϕ) / oneOverS
if i := clamp(x0i+1, width); i < uint(len(buf)) {
// In ideal math:
// buf[i] += uint32(d * (a1 - a0))
// or equivalently (but better in non-ideal, integer math,
// with respect to rounding errors),
// buf[i] += uint32(A * d / twoOverS)
// where
// A = (a1 - a0) * twoOverS
// = a1*twoOverS - a0*twoOverS
// Noting that twoOverS/oneOverS equals 2, substituting for
// a0 and then a1, given above, yields:
// A = a1*twoOverS - oneMinusX0fSquared
// = (fxOneAndAHalf-x0f)<<(ϕ+1) - oneMinusX0fSquared
// = fxOneAndAHalf<<(ϕ+1) - x0f<<(ϕ+1) - oneMinusX0fSquared
//
// This is a positive number minus two non-negative
// numbers. For an upper bound on A, the positive number is
// P = fxOneAndAHalf<<(ϕ+1)
// < (2*fxOne)<<(ϕ+1)
// = fxOne<<(ϕ+2)
// = 1<<(2*ϕ+2)
//
// For a lower bound on A, the two non-negative numbers are
// N = x0f<<(ϕ+1) + oneMinusX0fSquared
// ≤ x0f<<(ϕ+1) + fxOne*fxOne
// = x0f<<(ϕ+1) + 1<<(2*ϕ)
// < x0f<<(ϕ+1) + 1<<(2*ϕ+1)
// ≤ fxOne<<(ϕ+1) + 1<<(2*ϕ+1)
// = 1<<(2*ϕ+1) + 1<<(2*ϕ+1)
// = 1<<(2*ϕ+2)
//
// Thus, A ranges up to ±1<<(2*ϕ+2). It is possible to
// derive a tighter bound, but this bound is sufficient to
// reason about overflow.
D := (fxOneAndAHalf-x0f)<<(ϕ+1) - oneMinusX0fSquared // D ranges up to ±1<<(2*ϕ+2).
D *= d // D ranges up to ±1<<(3*ϕ+2).
D /= twoOverS
buf[i] += uint32(D)
}
dTimesS := uint32((d << (2 * ϕ)) / oneOverS)
for xi := x0i + 2; xi < x1i-1; xi++ {
if i := clamp(xi, width); i < uint(len(buf)) {
buf[i] += dTimesS
}
}
// This is commented out for the same reason as a0 and am.
//
// a2 := a1 + (int1ϕ(x1i-x0i-3)<<(2*ϕ))/oneOverS
if i := clamp(x1i-1, width); i < uint(len(buf)) {
// In ideal math:
// buf[i] += uint32(d * (fxOne - a2 - am))
// or equivalently (but better in non-ideal, integer math,
// with respect to rounding errors),
// buf[i] += uint32(A * d / twoOverS)
// where
// A = (fxOne - a2 - am) * twoOverS
// = twoOverS<<ϕ - a2*twoOverS - am*twoOverS
// Noting that twoOverS/oneOverS equals 2, substituting for
// am and then a2, given above, yields:
// A = twoOverS<<ϕ - a2*twoOverS - x1f*x1f
// = twoOverS<<ϕ - a1*twoOverS - (int1ϕ(x1i-x0i-3)<<(2*ϕ))*2 - x1f*x1f
// = twoOverS<<ϕ - a1*twoOverS - int1ϕ(x1i-x0i-3)<<(2*ϕ+1) - x1f*x1f
// Substituting for a1, given above, yields:
// A = twoOverS<<ϕ - ((fxOneAndAHalf-x0f)<<ϕ)*2 - int1ϕ(x1i-x0i-3)<<(2*ϕ+1) - x1f*x1f
// = twoOverS<<ϕ - (fxOneAndAHalf-x0f)<<(ϕ+1) - int1ϕ(x1i-x0i-3)<<(2*ϕ+1) - x1f*x1f
// = B<<ϕ - x1f*x1f
// where
// B = twoOverS - (fxOneAndAHalf-x0f)<<1 - int1ϕ(x1i-x0i-3)<<(ϕ+1)
// = (x1-x0)<<1 - (fxOneAndAHalf-x0f)<<1 - int1ϕ(x1i-x0i-3)<<(ϕ+1)
//
// Re-arranging the defintions given above:
// x0Floor := int1ϕ(x0i) << ϕ
// x0f := x0 - x0Floor
// x1Ceil := int1ϕ(x1i) << ϕ
// x1f := x1 - x1Ceil + fxOne
// combined with fxOne = 1<<ϕ yields:
// x0 = x0f + int1ϕ(x0i)<<ϕ
// x1 = x1f + int1ϕ(x1i-1)<<ϕ
// so that expanding (x1-x0) yields:
// B = (x1f-x0f + int1ϕ(x1i-x0i-1)<<ϕ)<<1 - (fxOneAndAHalf-x0f)<<1 - int1ϕ(x1i-x0i-3)<<(ϕ+1)
// = (x1f-x0f)<<1 + int1ϕ(x1i-x0i-1)<<(ϕ+1) - (fxOneAndAHalf-x0f)<<1 - int1ϕ(x1i-x0i-3)<<(ϕ+1)
// A large part of the second and fourth terms cancel:
// B = (x1f-x0f)<<1 - (fxOneAndAHalf-x0f)<<1 - int1ϕ(-2)<<(ϕ+1)
// = (x1f-x0f)<<1 - (fxOneAndAHalf-x0f)<<1 + 1<<(ϕ+2)
// = (x1f - fxOneAndAHalf)<<1 + 1<<(ϕ+2)
// The first term, (x1f - fxOneAndAHalf)<<1, is a negative
// number, bounded below by -fxOneAndAHalf<<1, which is
// greater than -fxOne<<2, or -1<<(ϕ+2). Thus, B ranges up
// to ±1<<(ϕ+2). One final simplification:
// B = x1f<<1 + (1<<(ϕ+2) - fxOneAndAHalf<<1)
const C = 1<<(ϕ+2) - fxOneAndAHalf<<1
D := x1f<<1 + C // D ranges up to ±1<<(1*ϕ+2).
D <<= ϕ // D ranges up to ±1<<(2*ϕ+2).
D -= x1fSquared // D ranges up to ±1<<(2*ϕ+3).
D *= d // D ranges up to ±1<<(3*ϕ+3).
D /= twoOverS
buf[i] += uint32(D)
}
}
if i := clamp(x1i, width); i < uint(len(buf)) {
// In ideal math: buf[i] += uint32(d * am)
D := x1fSquared // D ranges up to ±1<<(2*ϕ).
D *= d // D ranges up to ±1<<(3*ϕ).
D /= twoOverS
buf[i] += uint32(D)
}
}
x = xNext
}
}
func fixedAccumulateOpOver(dst []uint8, src []uint32) {
// Sanity check that len(dst) >= len(src).
if len(dst) < len(src) {
return
}
acc := int2ϕ(0)
for i, v := range src {
acc += int2ϕ(v)
a := acc
if a < 0 {
a = -a
}
a >>= 2*ϕ - 16
if a > 0xffff {
a = 0xffff
}
// This algorithm comes from the standard library's image/draw package.
dstA := uint32(dst[i]) * 0x101
maskA := uint32(a)
outA := dstA*(0xffff-maskA)/0xffff + maskA
dst[i] = uint8(outA >> 8)
}
}
func fixedAccumulateOpSrc(dst []uint8, src []uint32) {
// Sanity check that len(dst) >= len(src).
if len(dst) < len(src) {
return
}
acc := int2ϕ(0)
for i, v := range src {
acc += int2ϕ(v)
a := acc
if a < 0 {
a = -a
}
a >>= 2*ϕ - 8
if a > 0xff {
a = 0xff
}
dst[i] = uint8(a)
}
}
func fixedAccumulateMask(buf []uint32) {
acc := int2ϕ(0)
for i, v := range buf {
acc += int2ϕ(v)
a := acc
if a < 0 {
a = -a
}
a >>= 2*ϕ - 16
if a > 0xffff {
a = 0xffff
}
buf[i] = uint32(a)
}
}

91
vendor/golang.org/x/image/vector/raster_floating.go сгенерированный поставляемый
Просмотреть файл

@@ -9,8 +9,6 @@ package vector
import (
"math"
"golang.org/x/image/math/f32"
)
func floatingMax(x, y float32) float32 {
@@ -30,38 +28,38 @@ func floatingMin(x, y float32) float32 {
func floatingFloor(x float32) int32 { return int32(math.Floor(float64(x))) }
func floatingCeil(x float32) int32 { return int32(math.Ceil(float64(x))) }
func (z *Rasterizer) floatingLineTo(b f32.Vec2) {
a := z.pen
z.pen = b
func (z *Rasterizer) floatingLineTo(bx, by float32) {
ax, ay := z.penX, z.penY
z.penX, z.penY = bx, by
dir := float32(1)
if a[1] > b[1] {
dir, a, b = -1, b, a
if ay > by {
dir, ax, ay, bx, by = -1, bx, by, ax, ay
}
// Horizontal line segments yield no change in coverage. Almost horizontal
// segments would yield some change, in ideal math, but the computation
// further below, involving 1 / (b[1] - a[1]), is unstable in floating
// point math, so we treat the segment as if it was perfectly horizontal.
if b[1]-a[1] <= 0.000001 {
// further below, involving 1 / (by - ay), is unstable in floating point
// math, so we treat the segment as if it was perfectly horizontal.
if by-ay <= 0.000001 {
return
}
dxdy := (b[0] - a[0]) / (b[1] - a[1])
dxdy := (bx - ax) / (by - ay)
x := a[0]
y := floatingFloor(a[1])
yMax := floatingCeil(b[1])
x := ax
y := floatingFloor(ay)
yMax := floatingCeil(by)
if yMax > int32(z.size.Y) {
yMax = int32(z.size.Y)
}
width := int32(z.size.X)
for ; y < yMax; y++ {
dy := floatingMin(float32(y+1), b[1]) - floatingMax(float32(y), a[1])
dy := floatingMin(float32(y+1), by) - floatingMax(float32(y), ay)
xNext := x + dy*dxdy
if y < 0 {
x = xNext
continue
}
buf := z.area[y*width:]
buf := z.bufF32[y*width:]
d := dy * dir
x0, x1 := x, xNext
if x > xNext {
@@ -122,7 +120,7 @@ func (z *Rasterizer) floatingLineTo(b f32.Vec2) {
}
}
func floatingAccumulate(dst []uint8, src []float32) {
const (
// almost256 scales a floating point value in the range [0, 1] to a uint8
// value in the range [0x00, 0xff].
//
@@ -136,7 +134,44 @@ func floatingAccumulate(dst []uint8, src []float32) {
// instead of the maximal value 0xff.
//
// math.Float32bits(almost256) is 0x437fffff.
const almost256 = 255.99998
almost256 = 255.99998
// almost65536 scales a floating point value in the range [0, 1] to a
// uint16 value in the range [0x0000, 0xffff].
//
// math.Float32bits(almost65536) is 0x477fffff.
almost65536 = almost256 * 256
)
func floatingAccumulateOpOver(dst []uint8, src []float32) {
// Sanity check that len(dst) >= len(src).
if len(dst) < len(src) {
return
}
acc := float32(0)
for i, v := range src {
acc += v
a := acc
if a < 0 {
a = -a
}
if a > 1 {
a = 1
}
// This algorithm comes from the standard library's image/draw package.
dstA := uint32(dst[i]) * 0x101
maskA := uint32(almost65536 * a)
outA := dstA*(0xffff-maskA)/0xffff + maskA
dst[i] = uint8(outA >> 8)
}
}
func floatingAccumulateOpSrc(dst []uint8, src []float32) {
// Sanity check that len(dst) >= len(src).
if len(dst) < len(src) {
return
}
acc := float32(0)
for i, v := range src {
@@ -151,3 +186,23 @@ func floatingAccumulate(dst []uint8, src []float32) {
dst[i] = uint8(almost256 * a)
}
}
func floatingAccumulateMask(dst []uint32, src []float32) {
// Sanity check that len(dst) >= len(src).
if len(dst) < len(src) {
return
}
acc := float32(0)
for i, v := range src {
acc += v
a := acc
if a < 0 {
a = -a
}
if a > 1 {
a = 1
}
dst[i] = uint32(almost65536 * a)
}
}

396
vendor/golang.org/x/image/vector/vector.go сгенерированный поставляемый
Просмотреть файл

@@ -2,6 +2,11 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:generate go run gen.go
//go:generate asmfmt -w acc_amd64.s
// asmfmt is https://github.com/klauspost/asmfmt
// Package vector provides a rasterizer for 2-D vector graphics.
package vector // import "golang.org/x/image/vector"
@@ -18,24 +23,33 @@ package vector // import "golang.org/x/image/vector"
import (
"image"
"image/color"
"image/draw"
"math"
"golang.org/x/image/math/f32"
)
func midPoint(p, q f32.Vec2) f32.Vec2 {
return f32.Vec2{
(p[0] + q[0]) * 0.5,
(p[1] + q[1]) * 0.5,
}
}
// floatingPointMathThreshold is the width or height above which the rasterizer
// chooses to used floating point math instead of fixed point math.
//
// Both implementations of line segmentation rasterization (see raster_fixed.go
// and raster_floating.go) implement the same algorithm (in ideal, infinite
// precision math) but they perform differently in practice. The fixed point
// math version is roughtly 1.25x faster (on GOARCH=amd64) on the benchmarks,
// but at sufficiently large scales, the computations will overflow and hence
// show rendering artifacts. The floating point math version has more
// consistent quality over larger scales, but it is significantly slower.
//
// This constant determines when to use the faster implementation and when to
// use the better quality implementation.
//
// The rationale for this particular value is that TestRasterizePolygon in
// vector_test.go checks the rendering quality of polygon edges at various
// angles, inscribed in a circle of diameter 512. It may be that a higher value
// would still produce acceptable quality, but 512 seems to work.
const floatingPointMathThreshold = 512
func lerp(t float32, p, q f32.Vec2) f32.Vec2 {
return f32.Vec2{
p[0] + t*(q[0]-p[0]),
p[1] + t*(q[1]-p[1]),
}
func lerp(t, px, py, qx, qy float32) (x, y float32) {
return px + t*(qx-px), py + t*(qy-py)
}
func clamp(i, width int32) uint {
@@ -51,18 +65,40 @@ func clamp(i, width int32) uint {
// NewRasterizer returns a new Rasterizer whose rendered mask image is bounded
// by the given width and height.
func NewRasterizer(w, h int) *Rasterizer {
return &Rasterizer{
area: make([]float32, w*h),
size: image.Point{w, h},
}
z := &Rasterizer{}
z.Reset(w, h)
return z
}
// Raster is a 2-D vector graphics rasterizer.
//
// The zero value is usable, in that it is a Rasterizer whose rendered mask
// image has zero width and zero height. Call Reset to change its bounds.
type Rasterizer struct {
area []float32
size image.Point
first f32.Vec2
pen f32.Vec2
// bufXxx are buffers of float32 or uint32 values, holding either the
// individual or cumulative area values.
//
// We don't actually need both values at any given time, and to conserve
// memory, the integration of the individual to the cumulative could modify
// the buffer in place. In other words, we could use a single buffer, say
// of type []uint32, and add some math.Float32bits and math.Float32frombits
// calls to satisfy the compiler's type checking. As of Go 1.7, though,
// there is a performance penalty between:
// bufF32[i] += x
// and
// bufU32[i] = math.Float32bits(x + math.Float32frombits(bufU32[i]))
//
// See golang.org/issue/17220 for some discussion.
bufF32 []float32
bufU32 []uint32
useFloatingPointMath bool
size image.Point
firstX float32
firstY float32
penX float32
penY float32
// DrawOp is the operator used for the Draw method.
//
@@ -77,18 +113,39 @@ type Rasterizer struct {
//
// This includes setting z.DrawOp to draw.Over.
func (z *Rasterizer) Reset(w, h int) {
if n := w * h; n > cap(z.area) {
z.area = make([]float32, n)
z.size = image.Point{w, h}
z.firstX = 0
z.firstY = 0
z.penX = 0
z.penY = 0
z.DrawOp = draw.Over
z.setUseFloatingPointMath(w > floatingPointMathThreshold || h > floatingPointMathThreshold)
}
func (z *Rasterizer) setUseFloatingPointMath(b bool) {
z.useFloatingPointMath = b
// Make z.bufF32 or z.bufU32 large enough to hold width * height samples.
if z.useFloatingPointMath {
if n := z.size.X * z.size.Y; n > cap(z.bufF32) {
z.bufF32 = make([]float32, n)
} else {
z.bufF32 = z.bufF32[:n]
for i := range z.bufF32 {
z.bufF32[i] = 0
}
}
} else {
z.area = z.area[:n]
for i := range z.area {
z.area[i] = 0
if n := z.size.X * z.size.Y; n > cap(z.bufU32) {
z.bufU32 = make([]uint32, n)
} else {
z.bufU32 = z.bufU32[:n]
for i := range z.bufU32 {
z.bufU32[i] = 0
}
}
}
z.size = image.Point{w, h}
z.first = f32.Vec2{}
z.pen = f32.Vec2{}
z.DrawOp = draw.Over
}
// Size returns the width and height passed to NewRasterizer or Reset.
@@ -104,60 +161,66 @@ func (z *Rasterizer) Bounds() image.Rectangle {
// Pen returns the location of the path-drawing pen: the last argument to the
// most recent XxxTo call.
func (z *Rasterizer) Pen() f32.Vec2 {
return z.pen
func (z *Rasterizer) Pen() (x, y float32) {
return z.penX, z.penY
}
// ClosePath closes the current path.
func (z *Rasterizer) ClosePath() {
z.LineTo(z.first)
z.LineTo(z.firstX, z.firstY)
}
// MoveTo starts a new path and moves the pen to a.
// MoveTo starts a new path and moves the pen to (ax, ay).
//
// The coordinates are allowed to be out of the Rasterizer's bounds.
func (z *Rasterizer) MoveTo(a f32.Vec2) {
z.first = a
z.pen = a
func (z *Rasterizer) MoveTo(ax, ay float32) {
z.firstX = ax
z.firstY = ay
z.penX = ax
z.penY = ay
}
// LineTo adds a line segment, from the pen to b, and moves the pen to b.
// LineTo adds a line segment, from the pen to (bx, by), and moves the pen to
// (bx, by).
//
// The coordinates are allowed to be out of the Rasterizer's bounds.
func (z *Rasterizer) LineTo(b f32.Vec2) {
// TODO: add a fixed point math implementation.
z.floatingLineTo(b)
func (z *Rasterizer) LineTo(bx, by float32) {
if z.useFloatingPointMath {
z.floatingLineTo(bx, by)
} else {
z.fixedLineTo(bx, by)
}
}
// QuadTo adds a quadratic Bézier segment, from the pen via b to c, and moves
// the pen to c.
// QuadTo adds a quadratic Bézier segment, from the pen via (bx, by) to (cx,
// cy), and moves the pen to (cx, cy).
//
// The coordinates are allowed to be out of the Rasterizer's bounds.
func (z *Rasterizer) QuadTo(b, c f32.Vec2) {
a := z.pen
devsq := devSquared(a, b, c)
func (z *Rasterizer) QuadTo(bx, by, cx, cy float32) {
ax, ay := z.penX, z.penY
devsq := devSquared(ax, ay, bx, by, cx, cy)
if devsq >= 0.333 {
const tol = 3
n := 1 + int(math.Sqrt(math.Sqrt(tol*float64(devsq))))
t, nInv := float32(0), 1/float32(n)
for i := 0; i < n-1; i++ {
t += nInv
ab := lerp(t, a, b)
bc := lerp(t, b, c)
z.LineTo(lerp(t, ab, bc))
abx, aby := lerp(t, ax, ay, bx, by)
bcx, bcy := lerp(t, bx, by, cx, cy)
z.LineTo(lerp(t, abx, aby, bcx, bcy))
}
}
z.LineTo(c)
z.LineTo(cx, cy)
}
// CubeTo adds a cubic Bézier segment, from the pen via b and c to d, and moves
// the pen to d.
// CubeTo adds a cubic Bézier segment, from the pen via (bx, by) and (cx, cy)
// to (dx, dy), and moves the pen to (dx, dy).
//
// The coordinates are allowed to be out of the Rasterizer's bounds.
func (z *Rasterizer) CubeTo(b, c, d f32.Vec2) {
a := z.pen
devsq := devSquared(a, b, d)
if devsqAlt := devSquared(a, c, d); devsq < devsqAlt {
func (z *Rasterizer) CubeTo(bx, by, cx, cy, dx, dy float32) {
ax, ay := z.penX, z.penY
devsq := devSquared(ax, ay, bx, by, dx, dy)
if devsqAlt := devSquared(ax, ay, cx, cy, dx, dy); devsq < devsqAlt {
devsq = devsqAlt
}
if devsq >= 0.333 {
@@ -166,19 +229,20 @@ func (z *Rasterizer) CubeTo(b, c, d f32.Vec2) {
t, nInv := float32(0), 1/float32(n)
for i := 0; i < n-1; i++ {
t += nInv
ab := lerp(t, a, b)
bc := lerp(t, b, c)
cd := lerp(t, c, d)
abc := lerp(t, ab, bc)
bcd := lerp(t, bc, cd)
z.LineTo(lerp(t, abc, bcd))
abx, aby := lerp(t, ax, ay, bx, by)
bcx, bcy := lerp(t, bx, by, cx, cy)
cdx, cdy := lerp(t, cx, cy, dx, dy)
abcx, abcy := lerp(t, abx, aby, bcx, bcy)
bcdx, bcdy := lerp(t, bcx, bcy, cdx, cdy)
z.LineTo(lerp(t, abcx, abcy, bcdx, bcdy))
}
}
z.LineTo(d)
z.LineTo(dx, dy)
}
// devSquared returns a measure of how curvy the sequnce a to b to c is. It
// determines how many line segments will approximate a Bézier curve segment.
// devSquared returns a measure of how curvy the sequence (ax, ay) to (bx, by)
// to (cx, cy) is. It determines how many line segments will approximate a
// Bézier curve segment.
//
// http://lists.nongnu.org/archive/html/freetype-devel/2016-08/msg00080.html
// gives the rationale for this evenly spaced heuristic instead of a recursive
@@ -190,9 +254,9 @@ func (z *Rasterizer) CubeTo(b, c, d f32.Vec2) {
// Taking a circular arc as a simplifying assumption (ie a spherical cow),
// where I get n, a recursive approach would get 2^⌈lg n⌉, which, if I haven't
// made any horrible mistakes, is expected to be 33% more in the limit.
func devSquared(a, b, c f32.Vec2) float32 {
devx := a[0] - 2*b[0] + c[0]
devy := a[1] - 2*b[1] + c[1]
func devSquared(ax, ay, bx, by, cx, cy float32) float32 {
devx := ax - 2*bx + cx
devy := ay - 2*by + cy
return devx*devx + devy*devy
}
@@ -202,27 +266,207 @@ func devSquared(a, b, c f32.Vec2) float32 {
// The vector paths previously added via the XxxTo calls become the mask for
// drawing src onto dst.
func (z *Rasterizer) Draw(dst draw.Image, r image.Rectangle, src image.Image, sp image.Point) {
// TODO: adjust r and sp (and mp?) if src.Bounds() doesn't contain
// r.Add(sp.Sub(r.Min)).
if src, ok := src.(*image.Uniform); ok {
_, _, _, srcA := src.RGBA()
srcR, srcG, srcB, srcA := src.RGBA()
switch dst := dst.(type) {
case *image.Alpha:
// Fast path for glyph rendering.
if srcA == 0xffff && z.DrawOp == draw.Src {
z.rasterizeDstAlphaSrcOpaqueOpSrc(dst, r)
if srcA == 0xffff {
if z.DrawOp == draw.Over {
z.rasterizeDstAlphaSrcOpaqueOpOver(dst, r)
} else {
z.rasterizeDstAlphaSrcOpaqueOpSrc(dst, r)
}
return
}
case *image.RGBA:
if z.DrawOp == draw.Over {
z.rasterizeDstRGBASrcUniformOpOver(dst, r, srcR, srcG, srcB, srcA)
} else {
z.rasterizeDstRGBASrcUniformOpSrc(dst, r, srcR, srcG, srcB, srcA)
}
return
}
}
if z.DrawOp == draw.Over {
z.rasterizeOpOver(dst, r, src, sp)
} else {
z.rasterizeOpSrc(dst, r, src, sp)
}
}
func (z *Rasterizer) accumulateMask() {
if z.useFloatingPointMath {
if n := z.size.X * z.size.Y; n > cap(z.bufU32) {
z.bufU32 = make([]uint32, n)
} else {
z.bufU32 = z.bufU32[:n]
}
if haveFloatingAccumulateSIMD {
floatingAccumulateMaskSIMD(z.bufU32, z.bufF32)
} else {
floatingAccumulateMask(z.bufU32, z.bufF32)
}
} else {
if haveFixedAccumulateSIMD {
fixedAccumulateMaskSIMD(z.bufU32)
} else {
fixedAccumulateMask(z.bufU32)
}
}
}
func (z *Rasterizer) rasterizeDstAlphaSrcOpaqueOpOver(dst *image.Alpha, r image.Rectangle) {
// TODO: non-zero vs even-odd winding?
if r == dst.Bounds() && r == z.Bounds() {
// We bypass the z.accumulateMask step and convert straight from
// z.bufF32 or z.bufU32 to dst.Pix.
if z.useFloatingPointMath {
if haveFloatingAccumulateSIMD {
floatingAccumulateOpOverSIMD(dst.Pix, z.bufF32)
} else {
floatingAccumulateOpOver(dst.Pix, z.bufF32)
}
} else {
if haveFixedAccumulateSIMD {
fixedAccumulateOpOverSIMD(dst.Pix, z.bufU32)
} else {
fixedAccumulateOpOver(dst.Pix, z.bufU32)
}
}
return
}
z.accumulateMask()
pix := dst.Pix[dst.PixOffset(r.Min.X, r.Min.Y):]
for y, y1 := 0, r.Max.Y-r.Min.Y; y < y1; y++ {
for x, x1 := 0, r.Max.X-r.Min.X; x < x1; x++ {
ma := z.bufU32[y*z.size.X+x]
i := y*dst.Stride + x
// This formula is like rasterizeOpOver's, simplified for the
// concrete dst type and opaque src assumption.
a := 0xffff - ma
pix[i] = uint8((uint32(pix[i])*0x101*a/0xffff + ma) >> 8)
}
}
println("TODO: the general case")
}
func (z *Rasterizer) rasterizeDstAlphaSrcOpaqueOpSrc(dst *image.Alpha, r image.Rectangle) {
// TODO: add SIMD implementations.
// TODO: add a fixed point math implementation.
// TODO: non-zero vs even-odd winding?
if r == dst.Bounds() && r == z.Bounds() {
floatingAccumulate(dst.Pix, z.area)
// We bypass the z.accumulateMask step and convert straight from
// z.bufF32 or z.bufU32 to dst.Pix.
if z.useFloatingPointMath {
if haveFloatingAccumulateSIMD {
floatingAccumulateOpSrcSIMD(dst.Pix, z.bufF32)
} else {
floatingAccumulateOpSrc(dst.Pix, z.bufF32)
}
} else {
if haveFixedAccumulateSIMD {
fixedAccumulateOpSrcSIMD(dst.Pix, z.bufU32)
} else {
fixedAccumulateOpSrc(dst.Pix, z.bufU32)
}
}
return
}
println("TODO: the general case")
z.accumulateMask()
pix := dst.Pix[dst.PixOffset(r.Min.X, r.Min.Y):]
for y, y1 := 0, r.Max.Y-r.Min.Y; y < y1; y++ {
for x, x1 := 0, r.Max.X-r.Min.X; x < x1; x++ {
ma := z.bufU32[y*z.size.X+x]
// This formula is like rasterizeOpSrc's, simplified for the
// concrete dst type and opaque src assumption.
pix[y*dst.Stride+x] = uint8(ma >> 8)
}
}
}
func (z *Rasterizer) rasterizeDstRGBASrcUniformOpOver(dst *image.RGBA, r image.Rectangle, sr, sg, sb, sa uint32) {
z.accumulateMask()
pix := dst.Pix[dst.PixOffset(r.Min.X, r.Min.Y):]
for y, y1 := 0, r.Max.Y-r.Min.Y; y < y1; y++ {
for x, x1 := 0, r.Max.X-r.Min.X; x < x1; x++ {
ma := z.bufU32[y*z.size.X+x]
// This formula is like rasterizeOpOver's, simplified for the
// concrete dst type and uniform src assumption.
a := 0xffff - (sa * ma / 0xffff)
i := y*dst.Stride + 4*x
pix[i+0] = uint8(((uint32(pix[i+0])*0x101*a + sr*ma) / 0xffff) >> 8)
pix[i+1] = uint8(((uint32(pix[i+1])*0x101*a + sg*ma) / 0xffff) >> 8)
pix[i+2] = uint8(((uint32(pix[i+2])*0x101*a + sb*ma) / 0xffff) >> 8)
pix[i+3] = uint8(((uint32(pix[i+3])*0x101*a + sa*ma) / 0xffff) >> 8)
}
}
}
func (z *Rasterizer) rasterizeDstRGBASrcUniformOpSrc(dst *image.RGBA, r image.Rectangle, sr, sg, sb, sa uint32) {
z.accumulateMask()
pix := dst.Pix[dst.PixOffset(r.Min.X, r.Min.Y):]
for y, y1 := 0, r.Max.Y-r.Min.Y; y < y1; y++ {
for x, x1 := 0, r.Max.X-r.Min.X; x < x1; x++ {
ma := z.bufU32[y*z.size.X+x]
// This formula is like rasterizeOpSrc's, simplified for the
// concrete dst type and uniform src assumption.
i := y*dst.Stride + 4*x
pix[i+0] = uint8((sr * ma / 0xffff) >> 8)
pix[i+1] = uint8((sg * ma / 0xffff) >> 8)
pix[i+2] = uint8((sb * ma / 0xffff) >> 8)
pix[i+3] = uint8((sa * ma / 0xffff) >> 8)
}
}
}
func (z *Rasterizer) rasterizeOpOver(dst draw.Image, r image.Rectangle, src image.Image, sp image.Point) {
z.accumulateMask()
out := color.RGBA64{}
outc := color.Color(&out)
for y, y1 := 0, r.Max.Y-r.Min.Y; y < y1; y++ {
for x, x1 := 0, r.Max.X-r.Min.X; x < x1; x++ {
sr, sg, sb, sa := src.At(sp.X+x, sp.Y+y).RGBA()
ma := z.bufU32[y*z.size.X+x]
// This algorithm comes from the standard library's image/draw
// package.
dr, dg, db, da := dst.At(r.Min.X+x, r.Min.Y+y).RGBA()
a := 0xffff - (sa * ma / 0xffff)
out.R = uint16((dr*a + sr*ma) / 0xffff)
out.G = uint16((dg*a + sg*ma) / 0xffff)
out.B = uint16((db*a + sb*ma) / 0xffff)
out.A = uint16((da*a + sa*ma) / 0xffff)
dst.Set(r.Min.X+x, r.Min.Y+y, outc)
}
}
}
func (z *Rasterizer) rasterizeOpSrc(dst draw.Image, r image.Rectangle, src image.Image, sp image.Point) {
z.accumulateMask()
out := color.RGBA64{}
outc := color.Color(&out)
for y, y1 := 0, r.Max.Y-r.Min.Y; y < y1; y++ {
for x, x1 := 0, r.Max.X-r.Min.X; x < x1; x++ {
sr, sg, sb, sa := src.At(sp.X+x, sp.Y+y).RGBA()
ma := z.bufU32[y*z.size.X+x]
// This algorithm comes from the standard library's image/draw
// package.
out.R = uint16(sr * ma / 0xffff)
out.G = uint16(sg * ma / 0xffff)
out.B = uint16(sb * ma / 0xffff)
out.A = uint16(sa * ma / 0xffff)
dst.Set(r.Min.X+x, r.Min.Y+y, outc)
}
}
}

492
vendor/golang.org/x/image/vector/vector_test.go сгенерированный поставляемый
Просмотреть файл

@@ -7,13 +7,16 @@ package vector
// TODO: add tests for NaN and Inf coordinates.
import (
"fmt"
"image"
"image/color"
"image/draw"
"image/png"
"math"
"math/rand"
"os"
"path/filepath"
"testing"
"golang.org/x/image/math/f32"
)
// encodePNG is useful for manually debugging the tests.
@@ -30,47 +33,476 @@ func encodePNG(dstFilename string, src image.Image) error {
return closeErr
}
func TestBasicPath(t *testing.T) {
want := []byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xaa, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x5f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x24, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa1, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x14, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4a, 0x00, 0x00,
0x00, 0x00, 0xcc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0x00, 0x00,
0x00, 0x00, 0x66, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xe4, 0xff, 0xff, 0xff, 0xb6, 0x00, 0x00,
0x00, 0x00, 0x0c, 0xf2, 0xff, 0xff, 0xfe, 0x9e, 0x15, 0x00, 0x15, 0x96, 0xff, 0xce, 0x00, 0x00,
0x00, 0x00, 0x00, 0x88, 0xfc, 0xe3, 0x43, 0x00, 0x00, 0x00, 0x00, 0x06, 0xcd, 0xdc, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0xde, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}
func pointOnCircle(center, radius, index, number int) (x, y float32) {
c := float64(center)
r := float64(radius)
i := float64(index)
n := float64(number)
return float32(c + r*(math.Cos(2*math.Pi*i/n))),
float32(c + r*(math.Sin(2*math.Pi*i/n)))
}
z := NewRasterizer(16, 16)
z.MoveTo(f32.Vec2{2, 2})
z.LineTo(f32.Vec2{8, 2})
z.QuadTo(f32.Vec2{14, 2}, f32.Vec2{14, 14})
z.CubeTo(f32.Vec2{8, 2}, f32.Vec2{5, 20}, f32.Vec2{2, 8})
func TestRasterizeOutOfBounds(t *testing.T) {
// Set this to a non-empty string such as "/tmp" to manually inspect the
// rasterization.
//
// If empty, this test simply checks that calling LineTo with points out of
// the rasterizer's bounds doesn't panic.
const tmpDir = ""
const center, radius, n = 16, 20, 16
var z Rasterizer
for i := 0; i < n; i++ {
for j := 1; j < n/2; j++ {
z.Reset(2*center, 2*center)
z.MoveTo(1*center, 1*center)
z.LineTo(pointOnCircle(center, radius, i+0, n))
z.LineTo(pointOnCircle(center, radius, i+j, n))
z.ClosePath()
z.MoveTo(0*center, 0*center)
z.LineTo(0*center, 2*center)
z.LineTo(2*center, 2*center)
z.LineTo(2*center, 0*center)
z.ClosePath()
dst := image.NewAlpha(z.Bounds())
z.Draw(dst, dst.Bounds(), image.Opaque, image.Point{})
if tmpDir == "" {
continue
}
filename := filepath.Join(tmpDir, fmt.Sprintf("out-%02d-%02d.png", i, j))
if err := encodePNG(filename, dst); err != nil {
t.Error(err)
}
t.Logf("wrote %s", filename)
}
}
}
func TestRasterizePolygon(t *testing.T) {
var z Rasterizer
for radius := 4; radius <= 256; radius *= 2 {
for n := 3; n <= 19; n += 4 {
z.Reset(2*radius, 2*radius)
z.MoveTo(float32(2*radius), float32(1*radius))
for i := 1; i < n; i++ {
z.LineTo(pointOnCircle(radius, radius, i, n))
}
z.ClosePath()
dst := image.NewAlpha(z.Bounds())
z.Draw(dst, dst.Bounds(), image.Opaque, image.Point{})
if err := checkCornersCenter(dst); err != nil {
t.Errorf("radius=%d, n=%d: %v", radius, n, err)
}
}
}
}
func TestRasterizeAlmostAxisAligned(t *testing.T) {
z := NewRasterizer(8, 8)
z.MoveTo(2, 2)
z.LineTo(6, math.Nextafter32(2, 0))
z.LineTo(6, 6)
z.LineTo(math.Nextafter32(2, 0), 6)
z.ClosePath()
dst := image.NewAlpha(z.Bounds())
z.DrawOp = draw.Src
z.Draw(dst, dst.Bounds(), image.Opaque, image.Point{})
got := dst.Pix
if err := checkCornersCenter(dst); err != nil {
t.Error(err)
}
}
func TestRasterizeWideAlmostHorizontalLines(t *testing.T) {
var z Rasterizer
for i := uint(3); i < 16; i++ {
x := float32(int(1 << i))
z.Reset(8, 8)
z.MoveTo(-x, 3)
z.LineTo(+x, 4)
z.LineTo(+x, 6)
z.LineTo(-x, 6)
z.ClosePath()
dst := image.NewAlpha(z.Bounds())
z.Draw(dst, dst.Bounds(), image.Opaque, image.Point{})
if err := checkCornersCenter(dst); err != nil {
t.Errorf("i=%d: %v", i, err)
}
}
}
func TestRasterize30Degrees(t *testing.T) {
z := NewRasterizer(8, 8)
z.MoveTo(4, 4)
z.LineTo(8, 4)
z.LineTo(4, 6)
z.ClosePath()
dst := image.NewAlpha(z.Bounds())
z.Draw(dst, dst.Bounds(), image.Opaque, image.Point{})
if err := checkCornersCenter(dst); err != nil {
t.Error(err)
}
}
func TestRasterizeRandomLineTos(t *testing.T) {
var z Rasterizer
for i := 5; i < 50; i++ {
n, rng := 0, rand.New(rand.NewSource(int64(i)))
z.Reset(i+2, i+2)
z.MoveTo(float32(i/2), float32(i/2))
for ; rng.Intn(16) != 0; n++ {
x := 1 + rng.Intn(i)
y := 1 + rng.Intn(i)
z.LineTo(float32(x), float32(y))
}
z.ClosePath()
dst := image.NewAlpha(z.Bounds())
z.Draw(dst, dst.Bounds(), image.Opaque, image.Point{})
if err := checkCorners(dst); err != nil {
t.Errorf("i=%d (%d nodes): %v", i, n, err)
}
}
}
// checkCornersCenter checks that the corners of the image are all 0x00 and the
// center is 0xff.
func checkCornersCenter(m *image.Alpha) error {
if err := checkCorners(m); err != nil {
return err
}
size := m.Bounds().Size()
center := m.Pix[(size.Y/2)*m.Stride+(size.X/2)]
if center != 0xff {
return fmt.Errorf("center: got %#02x, want 0xff", center)
}
return nil
}
// checkCorners checks that the corners of the image are all 0x00.
func checkCorners(m *image.Alpha) error {
size := m.Bounds().Size()
corners := [4]uint8{
m.Pix[(0*size.Y+0)*m.Stride+(0*size.X+0)],
m.Pix[(0*size.Y+0)*m.Stride+(1*size.X-1)],
m.Pix[(1*size.Y-1)*m.Stride+(0*size.X+0)],
m.Pix[(1*size.Y-1)*m.Stride+(1*size.X-1)],
}
if corners != [4]uint8{} {
return fmt.Errorf("corners were not all zero: %v", corners)
}
return nil
}
var basicMask = []byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xaa, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x5f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x24, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa1, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x14, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4a, 0x00, 0x00,
0x00, 0x00, 0xcc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0x00, 0x00,
0x00, 0x00, 0x66, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xe4, 0xff, 0xff, 0xff, 0xb6, 0x00, 0x00,
0x00, 0x00, 0x0c, 0xf2, 0xff, 0xff, 0xfe, 0x9e, 0x15, 0x00, 0x15, 0x96, 0xff, 0xce, 0x00, 0x00,
0x00, 0x00, 0x00, 0x88, 0xfc, 0xe3, 0x43, 0x00, 0x00, 0x00, 0x00, 0x06, 0xcd, 0xdc, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0xde, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}
func testBasicPath(t *testing.T, prefix string, dst draw.Image, src image.Image, op draw.Op, want []byte) {
z := NewRasterizer(16, 16)
z.MoveTo(2, 2)
z.LineTo(8, 2)
z.QuadTo(14, 2, 14, 14)
z.CubeTo(8, 2, 5, 20, 2, 8)
z.ClosePath()
z.DrawOp = op
z.Draw(dst, z.Bounds(), src, image.Point{})
var got []byte
switch dst := dst.(type) {
case *image.Alpha:
got = dst.Pix
case *image.RGBA:
got = dst.Pix
default:
t.Errorf("%s: unrecognized dst image type %T", prefix, dst)
}
if len(got) != len(want) {
t.Fatalf("len(got)=%d and len(want)=%d differ", len(got), len(want))
t.Errorf("%s: len(got)=%d and len(want)=%d differ", prefix, len(got), len(want))
return
}
for i := range got {
delta := int(got[i]) - int(want[i])
// The +/- 2 allows different implementations to give different
// rounding errors.
if delta < -2 || +2 < delta {
t.Errorf("i=%d: got %#02x, want %#02x", i, got[i], want[i])
t.Errorf("%s: i=%d: got %#02x, want %#02x", prefix, i, got[i], want[i])
return
}
}
}
func TestBasicPathDstAlpha(t *testing.T) {
for _, background := range []uint8{0x00, 0x80} {
for _, op := range []draw.Op{draw.Over, draw.Src} {
for _, xPadding := range []int{0, 7} {
bounds := image.Rect(0, 0, 16+xPadding, 16)
dst := image.NewAlpha(bounds)
for i := range dst.Pix {
dst.Pix[i] = background
}
want := make([]byte, len(dst.Pix))
copy(want, dst.Pix)
if op == draw.Over && background == 0x80 {
for y := 0; y < 16; y++ {
for x := 0; x < 16; x++ {
ma := basicMask[16*y+x]
i := dst.PixOffset(x, y)
want[i] = 0xff - (0xff-ma)/2
}
}
} else {
for y := 0; y < 16; y++ {
for x := 0; x < 16; x++ {
ma := basicMask[16*y+x]
i := dst.PixOffset(x, y)
want[i] = ma
}
}
}
prefix := fmt.Sprintf("background=%#02x, op=%v, xPadding=%d", background, op, xPadding)
testBasicPath(t, prefix, dst, image.Opaque, op, want)
}
}
}
}
func TestBasicPathDstRGBA(t *testing.T) {
blue := image.NewUniform(color.RGBA{0x00, 0x00, 0xff, 0xff})
for _, op := range []draw.Op{draw.Over, draw.Src} {
for _, xPadding := range []int{0, 7} {
bounds := image.Rect(0, 0, 16+xPadding, 16)
dst := image.NewRGBA(bounds)
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
for x := bounds.Min.X; x < bounds.Max.X; x++ {
dst.SetRGBA(x, y, color.RGBA{
R: uint8(y * 0x07),
G: uint8(x * 0x05),
B: 0x00,
A: 0x80,
})
}
}
want := make([]byte, len(dst.Pix))
copy(want, dst.Pix)
if op == draw.Over {
for y := 0; y < 16; y++ {
for x := 0; x < 16; x++ {
ma := basicMask[16*y+x]
i := dst.PixOffset(x, y)
want[i+0] = uint8((uint32(0xff-ma) * uint32(y*0x07)) / 0xff)
want[i+1] = uint8((uint32(0xff-ma) * uint32(x*0x05)) / 0xff)
want[i+2] = ma
want[i+3] = ma/2 + 0x80
}
}
} else {
for y := 0; y < 16; y++ {
for x := 0; x < 16; x++ {
ma := basicMask[16*y+x]
i := dst.PixOffset(x, y)
want[i+0] = 0x00
want[i+1] = 0x00
want[i+2] = ma
want[i+3] = ma
}
}
}
prefix := fmt.Sprintf("op=%v, xPadding=%d", op, xPadding)
testBasicPath(t, prefix, dst, blue, op, want)
}
}
}
const (
benchmarkGlyphWidth = 893
benchmarkGlyphHeight = 1122
)
type benchmarkGlyphDatum struct {
// n being 0, 1 or 2 means moveTo, lineTo or quadTo.
n uint32
px float32
py float32
qx float32
qy float32
}
// benchmarkGlyphData is the 'a' glyph from the Roboto Regular font, translated
// so that its top left corner is (0, 0).
var benchmarkGlyphData = []benchmarkGlyphDatum{
{0, 699, 1102, 0, 0},
{2, 683, 1070, 673, 988},
{2, 544, 1122, 365, 1122},
{2, 205, 1122, 102.5, 1031.5},
{2, 0, 941, 0, 802},
{2, 0, 633, 128.5, 539.5},
{2, 257, 446, 490, 446},
{1, 670, 446, 0, 0},
{1, 670, 361, 0, 0},
{2, 670, 264, 612, 206.5},
{2, 554, 149, 441, 149},
{2, 342, 149, 275, 199},
{2, 208, 249, 208, 320},
{1, 22, 320, 0, 0},
{2, 22, 239, 79.5, 163.5},
{2, 137, 88, 235.5, 44},
{2, 334, 0, 452, 0},
{2, 639, 0, 745, 93.5},
{2, 851, 187, 855, 351},
{1, 855, 849, 0, 0},
{2, 855, 998, 893, 1086},
{1, 893, 1102, 0, 0},
{1, 699, 1102, 0, 0},
{0, 392, 961, 0, 0},
{2, 479, 961, 557, 916},
{2, 635, 871, 670, 799},
{1, 670, 577, 0, 0},
{1, 525, 577, 0, 0},
{2, 185, 577, 185, 776},
{2, 185, 863, 243, 912},
{2, 301, 961, 392, 961},
}
func scaledBenchmarkGlyphData(height int) (width int, data []benchmarkGlyphDatum) {
scale := float32(height) / benchmarkGlyphHeight
// Clone the benchmarkGlyphData slice and scale its coordinates.
data = append(data, benchmarkGlyphData...)
for i := range data {
data[i].px *= scale
data[i].py *= scale
data[i].qx *= scale
data[i].qy *= scale
}
return int(math.Ceil(float64(benchmarkGlyphWidth * scale))), data
}
// benchGlyph benchmarks rasterizing a TrueType glyph.
//
// Note that, compared to the github.com/google/font-go prototype, the height
// here is the height of the bounding box, not the pixels per em used to scale
// a glyph's vectors. A height of 64 corresponds to a ppem greater than 64.
func benchGlyph(b *testing.B, colorModel byte, loose bool, height int, op draw.Op) {
width, data := scaledBenchmarkGlyphData(height)
z := NewRasterizer(width, height)
bounds := z.Bounds()
if loose {
bounds.Max.X++
}
dst, src := draw.Image(nil), image.Image(nil)
switch colorModel {
case 'A':
dst = image.NewAlpha(bounds)
src = image.Opaque
case 'N':
dst = image.NewNRGBA(bounds)
src = image.NewUniform(color.NRGBA{0x40, 0x80, 0xc0, 0xff})
case 'R':
dst = image.NewRGBA(bounds)
src = image.NewUniform(color.RGBA{0x40, 0x80, 0xc0, 0xff})
default:
b.Fatal("unsupported color model")
}
bounds = z.Bounds()
b.ResetTimer()
for i := 0; i < b.N; i++ {
z.Reset(width, height)
z.DrawOp = op
for _, d := range data {
switch d.n {
case 0:
z.MoveTo(d.px, d.py)
case 1:
z.LineTo(d.px, d.py)
case 2:
z.QuadTo(d.px, d.py, d.qx, d.qy)
}
}
z.Draw(dst, bounds, src, image.Point{})
}
}
func BenchmarkGlyphAlpha16Over(b *testing.B) { benchGlyph(b, 'A', false, 16, draw.Over) }
func BenchmarkGlyphAlpha16Src(b *testing.B) { benchGlyph(b, 'A', false, 16, draw.Src) }
func BenchmarkGlyphAlpha32Over(b *testing.B) { benchGlyph(b, 'A', false, 32, draw.Over) }
func BenchmarkGlyphAlpha32Src(b *testing.B) { benchGlyph(b, 'A', false, 32, draw.Src) }
func BenchmarkGlyphAlpha64Over(b *testing.B) { benchGlyph(b, 'A', false, 64, draw.Over) }
func BenchmarkGlyphAlpha64Src(b *testing.B) { benchGlyph(b, 'A', false, 64, draw.Src) }
func BenchmarkGlyphAlpha128Over(b *testing.B) { benchGlyph(b, 'A', false, 128, draw.Over) }
func BenchmarkGlyphAlpha128Src(b *testing.B) { benchGlyph(b, 'A', false, 128, draw.Src) }
func BenchmarkGlyphAlpha256Over(b *testing.B) { benchGlyph(b, 'A', false, 256, draw.Over) }
func BenchmarkGlyphAlpha256Src(b *testing.B) { benchGlyph(b, 'A', false, 256, draw.Src) }
func BenchmarkGlyphAlphaLoose16Over(b *testing.B) { benchGlyph(b, 'A', true, 16, draw.Over) }
func BenchmarkGlyphAlphaLoose16Src(b *testing.B) { benchGlyph(b, 'A', true, 16, draw.Src) }
func BenchmarkGlyphAlphaLoose32Over(b *testing.B) { benchGlyph(b, 'A', true, 32, draw.Over) }
func BenchmarkGlyphAlphaLoose32Src(b *testing.B) { benchGlyph(b, 'A', true, 32, draw.Src) }
func BenchmarkGlyphAlphaLoose64Over(b *testing.B) { benchGlyph(b, 'A', true, 64, draw.Over) }
func BenchmarkGlyphAlphaLoose64Src(b *testing.B) { benchGlyph(b, 'A', true, 64, draw.Src) }
func BenchmarkGlyphAlphaLoose128Over(b *testing.B) { benchGlyph(b, 'A', true, 128, draw.Over) }
func BenchmarkGlyphAlphaLoose128Src(b *testing.B) { benchGlyph(b, 'A', true, 128, draw.Src) }
func BenchmarkGlyphAlphaLoose256Over(b *testing.B) { benchGlyph(b, 'A', true, 256, draw.Over) }
func BenchmarkGlyphAlphaLoose256Src(b *testing.B) { benchGlyph(b, 'A', true, 256, draw.Src) }
func BenchmarkGlyphRGBA16Over(b *testing.B) { benchGlyph(b, 'R', false, 16, draw.Over) }
func BenchmarkGlyphRGBA16Src(b *testing.B) { benchGlyph(b, 'R', false, 16, draw.Src) }
func BenchmarkGlyphRGBA32Over(b *testing.B) { benchGlyph(b, 'R', false, 32, draw.Over) }
func BenchmarkGlyphRGBA32Src(b *testing.B) { benchGlyph(b, 'R', false, 32, draw.Src) }
func BenchmarkGlyphRGBA64Over(b *testing.B) { benchGlyph(b, 'R', false, 64, draw.Over) }
func BenchmarkGlyphRGBA64Src(b *testing.B) { benchGlyph(b, 'R', false, 64, draw.Src) }
func BenchmarkGlyphRGBA128Over(b *testing.B) { benchGlyph(b, 'R', false, 128, draw.Over) }
func BenchmarkGlyphRGBA128Src(b *testing.B) { benchGlyph(b, 'R', false, 128, draw.Src) }
func BenchmarkGlyphRGBA256Over(b *testing.B) { benchGlyph(b, 'R', false, 256, draw.Over) }
func BenchmarkGlyphRGBA256Src(b *testing.B) { benchGlyph(b, 'R', false, 256, draw.Src) }
func BenchmarkGlyphNRGBA16Over(b *testing.B) { benchGlyph(b, 'N', false, 16, draw.Over) }
func BenchmarkGlyphNRGBA16Src(b *testing.B) { benchGlyph(b, 'N', false, 16, draw.Src) }
func BenchmarkGlyphNRGBA32Over(b *testing.B) { benchGlyph(b, 'N', false, 32, draw.Over) }
func BenchmarkGlyphNRGBA32Src(b *testing.B) { benchGlyph(b, 'N', false, 32, draw.Src) }
func BenchmarkGlyphNRGBA64Over(b *testing.B) { benchGlyph(b, 'N', false, 64, draw.Over) }
func BenchmarkGlyphNRGBA64Src(b *testing.B) { benchGlyph(b, 'N', false, 64, draw.Src) }
func BenchmarkGlyphNRGBA128Over(b *testing.B) { benchGlyph(b, 'N', false, 128, draw.Over) }
func BenchmarkGlyphNRGBA128Src(b *testing.B) { benchGlyph(b, 'N', false, 128, draw.Src) }
func BenchmarkGlyphNRGBA256Over(b *testing.B) { benchGlyph(b, 'N', false, 256, draw.Over) }
func BenchmarkGlyphNRGBA256Src(b *testing.B) { benchGlyph(b, 'N', false, 256, draw.Src) }

2
vendor/golang.org/x/net/dict/dict.go сгенерированный поставляемый
Просмотреть файл

@@ -1,4 +1,4 @@
// Copyright 2010 The Go Authors. All rights reserved.
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

12
vendor/golang.org/x/net/http2/go17.go сгенерированный поставляемый
Просмотреть файл

@@ -39,6 +39,13 @@ type clientTrace httptrace.ClientTrace
func reqContext(r *http.Request) context.Context { return r.Context() }
func (t *Transport) idleConnTimeout() time.Duration {
if t.t1 != nil {
return t.t1.IdleConnTimeout
}
return 0
}
func setResponseUncompressed(res *http.Response) { res.Uncompressed = true }
func traceGotConn(req *http.Request, cc *ClientConn) {
@@ -92,3 +99,8 @@ func requestTrace(req *http.Request) *clientTrace {
trace := httptrace.ContextClientTrace(req.Context())
return (*clientTrace)(trace)
}
// Ping sends a PING frame to the server and waits for the ack.
func (cc *ClientConn) Ping(ctx context.Context) error {
return cc.ping(ctx)
}

32
vendor/golang.org/x/net/http2/go18.go сгенерированный поставляемый
Просмотреть файл

@@ -6,6 +6,36 @@
package http2
import "crypto/tls"
import (
"crypto/tls"
"net/http"
)
func cloneTLSConfig(c *tls.Config) *tls.Config { return c.Clone() }
var _ http.Pusher = (*responseWriter)(nil)
// Push implements http.Pusher.
func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
internalOpts := pushOptions{}
if opts != nil {
internalOpts.Method = opts.Method
internalOpts.Header = opts.Header
}
return w.push(target, internalOpts)
}
func configureServer18(h1 *http.Server, h2 *Server) error {
if h2.IdleTimeout == 0 {
if h1.IdleTimeout != 0 {
h2.IdleTimeout = h1.IdleTimeout
} else {
h2.IdleTimeout = h1.ReadTimeout
}
}
return nil
}
func shouldLogPanic(panicValue interface{}) bool {
return panicValue != nil && panicValue != http.ErrAbortHandler
}

66
vendor/golang.org/x/net/http2/go18_test.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,66 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.8
package http2
import (
"net/http"
"testing"
"time"
)
// Tests that http2.Server.IdleTimeout is initialized from
// http.Server.{Idle,Read}Timeout. http.Server.IdleTimeout was
// added in Go 1.8.
func TestConfigureServerIdleTimeout_Go18(t *testing.T) {
const timeout = 5 * time.Second
const notThisOne = 1 * time.Second
// With a zero http2.Server, verify that it copies IdleTimeout:
{
s1 := &http.Server{
IdleTimeout: timeout,
ReadTimeout: notThisOne,
}
s2 := &Server{}
if err := ConfigureServer(s1, s2); err != nil {
t.Fatal(err)
}
if s2.IdleTimeout != timeout {
t.Errorf("s2.IdleTimeout = %v; want %v", s2.IdleTimeout, timeout)
}
}
// And that it falls back to ReadTimeout:
{
s1 := &http.Server{
ReadTimeout: timeout,
}
s2 := &Server{}
if err := ConfigureServer(s1, s2); err != nil {
t.Fatal(err)
}
if s2.IdleTimeout != timeout {
t.Errorf("s2.IdleTimeout = %v; want %v", s2.IdleTimeout, timeout)
}
}
// Verify that s1's IdleTimeout doesn't overwrite an existing setting:
{
s1 := &http.Server{
IdleTimeout: notThisOne,
}
s2 := &Server{
IdleTimeout: timeout,
}
if err := ConfigureServer(s1, s2); err != nil {
t.Fatal(err)
}
if s2.IdleTimeout != timeout {
t.Errorf("s2.IdleTimeout = %v; want %v", s2.IdleTimeout, timeout)
}
}
}

36
vendor/golang.org/x/net/http2/h2demo/h2demo.go сгенерированный поставляемый
Просмотреть файл

@@ -19,6 +19,7 @@ import (
"log"
"net"
"net/http"
"os"
"path"
"regexp"
"runtime"
@@ -27,8 +28,8 @@ import (
"sync"
"time"
"camlistore.org/pkg/googlestorage"
"go4.org/syncutil/singleflight"
"golang.org/x/crypto/acme/autocert"
"golang.org/x/net/http2"
)
@@ -378,37 +379,18 @@ func httpHost() string {
}
func serveProdTLS() error {
c, err := googlestorage.NewServiceClient()
if err != nil {
const cacheDir = "/var/cache/autocert"
if err := os.MkdirAll(cacheDir, 0700); err != nil {
return err
}
slurp := func(key string) ([]byte, error) {
const bucket = "http2-demo-server-tls"
rc, _, err := c.GetObject(&googlestorage.Object{
Bucket: bucket,
Key: key,
})
if err != nil {
return nil, fmt.Errorf("Error fetching GCS object %q in bucket %q: %v", key, bucket, err)
}
defer rc.Close()
return ioutil.ReadAll(rc)
}
certPem, err := slurp("http2.golang.org.chained.pem")
if err != nil {
return err
}
keyPem, err := slurp("http2.golang.org.key")
if err != nil {
return err
}
cert, err := tls.X509KeyPair(certPem, keyPem)
if err != nil {
return err
m := autocert.Manager{
Cache: autocert.DirCache(cacheDir),
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist("http2.golang.org"),
}
srv := &http.Server{
TLSConfig: &tls.Config{
Certificates: []tls.Certificate{cert},
GetCertificate: m.GetCertificate,
},
}
http2.ConfigureServer(srv, &http2.Server{})

8
vendor/golang.org/x/net/http2/h2i/h2i.go сгенерированный поставляемый
Просмотреть файл

@@ -168,7 +168,7 @@ func (app *h2i) Main() error {
app.framer = http2.NewFramer(tc, tc)
oldState, err := terminal.MakeRaw(0)
oldState, err := terminal.MakeRaw(int(os.Stdin.Fd()))
if err != nil {
return err
}
@@ -238,7 +238,7 @@ func (app *h2i) Main() error {
}
func (app *h2i) logf(format string, args ...interface{}) {
fmt.Fprintf(app.term, format+"\n", args...)
fmt.Fprintf(app.term, format+"\r\n", args...)
}
func (app *h2i) readConsole() error {
@@ -435,9 +435,9 @@ func (app *h2i) readFrames() error {
return nil
})
case *http2.WindowUpdateFrame:
app.logf(" Window-Increment = %v\n", f.Increment)
app.logf(" Window-Increment = %v", f.Increment)
case *http2.GoAwayFrame:
app.logf(" Last-Stream-ID = %d; Error-Code = %v (%d)\n", f.LastStreamID, f.ErrCode, f.ErrCode)
app.logf(" Last-Stream-ID = %d; Error-Code = %v (%d)", f.LastStreamID, f.ErrCode, f.ErrCode)
case *http2.DataFrame:
app.logf(" %q", f.Data())
case *http2.HeadersFrame:

36
vendor/golang.org/x/net/http2/http2.go сгенерированный поставляемый
Просмотреть файл

@@ -36,6 +36,7 @@ var (
VerboseLogs bool
logFrameWrites bool
logFrameReads bool
inTests bool
)
func init() {
@@ -77,13 +78,23 @@ var (
type streamState int
// HTTP/2 stream states.
//
// See http://tools.ietf.org/html/rfc7540#section-5.1.
//
// For simplicity, the server code merges "reserved (local)" into
// "half-closed (remote)". This is one less state transition to track.
// The only downside is that we send PUSH_PROMISEs slightly less
// liberally than allowable. More discussion here:
// https://lists.w3.org/Archives/Public/ietf-http-wg/2016JulSep/0599.html
//
// "reserved (remote)" is omitted since the client code does not
// support server push.
const (
stateIdle streamState = iota
stateOpen
stateHalfClosedLocal
stateHalfClosedRemote
stateResvLocal
stateResvRemote
stateClosed
)
@@ -92,8 +103,6 @@ var stateName = [...]string{
stateOpen: "Open",
stateHalfClosedLocal: "HalfClosedLocal",
stateHalfClosedRemote: "HalfClosedRemote",
stateResvLocal: "ResvLocal",
stateResvRemote: "ResvRemote",
stateClosed: "Closed",
}
@@ -253,14 +262,27 @@ func newBufferedWriter(w io.Writer) *bufferedWriter {
return &bufferedWriter{w: w}
}
// bufWriterPoolBufferSize is the size of bufio.Writer's
// buffers created using bufWriterPool.
//
// TODO: pick a less arbitrary value? this is a bit under
// (3 x typical 1500 byte MTU) at least. Other than that,
// not much thought went into it.
const bufWriterPoolBufferSize = 4 << 10
var bufWriterPool = sync.Pool{
New: func() interface{} {
// TODO: pick something better? this is a bit under
// (3 x typical 1500 byte MTU) at least.
return bufio.NewWriterSize(nil, 4<<10)
return bufio.NewWriterSize(nil, bufWriterPoolBufferSize)
},
}
func (w *bufferedWriter) Available() int {
if w.bw == nil {
return bufWriterPoolBufferSize
}
return w.bw.Available()
}
func (w *bufferedWriter) Write(p []byte) (n int, err error) {
if w.bw == nil {
bw := bufWriterPool.Get().(*bufio.Writer)

1
vendor/golang.org/x/net/http2/http2_test.go сгенерированный поставляемый
Просмотреть файл

@@ -27,6 +27,7 @@ func condSkipFailingTest(t *testing.T) {
}
func init() {
inTests = true
DebugGoroutines = true
flag.BoolVar(&VerboseLogs, "verboseh2", VerboseLogs, "Verbose HTTP/2 debug logging")
}

12
vendor/golang.org/x/net/http2/not_go17.go сгенерированный поставляемый
Просмотреть файл

@@ -10,9 +10,13 @@ import (
"crypto/tls"
"net"
"net/http"
"time"
)
type contextContext interface{}
type contextContext interface {
Done() <-chan struct{}
Err() error
}
type fakeContext struct{}
@@ -75,3 +79,9 @@ func cloneTLSConfig(c *tls.Config) *tls.Config {
CurvePreferences: c.CurvePreferences,
}
}
func (cc *ClientConn) Ping(ctx contextContext) error {
return cc.ping(ctx)
}
func (t *Transport) idleConnTimeout() time.Duration { return 0 }

18
vendor/golang.org/x/net/http2/not_go18.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,18 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !go1.8
package http2
import "net/http"
func configureServer18(h1 *http.Server, h2 *Server) error {
// No IdleTimeout to sync prior to Go 1.8.
return nil
}
func shouldLogPanic(panicValue interface{}) bool {
return panicValue != nil
}

118
vendor/golang.org/x/net/http2/priority_test.go сгенерированный поставляемый
Просмотреть файл

@@ -1,118 +0,0 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package http2
import (
"testing"
)
func TestPriority(t *testing.T) {
// A -> B
// move A's parent to B
streams := make(map[uint32]*stream)
a := &stream{
parent: nil,
weight: 16,
}
streams[1] = a
b := &stream{
parent: a,
weight: 16,
}
streams[2] = b
adjustStreamPriority(streams, 1, PriorityParam{
Weight: 20,
StreamDep: 2,
})
if a.parent != b {
t.Errorf("Expected A's parent to be B")
}
if a.weight != 20 {
t.Errorf("Expected A's weight to be 20; got %d", a.weight)
}
if b.parent != nil {
t.Errorf("Expected B to have no parent")
}
if b.weight != 16 {
t.Errorf("Expected B's weight to be 16; got %d", b.weight)
}
}
func TestPriorityExclusiveZero(t *testing.T) {
// A B and C are all children of the 0 stream.
// Exclusive reprioritization to any of the streams
// should bring the rest of the streams under the
// reprioritized stream
streams := make(map[uint32]*stream)
a := &stream{
parent: nil,
weight: 16,
}
streams[1] = a
b := &stream{
parent: nil,
weight: 16,
}
streams[2] = b
c := &stream{
parent: nil,
weight: 16,
}
streams[3] = c
adjustStreamPriority(streams, 3, PriorityParam{
Weight: 20,
StreamDep: 0,
Exclusive: true,
})
if a.parent != c {
t.Errorf("Expected A's parent to be C")
}
if a.weight != 16 {
t.Errorf("Expected A's weight to be 16; got %d", a.weight)
}
if b.parent != c {
t.Errorf("Expected B's parent to be C")
}
if b.weight != 16 {
t.Errorf("Expected B's weight to be 16; got %d", b.weight)
}
if c.parent != nil {
t.Errorf("Expected C to have no parent")
}
if c.weight != 20 {
t.Errorf("Expected C's weight to be 20; got %d", b.weight)
}
}
func TestPriorityOwnParent(t *testing.T) {
streams := make(map[uint32]*stream)
a := &stream{
parent: nil,
weight: 16,
}
streams[1] = a
b := &stream{
parent: a,
weight: 16,
}
streams[2] = b
adjustStreamPriority(streams, 1, PriorityParam{
Weight: 20,
StreamDep: 1,
})
if a.parent != nil {
t.Errorf("Expected A's parent to be nil")
}
if a.weight != 20 {
t.Errorf("Expected A's weight to be 20; got %d", a.weight)
}
if b.parent != a {
t.Errorf("Expected B's parent to be A")
}
if b.weight != 16 {
t.Errorf("Expected B's weight to be 16; got %d", b.weight)
}
}

1016
vendor/golang.org/x/net/http2/server.go сгенерированный поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

470
vendor/golang.org/x/net/http2/server_push_test.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,470 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.8
package http2
import (
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"reflect"
"strconv"
"sync"
"testing"
"time"
)
func TestServer_Push_Success(t *testing.T) {
const (
mainBody = "<html>index page</html>"
pushedBody = "<html>pushed page</html>"
userAgent = "testagent"
cookie = "testcookie"
)
var stURL string
checkPromisedReq := func(r *http.Request, wantMethod string, wantH http.Header) error {
if got, want := r.Method, wantMethod; got != want {
return fmt.Errorf("promised Req.Method=%q, want %q", got, want)
}
if got, want := r.Header, wantH; !reflect.DeepEqual(got, want) {
return fmt.Errorf("promised Req.Header=%q, want %q", got, want)
}
if got, want := "https://"+r.Host, stURL; got != want {
return fmt.Errorf("promised Req.Host=%q, want %q", got, want)
}
if r.Body == nil {
return fmt.Errorf("nil Body")
}
if buf, err := ioutil.ReadAll(r.Body); err != nil || len(buf) != 0 {
return fmt.Errorf("ReadAll(Body)=%q,%v, want '',nil", buf, err)
}
return nil
}
errc := make(chan error, 3)
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
switch r.URL.RequestURI() {
case "/":
// Push "/pushed?get" as a GET request, using an absolute URL.
opt := &http.PushOptions{
Header: http.Header{
"User-Agent": {userAgent},
},
}
if err := w.(http.Pusher).Push(stURL+"/pushed?get", opt); err != nil {
errc <- fmt.Errorf("error pushing /pushed?get: %v", err)
return
}
// Push "/pushed?head" as a HEAD request, using a path.
opt = &http.PushOptions{
Method: "HEAD",
Header: http.Header{
"User-Agent": {userAgent},
"Cookie": {cookie},
},
}
if err := w.(http.Pusher).Push("/pushed?head", opt); err != nil {
errc <- fmt.Errorf("error pushing /pushed?head: %v", err)
return
}
w.Header().Set("Content-Type", "text/html")
w.Header().Set("Content-Length", strconv.Itoa(len(mainBody)))
w.WriteHeader(200)
io.WriteString(w, mainBody)
errc <- nil
case "/pushed?get":
wantH := http.Header{}
wantH.Set("User-Agent", userAgent)
if err := checkPromisedReq(r, "GET", wantH); err != nil {
errc <- fmt.Errorf("/pushed?get: %v", err)
return
}
w.Header().Set("Content-Type", "text/html")
w.Header().Set("Content-Length", strconv.Itoa(len(pushedBody)))
w.WriteHeader(200)
io.WriteString(w, pushedBody)
errc <- nil
case "/pushed?head":
wantH := http.Header{}
wantH.Set("User-Agent", userAgent)
wantH.Set("Cookie", cookie)
if err := checkPromisedReq(r, "HEAD", wantH); err != nil {
errc <- fmt.Errorf("/pushed?head: %v", err)
return
}
w.WriteHeader(204)
errc <- nil
default:
errc <- fmt.Errorf("unknown RequestURL %q", r.URL.RequestURI())
}
})
stURL = st.ts.URL
// Send one request, which should push two responses.
st.greet()
getSlash(st)
for k := 0; k < 3; k++ {
select {
case <-time.After(2 * time.Second):
t.Errorf("timeout waiting for handler %d to finish", k)
case err := <-errc:
if err != nil {
t.Fatal(err)
}
}
}
checkPushPromise := func(f Frame, promiseID uint32, wantH [][2]string) error {
pp, ok := f.(*PushPromiseFrame)
if !ok {
return fmt.Errorf("got a %T; want *PushPromiseFrame", f)
}
if !pp.HeadersEnded() {
return fmt.Errorf("want END_HEADERS flag in PushPromiseFrame")
}
if got, want := pp.PromiseID, promiseID; got != want {
return fmt.Errorf("got PromiseID %v; want %v", got, want)
}
gotH := st.decodeHeader(pp.HeaderBlockFragment())
if !reflect.DeepEqual(gotH, wantH) {
return fmt.Errorf("got promised headers %v; want %v", gotH, wantH)
}
return nil
}
checkHeaders := func(f Frame, wantH [][2]string) error {
hf, ok := f.(*HeadersFrame)
if !ok {
return fmt.Errorf("got a %T; want *HeadersFrame", f)
}
gotH := st.decodeHeader(hf.HeaderBlockFragment())
if !reflect.DeepEqual(gotH, wantH) {
return fmt.Errorf("got response headers %v; want %v", gotH, wantH)
}
return nil
}
checkData := func(f Frame, wantData string) error {
df, ok := f.(*DataFrame)
if !ok {
return fmt.Errorf("got a %T; want *DataFrame", f)
}
if gotData := string(df.Data()); gotData != wantData {
return fmt.Errorf("got response data %q; want %q", gotData, wantData)
}
return nil
}
// Stream 1 has 2 PUSH_PROMISE + HEADERS + DATA
// Stream 2 has HEADERS + DATA
// Stream 4 has HEADERS
expected := map[uint32][]func(Frame) error{
1: {
func(f Frame) error {
return checkPushPromise(f, 2, [][2]string{
{":method", "GET"},
{":scheme", "https"},
{":authority", st.ts.Listener.Addr().String()},
{":path", "/pushed?get"},
{"user-agent", userAgent},
})
},
func(f Frame) error {
return checkPushPromise(f, 4, [][2]string{
{":method", "HEAD"},
{":scheme", "https"},
{":authority", st.ts.Listener.Addr().String()},
{":path", "/pushed?head"},
{"cookie", cookie},
{"user-agent", userAgent},
})
},
func(f Frame) error {
return checkHeaders(f, [][2]string{
{":status", "200"},
{"content-type", "text/html"},
{"content-length", strconv.Itoa(len(mainBody))},
})
},
func(f Frame) error {
return checkData(f, mainBody)
},
},
2: {
func(f Frame) error {
return checkHeaders(f, [][2]string{
{":status", "200"},
{"content-type", "text/html"},
{"content-length", strconv.Itoa(len(pushedBody))},
})
},
func(f Frame) error {
return checkData(f, pushedBody)
},
},
4: {
func(f Frame) error {
return checkHeaders(f, [][2]string{
{":status", "204"},
})
},
},
}
consumed := map[uint32]int{}
for k := 0; len(expected) > 0; k++ {
f, err := st.readFrame()
if err != nil {
for id, left := range expected {
t.Errorf("stream %d: missing %d frames", id, len(left))
}
t.Fatalf("readFrame %d: %v", k, err)
}
id := f.Header().StreamID
label := fmt.Sprintf("stream %d, frame %d", id, consumed[id])
if len(expected[id]) == 0 {
t.Fatalf("%s: unexpected frame %#+v", label, f)
}
check := expected[id][0]
expected[id] = expected[id][1:]
if len(expected[id]) == 0 {
delete(expected, id)
}
if err := check(f); err != nil {
t.Fatalf("%s: %v", label, err)
}
consumed[id]++
}
}
func TestServer_Push_RejectRecursivePush(t *testing.T) {
// Expect two requests, but might get three if there's a bug and the second push succeeds.
errc := make(chan error, 3)
handler := func(w http.ResponseWriter, r *http.Request) error {
baseURL := "https://" + r.Host
switch r.URL.Path {
case "/":
if err := w.(http.Pusher).Push(baseURL+"/push1", nil); err != nil {
return fmt.Errorf("first Push()=%v, want nil", err)
}
return nil
case "/push1":
if got, want := w.(http.Pusher).Push(baseURL+"/push2", nil), ErrRecursivePush; got != want {
return fmt.Errorf("Push()=%v, want %v", got, want)
}
return nil
default:
return fmt.Errorf("unexpected path: %q", r.URL.Path)
}
}
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
errc <- handler(w, r)
})
defer st.Close()
st.greet()
getSlash(st)
if err := <-errc; err != nil {
t.Errorf("First request failed: %v", err)
}
if err := <-errc; err != nil {
t.Errorf("Second request failed: %v", err)
}
}
func testServer_Push_RejectSingleRequest(t *testing.T, doPush func(http.Pusher, *http.Request) error, settings ...Setting) {
// Expect one request, but might get two if there's a bug and the push succeeds.
errc := make(chan error, 2)
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
errc <- doPush(w.(http.Pusher), r)
})
defer st.Close()
st.greet()
if err := st.fr.WriteSettings(settings...); err != nil {
st.t.Fatalf("WriteSettings: %v", err)
}
st.wantSettingsAck()
getSlash(st)
if err := <-errc; err != nil {
t.Error(err)
}
// Should not get a PUSH_PROMISE frame.
hf := st.wantHeaders()
if !hf.StreamEnded() {
t.Error("stream should end after headers")
}
}
func TestServer_Push_RejectIfDisabled(t *testing.T) {
testServer_Push_RejectSingleRequest(t,
func(p http.Pusher, r *http.Request) error {
if got, want := p.Push("https://"+r.Host+"/pushed", nil), http.ErrNotSupported; got != want {
return fmt.Errorf("Push()=%v, want %v", got, want)
}
return nil
},
Setting{SettingEnablePush, 0})
}
func TestServer_Push_RejectWhenNoConcurrentStreams(t *testing.T) {
testServer_Push_RejectSingleRequest(t,
func(p http.Pusher, r *http.Request) error {
if got, want := p.Push("https://"+r.Host+"/pushed", nil), ErrPushLimitReached; got != want {
return fmt.Errorf("Push()=%v, want %v", got, want)
}
return nil
},
Setting{SettingMaxConcurrentStreams, 0})
}
func TestServer_Push_RejectWrongScheme(t *testing.T) {
testServer_Push_RejectSingleRequest(t,
func(p http.Pusher, r *http.Request) error {
if err := p.Push("http://"+r.Host+"/pushed", nil); err == nil {
return errors.New("Push() should have failed (push target URL is http)")
}
return nil
})
}
func TestServer_Push_RejectMissingHost(t *testing.T) {
testServer_Push_RejectSingleRequest(t,
func(p http.Pusher, r *http.Request) error {
if err := p.Push("https:pushed", nil); err == nil {
return errors.New("Push() should have failed (push target URL missing host)")
}
return nil
})
}
func TestServer_Push_RejectRelativePath(t *testing.T) {
testServer_Push_RejectSingleRequest(t,
func(p http.Pusher, r *http.Request) error {
if err := p.Push("../test", nil); err == nil {
return errors.New("Push() should have failed (push target is a relative path)")
}
return nil
})
}
func TestServer_Push_RejectForbiddenMethod(t *testing.T) {
testServer_Push_RejectSingleRequest(t,
func(p http.Pusher, r *http.Request) error {
if err := p.Push("https://"+r.Host+"/pushed", &http.PushOptions{Method: "POST"}); err == nil {
return errors.New("Push() should have failed (cannot promise a POST)")
}
return nil
})
}
func TestServer_Push_RejectForbiddenHeader(t *testing.T) {
testServer_Push_RejectSingleRequest(t,
func(p http.Pusher, r *http.Request) error {
header := http.Header{
"Content-Length": {"10"},
"Content-Encoding": {"gzip"},
"Trailer": {"Foo"},
"Te": {"trailers"},
"Host": {"test.com"},
":authority": {"test.com"},
}
if err := p.Push("https://"+r.Host+"/pushed", &http.PushOptions{Header: header}); err == nil {
return errors.New("Push() should have failed (forbidden headers)")
}
return nil
})
}
func TestServer_Push_StateTransitions(t *testing.T) {
const body = "foo"
startedPromise := make(chan bool)
finishedPush := make(chan bool)
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
switch r.URL.RequestURI() {
case "/":
if err := w.(http.Pusher).Push("/pushed", nil); err != nil {
t.Errorf("Push error: %v", err)
}
close(startedPromise)
// Don't finish this request until the push finishes so we don't
// nondeterministically interleave output frames with the push.
<-finishedPush
}
w.Header().Set("Content-Type", "text/html")
w.Header().Set("Content-Length", strconv.Itoa(len(body)))
w.WriteHeader(200)
io.WriteString(w, body)
})
defer st.Close()
st.greet()
if st.stream(2) != nil {
t.Fatal("stream 2 should be empty")
}
if got, want := st.streamState(2), stateIdle; got != want {
t.Fatalf("streamState(2)=%v, want %v", got, want)
}
getSlash(st)
<-startedPromise
if got, want := st.streamState(2), stateHalfClosedRemote; got != want {
t.Fatalf("streamState(2)=%v, want %v", got, want)
}
st.wantPushPromise()
st.wantHeaders()
if df := st.wantData(); !df.StreamEnded() {
t.Fatal("expected END_STREAM flag on DATA")
}
if got, want := st.streamState(2), stateClosed; got != want {
t.Fatalf("streamState(2)=%v, want %v", got, want)
}
close(finishedPush)
}
func TestServer_Push_RejectAfterGoAway(t *testing.T) {
var readyOnce sync.Once
ready := make(chan struct{})
errc := make(chan error, 2)
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
select {
case <-ready:
case <-time.After(5 * time.Second):
errc <- fmt.Errorf("timeout waiting for GOAWAY to be processed")
}
if got, want := w.(http.Pusher).Push("https://"+r.Host+"/pushed", nil), http.ErrNotSupported; got != want {
errc <- fmt.Errorf("Push()=%v, want %v", got, want)
}
errc <- nil
})
defer st.Close()
st.greet()
getSlash(st)
// Send GOAWAY and wait for it to be processed.
st.fr.WriteGoAway(1, ErrCodeNo, nil)
go func() {
for {
select {
case <-ready:
return
default:
}
st.sc.testHookCh <- func(loopNum int) {
if !st.sc.pushEnabled {
readyOnce.Do(func() { close(ready) })
}
}
}
}()
if err := <-errc; err != nil {
t.Error(err)
}
}

251
vendor/golang.org/x/net/http2/server_test.go сгенерированный поставляемый
Просмотреть файл

@@ -80,18 +80,19 @@ func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...interface{}
tlsConfig := &tls.Config{
InsecureSkipVerify: true,
// The h2-14 is temporary, until curl is updated. (as used by unit tests
// in Docker)
NextProtos: []string{NextProtoTLS, "h2-14"},
NextProtos: []string{NextProtoTLS},
}
var onlyServer, quiet bool
h2server := new(Server)
for _, opt := range opts {
switch v := opt.(type) {
case func(*tls.Config):
v(tlsConfig)
case func(*httptest.Server):
v(ts)
case func(*Server):
v(h2server)
case serverTesterOpt:
switch v {
case optOnlyServer:
@@ -106,7 +107,7 @@ func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...interface{}
}
}
ConfigureServer(ts.Config, &Server{})
ConfigureServer(ts.Config, h2server)
st := &serverTester{
t: t,
@@ -253,6 +254,12 @@ func (st *serverTester) writeHeaders(p HeadersFrameParam) {
}
}
func (st *serverTester) writePriority(id uint32, p PriorityParam) {
if err := st.fr.WritePriority(id, p); err != nil {
st.t.Fatalf("Error writing PRIORITY: %v", err)
}
}
func (st *serverTester) encodeHeaderField(k, v string) {
err := st.hpackEnc.WriteField(hpack.HeaderField{Name: k, Value: v})
if err != nil {
@@ -278,37 +285,42 @@ func (st *serverTester) encodeHeaderRaw(headers ...string) []byte {
// encodeHeader encodes headers and returns their HPACK bytes. headers
// must contain an even number of key/value pairs. There may be
// multiple pairs for keys (e.g. "cookie"). The :method, :path, and
// :scheme headers default to GET, / and https.
// :scheme headers default to GET, / and https. The :authority header
// defaults to st.ts.Listener.Addr().
func (st *serverTester) encodeHeader(headers ...string) []byte {
if len(headers)%2 == 1 {
panic("odd number of kv args")
}
st.headerBuf.Reset()
defaultAuthority := st.ts.Listener.Addr().String()
if len(headers) == 0 {
// Fast path, mostly for benchmarks, so test code doesn't pollute
// profiles when we're looking to improve server allocations.
st.encodeHeaderField(":method", "GET")
st.encodeHeaderField(":path", "/")
st.encodeHeaderField(":scheme", "https")
st.encodeHeaderField(":authority", defaultAuthority)
st.encodeHeaderField(":path", "/")
return st.headerBuf.Bytes()
}
if len(headers) == 2 && headers[0] == ":method" {
// Another fast path for benchmarks.
st.encodeHeaderField(":method", headers[1])
st.encodeHeaderField(":path", "/")
st.encodeHeaderField(":scheme", "https")
st.encodeHeaderField(":authority", defaultAuthority)
st.encodeHeaderField(":path", "/")
return st.headerBuf.Bytes()
}
pseudoCount := map[string]int{}
keys := []string{":method", ":path", ":scheme"}
keys := []string{":method", ":scheme", ":authority", ":path"}
vals := map[string][]string{
":method": {"GET"},
":path": {"/"},
":scheme": {"https"},
":method": {"GET"},
":scheme": {"https"},
":authority": {defaultAuthority},
":path": {"/"},
}
for len(headers) > 0 {
k, v := headers[0], headers[1]
@@ -503,7 +515,18 @@ func (st *serverTester) wantSettingsAck() {
if !sf.Header().Flags.Has(FlagSettingsAck) {
st.t.Fatal("Settings Frame didn't have ACK set")
}
}
func (st *serverTester) wantPushPromise() *PushPromiseFrame {
f, err := st.readFrame()
if err != nil {
st.t.Fatal(err)
}
ppf, ok := f.(*PushPromiseFrame)
if !ok {
st.t.Fatalf("Wanted PushPromise, received %T", ppf)
}
return ppf
}
func TestServer(t *testing.T) {
@@ -758,7 +781,7 @@ func TestServer_Request_Get_Host(t *testing.T) {
testServerRequest(t, func(st *serverTester) {
st.writeHeaders(HeadersFrameParam{
StreamID: 1, // clients send odd numbers
BlockFragment: st.encodeHeader("host", host),
BlockFragment: st.encodeHeader(":authority", "", "host", host),
EndStream: true,
EndHeaders: true,
})
@@ -937,7 +960,7 @@ func TestServer_Request_Reject_Pseudo_Unknown(t *testing.T) {
func testRejectRequest(t *testing.T, send func(*serverTester)) {
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
t.Fatal("server request made it to handler; should've been rejected")
t.Error("server request made it to handler; should've been rejected")
})
defer st.Close()
@@ -946,6 +969,39 @@ func testRejectRequest(t *testing.T, send func(*serverTester)) {
st.wantRSTStream(1, ErrCodeProtocol)
}
func testRejectRequestWithProtocolError(t *testing.T, send func(*serverTester)) {
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
t.Error("server request made it to handler; should've been rejected")
}, optQuiet)
defer st.Close()
st.greet()
send(st)
gf := st.wantGoAway()
if gf.ErrCode != ErrCodeProtocol {
t.Errorf("err code = %v; want %v", gf.ErrCode, ErrCodeProtocol)
}
}
// Section 5.1, on idle connections: "Receiving any frame other than
// HEADERS or PRIORITY on a stream in this state MUST be treated as a
// connection error (Section 5.4.1) of type PROTOCOL_ERROR."
func TestRejectFrameOnIdle_WindowUpdate(t *testing.T) {
testRejectRequestWithProtocolError(t, func(st *serverTester) {
st.fr.WriteWindowUpdate(123, 456)
})
}
func TestRejectFrameOnIdle_Data(t *testing.T) {
testRejectRequestWithProtocolError(t, func(st *serverTester) {
st.fr.WriteData(123, true, nil)
})
}
func TestRejectFrameOnIdle_RSTStream(t *testing.T) {
testRejectRequestWithProtocolError(t, func(st *serverTester) {
st.fr.WriteRSTStream(123, ErrCodeCancel)
})
}
func TestServer_Request_Connect(t *testing.T) {
testServerRequest(t, func(st *serverTester) {
st.writeHeaders(HeadersFrameParam{
@@ -1445,6 +1501,36 @@ func TestServer_Rejects_Continuation0(t *testing.T) {
})
}
// No PRIORITY on stream 0.
func TestServer_Rejects_Priority0(t *testing.T) {
testServerRejectsConn(t, func(st *serverTester) {
st.fr.AllowIllegalWrites = true
st.writePriority(0, PriorityParam{StreamDep: 1})
})
}
// No HEADERS frame with a self-dependence.
func TestServer_Rejects_HeadersSelfDependence(t *testing.T) {
testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) {
st.fr.AllowIllegalWrites = true
st.writeHeaders(HeadersFrameParam{
StreamID: 1,
BlockFragment: st.encodeHeader(),
EndStream: true,
EndHeaders: true,
Priority: PriorityParam{StreamDep: 1},
})
})
}
// No PRIORTY frame with a self-dependence.
func TestServer_Rejects_PrioritySelfDependence(t *testing.T) {
testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) {
st.fr.AllowIllegalWrites = true
st.writePriority(1, PriorityParam{StreamDep: 1})
})
}
func TestServer_Rejects_PushPromise(t *testing.T) {
testServerRejectsConn(t, func(st *serverTester) {
pp := PushPromiseParam{
@@ -2840,6 +2926,12 @@ func BenchmarkServerPosts(b *testing.B) {
const msg = "Hello, world"
st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) {
// Consume the (empty) body from th peer before replying, otherwise
// the server will sometimes (depending on scheduling) send the peer a
// a RST_STREAM with the CANCEL error code.
if n, err := io.Copy(ioutil.Discard, r.Body); n != 0 || err != nil {
b.Errorf("Copy error; got %v, %v; want 0, nil", n, err)
}
io.WriteString(w, msg)
})
defer st.Close()
@@ -3236,40 +3328,40 @@ func (he *hpackEncoder) encodeHeaderRaw(t *testing.T, headers ...string) []byte
func TestCheckValidHTTP2Request(t *testing.T) {
tests := []struct {
req *http.Request
h http.Header
want error
}{
{
req: &http.Request{Header: http.Header{"Te": {"trailers"}}},
h: http.Header{"Te": {"trailers"}},
want: nil,
},
{
req: &http.Request{Header: http.Header{"Te": {"trailers", "bogus"}}},
h: http.Header{"Te": {"trailers", "bogus"}},
want: errors.New(`request header "TE" may only be "trailers" in HTTP/2`),
},
{
req: &http.Request{Header: http.Header{"Foo": {""}}},
h: http.Header{"Foo": {""}},
want: nil,
},
{
req: &http.Request{Header: http.Header{"Connection": {""}}},
h: http.Header{"Connection": {""}},
want: errors.New(`request header "Connection" is not valid in HTTP/2`),
},
{
req: &http.Request{Header: http.Header{"Proxy-Connection": {""}}},
h: http.Header{"Proxy-Connection": {""}},
want: errors.New(`request header "Proxy-Connection" is not valid in HTTP/2`),
},
{
req: &http.Request{Header: http.Header{"Keep-Alive": {""}}},
h: http.Header{"Keep-Alive": {""}},
want: errors.New(`request header "Keep-Alive" is not valid in HTTP/2`),
},
{
req: &http.Request{Header: http.Header{"Upgrade": {""}}},
h: http.Header{"Upgrade": {""}},
want: errors.New(`request header "Upgrade" is not valid in HTTP/2`),
},
}
for i, tt := range tests {
got := checkValidHTTP2Request(tt.req)
got := checkValidHTTP2RequestHeaders(tt.h)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("%d. checkValidHTTP2Request = %v; want %v", i, got, tt.want)
}
@@ -3366,3 +3458,118 @@ func TestUnreadFlowControlReturned_Server(t *testing.T) {
}
}
func TestServerIdleTimeout(t *testing.T) {
if testing.Short() {
t.Skip("skipping in short mode")
}
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
}, func(h2s *Server) {
h2s.IdleTimeout = 500 * time.Millisecond
})
defer st.Close()
st.greet()
ga := st.wantGoAway()
if ga.ErrCode != ErrCodeNo {
t.Errorf("GOAWAY error = %v; want ErrCodeNo", ga.ErrCode)
}
}
func TestServerIdleTimeout_AfterRequest(t *testing.T) {
if testing.Short() {
t.Skip("skipping in short mode")
}
const timeout = 250 * time.Millisecond
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
time.Sleep(timeout * 2)
}, func(h2s *Server) {
h2s.IdleTimeout = timeout
})
defer st.Close()
st.greet()
// Send a request which takes twice the timeout. Verifies the
// idle timeout doesn't fire while we're in a request:
st.bodylessReq1()
st.wantHeaders()
// But the idle timeout should be rearmed after the request
// is done:
ga := st.wantGoAway()
if ga.ErrCode != ErrCodeNo {
t.Errorf("GOAWAY error = %v; want ErrCodeNo", ga.ErrCode)
}
}
// grpc-go closes the Request.Body currently with a Read.
// Verify that it doesn't race.
// See https://github.com/grpc/grpc-go/pull/938
func TestRequestBodyReadCloseRace(t *testing.T) {
for i := 0; i < 100; i++ {
body := &requestBody{
pipe: &pipe{
b: new(bytes.Buffer),
},
}
body.pipe.CloseWithError(io.EOF)
done := make(chan bool, 1)
buf := make([]byte, 10)
go func() {
time.Sleep(1 * time.Millisecond)
body.Close()
done <- true
}()
body.Read(buf)
<-done
}
}
func TestServerGracefulShutdown(t *testing.T) {
shutdownCh := make(chan struct{})
defer func() { testh1ServerShutdownChan = nil }()
testh1ServerShutdownChan = func(*http.Server) <-chan struct{} { return shutdownCh }
var st *serverTester
handlerDone := make(chan struct{})
st = newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
defer close(handlerDone)
close(shutdownCh)
ga := st.wantGoAway()
if ga.ErrCode != ErrCodeNo {
t.Errorf("GOAWAY error = %v; want ErrCodeNo", ga.ErrCode)
}
if ga.LastStreamID != 1 {
t.Errorf("GOAWAY LastStreamID = %v; want 1", ga.LastStreamID)
}
w.Header().Set("x-foo", "bar")
})
defer st.Close()
st.greet()
st.bodylessReq1()
<-handlerDone
hf := st.wantHeaders()
goth := st.decodeHeader(hf.HeaderBlockFragment())
wanth := [][2]string{
{":status", "200"},
{"x-foo", "bar"},
{"content-type", "text/plain; charset=utf-8"},
{"content-length", "0"},
}
if !reflect.DeepEqual(goth, wanth) {
t.Errorf("Got headers %v; want %v", goth, wanth)
}
n, err := st.cc.Read([]byte{0})
if n != 0 || err == nil {
t.Errorf("Read = %v, %v; want 0, non-nil", n, err)
}
}

147
vendor/golang.org/x/net/http2/transport.go сгенерированный поставляемый
Просмотреть файл

@@ -10,6 +10,7 @@ import (
"bufio"
"bytes"
"compress/gzip"
"crypto/rand"
"crypto/tls"
"errors"
"fmt"
@@ -150,6 +151,9 @@ type ClientConn struct {
readerDone chan struct{} // closed on error
readerErr error // set before readerDone is closed
idleTimeout time.Duration // or 0 for never
idleTimer *time.Timer
mu sync.Mutex // guards following
cond *sync.Cond // hold mu; broadcast on flow/closed changes
flow flow // our conn-level flow control quota (cs.flow is per stream)
@@ -160,6 +164,7 @@ type ClientConn struct {
goAwayDebug string // goAway frame's debug data, retained as a string
streams map[uint32]*clientStream // client-initiated
nextStreamID uint32
pings map[[8]byte]chan struct{} // in flight ping data to notification channel
bw *bufio.Writer
br *bufio.Reader
fr *Framer
@@ -194,6 +199,7 @@ type clientStream struct {
bytesRemain int64 // -1 means unknown; owned by transportResponseBody.Read
readErr error // sticky read error; owned by transportResponseBody.Read
stopReqBody error // if non-nil, stop writing req body; guarded by cc.mu
didReset bool // whether we sent a RST_STREAM to the server; guarded by cc.mu
peerReset chan struct{} // closed on peer reset
resetErr error // populated before peerReset is closed
@@ -221,15 +227,26 @@ func (cs *clientStream) awaitRequestCancel(req *http.Request) {
}
select {
case <-req.Cancel:
cs.cancelStream()
cs.bufPipe.CloseWithError(errRequestCanceled)
cs.cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
case <-ctx.Done():
cs.cancelStream()
cs.bufPipe.CloseWithError(ctx.Err())
cs.cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
case <-cs.done:
}
}
func (cs *clientStream) cancelStream() {
cs.cc.mu.Lock()
didReset := cs.didReset
cs.didReset = true
cs.cc.mu.Unlock()
if !didReset {
cs.cc.writeStreamReset(cs.ID, ErrCodeCancel, nil)
}
}
// checkResetOrDone reports any error sent in a RST_STREAM frame by the
// server, or errStreamClosed if the stream is complete.
func (cs *clientStream) checkResetOrDone() error {
@@ -431,6 +448,11 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
streams: make(map[uint32]*clientStream),
singleUse: singleUse,
wantSettingsAck: true,
pings: make(map[[8]byte]chan struct{}),
}
if d := t.idleConnTimeout(); d != 0 {
cc.idleTimeout = d
cc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout)
}
if VerboseLogs {
t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr())
@@ -508,6 +530,16 @@ func (cc *ClientConn) canTakeNewRequestLocked() bool {
cc.nextStreamID < math.MaxInt32
}
// onIdleTimeout is called from a time.AfterFunc goroutine. It will
// only be called when we're idle, but because we're coming from a new
// goroutine, there could be a new request coming in at the same time,
// so this simply calls the synchronized closeIfIdle to shut down this
// connection. The timer could just call closeIfIdle, but this is more
// clear.
func (cc *ClientConn) onIdleTimeout() {
cc.closeIfIdle()
}
func (cc *ClientConn) closeIfIdle() {
cc.mu.Lock()
if len(cc.streams) > 0 {
@@ -604,51 +636,37 @@ func (cc *ClientConn) responseHeaderTimeout() time.Duration {
// Certain headers are special-cased as okay but not transmitted later.
func checkConnHeaders(req *http.Request) error {
if v := req.Header.Get("Upgrade"); v != "" {
return errors.New("http2: invalid Upgrade request header")
return fmt.Errorf("http2: invalid Upgrade request header: %q", req.Header["Upgrade"])
}
if v := req.Header.Get("Transfer-Encoding"); (v != "" && v != "chunked") || len(req.Header["Transfer-Encoding"]) > 1 {
return errors.New("http2: invalid Transfer-Encoding request header")
if vv := req.Header["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") {
return fmt.Errorf("http2: invalid Transfer-Encoding request header: %q", vv)
}
if v := req.Header.Get("Connection"); (v != "" && v != "close" && v != "keep-alive") || len(req.Header["Connection"]) > 1 {
return errors.New("http2: invalid Connection request header")
if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "close" && vv[0] != "keep-alive") {
return fmt.Errorf("http2: invalid Connection request header: %q", vv)
}
return nil
}
func bodyAndLength(req *http.Request) (body io.Reader, contentLen int64) {
body = req.Body
if body == nil {
return nil, 0
// actualContentLength returns a sanitized version of
// req.ContentLength, where 0 actually means zero (not unknown) and -1
// means unknown.
func actualContentLength(req *http.Request) int64 {
if req.Body == nil {
return 0
}
if req.ContentLength != 0 {
return req.Body, req.ContentLength
return req.ContentLength
}
// We have a body but a zero content length. Test to see if
// it's actually zero or just unset.
var buf [1]byte
n, rerr := body.Read(buf[:])
if rerr != nil && rerr != io.EOF {
return errorReader{rerr}, -1
}
if n == 1 {
// Oh, guess there is data in this Body Reader after all.
// The ContentLength field just wasn't set.
// Stitch the Body back together again, re-attaching our
// consumed byte.
if rerr == io.EOF {
return bytes.NewReader(buf[:]), 1
}
return io.MultiReader(bytes.NewReader(buf[:]), body), -1
}
// Body is actually zero bytes.
return nil, 0
return -1
}
func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
if err := checkConnHeaders(req); err != nil {
return nil, err
}
if cc.idleTimer != nil {
cc.idleTimer.Stop()
}
trailers, err := commaSeparatedTrailers(req)
if err != nil {
@@ -663,8 +681,9 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
return nil, errClientConnUnusable
}
body, contentLen := bodyAndLength(req)
body := req.Body
hasBody := body != nil
contentLen := actualContentLength(req)
// TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?
var requestedGzip bool
@@ -1046,7 +1065,7 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail
cc.writeHeader(":method", req.Method)
if req.Method != "CONNECT" {
cc.writeHeader(":path", path)
cc.writeHeader(":scheme", "https")
cc.writeHeader(":scheme", req.URL.Scheme)
}
if trailers != "" {
cc.writeHeader("trailer", trailers)
@@ -1173,6 +1192,9 @@ func (cc *ClientConn) streamByID(id uint32, andRemove bool) *clientStream {
if andRemove && cs != nil && !cc.closed {
cc.lastActive = time.Now()
delete(cc.streams, id)
if len(cc.streams) == 0 && cc.idleTimer != nil {
cc.idleTimer.Reset(cc.idleTimeout)
}
close(cs.done)
cc.cond.Broadcast() // wake up checkResetOrDone via clientStream.awaitFlowControl
}
@@ -1229,6 +1251,10 @@ func (rl *clientConnReadLoop) cleanup() {
defer cc.t.connPool().MarkDead(cc)
defer close(cc.readerDone)
if cc.idleTimer != nil {
cc.idleTimer.Stop()
}
// Close any response bodies if the server closes prematurely.
// TODO: also do this if we've written the headers but not
// gotten a response yet.
@@ -1652,9 +1678,10 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error {
cc.bw.Flush()
cc.wmu.Unlock()
}
didReset := cs.didReset
cc.mu.Unlock()
if len(data) > 0 {
if len(data) > 0 && !didReset {
if _, err := cs.bufPipe.Write(data); err != nil {
rl.endStreamError(cs, err)
return err
@@ -1815,10 +1842,56 @@ func (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error {
return nil
}
// Ping sends a PING frame to the server and waits for the ack.
// Public implementation is in go17.go and not_go17.go
func (cc *ClientConn) ping(ctx contextContext) error {
c := make(chan struct{})
// Generate a random payload
var p [8]byte
for {
if _, err := rand.Read(p[:]); err != nil {
return err
}
cc.mu.Lock()
// check for dup before insert
if _, found := cc.pings[p]; !found {
cc.pings[p] = c
cc.mu.Unlock()
break
}
cc.mu.Unlock()
}
cc.wmu.Lock()
if err := cc.fr.WritePing(false, p); err != nil {
cc.wmu.Unlock()
return err
}
if err := cc.bw.Flush(); err != nil {
cc.wmu.Unlock()
return err
}
cc.wmu.Unlock()
select {
case <-c:
return nil
case <-ctx.Done():
return ctx.Err()
case <-cc.readerDone:
// connection closed
return cc.readerErr
}
}
func (rl *clientConnReadLoop) processPing(f *PingFrame) error {
if f.IsAck() {
// 6.7 PING: " An endpoint MUST NOT respond to PING frames
// containing this flag."
cc := rl.cc
cc.mu.Lock()
defer cc.mu.Unlock()
// If ack, notify listener if any
if c, ok := cc.pings[f.Data]; ok {
close(c)
delete(cc.pings, f.Data)
}
return nil
}
cc := rl.cc

147
vendor/golang.org/x/net/http2/transport_test.go сгенерированный поставляемый
Просмотреть файл

@@ -39,6 +39,13 @@ var (
var tlsConfigInsecure = &tls.Config{InsecureSkipVerify: true}
type testContext struct{}
func (testContext) Done() <-chan struct{} { return make(chan struct{}) }
func (testContext) Err() error { panic("should not be called") }
func (testContext) Deadline() (deadline time.Time, ok bool) { return time.Time{}, false }
func (testContext) Value(key interface{}) interface{} { return nil }
func TestTransportExternal(t *testing.T) {
if !*extNet {
t.Skip("skipping external network test")
@@ -52,6 +59,16 @@ func TestTransportExternal(t *testing.T) {
res.Write(os.Stdout)
}
type fakeTLSConn struct {
net.Conn
}
func (c *fakeTLSConn) ConnectionState() tls.ConnectionState {
return tls.ConnectionState{
Version: tls.VersionTLS12,
}
}
func startH2cServer(t *testing.T) net.Listener {
h2Server := &Server{}
l := newLocalListener(t)
@@ -61,8 +78,8 @@ func startH2cServer(t *testing.T) net.Listener {
t.Error(err)
return
}
h2Server.ServeConn(conn, &ServeConnOpts{Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %v", r.URL.Path)
h2Server.ServeConn(&fakeTLSConn{conn}, &ServeConnOpts{Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %v, http: %v", r.URL.Path, r.TLS == nil)
})})
}()
return l
@@ -92,7 +109,7 @@ func TestTransportH2c(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if got, want := string(body), "Hello, /foobar"; got != want {
if got, want := string(body), "Hello, /foobar, http: true"; got != want {
t.Fatalf("response got %v, want %v", got, want)
}
}
@@ -374,6 +391,40 @@ func randString(n int) string {
return string(b)
}
type panicReader struct{}
func (panicReader) Read([]byte) (int, error) { panic("unexpected Read") }
func (panicReader) Close() error { panic("unexpected Close") }
func TestActualContentLength(t *testing.T) {
tests := []struct {
req *http.Request
want int64
}{
// Verify we don't read from Body:
0: {
req: &http.Request{Body: panicReader{}},
want: -1,
},
// nil Body means 0, regardless of ContentLength:
1: {
req: &http.Request{Body: nil, ContentLength: 5},
want: 0,
},
// ContentLength is used if set.
2: {
req: &http.Request{Body: panicReader{}, ContentLength: 5},
want: 5,
},
}
for i, tt := range tests {
got := actualContentLength(tt.req)
if got != tt.want {
t.Errorf("test[%d]: got %d; want %d", i, got, tt.want)
}
}
}
func TestTransportBody(t *testing.T) {
bodyTests := []struct {
body string
@@ -381,8 +432,6 @@ func TestTransportBody(t *testing.T) {
}{
{body: "some message"},
{body: "some message", noContentLen: true},
{body: ""},
{body: "", noContentLen: true},
{body: strings.Repeat("a", 1<<20), noContentLen: true},
{body: strings.Repeat("a", 1<<20)},
{body: randString(16<<10 - 1)},
@@ -1690,12 +1739,12 @@ func TestTransportRejectsConnHeaders(t *testing.T) {
{
key: "Upgrade",
value: []string{"anything"},
want: "ERROR: http2: invalid Upgrade request header",
want: "ERROR: http2: invalid Upgrade request header: [\"anything\"]",
},
{
key: "Connection",
value: []string{"foo"},
want: "ERROR: http2: invalid Connection request header",
want: "ERROR: http2: invalid Connection request header: [\"foo\"]",
},
{
key: "Connection",
@@ -1705,7 +1754,7 @@ func TestTransportRejectsConnHeaders(t *testing.T) {
{
key: "Connection",
value: []string{"close", "something-else"},
want: "ERROR: http2: invalid Connection request header",
want: "ERROR: http2: invalid Connection request header: [\"close\" \"something-else\"]",
},
{
key: "Connection",
@@ -1725,7 +1774,7 @@ func TestTransportRejectsConnHeaders(t *testing.T) {
{
key: "Transfer-Encoding",
value: []string{"foo"},
want: "ERROR: http2: invalid Transfer-Encoding request header",
want: "ERROR: http2: invalid Transfer-Encoding request header: [\"foo\"]",
},
{
key: "Transfer-Encoding",
@@ -1735,7 +1784,7 @@ func TestTransportRejectsConnHeaders(t *testing.T) {
{
key: "Transfer-Encoding",
value: []string{"chunked", "other"},
want: "ERROR: http2: invalid Transfer-Encoding request header",
want: "ERROR: http2: invalid Transfer-Encoding request header: [\"chunked\" \"other\"]",
},
{
key: "Content-Length",
@@ -1898,8 +1947,17 @@ func TestTransportNewTLSConfig(t *testing.T) {
},
}
for i, tt := range tests {
// Ignore the session ticket keys part, which ends up populating
// unexported fields in the Config:
if tt.conf != nil {
tt.conf.SessionTicketsDisabled = true
}
tr := &Transport{TLSClientConfig: tt.conf}
got := tr.newTLSConfig(tt.host)
got.SessionTicketsDisabled = false
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("%d. got %#v; want %#v", i, got, tt.want)
}
@@ -2618,3 +2676,72 @@ func TestRoundTripDoesntConsumeRequestBodyEarly(t *testing.T) {
t.Errorf("Body = %q; want %q", slurp, body)
}
}
func TestClientConnPing(t *testing.T) {
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {}, optOnlyServer)
defer st.Close()
tr := &Transport{TLSClientConfig: tlsConfigInsecure}
defer tr.CloseIdleConnections()
cc, err := tr.dialClientConn(st.ts.Listener.Addr().String(), false)
if err != nil {
t.Fatal(err)
}
if err = cc.Ping(testContext{}); err != nil {
t.Fatal(err)
}
}
// Issue 16974: if the server sent a DATA frame after the user
// canceled the Transport's Request, the Transport previously wrote to a
// closed pipe, got an error, and ended up closing the whole TCP
// connection.
func TestTransportCancelDataResponseRace(t *testing.T) {
cancel := make(chan struct{})
clientGotError := make(chan bool, 1)
const msg = "Hello."
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
if strings.Contains(r.URL.Path, "/hello") {
time.Sleep(50 * time.Millisecond)
io.WriteString(w, msg)
return
}
for i := 0; i < 50; i++ {
io.WriteString(w, "Some data.")
w.(http.Flusher).Flush()
if i == 2 {
close(cancel)
<-clientGotError
}
time.Sleep(10 * time.Millisecond)
}
}, optOnlyServer)
defer st.Close()
tr := &Transport{TLSClientConfig: tlsConfigInsecure}
defer tr.CloseIdleConnections()
c := &http.Client{Transport: tr}
req, _ := http.NewRequest("GET", st.ts.URL, nil)
req.Cancel = cancel
res, err := c.Do(req)
if err != nil {
t.Fatal(err)
}
if _, err = io.Copy(ioutil.Discard, res.Body); err == nil {
t.Fatal("unexpected success")
}
clientGotError <- true
res, err = c.Get(st.ts.URL + "/hello")
if err != nil {
t.Fatal(err)
}
slurp, err := ioutil.ReadAll(res.Body)
if err != nil {
t.Fatal(err)
}
if string(slurp) != msg {
t.Errorf("Got = %q; want %q", slurp, msg)
}
}

167
vendor/golang.org/x/net/http2/write.go сгенерированный поставляемый
Просмотреть файл

@@ -9,6 +9,7 @@ import (
"fmt"
"log"
"net/http"
"net/url"
"time"
"golang.org/x/net/http2/hpack"
@@ -18,6 +19,11 @@ import (
// writeFramer is implemented by any type that is used to write frames.
type writeFramer interface {
writeFrame(writeContext) error
// staysWithinBuffer reports whether this writer promises that
// it will only write less than or equal to size bytes, and it
// won't Flush the write context.
staysWithinBuffer(size int) bool
}
// writeContext is the interface needed by the various frame writer
@@ -62,8 +68,16 @@ func (flushFrameWriter) writeFrame(ctx writeContext) error {
return ctx.Flush()
}
func (flushFrameWriter) staysWithinBuffer(max int) bool { return false }
type writeSettings []Setting
func (s writeSettings) staysWithinBuffer(max int) bool {
const settingSize = 6 // uint16 + uint32
return frameHeaderLen+settingSize*len(s) <= max
}
func (s writeSettings) writeFrame(ctx writeContext) error {
return ctx.Framer().WriteSettings([]Setting(s)...)
}
@@ -83,6 +97,8 @@ func (p *writeGoAway) writeFrame(ctx writeContext) error {
return err
}
func (*writeGoAway) staysWithinBuffer(max int) bool { return false } // flushes
type writeData struct {
streamID uint32
p []byte
@@ -97,6 +113,10 @@ func (w *writeData) writeFrame(ctx writeContext) error {
return ctx.Framer().WriteData(w.streamID, w.endStream, w.p)
}
func (w *writeData) staysWithinBuffer(max int) bool {
return frameHeaderLen+len(w.p) <= max
}
// handlerPanicRST is the message sent from handler goroutines when
// the handler panics.
type handlerPanicRST struct {
@@ -107,22 +127,57 @@ func (hp handlerPanicRST) writeFrame(ctx writeContext) error {
return ctx.Framer().WriteRSTStream(hp.StreamID, ErrCodeInternal)
}
func (hp handlerPanicRST) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max }
func (se StreamError) writeFrame(ctx writeContext) error {
return ctx.Framer().WriteRSTStream(se.StreamID, se.Code)
}
func (se StreamError) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max }
type writePingAck struct{ pf *PingFrame }
func (w writePingAck) writeFrame(ctx writeContext) error {
return ctx.Framer().WritePing(true, w.pf.Data)
}
func (w writePingAck) staysWithinBuffer(max int) bool { return frameHeaderLen+len(w.pf.Data) <= max }
type writeSettingsAck struct{}
func (writeSettingsAck) writeFrame(ctx writeContext) error {
return ctx.Framer().WriteSettingsAck()
}
func (writeSettingsAck) staysWithinBuffer(max int) bool { return frameHeaderLen <= max }
// splitHeaderBlock splits headerBlock into fragments so that each fragment fits
// in a single frame, then calls fn for each fragment. firstFrag/lastFrag are true
// for the first/last fragment, respectively.
func splitHeaderBlock(ctx writeContext, headerBlock []byte, fn func(ctx writeContext, frag []byte, firstFrag, lastFrag bool) error) error {
// For now we're lazy and just pick the minimum MAX_FRAME_SIZE
// that all peers must support (16KB). Later we could care
// more and send larger frames if the peer advertised it, but
// there's little point. Most headers are small anyway (so we
// generally won't have CONTINUATION frames), and extra frames
// only waste 9 bytes anyway.
const maxFrameSize = 16384
first := true
for len(headerBlock) > 0 {
frag := headerBlock
if len(frag) > maxFrameSize {
frag = frag[:maxFrameSize]
}
headerBlock = headerBlock[len(frag):]
if err := fn(ctx, frag, first, len(headerBlock) == 0); err != nil {
return err
}
first = false
}
return nil
}
// writeResHeaders is a request to write a HEADERS and 0+ CONTINUATION frames
// for HTTP response headers or trailers from a server handler.
type writeResHeaders struct {
@@ -144,6 +199,17 @@ func encKV(enc *hpack.Encoder, k, v string) {
enc.WriteField(hpack.HeaderField{Name: k, Value: v})
}
func (w *writeResHeaders) staysWithinBuffer(max int) bool {
// TODO: this is a common one. It'd be nice to return true
// here and get into the fast path if we could be clever and
// calculate the size fast enough, or at least a conservative
// uppper bound that usually fires. (Maybe if w.h and
// w.trailers are nil, so we don't need to enumerate it.)
// Otherwise I'm afraid that just calculating the length to
// answer this question would be slower than the ~2µs benefit.
return false
}
func (w *writeResHeaders) writeFrame(ctx writeContext) error {
enc, buf := ctx.HeaderEncoder()
buf.Reset()
@@ -169,39 +235,69 @@ func (w *writeResHeaders) writeFrame(ctx writeContext) error {
panic("unexpected empty hpack")
}
// For now we're lazy and just pick the minimum MAX_FRAME_SIZE
// that all peers must support (16KB). Later we could care
// more and send larger frames if the peer advertised it, but
// there's little point. Most headers are small anyway (so we
// generally won't have CONTINUATION frames), and extra frames
// only waste 9 bytes anyway.
const maxFrameSize = 16384
return splitHeaderBlock(ctx, headerBlock, w.writeHeaderBlock)
}
first := true
for len(headerBlock) > 0 {
frag := headerBlock
if len(frag) > maxFrameSize {
frag = frag[:maxFrameSize]
}
headerBlock = headerBlock[len(frag):]
endHeaders := len(headerBlock) == 0
var err error
if first {
first = false
err = ctx.Framer().WriteHeaders(HeadersFrameParam{
StreamID: w.streamID,
BlockFragment: frag,
EndStream: w.endStream,
EndHeaders: endHeaders,
})
} else {
err = ctx.Framer().WriteContinuation(w.streamID, endHeaders, frag)
}
if err != nil {
return err
}
func (w *writeResHeaders) writeHeaderBlock(ctx writeContext, frag []byte, firstFrag, lastFrag bool) error {
if firstFrag {
return ctx.Framer().WriteHeaders(HeadersFrameParam{
StreamID: w.streamID,
BlockFragment: frag,
EndStream: w.endStream,
EndHeaders: lastFrag,
})
} else {
return ctx.Framer().WriteContinuation(w.streamID, lastFrag, frag)
}
}
// writePushPromise is a request to write a PUSH_PROMISE and 0+ CONTINUATION frames.
type writePushPromise struct {
streamID uint32 // pusher stream
method string // for :method
url *url.URL // for :scheme, :authority, :path
h http.Header
// Creates an ID for a pushed stream. This runs on serveG just before
// the frame is written. The returned ID is copied to promisedID.
allocatePromisedID func() (uint32, error)
promisedID uint32
}
func (w *writePushPromise) staysWithinBuffer(max int) bool {
// TODO: see writeResHeaders.staysWithinBuffer
return false
}
func (w *writePushPromise) writeFrame(ctx writeContext) error {
enc, buf := ctx.HeaderEncoder()
buf.Reset()
encKV(enc, ":method", w.method)
encKV(enc, ":scheme", w.url.Scheme)
encKV(enc, ":authority", w.url.Host)
encKV(enc, ":path", w.url.RequestURI())
encodeHeaders(enc, w.h, nil)
headerBlock := buf.Bytes()
if len(headerBlock) == 0 {
panic("unexpected empty hpack")
}
return splitHeaderBlock(ctx, headerBlock, w.writeHeaderBlock)
}
func (w *writePushPromise) writeHeaderBlock(ctx writeContext, frag []byte, firstFrag, lastFrag bool) error {
if firstFrag {
return ctx.Framer().WritePushPromise(PushPromiseParam{
StreamID: w.streamID,
PromiseID: w.promisedID,
BlockFragment: frag,
EndHeaders: lastFrag,
})
} else {
return ctx.Framer().WriteContinuation(w.streamID, lastFrag, frag)
}
return nil
}
type write100ContinueHeadersFrame struct {
@@ -220,15 +316,24 @@ func (w write100ContinueHeadersFrame) writeFrame(ctx writeContext) error {
})
}
func (w write100ContinueHeadersFrame) staysWithinBuffer(max int) bool {
// Sloppy but conservative:
return 9+2*(len(":status")+len("100")) <= max
}
type writeWindowUpdate struct {
streamID uint32 // or 0 for conn-level
n uint32
}
func (wu writeWindowUpdate) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max }
func (wu writeWindowUpdate) writeFrame(ctx writeContext) error {
return ctx.Framer().WriteWindowUpdate(wu.streamID, wu.n)
}
// encodeHeaders encodes an http.Header. If keys is not nil, then (k, h[k])
// is encoded only only if k is in keys.
func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) {
if keys == nil {
sorter := sorterPool.Get().(*sorter)

417
vendor/golang.org/x/net/http2/writesched.go сгенерированный поставляемый
Просмотреть файл

@@ -6,14 +6,53 @@ package http2
import "fmt"
// frameWriteMsg is a request to write a frame.
type frameWriteMsg struct {
// WriteScheduler is the interface implemented by HTTP/2 write schedulers.
// Methods are never called concurrently.
type WriteScheduler interface {
// OpenStream opens a new stream in the write scheduler.
// It is illegal to call this with streamID=0 or with a streamID that is
// already open -- the call may panic.
OpenStream(streamID uint32, options OpenStreamOptions)
// CloseStream closes a stream in the write scheduler. Any frames queued on
// this stream should be discarded. It is illegal to call this on a stream
// that is not open -- the call may panic.
CloseStream(streamID uint32)
// AdjustStream adjusts the priority of the given stream. This may be called
// on a stream that has not yet been opened or has been closed. Note that
// RFC 7540 allows PRIORITY frames to be sent on streams in any state. See:
// https://tools.ietf.org/html/rfc7540#section-5.1
AdjustStream(streamID uint32, priority PriorityParam)
// Push queues a frame in the scheduler. In most cases, this will not be
// called with wr.StreamID()!=0 unless that stream is currently open. The one
// exception is RST_STREAM frames, which may be sent on idle or closed streams.
Push(wr FrameWriteRequest)
// Pop dequeues the next frame to write. Returns false if no frames can
// be written. Frames with a given wr.StreamID() are Pop'd in the same
// order they are Push'd.
Pop() (wr FrameWriteRequest, ok bool)
}
// OpenStreamOptions specifies extra options for WriteScheduler.OpenStream.
type OpenStreamOptions struct {
// PusherID is zero if the stream was initiated by the client. Otherwise,
// PusherID names the stream that pushed the newly opened stream.
PusherID uint32
}
// FrameWriteRequest is a request to write a frame.
type FrameWriteRequest struct {
// write is the interface value that does the writing, once the
// writeScheduler (below) has decided to select this frame
// to write. The write functions are all defined in write.go.
// WriteScheduler has selected this frame to write. The write
// functions are all defined in write.go.
write writeFramer
stream *stream // used for prioritization. nil for non-stream frames.
// stream is the stream on which this frame will be written.
// nil for non-stream frames like PING and SETTINGS.
stream *stream
// done, if non-nil, must be a buffered channel with space for
// 1 message and is sent the return value from write (or an
@@ -21,263 +60,169 @@ type frameWriteMsg struct {
done chan error
}
// for debugging only:
func (wm frameWriteMsg) String() string {
var streamID uint32
if wm.stream != nil {
streamID = wm.stream.id
}
var des string
if s, ok := wm.write.(fmt.Stringer); ok {
des = s.String()
} else {
des = fmt.Sprintf("%T", wm.write)
}
return fmt.Sprintf("[frameWriteMsg stream=%d, ch=%v, type: %v]", streamID, wm.done != nil, des)
}
// writeScheduler tracks pending frames to write, priorities, and decides
// the next one to use. It is not thread-safe.
type writeScheduler struct {
// zero are frames not associated with a specific stream.
// They're sent before any stream-specific freams.
zero writeQueue
// maxFrameSize is the maximum size of a DATA frame
// we'll write. Must be non-zero and between 16K-16M.
maxFrameSize uint32
// sq contains the stream-specific queues, keyed by stream ID.
// when a stream is idle, it's deleted from the map.
sq map[uint32]*writeQueue
// canSend is a slice of memory that's reused between frame
// scheduling decisions to hold the list of writeQueues (from sq)
// which have enough flow control data to send. After canSend is
// built, the best is selected.
canSend []*writeQueue
// pool of empty queues for reuse.
queuePool []*writeQueue
}
func (ws *writeScheduler) putEmptyQueue(q *writeQueue) {
if len(q.s) != 0 {
panic("queue must be empty")
}
ws.queuePool = append(ws.queuePool, q)
}
func (ws *writeScheduler) getEmptyQueue() *writeQueue {
ln := len(ws.queuePool)
if ln == 0 {
return new(writeQueue)
}
q := ws.queuePool[ln-1]
ws.queuePool = ws.queuePool[:ln-1]
return q
}
func (ws *writeScheduler) empty() bool { return ws.zero.empty() && len(ws.sq) == 0 }
func (ws *writeScheduler) add(wm frameWriteMsg) {
st := wm.stream
if st == nil {
ws.zero.push(wm)
} else {
ws.streamQueue(st.id).push(wm)
}
}
func (ws *writeScheduler) streamQueue(streamID uint32) *writeQueue {
if q, ok := ws.sq[streamID]; ok {
return q
}
if ws.sq == nil {
ws.sq = make(map[uint32]*writeQueue)
}
q := ws.getEmptyQueue()
ws.sq[streamID] = q
return q
}
// take returns the most important frame to write and removes it from the scheduler.
// It is illegal to call this if the scheduler is empty or if there are no connection-level
// flow control bytes available.
func (ws *writeScheduler) take() (wm frameWriteMsg, ok bool) {
if ws.maxFrameSize == 0 {
panic("internal error: ws.maxFrameSize not initialized or invalid")
}
// If there any frames not associated with streams, prefer those first.
// These are usually SETTINGS, etc.
if !ws.zero.empty() {
return ws.zero.shift(), true
}
if len(ws.sq) == 0 {
return
}
// Next, prioritize frames on streams that aren't DATA frames (no cost).
for id, q := range ws.sq {
if q.firstIsNoCost() {
return ws.takeFrom(id, q)
// StreamID returns the id of the stream this frame will be written to.
// 0 is used for non-stream frames such as PING and SETTINGS.
func (wr FrameWriteRequest) StreamID() uint32 {
if wr.stream == nil {
if se, ok := wr.write.(StreamError); ok {
// (*serverConn).resetStream doesn't set
// stream because it doesn't necessarily have
// one. So special case this type of write
// message.
return se.StreamID
}
}
// Now, all that remains are DATA frames with non-zero bytes to
// send. So pick the best one.
if len(ws.canSend) != 0 {
panic("should be empty")
}
for _, q := range ws.sq {
if n := ws.streamWritableBytes(q); n > 0 {
ws.canSend = append(ws.canSend, q)
}
}
if len(ws.canSend) == 0 {
return
}
defer ws.zeroCanSend()
// TODO: find the best queue
q := ws.canSend[0]
return ws.takeFrom(q.streamID(), q)
}
// zeroCanSend is defered from take.
func (ws *writeScheduler) zeroCanSend() {
for i := range ws.canSend {
ws.canSend[i] = nil
}
ws.canSend = ws.canSend[:0]
}
// streamWritableBytes returns the number of DATA bytes we could write
// from the given queue's stream, if this stream/queue were
// selected. It is an error to call this if q's head isn't a
// *writeData.
func (ws *writeScheduler) streamWritableBytes(q *writeQueue) int32 {
wm := q.head()
ret := wm.stream.flow.available() // max we can write
if ret == 0 {
return 0
}
if int32(ws.maxFrameSize) < ret {
ret = int32(ws.maxFrameSize)
}
if ret == 0 {
panic("internal error: ws.maxFrameSize not initialized or invalid")
}
wd := wm.write.(*writeData)
if len(wd.p) < int(ret) {
ret = int32(len(wd.p))
}
return ret
return wr.stream.id
}
func (ws *writeScheduler) takeFrom(id uint32, q *writeQueue) (wm frameWriteMsg, ok bool) {
wm = q.head()
// If the first item in this queue costs flow control tokens
// and we don't have enough, write as much as we can.
if wd, ok := wm.write.(*writeData); ok && len(wd.p) > 0 {
allowed := wm.stream.flow.available() // max we can write
if allowed == 0 {
// No quota available. Caller can try the next stream.
return frameWriteMsg{}, false
}
if int32(ws.maxFrameSize) < allowed {
allowed = int32(ws.maxFrameSize)
}
// TODO: further restrict the allowed size, because even if
// the peer says it's okay to write 16MB data frames, we might
// want to write smaller ones to properly weight competing
// streams' priorities.
if len(wd.p) > int(allowed) {
wm.stream.flow.take(allowed)
chunk := wd.p[:allowed]
wd.p = wd.p[allowed:]
// Make up a new write message of a valid size, rather
// than shifting one off the queue.
return frameWriteMsg{
stream: wm.stream,
write: &writeData{
streamID: wd.streamID,
p: chunk,
// even if the original had endStream set, there
// arebytes remaining because len(wd.p) > allowed,
// so we know endStream is false:
endStream: false,
},
// our caller is blocking on the final DATA frame, not
// these intermediates, so no need to wait:
done: nil,
}, true
}
wm.stream.flow.take(int32(len(wd.p)))
// DataSize returns the number of flow control bytes that must be consumed
// to write this entire frame. This is 0 for non-DATA frames.
func (wr FrameWriteRequest) DataSize() int {
if wd, ok := wr.write.(*writeData); ok {
return len(wd.p)
}
q.shift()
if q.empty() {
ws.putEmptyQueue(q)
delete(ws.sq, id)
}
return wm, true
return 0
}
func (ws *writeScheduler) forgetStream(id uint32) {
q, ok := ws.sq[id]
if !ok {
return
}
delete(ws.sq, id)
// Consume consumes min(n, available) bytes from this frame, where available
// is the number of flow control bytes available on the stream. Consume returns
// 0, 1, or 2 frames, where the integer return value gives the number of frames
// returned.
//
// If flow control prevents consuming any bytes, this returns (_, _, 0). If
// the entire frame was consumed, this returns (wr, _, 1). Otherwise, this
// returns (consumed, rest, 2), where 'consumed' contains the consumed bytes and
// 'rest' contains the remaining bytes. The consumed bytes are deducted from the
// underlying stream's flow control budget.
func (wr FrameWriteRequest) Consume(n int32) (FrameWriteRequest, FrameWriteRequest, int) {
var empty FrameWriteRequest
// But keep it for others later.
for i := range q.s {
q.s[i] = frameWriteMsg{}
// Non-DATA frames are always consumed whole.
wd, ok := wr.write.(*writeData)
if !ok || len(wd.p) == 0 {
return wr, empty, 1
}
q.s = q.s[:0]
ws.putEmptyQueue(q)
// Might need to split after applying limits.
allowed := wr.stream.flow.available()
if n < allowed {
allowed = n
}
if wr.stream.sc.maxFrameSize < allowed {
allowed = wr.stream.sc.maxFrameSize
}
if allowed <= 0 {
return empty, empty, 0
}
if len(wd.p) > int(allowed) {
wr.stream.flow.take(allowed)
consumed := FrameWriteRequest{
stream: wr.stream,
write: &writeData{
streamID: wd.streamID,
p: wd.p[:allowed],
// Even if the original had endStream set, there
// are bytes remaining because len(wd.p) > allowed,
// so we know endStream is false.
endStream: false,
},
// Our caller is blocking on the final DATA frame, not
// this intermediate frame, so no need to wait.
done: nil,
}
rest := FrameWriteRequest{
stream: wr.stream,
write: &writeData{
streamID: wd.streamID,
p: wd.p[allowed:],
endStream: wd.endStream,
},
done: wr.done,
}
return consumed, rest, 2
}
// The frame is consumed whole.
// NB: This cast cannot overflow because allowed is <= math.MaxInt32.
wr.stream.flow.take(int32(len(wd.p)))
return wr, empty, 1
}
// String is for debugging only.
func (wr FrameWriteRequest) String() string {
var des string
if s, ok := wr.write.(fmt.Stringer); ok {
des = s.String()
} else {
des = fmt.Sprintf("%T", wr.write)
}
return fmt.Sprintf("[FrameWriteRequest stream=%d, ch=%v, writer=%v]", wr.StreamID(), wr.done != nil, des)
}
// writeQueue is used by implementations of WriteScheduler.
type writeQueue struct {
s []frameWriteMsg
s []FrameWriteRequest
}
// streamID returns the stream ID for a non-empty stream-specific queue.
func (q *writeQueue) streamID() uint32 { return q.s[0].stream.id }
func (q *writeQueue) empty() bool { return len(q.s) == 0 }
func (q *writeQueue) push(wm frameWriteMsg) {
q.s = append(q.s, wm)
func (q *writeQueue) push(wr FrameWriteRequest) {
q.s = append(q.s, wr)
}
// head returns the next item that would be removed by shift.
func (q *writeQueue) head() frameWriteMsg {
func (q *writeQueue) shift() FrameWriteRequest {
if len(q.s) == 0 {
panic("invalid use of queue")
}
return q.s[0]
}
func (q *writeQueue) shift() frameWriteMsg {
if len(q.s) == 0 {
panic("invalid use of queue")
}
wm := q.s[0]
wr := q.s[0]
// TODO: less copy-happy queue.
copy(q.s, q.s[1:])
q.s[len(q.s)-1] = frameWriteMsg{}
q.s[len(q.s)-1] = FrameWriteRequest{}
q.s = q.s[:len(q.s)-1]
return wm
return wr
}
func (q *writeQueue) firstIsNoCost() bool {
if df, ok := q.s[0].write.(*writeData); ok {
return len(df.p) == 0
// consume consumes up to n bytes from q.s[0]. If the frame is
// entirely consumed, it is removed from the queue. If the frame
// is partially consumed, the frame is kept with the consumed
// bytes removed. Returns true iff any bytes were consumed.
func (q *writeQueue) consume(n int32) (FrameWriteRequest, bool) {
if len(q.s) == 0 {
return FrameWriteRequest{}, false
}
return true
consumed, rest, numresult := q.s[0].Consume(n)
switch numresult {
case 0:
return FrameWriteRequest{}, false
case 1:
q.shift()
case 2:
q.s[0] = rest
}
return consumed, true
}
type writeQueuePool []*writeQueue
// put inserts an unused writeQueue into the pool.
func (p *writeQueuePool) put(q *writeQueue) {
for i := range q.s {
q.s[i] = FrameWriteRequest{}
}
q.s = q.s[:0]
*p = append(*p, q)
}
// get returns an empty writeQueue.
func (p *writeQueuePool) get() *writeQueue {
ln := len(*p)
if ln == 0 {
return new(writeQueue)
}
x := ln - 1
q := (*p)[x]
(*p)[x] = nil
*p = (*p)[:x]
return q
}

452
vendor/golang.org/x/net/http2/writesched_priority.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,452 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package http2
import (
"fmt"
"math"
"sort"
)
// RFC 7540, Section 5.3.5: the default weight is 16.
const priorityDefaultWeight = 15 // 16 = 15 + 1
// PriorityWriteSchedulerConfig configures a priorityWriteScheduler.
type PriorityWriteSchedulerConfig struct {
// MaxClosedNodesInTree controls the maximum number of closed streams to
// retain in the priority tree. Setting this to zero saves a small amount
// of memory at the cost of performance.
//
// See RFC 7540, Section 5.3.4:
// "It is possible for a stream to become closed while prioritization
// information ... is in transit. ... This potentially creates suboptimal
// prioritization, since the stream could be given a priority that is
// different from what is intended. To avoid these problems, an endpoint
// SHOULD retain stream prioritization state for a period after streams
// become closed. The longer state is retained, the lower the chance that
// streams are assigned incorrect or default priority values."
MaxClosedNodesInTree int
// MaxIdleNodesInTree controls the maximum number of idle streams to
// retain in the priority tree. Setting this to zero saves a small amount
// of memory at the cost of performance.
//
// See RFC 7540, Section 5.3.4:
// Similarly, streams that are in the "idle" state can be assigned
// priority or become a parent of other streams. This allows for the
// creation of a grouping node in the dependency tree, which enables
// more flexible expressions of priority. Idle streams begin with a
// default priority (Section 5.3.5).
MaxIdleNodesInTree int
// ThrottleOutOfOrderWrites enables write throttling to help ensure that
// data is delivered in priority order. This works around a race where
// stream B depends on stream A and both streams are about to call Write
// to queue DATA frames. If B wins the race, a naive scheduler would eagerly
// write as much data from B as possible, but this is suboptimal because A
// is a higher-priority stream. With throttling enabled, we write a small
// amount of data from B to minimize the amount of bandwidth that B can
// steal from A.
ThrottleOutOfOrderWrites bool
}
// NewPriorityWriteScheduler constructs a WriteScheduler that schedules
// frames by following HTTP/2 priorities as described in RFC 7340 Section 5.3.
// If cfg is nil, default options are used.
func NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler {
if cfg == nil {
// For justification of these defaults, see:
// https://docs.google.com/document/d/1oLhNg1skaWD4_DtaoCxdSRN5erEXrH-KnLrMwEpOtFY
cfg = &PriorityWriteSchedulerConfig{
MaxClosedNodesInTree: 10,
MaxIdleNodesInTree: 10,
ThrottleOutOfOrderWrites: false,
}
}
ws := &priorityWriteScheduler{
nodes: make(map[uint32]*priorityNode),
maxClosedNodesInTree: cfg.MaxClosedNodesInTree,
maxIdleNodesInTree: cfg.MaxIdleNodesInTree,
enableWriteThrottle: cfg.ThrottleOutOfOrderWrites,
}
ws.nodes[0] = &ws.root
if cfg.ThrottleOutOfOrderWrites {
ws.writeThrottleLimit = 1024
} else {
ws.writeThrottleLimit = math.MaxInt32
}
return ws
}
type priorityNodeState int
const (
priorityNodeOpen priorityNodeState = iota
priorityNodeClosed
priorityNodeIdle
)
// priorityNode is a node in an HTTP/2 priority tree.
// Each node is associated with a single stream ID.
// See RFC 7540, Section 5.3.
type priorityNode struct {
q writeQueue // queue of pending frames to write
id uint32 // id of the stream, or 0 for the root of the tree
weight uint8 // the actual weight is weight+1, so the value is in [1,256]
state priorityNodeState // open | closed | idle
bytes int64 // number of bytes written by this node, or 0 if closed
subtreeBytes int64 // sum(node.bytes) of all nodes in this subtree
// These links form the priority tree.
parent *priorityNode
kids *priorityNode // start of the kids list
prev, next *priorityNode // doubly-linked list of siblings
}
func (n *priorityNode) setParent(parent *priorityNode) {
if n == parent {
panic("setParent to self")
}
if n.parent == parent {
return
}
// Unlink from current parent.
if parent := n.parent; parent != nil {
if n.prev == nil {
parent.kids = n.next
} else {
n.prev.next = n.next
}
if n.next != nil {
n.next.prev = n.prev
}
}
// Link to new parent.
// If parent=nil, remove n from the tree.
// Always insert at the head of parent.kids (this is assumed by walkReadyInOrder).
n.parent = parent
if parent == nil {
n.next = nil
n.prev = nil
} else {
n.next = parent.kids
n.prev = nil
if n.next != nil {
n.next.prev = n
}
parent.kids = n
}
}
func (n *priorityNode) addBytes(b int64) {
n.bytes += b
for ; n != nil; n = n.parent {
n.subtreeBytes += b
}
}
// walkReadyInOrder iterates over the tree in priority order, calling f for each node
// with a non-empty write queue. When f returns true, this funcion returns true and the
// walk halts. tmp is used as scratch space for sorting.
//
// f(n, openParent) takes two arguments: the node to visit, n, and a bool that is true
// if any ancestor p of n is still open (ignoring the root node).
func (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f func(*priorityNode, bool) bool) bool {
if !n.q.empty() && f(n, openParent) {
return true
}
if n.kids == nil {
return false
}
// Don't consider the root "open" when updating openParent since
// we can't send data frames on the root stream (only control frames).
if n.id != 0 {
openParent = openParent || (n.state == priorityNodeOpen)
}
// Common case: only one kid or all kids have the same weight.
// Some clients don't use weights; other clients (like web browsers)
// use mostly-linear priority trees.
w := n.kids.weight
needSort := false
for k := n.kids.next; k != nil; k = k.next {
if k.weight != w {
needSort = true
break
}
}
if !needSort {
for k := n.kids; k != nil; k = k.next {
if k.walkReadyInOrder(openParent, tmp, f) {
return true
}
}
return false
}
// Uncommon case: sort the child nodes. We remove the kids from the parent,
// then re-insert after sorting so we can reuse tmp for future sort calls.
*tmp = (*tmp)[:0]
for n.kids != nil {
*tmp = append(*tmp, n.kids)
n.kids.setParent(nil)
}
sort.Sort(sortPriorityNodeSiblings(*tmp))
for i := len(*tmp) - 1; i >= 0; i-- {
(*tmp)[i].setParent(n) // setParent inserts at the head of n.kids
}
for k := n.kids; k != nil; k = k.next {
if k.walkReadyInOrder(openParent, tmp, f) {
return true
}
}
return false
}
type sortPriorityNodeSiblings []*priorityNode
func (z sortPriorityNodeSiblings) Len() int { return len(z) }
func (z sortPriorityNodeSiblings) Swap(i, k int) { z[i], z[k] = z[k], z[i] }
func (z sortPriorityNodeSiblings) Less(i, k int) bool {
// Prefer the subtree that has sent fewer bytes relative to its weight.
// See sections 5.3.2 and 5.3.4.
wi, bi := float64(z[i].weight+1), float64(z[i].subtreeBytes)
wk, bk := float64(z[k].weight+1), float64(z[k].subtreeBytes)
if bi == 0 && bk == 0 {
return wi >= wk
}
if bk == 0 {
return false
}
return bi/bk <= wi/wk
}
type priorityWriteScheduler struct {
// root is the root of the priority tree, where root.id = 0.
// The root queues control frames that are not associated with any stream.
root priorityNode
// nodes maps stream ids to priority tree nodes.
nodes map[uint32]*priorityNode
// maxID is the maximum stream id in nodes.
maxID uint32
// lists of nodes that have been closed or are idle, but are kept in
// the tree for improved prioritization. When the lengths exceed either
// maxClosedNodesInTree or maxIdleNodesInTree, old nodes are discarded.
closedNodes, idleNodes []*priorityNode
// From the config.
maxClosedNodesInTree int
maxIdleNodesInTree int
writeThrottleLimit int32
enableWriteThrottle bool
// tmp is scratch space for priorityNode.walkReadyInOrder to reduce allocations.
tmp []*priorityNode
// pool of empty queues for reuse.
queuePool writeQueuePool
}
func (ws *priorityWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) {
// The stream may be currently idle but cannot be opened or closed.
if curr := ws.nodes[streamID]; curr != nil {
if curr.state != priorityNodeIdle {
panic(fmt.Sprintf("stream %d already opened", streamID))
}
curr.state = priorityNodeOpen
return
}
// RFC 7540, Section 5.3.5:
// "All streams are initially assigned a non-exclusive dependency on stream 0x0.
// Pushed streams initially depend on their associated stream. In both cases,
// streams are assigned a default weight of 16."
parent := ws.nodes[options.PusherID]
if parent == nil {
parent = &ws.root
}
n := &priorityNode{
q: *ws.queuePool.get(),
id: streamID,
weight: priorityDefaultWeight,
state: priorityNodeOpen,
}
n.setParent(parent)
ws.nodes[streamID] = n
if streamID > ws.maxID {
ws.maxID = streamID
}
}
func (ws *priorityWriteScheduler) CloseStream(streamID uint32) {
if streamID == 0 {
panic("violation of WriteScheduler interface: cannot close stream 0")
}
if ws.nodes[streamID] == nil {
panic(fmt.Sprintf("violation of WriteScheduler interface: unknown stream %d", streamID))
}
if ws.nodes[streamID].state != priorityNodeOpen {
panic(fmt.Sprintf("violation of WriteScheduler interface: stream %d already closed", streamID))
}
n := ws.nodes[streamID]
n.state = priorityNodeClosed
n.addBytes(-n.bytes)
q := n.q
ws.queuePool.put(&q)
n.q.s = nil
if ws.maxClosedNodesInTree > 0 {
ws.addClosedOrIdleNode(&ws.closedNodes, ws.maxClosedNodesInTree, n)
} else {
ws.removeNode(n)
}
}
func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) {
if streamID == 0 {
panic("adjustPriority on root")
}
// If streamID does not exist, there are two cases:
// - A closed stream that has been removed (this will have ID <= maxID)
// - An idle stream that is being used for "grouping" (this will have ID > maxID)
n := ws.nodes[streamID]
if n == nil {
if streamID <= ws.maxID || ws.maxIdleNodesInTree == 0 {
return
}
ws.maxID = streamID
n = &priorityNode{
q: *ws.queuePool.get(),
id: streamID,
weight: priorityDefaultWeight,
state: priorityNodeIdle,
}
n.setParent(&ws.root)
ws.nodes[streamID] = n
ws.addClosedOrIdleNode(&ws.idleNodes, ws.maxIdleNodesInTree, n)
}
// Section 5.3.1: A dependency on a stream that is not currently in the tree
// results in that stream being given a default priority (Section 5.3.5).
parent := ws.nodes[priority.StreamDep]
if parent == nil {
n.setParent(&ws.root)
n.weight = priorityDefaultWeight
return
}
// Ignore if the client tries to make a node its own parent.
if n == parent {
return
}
// Section 5.3.3:
// "If a stream is made dependent on one of its own dependencies, the
// formerly dependent stream is first moved to be dependent on the
// reprioritized stream's previous parent. The moved dependency retains
// its weight."
//
// That is: if parent depends on n, move parent to depend on n.parent.
for x := parent.parent; x != nil; x = x.parent {
if x == n {
parent.setParent(n.parent)
break
}
}
// Section 5.3.3: The exclusive flag causes the stream to become the sole
// dependency of its parent stream, causing other dependencies to become
// dependent on the exclusive stream.
if priority.Exclusive {
k := parent.kids
for k != nil {
next := k.next
if k != n {
k.setParent(n)
}
k = next
}
}
n.setParent(parent)
n.weight = priority.Weight
}
func (ws *priorityWriteScheduler) Push(wr FrameWriteRequest) {
var n *priorityNode
if id := wr.StreamID(); id == 0 {
n = &ws.root
} else {
n = ws.nodes[id]
if n == nil {
// id is an idle or closed stream. wr should not be a HEADERS or
// DATA frame. However, wr can be a RST_STREAM. In this case, we
// push wr onto the root, rather than creating a new priorityNode,
// since RST_STREAM is tiny and the stream's priority is unknown
// anyway. See issue #17919.
if wr.DataSize() > 0 {
panic("add DATA on non-open stream")
}
n = &ws.root
}
}
n.q.push(wr)
}
func (ws *priorityWriteScheduler) Pop() (wr FrameWriteRequest, ok bool) {
ws.root.walkReadyInOrder(false, &ws.tmp, func(n *priorityNode, openParent bool) bool {
limit := int32(math.MaxInt32)
if openParent {
limit = ws.writeThrottleLimit
}
wr, ok = n.q.consume(limit)
if !ok {
return false
}
n.addBytes(int64(wr.DataSize()))
// If B depends on A and B continuously has data available but A
// does not, gradually increase the throttling limit to allow B to
// steal more and more bandwidth from A.
if openParent {
ws.writeThrottleLimit += 1024
if ws.writeThrottleLimit < 0 {
ws.writeThrottleLimit = math.MaxInt32
}
} else if ws.enableWriteThrottle {
ws.writeThrottleLimit = 1024
}
return true
})
return wr, ok
}
func (ws *priorityWriteScheduler) addClosedOrIdleNode(list *[]*priorityNode, maxSize int, n *priorityNode) {
if maxSize == 0 {
return
}
if len(*list) == maxSize {
// Remove the oldest node, then shift left.
ws.removeNode((*list)[0])
x := (*list)[1:]
copy(*list, x)
*list = (*list)[:len(x)]
}
*list = append(*list, n)
}
func (ws *priorityWriteScheduler) removeNode(n *priorityNode) {
for k := n.kids; k != nil; k = k.next {
k.setParent(n.parent)
}
n.setParent(nil)
delete(ws.nodes, n.id)
}

541
vendor/golang.org/x/net/http2/writesched_priority_test.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,541 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package http2
import (
"bytes"
"fmt"
"sort"
"testing"
)
func defaultPriorityWriteScheduler() *priorityWriteScheduler {
return NewPriorityWriteScheduler(nil).(*priorityWriteScheduler)
}
func checkPriorityWellFormed(ws *priorityWriteScheduler) error {
for id, n := range ws.nodes {
if id != n.id {
return fmt.Errorf("bad ws.nodes: ws.nodes[%d] = %d", id, n.id)
}
if n.parent == nil {
if n.next != nil || n.prev != nil {
return fmt.Errorf("bad node %d: nil parent but prev/next not nil", id)
}
continue
}
found := false
for k := n.parent.kids; k != nil; k = k.next {
if k.id == id {
found = true
break
}
}
if !found {
return fmt.Errorf("bad node %d: not found in parent %d kids list", id, n.parent.id)
}
}
return nil
}
func fmtTree(ws *priorityWriteScheduler, fmtNode func(*priorityNode) string) string {
var ids []int
for _, n := range ws.nodes {
ids = append(ids, int(n.id))
}
sort.Ints(ids)
var buf bytes.Buffer
for _, id := range ids {
if buf.Len() != 0 {
buf.WriteString(" ")
}
if id == 0 {
buf.WriteString(fmtNode(&ws.root))
} else {
buf.WriteString(fmtNode(ws.nodes[uint32(id)]))
}
}
return buf.String()
}
func fmtNodeParentSkipRoot(n *priorityNode) string {
switch {
case n.id == 0:
return ""
case n.parent == nil:
return fmt.Sprintf("%d{parent:nil}", n.id)
default:
return fmt.Sprintf("%d{parent:%d}", n.id, n.parent.id)
}
}
func fmtNodeWeightParentSkipRoot(n *priorityNode) string {
switch {
case n.id == 0:
return ""
case n.parent == nil:
return fmt.Sprintf("%d{weight:%d,parent:nil}", n.id, n.weight)
default:
return fmt.Sprintf("%d{weight:%d,parent:%d}", n.id, n.weight, n.parent.id)
}
}
func TestPriorityTwoStreams(t *testing.T) {
ws := defaultPriorityWriteScheduler()
ws.OpenStream(1, OpenStreamOptions{})
ws.OpenStream(2, OpenStreamOptions{})
want := "1{weight:15,parent:0} 2{weight:15,parent:0}"
if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
t.Errorf("After open\ngot %q\nwant %q", got, want)
}
// Move 1's parent to 2.
ws.AdjustStream(1, PriorityParam{
StreamDep: 2,
Weight: 32,
Exclusive: false,
})
want = "1{weight:32,parent:2} 2{weight:15,parent:0}"
if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
t.Errorf("After adjust\ngot %q\nwant %q", got, want)
}
if err := checkPriorityWellFormed(ws); err != nil {
t.Error(err)
}
}
func TestPriorityAdjustExclusiveZero(t *testing.T) {
// 1, 2, and 3 are all children of the 0 stream.
// Exclusive reprioritization to any of the streams should bring
// the rest of the streams under the reprioritized stream.
ws := defaultPriorityWriteScheduler()
ws.OpenStream(1, OpenStreamOptions{})
ws.OpenStream(2, OpenStreamOptions{})
ws.OpenStream(3, OpenStreamOptions{})
want := "1{weight:15,parent:0} 2{weight:15,parent:0} 3{weight:15,parent:0}"
if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
t.Errorf("After open\ngot %q\nwant %q", got, want)
}
ws.AdjustStream(2, PriorityParam{
StreamDep: 0,
Weight: 20,
Exclusive: true,
})
want = "1{weight:15,parent:2} 2{weight:20,parent:0} 3{weight:15,parent:2}"
if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
t.Errorf("After adjust\ngot %q\nwant %q", got, want)
}
if err := checkPriorityWellFormed(ws); err != nil {
t.Error(err)
}
}
func TestPriorityAdjustOwnParent(t *testing.T) {
// Assigning a node as its own parent should have no effect.
ws := defaultPriorityWriteScheduler()
ws.OpenStream(1, OpenStreamOptions{})
ws.OpenStream(2, OpenStreamOptions{})
ws.AdjustStream(2, PriorityParam{
StreamDep: 2,
Weight: 20,
Exclusive: true,
})
want := "1{weight:15,parent:0} 2{weight:15,parent:0}"
if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
t.Errorf("After adjust\ngot %q\nwant %q", got, want)
}
if err := checkPriorityWellFormed(ws); err != nil {
t.Error(err)
}
}
func TestPriorityClosedStreams(t *testing.T) {
ws := NewPriorityWriteScheduler(&PriorityWriteSchedulerConfig{MaxClosedNodesInTree: 2}).(*priorityWriteScheduler)
ws.OpenStream(1, OpenStreamOptions{})
ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
ws.OpenStream(3, OpenStreamOptions{PusherID: 2})
ws.OpenStream(4, OpenStreamOptions{PusherID: 3})
// Close the first three streams. We lose 1, but keep 2 and 3.
ws.CloseStream(1)
ws.CloseStream(2)
ws.CloseStream(3)
want := "2{weight:15,parent:0} 3{weight:15,parent:2} 4{weight:15,parent:3}"
if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
t.Errorf("After close\ngot %q\nwant %q", got, want)
}
if err := checkPriorityWellFormed(ws); err != nil {
t.Error(err)
}
// Adding a stream as an exclusive child of 1 gives it default
// priorities, since 1 is gone.
ws.OpenStream(5, OpenStreamOptions{})
ws.AdjustStream(5, PriorityParam{StreamDep: 1, Weight: 15, Exclusive: true})
// Adding a stream as an exclusive child of 2 should work, since 2 is not gone.
ws.OpenStream(6, OpenStreamOptions{})
ws.AdjustStream(6, PriorityParam{StreamDep: 2, Weight: 15, Exclusive: true})
want = "2{weight:15,parent:0} 3{weight:15,parent:6} 4{weight:15,parent:3} 5{weight:15,parent:0} 6{weight:15,parent:2}"
if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
t.Errorf("After add streams\ngot %q\nwant %q", got, want)
}
if err := checkPriorityWellFormed(ws); err != nil {
t.Error(err)
}
}
func TestPriorityClosedStreamsDisabled(t *testing.T) {
ws := NewPriorityWriteScheduler(&PriorityWriteSchedulerConfig{}).(*priorityWriteScheduler)
ws.OpenStream(1, OpenStreamOptions{})
ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
ws.OpenStream(3, OpenStreamOptions{PusherID: 2})
// Close the first two streams. We keep only 3.
ws.CloseStream(1)
ws.CloseStream(2)
want := "3{weight:15,parent:0}"
if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
t.Errorf("After close\ngot %q\nwant %q", got, want)
}
if err := checkPriorityWellFormed(ws); err != nil {
t.Error(err)
}
}
func TestPriorityIdleStreams(t *testing.T) {
ws := NewPriorityWriteScheduler(&PriorityWriteSchedulerConfig{MaxIdleNodesInTree: 2}).(*priorityWriteScheduler)
ws.AdjustStream(1, PriorityParam{StreamDep: 0, Weight: 15}) // idle
ws.AdjustStream(2, PriorityParam{StreamDep: 0, Weight: 15}) // idle
ws.AdjustStream(3, PriorityParam{StreamDep: 2, Weight: 20}) // idle
ws.OpenStream(4, OpenStreamOptions{})
ws.OpenStream(5, OpenStreamOptions{})
ws.OpenStream(6, OpenStreamOptions{})
ws.AdjustStream(4, PriorityParam{StreamDep: 1, Weight: 15})
ws.AdjustStream(5, PriorityParam{StreamDep: 2, Weight: 15})
ws.AdjustStream(6, PriorityParam{StreamDep: 3, Weight: 15})
want := "2{weight:15,parent:0} 3{weight:20,parent:2} 4{weight:15,parent:0} 5{weight:15,parent:2} 6{weight:15,parent:3}"
if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
t.Errorf("After open\ngot %q\nwant %q", got, want)
}
if err := checkPriorityWellFormed(ws); err != nil {
t.Error(err)
}
}
func TestPriorityIdleStreamsDisabled(t *testing.T) {
ws := NewPriorityWriteScheduler(&PriorityWriteSchedulerConfig{}).(*priorityWriteScheduler)
ws.AdjustStream(1, PriorityParam{StreamDep: 0, Weight: 15}) // idle
ws.AdjustStream(2, PriorityParam{StreamDep: 0, Weight: 15}) // idle
ws.AdjustStream(3, PriorityParam{StreamDep: 2, Weight: 20}) // idle
ws.OpenStream(4, OpenStreamOptions{})
want := "4{weight:15,parent:0}"
if got := fmtTree(ws, fmtNodeWeightParentSkipRoot); got != want {
t.Errorf("After open\ngot %q\nwant %q", got, want)
}
if err := checkPriorityWellFormed(ws); err != nil {
t.Error(err)
}
}
func TestPrioritySection531NonExclusive(t *testing.T) {
// Example from RFC 7540 Section 5.3.1.
// A,B,C,D = 1,2,3,4
ws := defaultPriorityWriteScheduler()
ws.OpenStream(1, OpenStreamOptions{})
ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
ws.OpenStream(3, OpenStreamOptions{PusherID: 1})
ws.OpenStream(4, OpenStreamOptions{})
ws.AdjustStream(4, PriorityParam{
StreamDep: 1,
Weight: 15,
Exclusive: false,
})
want := "1{parent:0} 2{parent:1} 3{parent:1} 4{parent:1}"
if got := fmtTree(ws, fmtNodeParentSkipRoot); got != want {
t.Errorf("After adjust\ngot %q\nwant %q", got, want)
}
if err := checkPriorityWellFormed(ws); err != nil {
t.Error(err)
}
}
func TestPrioritySection531Exclusive(t *testing.T) {
// Example from RFC 7540 Section 5.3.1.
// A,B,C,D = 1,2,3,4
ws := defaultPriorityWriteScheduler()
ws.OpenStream(1, OpenStreamOptions{})
ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
ws.OpenStream(3, OpenStreamOptions{PusherID: 1})
ws.OpenStream(4, OpenStreamOptions{})
ws.AdjustStream(4, PriorityParam{
StreamDep: 1,
Weight: 15,
Exclusive: true,
})
want := "1{parent:0} 2{parent:4} 3{parent:4} 4{parent:1}"
if got := fmtTree(ws, fmtNodeParentSkipRoot); got != want {
t.Errorf("After adjust\ngot %q\nwant %q", got, want)
}
if err := checkPriorityWellFormed(ws); err != nil {
t.Error(err)
}
}
func makeSection533Tree() *priorityWriteScheduler {
// Initial tree from RFC 7540 Section 5.3.3.
// A,B,C,D,E,F = 1,2,3,4,5,6
ws := defaultPriorityWriteScheduler()
ws.OpenStream(1, OpenStreamOptions{})
ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
ws.OpenStream(3, OpenStreamOptions{PusherID: 1})
ws.OpenStream(4, OpenStreamOptions{PusherID: 3})
ws.OpenStream(5, OpenStreamOptions{PusherID: 3})
ws.OpenStream(6, OpenStreamOptions{PusherID: 4})
return ws
}
func TestPrioritySection533NonExclusive(t *testing.T) {
// Example from RFC 7540 Section 5.3.3.
// A,B,C,D,E,F = 1,2,3,4,5,6
ws := defaultPriorityWriteScheduler()
ws.OpenStream(1, OpenStreamOptions{})
ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
ws.OpenStream(3, OpenStreamOptions{PusherID: 1})
ws.OpenStream(4, OpenStreamOptions{PusherID: 3})
ws.OpenStream(5, OpenStreamOptions{PusherID: 3})
ws.OpenStream(6, OpenStreamOptions{PusherID: 4})
ws.AdjustStream(1, PriorityParam{
StreamDep: 4,
Weight: 15,
Exclusive: false,
})
want := "1{parent:4} 2{parent:1} 3{parent:1} 4{parent:0} 5{parent:3} 6{parent:4}"
if got := fmtTree(ws, fmtNodeParentSkipRoot); got != want {
t.Errorf("After adjust\ngot %q\nwant %q", got, want)
}
if err := checkPriorityWellFormed(ws); err != nil {
t.Error(err)
}
}
func TestPrioritySection533Exclusive(t *testing.T) {
// Example from RFC 7540 Section 5.3.3.
// A,B,C,D,E,F = 1,2,3,4,5,6
ws := defaultPriorityWriteScheduler()
ws.OpenStream(1, OpenStreamOptions{})
ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
ws.OpenStream(3, OpenStreamOptions{PusherID: 1})
ws.OpenStream(4, OpenStreamOptions{PusherID: 3})
ws.OpenStream(5, OpenStreamOptions{PusherID: 3})
ws.OpenStream(6, OpenStreamOptions{PusherID: 4})
ws.AdjustStream(1, PriorityParam{
StreamDep: 4,
Weight: 15,
Exclusive: true,
})
want := "1{parent:4} 2{parent:1} 3{parent:1} 4{parent:0} 5{parent:3} 6{parent:1}"
if got := fmtTree(ws, fmtNodeParentSkipRoot); got != want {
t.Errorf("After adjust\ngot %q\nwant %q", got, want)
}
if err := checkPriorityWellFormed(ws); err != nil {
t.Error(err)
}
}
func checkPopAll(ws WriteScheduler, order []uint32) error {
for k, id := range order {
wr, ok := ws.Pop()
if !ok {
return fmt.Errorf("Pop[%d]: got ok=false, want %d (order=%v)", k, id, order)
}
if got := wr.StreamID(); got != id {
return fmt.Errorf("Pop[%d]: got %v, want %d (order=%v)", k, got, id, order)
}
}
wr, ok := ws.Pop()
if ok {
return fmt.Errorf("Pop[%d]: got %v, want ok=false (order=%v)", len(order), wr.StreamID(), order)
}
return nil
}
func TestPriorityPopFrom533Tree(t *testing.T) {
ws := makeSection533Tree()
ws.Push(makeWriteHeadersRequest(3 /*C*/))
ws.Push(makeWriteNonStreamRequest())
ws.Push(makeWriteHeadersRequest(5 /*E*/))
ws.Push(makeWriteHeadersRequest(1 /*A*/))
t.Log("tree:", fmtTree(ws, fmtNodeParentSkipRoot))
if err := checkPopAll(ws, []uint32{0 /*NonStream*/, 1, 3, 5}); err != nil {
t.Error(err)
}
}
func TestPriorityPopFromLinearTree(t *testing.T) {
ws := defaultPriorityWriteScheduler()
ws.OpenStream(1, OpenStreamOptions{})
ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
ws.OpenStream(3, OpenStreamOptions{PusherID: 2})
ws.OpenStream(4, OpenStreamOptions{PusherID: 3})
ws.Push(makeWriteHeadersRequest(3))
ws.Push(makeWriteHeadersRequest(4))
ws.Push(makeWriteHeadersRequest(1))
ws.Push(makeWriteHeadersRequest(2))
ws.Push(makeWriteNonStreamRequest())
ws.Push(makeWriteNonStreamRequest())
t.Log("tree:", fmtTree(ws, fmtNodeParentSkipRoot))
if err := checkPopAll(ws, []uint32{0, 0 /*NonStreams*/, 1, 2, 3, 4}); err != nil {
t.Error(err)
}
}
func TestPriorityFlowControl(t *testing.T) {
ws := NewPriorityWriteScheduler(&PriorityWriteSchedulerConfig{ThrottleOutOfOrderWrites: false})
ws.OpenStream(1, OpenStreamOptions{})
ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
sc := &serverConn{maxFrameSize: 16}
st1 := &stream{id: 1, sc: sc}
st2 := &stream{id: 2, sc: sc}
ws.Push(FrameWriteRequest{&writeData{1, make([]byte, 16), false}, st1, nil})
ws.Push(FrameWriteRequest{&writeData{2, make([]byte, 16), false}, st2, nil})
ws.AdjustStream(2, PriorityParam{StreamDep: 1})
// No flow-control bytes available.
if wr, ok := ws.Pop(); ok {
t.Fatalf("Pop(limited by flow control)=%v,true, want false", wr)
}
// Add enough flow-control bytes to write st2 in two Pop calls.
// Should write data from st2 even though it's lower priority than st1.
for i := 1; i <= 2; i++ {
st2.flow.add(8)
wr, ok := ws.Pop()
if !ok {
t.Fatalf("Pop(%d)=false, want true", i)
}
if got, want := wr.DataSize(), 8; got != want {
t.Fatalf("Pop(%d)=%d bytes, want %d bytes", got, want)
}
}
}
func TestPriorityThrottleOutOfOrderWrites(t *testing.T) {
ws := NewPriorityWriteScheduler(&PriorityWriteSchedulerConfig{ThrottleOutOfOrderWrites: true})
ws.OpenStream(1, OpenStreamOptions{})
ws.OpenStream(2, OpenStreamOptions{PusherID: 1})
sc := &serverConn{maxFrameSize: 4096}
st1 := &stream{id: 1, sc: sc}
st2 := &stream{id: 2, sc: sc}
st1.flow.add(4096)
st2.flow.add(4096)
ws.Push(FrameWriteRequest{&writeData{2, make([]byte, 4096), false}, st2, nil})
ws.AdjustStream(2, PriorityParam{StreamDep: 1})
// We have enough flow-control bytes to write st2 in a single Pop call.
// However, due to out-of-order write throttling, the first call should
// only write 1KB.
wr, ok := ws.Pop()
if !ok {
t.Fatalf("Pop(st2.first)=false, want true")
}
if got, want := wr.StreamID(), uint32(2); got != want {
t.Fatalf("Pop(st2.first)=stream %d, want stream %d", got, want)
}
if got, want := wr.DataSize(), 1024; got != want {
t.Fatalf("Pop(st2.first)=%d bytes, want %d bytes", got, want)
}
// Now add data on st1. This should take precedence.
ws.Push(FrameWriteRequest{&writeData{1, make([]byte, 4096), false}, st1, nil})
wr, ok = ws.Pop()
if !ok {
t.Fatalf("Pop(st1)=false, want true")
}
if got, want := wr.StreamID(), uint32(1); got != want {
t.Fatalf("Pop(st1)=stream %d, want stream %d", got, want)
}
if got, want := wr.DataSize(), 4096; got != want {
t.Fatalf("Pop(st1)=%d bytes, want %d bytes", got, want)
}
// Should go back to writing 1KB from st2.
wr, ok = ws.Pop()
if !ok {
t.Fatalf("Pop(st2.last)=false, want true")
}
if got, want := wr.StreamID(), uint32(2); got != want {
t.Fatalf("Pop(st2.last)=stream %d, want stream %d", got, want)
}
if got, want := wr.DataSize(), 1024; got != want {
t.Fatalf("Pop(st2.last)=%d bytes, want %d bytes", got, want)
}
}
func TestPriorityWeights(t *testing.T) {
ws := defaultPriorityWriteScheduler()
ws.OpenStream(1, OpenStreamOptions{})
ws.OpenStream(2, OpenStreamOptions{})
sc := &serverConn{maxFrameSize: 8}
st1 := &stream{id: 1, sc: sc}
st2 := &stream{id: 2, sc: sc}
st1.flow.add(40)
st2.flow.add(40)
ws.Push(FrameWriteRequest{&writeData{1, make([]byte, 40), false}, st1, nil})
ws.Push(FrameWriteRequest{&writeData{2, make([]byte, 40), false}, st2, nil})
ws.AdjustStream(1, PriorityParam{StreamDep: 0, Weight: 34})
ws.AdjustStream(2, PriorityParam{StreamDep: 0, Weight: 9})
// st1 gets 3.5x the bandwidth of st2 (3.5 = (34+1)/(9+1)).
// The maximum frame size is 8 bytes. The write sequence should be:
// st1, total bytes so far is (st1=8, st=0)
// st2, total bytes so far is (st1=8, st=8)
// st1, total bytes so far is (st1=16, st=8)
// st1, total bytes so far is (st1=24, st=8) // 3x bandwidth
// st1, total bytes so far is (st1=32, st=8) // 4x bandwidth
// st2, total bytes so far is (st1=32, st=16) // 2x bandwidth
// st1, total bytes so far is (st1=40, st=16)
// st2, total bytes so far is (st1=40, st=24)
// st2, total bytes so far is (st1=40, st=32)
// st2, total bytes so far is (st1=40, st=40)
if err := checkPopAll(ws, []uint32{1, 2, 1, 1, 1, 2, 1, 2, 2, 2}); err != nil {
t.Error(err)
}
}
func TestPriorityRstStreamOnNonOpenStreams(t *testing.T) {
ws := NewPriorityWriteScheduler(&PriorityWriteSchedulerConfig{
MaxClosedNodesInTree: 0,
MaxIdleNodesInTree: 0,
})
ws.OpenStream(1, OpenStreamOptions{})
ws.CloseStream(1)
ws.Push(FrameWriteRequest{write: streamError(1, ErrCodeProtocol)})
ws.Push(FrameWriteRequest{write: streamError(2, ErrCodeProtocol)})
if err := checkPopAll(ws, []uint32{1, 2}); err != nil {
t.Error(err)
}
}

72
vendor/golang.org/x/net/http2/writesched_random.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,72 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package http2
import "math"
// NewRandomWriteScheduler constructs a WriteScheduler that ignores HTTP/2
// priorities. Control frames like SETTINGS and PING are written before DATA
// frames, but if no control frames are queued and multiple streams have queued
// HEADERS or DATA frames, Pop selects a ready stream arbitrarily.
func NewRandomWriteScheduler() WriteScheduler {
return &randomWriteScheduler{sq: make(map[uint32]*writeQueue)}
}
type randomWriteScheduler struct {
// zero are frames not associated with a specific stream.
zero writeQueue
// sq contains the stream-specific queues, keyed by stream ID.
// When a stream is idle or closed, it's deleted from the map.
sq map[uint32]*writeQueue
// pool of empty queues for reuse.
queuePool writeQueuePool
}
func (ws *randomWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) {
// no-op: idle streams are not tracked
}
func (ws *randomWriteScheduler) CloseStream(streamID uint32) {
q, ok := ws.sq[streamID]
if !ok {
return
}
delete(ws.sq, streamID)
ws.queuePool.put(q)
}
func (ws *randomWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) {
// no-op: priorities are ignored
}
func (ws *randomWriteScheduler) Push(wr FrameWriteRequest) {
id := wr.StreamID()
if id == 0 {
ws.zero.push(wr)
return
}
q, ok := ws.sq[id]
if !ok {
q = ws.queuePool.get()
ws.sq[id] = q
}
q.push(wr)
}
func (ws *randomWriteScheduler) Pop() (FrameWriteRequest, bool) {
// Control frames first.
if !ws.zero.empty() {
return ws.zero.shift(), true
}
// Iterate over all non-idle streams until finding one that can be consumed.
for _, q := range ws.sq {
if wr, ok := q.consume(math.MaxInt32); ok {
return wr, true
}
}
return FrameWriteRequest{}, false
}

44
vendor/golang.org/x/net/http2/writesched_random_test.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,44 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package http2
import "testing"
func TestRandomScheduler(t *testing.T) {
ws := NewRandomWriteScheduler()
ws.Push(makeWriteHeadersRequest(3))
ws.Push(makeWriteHeadersRequest(4))
ws.Push(makeWriteHeadersRequest(1))
ws.Push(makeWriteHeadersRequest(2))
ws.Push(makeWriteNonStreamRequest())
ws.Push(makeWriteNonStreamRequest())
// Pop all frames. Should get the non-stream requests first,
// followed by the stream requests in any order.
var order []FrameWriteRequest
for {
wr, ok := ws.Pop()
if !ok {
break
}
order = append(order, wr)
}
t.Logf("got frames: %v", order)
if len(order) != 6 {
t.Fatalf("got %d frames, expected 6", len(order))
}
if order[0].StreamID() != 0 || order[1].StreamID() != 0 {
t.Fatalf("expected non-stream frames first", order[0], order[1])
}
got := make(map[uint32]bool)
for _, wr := range order[2:] {
got[wr.StreamID()] = true
}
for id := uint32(1); id <= 4; id++ {
if !got[id] {
t.Errorf("frame not found for stream %d", id)
}
}
}

125
vendor/golang.org/x/net/http2/writesched_test.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,125 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package http2
import (
"fmt"
"math"
"reflect"
"testing"
)
func makeWriteNonStreamRequest() FrameWriteRequest {
return FrameWriteRequest{writeSettingsAck{}, nil, nil}
}
func makeWriteHeadersRequest(streamID uint32) FrameWriteRequest {
st := &stream{id: streamID}
return FrameWriteRequest{&writeResHeaders{streamID: streamID, httpResCode: 200}, st, nil}
}
func checkConsume(wr FrameWriteRequest, nbytes int32, want []FrameWriteRequest) error {
consumed, rest, n := wr.Consume(nbytes)
var wantConsumed, wantRest FrameWriteRequest
switch len(want) {
case 0:
case 1:
wantConsumed = want[0]
case 2:
wantConsumed = want[0]
wantRest = want[1]
}
if !reflect.DeepEqual(consumed, wantConsumed) || !reflect.DeepEqual(rest, wantRest) || n != len(want) {
return fmt.Errorf("got %v, %v, %v\nwant %v, %v, %v", consumed, rest, n, wantConsumed, wantRest, len(want))
}
return nil
}
func TestFrameWriteRequestNonData(t *testing.T) {
wr := makeWriteNonStreamRequest()
if got, want := wr.DataSize(), 0; got != want {
t.Errorf("DataSize: got %v, want %v", got, want)
}
// Non-DATA frames are always consumed whole.
if err := checkConsume(wr, 0, []FrameWriteRequest{wr}); err != nil {
t.Errorf("Consume:\n%v", err)
}
}
func TestFrameWriteRequestData(t *testing.T) {
st := &stream{
id: 1,
sc: &serverConn{maxFrameSize: 16},
}
const size = 32
wr := FrameWriteRequest{&writeData{st.id, make([]byte, size), true}, st, make(chan error)}
if got, want := wr.DataSize(), size; got != want {
t.Errorf("DataSize: got %v, want %v", got, want)
}
// No flow-control bytes available: cannot consume anything.
if err := checkConsume(wr, math.MaxInt32, []FrameWriteRequest{}); err != nil {
t.Errorf("Consume(limited by flow control):\n%v", err)
}
// Add enough flow-control bytes to consume the entire frame,
// but we're now restricted by st.sc.maxFrameSize.
st.flow.add(size)
want := []FrameWriteRequest{
{
write: &writeData{st.id, make([]byte, st.sc.maxFrameSize), false},
stream: st,
done: nil,
},
{
write: &writeData{st.id, make([]byte, size-st.sc.maxFrameSize), true},
stream: st,
done: wr.done,
},
}
if err := checkConsume(wr, math.MaxInt32, want); err != nil {
t.Errorf("Consume(limited by maxFrameSize):\n%v", err)
}
rest := want[1]
// Consume 8 bytes from the remaining frame.
want = []FrameWriteRequest{
{
write: &writeData{st.id, make([]byte, 8), false},
stream: st,
done: nil,
},
{
write: &writeData{st.id, make([]byte, size-st.sc.maxFrameSize-8), true},
stream: st,
done: wr.done,
},
}
if err := checkConsume(rest, 8, want); err != nil {
t.Errorf("Consume(8):\n%v", err)
}
rest = want[1]
// Consume all remaining bytes.
want = []FrameWriteRequest{
{
write: &writeData{st.id, make([]byte, size-st.sc.maxFrameSize-8), true},
stream: st,
done: wr.done,
},
}
if err := checkConsume(rest, math.MaxInt32, want); err != nil {
t.Errorf("Consume(remainder):\n%v", err)
}
}
func TestFrameWriteRequest_StreamID(t *testing.T) {
const streamID = 123
wr := FrameWriteRequest{write: streamError(streamID, ErrCodeNo)}
if got := wr.StreamID(); got != streamID {
t.Errorf("FrameWriteRequest(StreamError) = %v; want %v", got, streamID)
}
}

2
vendor/golang.org/x/net/icmp/echo.go сгенерированный поставляемый
Просмотреть файл

@@ -1,4 +1,4 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

2
vendor/golang.org/x/net/icmp/ipv6.go сгенерированный поставляемый
Просмотреть файл

@@ -1,4 +1,4 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

2
vendor/golang.org/x/net/icmp/message.go сгенерированный поставляемый
Просмотреть файл

@@ -1,4 +1,4 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

2
vendor/golang.org/x/net/icmp/messagebody.go сгенерированный поставляемый
Просмотреть файл

@@ -1,4 +1,4 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

2
vendor/golang.org/x/net/internal/iana/gen.go сгенерированный поставляемый
Просмотреть файл

@@ -1,4 +1,4 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

45
vendor/golang.org/x/net/internal/nettest/helper_bsd.go сгенерированный поставляемый
Просмотреть файл

@@ -13,6 +13,23 @@ import (
"syscall"
)
var darwinVersion int
func init() {
if runtime.GOOS == "darwin" {
// See http://support.apple.com/kb/HT1633.
s, err := syscall.Sysctl("kern.osrelease")
if err != nil {
return
}
ss := strings.Split(s, ".")
if len(ss) == 0 {
return
}
darwinVersion, _ = strconv.Atoi(ss[0])
}
}
func supportsIPv6MulticastDeliveryOnLoopback() bool {
switch runtime.GOOS {
case "freebsd":
@@ -22,27 +39,15 @@ func supportsIPv6MulticastDeliveryOnLoopback() bool {
// packets correctly.
return false
case "darwin":
// See http://support.apple.com/kb/HT1633.
s, err := syscall.Sysctl("kern.osrelease")
if err != nil {
return false
}
ss := strings.Split(s, ".")
if len(ss) == 0 {
return false
}
// OS X 10.9 (Darwin 13) or above seems to do the
// right thing; preserving the packet header as it's
// needed for the checksum calcuration with pseudo
// header on loopback multicast delivery process.
// If not, you'll probably see what is the slow-acting
// kernel crash caused by lazy mbuf corruption.
// See ip6_mloopback in netinet6/ip6_output.c.
if mjver, err := strconv.Atoi(ss[0]); err != nil || mjver < 13 {
return false
}
return true
return !causesIPv6Crash()
default:
return true
}
}
func causesIPv6Crash() bool {
// We see some kernel crash when running IPv6 with IP-level
// options on Darwin kernel version 12 or below.
// See golang.org/issues/17015.
return darwinVersion < 13
}

4
vendor/golang.org/x/net/internal/nettest/helper_nobsd.go сгенерированный поставляемый
Просмотреть файл

@@ -9,3 +9,7 @@ package nettest
func supportsIPv6MulticastDeliveryOnLoopback() bool {
return true
}
func causesIPv6Crash() bool {
return false
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше