github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/internal/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go (about)

     1  // Copyright 2016 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build go1.7,amd64,!gccgo,!appengine
     6  
     7  package chacha20poly1305
     8  
     9  import (
    10  	"encoding/binary"
    11  
    12  	"internal/cpu"
    13  )
    14  
    15  //go:noescape
    16  func chacha20Poly1305Open(dst []byte, key []uint32, src, ad []byte) bool
    17  
    18  //go:noescape
    19  func chacha20Poly1305Seal(dst []byte, key []uint32, src, ad []byte)
    20  
    21  var (
    22  	useASM  = cpu.X86.HasSSSE3
    23  	useAVX2 = cpu.X86.HasAVX2 && cpu.X86.HasBMI2
    24  )
    25  
    26  // setupState writes a ChaCha20 input matrix to state. See
    27  // https://tools.ietf.org/html/rfc7539#section-2.3.
    28  func setupState(state *[16]uint32, key *[8]uint32, nonce []byte) {
    29  	state[0] = 0x61707865
    30  	state[1] = 0x3320646e
    31  	state[2] = 0x79622d32
    32  	state[3] = 0x6b206574
    33  
    34  	state[4] = key[0]
    35  	state[5] = key[1]
    36  	state[6] = key[2]
    37  	state[7] = key[3]
    38  	state[8] = key[4]
    39  	state[9] = key[5]
    40  	state[10] = key[6]
    41  	state[11] = key[7]
    42  
    43  	state[12] = 0
    44  	state[13] = binary.LittleEndian.Uint32(nonce[:4])
    45  	state[14] = binary.LittleEndian.Uint32(nonce[4:8])
    46  	state[15] = binary.LittleEndian.Uint32(nonce[8:12])
    47  }
    48  
    49  func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []byte {
    50  	if !useASM {
    51  		return c.sealGeneric(dst, nonce, plaintext, additionalData)
    52  	}
    53  
    54  	var state [16]uint32
    55  	setupState(&state, &c.key, nonce)
    56  
    57  	ret, out := sliceForAppend(dst, len(plaintext)+16)
    58  	chacha20Poly1305Seal(out[:], state[:], plaintext, additionalData)
    59  	return ret
    60  }
    61  
    62  func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
    63  	if !useASM {
    64  		return c.openGeneric(dst, nonce, ciphertext, additionalData)
    65  	}
    66  
    67  	var state [16]uint32
    68  	setupState(&state, &c.key, nonce)
    69  
    70  	ciphertext = ciphertext[:len(ciphertext)-16]
    71  	ret, out := sliceForAppend(dst, len(ciphertext))
    72  	if !chacha20Poly1305Open(out, state[:], ciphertext, additionalData) {
    73  		for i := range out {
    74  			out[i] = 0
    75  		}
    76  		return nil, errOpen
    77  	}
    78  
    79  	return ret, nil
    80  }