// 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.

package salsa

import 

const rounds = 20

// core applies the Salsa20 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( *[64]byte,  *[16]byte,  *[32]byte,  *[16]byte) {
	 := uint32([0]) | uint32([1])<<8 | uint32([2])<<16 | uint32([3])<<24
	 := uint32([0]) | uint32([1])<<8 | uint32([2])<<16 | uint32([3])<<24
	 := uint32([4]) | uint32([5])<<8 | uint32([6])<<16 | uint32([7])<<24
	 := uint32([8]) | uint32([9])<<8 | uint32([10])<<16 | uint32([11])<<24
	 := uint32([12]) | uint32([13])<<8 | uint32([14])<<16 | uint32([15])<<24
	 := uint32([4]) | uint32([5])<<8 | uint32([6])<<16 | uint32([7])<<24
	 := uint32([0]) | uint32([1])<<8 | uint32([2])<<16 | uint32([3])<<24
	 := uint32([4]) | uint32([5])<<8 | uint32([6])<<16 | uint32([7])<<24
	 := uint32([8]) | uint32([9])<<8 | uint32([10])<<16 | uint32([11])<<24
	 := uint32([12]) | uint32([13])<<8 | uint32([14])<<16 | uint32([15])<<24
	 := uint32([8]) | uint32([9])<<8 | uint32([10])<<16 | uint32([11])<<24
	 := uint32([16]) | uint32([17])<<8 | uint32([18])<<16 | uint32([19])<<24
	 := uint32([20]) | uint32([21])<<8 | uint32([22])<<16 | uint32([23])<<24
	 := uint32([24]) | uint32([25])<<8 | uint32([26])<<16 | uint32([27])<<24
	 := uint32([28]) | uint32([29])<<8 | uint32([30])<<16 | uint32([31])<<24
	 := uint32([12]) | uint32([13])<<8 | uint32([14])<<16 | uint32([15])<<24

	, , , , , , , ,  := , , , , , , , , 
	, , , , , ,  := , , , , , , 

	for  := 0;  < rounds;  += 2 {
		 :=  + 
		 ^= bits.RotateLeft32(, 7)
		 =  + 
		 ^= bits.RotateLeft32(, 9)
		 =  + 
		 ^= bits.RotateLeft32(, 13)
		 =  + 
		 ^= bits.RotateLeft32(, 18)

		 =  + 
		 ^= bits.RotateLeft32(, 7)
		 =  + 
		 ^= bits.RotateLeft32(, 9)
		 =  + 
		 ^= bits.RotateLeft32(, 13)
		 =  + 
		 ^= bits.RotateLeft32(, 18)

		 =  + 
		 ^= bits.RotateLeft32(, 7)
		 =  + 
		 ^= bits.RotateLeft32(, 9)
		 =  + 
		 ^= bits.RotateLeft32(, 13)
		 =  + 
		 ^= bits.RotateLeft32(, 18)

		 =  + 
		 ^= bits.RotateLeft32(, 7)
		 =  + 
		 ^= bits.RotateLeft32(, 9)
		 =  + 
		 ^= bits.RotateLeft32(, 13)
		 =  + 
		 ^= bits.RotateLeft32(, 18)

		 =  + 
		 ^= bits.RotateLeft32(, 7)
		 =  + 
		 ^= bits.RotateLeft32(, 9)
		 =  + 
		 ^= bits.RotateLeft32(, 13)
		 =  + 
		 ^= bits.RotateLeft32(, 18)

		 =  + 
		 ^= bits.RotateLeft32(, 7)
		 =  + 
		 ^= bits.RotateLeft32(, 9)
		 =  + 
		 ^= bits.RotateLeft32(, 13)
		 =  + 
		 ^= bits.RotateLeft32(, 18)

		 =  + 
		 ^= bits.RotateLeft32(, 7)
		 =  + 
		 ^= bits.RotateLeft32(, 9)
		 =  + 
		 ^= bits.RotateLeft32(, 13)
		 =  + 
		 ^= bits.RotateLeft32(, 18)

		 =  + 
		 ^= bits.RotateLeft32(, 7)
		 =  + 
		 ^= bits.RotateLeft32(, 9)
		 =  + 
		 ^= bits.RotateLeft32(, 13)
		 =  + 
		 ^= bits.RotateLeft32(, 18)
	}
	 += 
	 += 
	 += 
	 += 
	 += 
	 += 
	 += 
	 += 
	 += 
	 += 
	 += 
	 += 
	 += 
	 += 
	 += 
	 += 

	[0] = byte()
	[1] = byte( >> 8)
	[2] = byte( >> 16)
	[3] = byte( >> 24)

	[4] = byte()
	[5] = byte( >> 8)
	[6] = byte( >> 16)
	[7] = byte( >> 24)

	[8] = byte()
	[9] = byte( >> 8)
	[10] = byte( >> 16)
	[11] = byte( >> 24)

	[12] = byte()
	[13] = byte( >> 8)
	[14] = byte( >> 16)
	[15] = byte( >> 24)

	[16] = byte()
	[17] = byte( >> 8)
	[18] = byte( >> 16)
	[19] = byte( >> 24)

	[20] = byte()
	[21] = byte( >> 8)
	[22] = byte( >> 16)
	[23] = byte( >> 24)

	[24] = byte()
	[25] = byte( >> 8)
	[26] = byte( >> 16)
	[27] = byte( >> 24)

	[28] = byte()
	[29] = byte( >> 8)
	[30] = byte( >> 16)
	[31] = byte( >> 24)

	[32] = byte()
	[33] = byte( >> 8)
	[34] = byte( >> 16)
	[35] = byte( >> 24)

	[36] = byte()
	[37] = byte( >> 8)
	[38] = byte( >> 16)
	[39] = byte( >> 24)

	[40] = byte()
	[41] = byte( >> 8)
	[42] = byte( >> 16)
	[43] = byte( >> 24)

	[44] = byte()
	[45] = byte( >> 8)
	[46] = byte( >> 16)
	[47] = byte( >> 24)

	[48] = byte()
	[49] = byte( >> 8)
	[50] = byte( >> 16)
	[51] = byte( >> 24)

	[52] = byte()
	[53] = byte( >> 8)
	[54] = byte( >> 16)
	[55] = byte( >> 24)

	[56] = byte()
	[57] = byte( >> 8)
	[58] = byte( >> 16)
	[59] = byte( >> 24)

	[60] = byte()
	[61] = byte( >> 8)
	[62] = byte( >> 16)
	[63] = byte( >> 24)
}

// genericXORKeyStream is the generic implementation of XORKeyStream to be used
// when no assembly implementation is available.
func genericXORKeyStream(,  []byte,  *[16]byte,  *[32]byte) {
	var  [64]byte
	var  [16]byte
	copy([:], [:])

	for len() >= 64 {
		core(&, &, , &Sigma)
		for ,  := range  {
			[] = [] ^ 
		}
		 := uint32(1)
		for  := 8;  < 16; ++ {
			 += uint32([])
			[] = byte()
			 >>= 8
		}
		 = [64:]
		 = [64:]
	}

	if len() > 0 {
		core(&, &, , &Sigma)
		for ,  := range  {
			[] =  ^ []
		}
	}
}