...

Source file src/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go

Documentation: golang.org/x/crypto/salsa20/salsa

     1  // Copyright 2012 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  package salsa
     6  
     7  import "math/bits"
     8  
     9  const rounds = 20
    10  
    11  // core applies the Salsa20 core function to 16-byte input in, 32-byte key k,
    12  // and 16-byte constant c, and puts the result into 64-byte array out.
    13  func core(out *[64]byte, in *[16]byte, k *[32]byte, c *[16]byte) {
    14  	j0 := uint32(c[0]) | uint32(c[1])<<8 | uint32(c[2])<<16 | uint32(c[3])<<24
    15  	j1 := uint32(k[0]) | uint32(k[1])<<8 | uint32(k[2])<<16 | uint32(k[3])<<24
    16  	j2 := uint32(k[4]) | uint32(k[5])<<8 | uint32(k[6])<<16 | uint32(k[7])<<24
    17  	j3 := uint32(k[8]) | uint32(k[9])<<8 | uint32(k[10])<<16 | uint32(k[11])<<24
    18  	j4 := uint32(k[12]) | uint32(k[13])<<8 | uint32(k[14])<<16 | uint32(k[15])<<24
    19  	j5 := uint32(c[4]) | uint32(c[5])<<8 | uint32(c[6])<<16 | uint32(c[7])<<24
    20  	j6 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24
    21  	j7 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24
    22  	j8 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24
    23  	j9 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24
    24  	j10 := uint32(c[8]) | uint32(c[9])<<8 | uint32(c[10])<<16 | uint32(c[11])<<24
    25  	j11 := uint32(k[16]) | uint32(k[17])<<8 | uint32(k[18])<<16 | uint32(k[19])<<24
    26  	j12 := uint32(k[20]) | uint32(k[21])<<8 | uint32(k[22])<<16 | uint32(k[23])<<24
    27  	j13 := uint32(k[24]) | uint32(k[25])<<8 | uint32(k[26])<<16 | uint32(k[27])<<24
    28  	j14 := uint32(k[28]) | uint32(k[29])<<8 | uint32(k[30])<<16 | uint32(k[31])<<24
    29  	j15 := uint32(c[12]) | uint32(c[13])<<8 | uint32(c[14])<<16 | uint32(c[15])<<24
    30  
    31  	x0, x1, x2, x3, x4, x5, x6, x7, x8 := j0, j1, j2, j3, j4, j5, j6, j7, j8
    32  	x9, x10, x11, x12, x13, x14, x15 := j9, j10, j11, j12, j13, j14, j15
    33  
    34  	for i := 0; i < rounds; i += 2 {
    35  		u := x0 + x12
    36  		x4 ^= bits.RotateLeft32(u, 7)
    37  		u = x4 + x0
    38  		x8 ^= bits.RotateLeft32(u, 9)
    39  		u = x8 + x4
    40  		x12 ^= bits.RotateLeft32(u, 13)
    41  		u = x12 + x8
    42  		x0 ^= bits.RotateLeft32(u, 18)
    43  
    44  		u = x5 + x1
    45  		x9 ^= bits.RotateLeft32(u, 7)
    46  		u = x9 + x5
    47  		x13 ^= bits.RotateLeft32(u, 9)
    48  		u = x13 + x9
    49  		x1 ^= bits.RotateLeft32(u, 13)
    50  		u = x1 + x13
    51  		x5 ^= bits.RotateLeft32(u, 18)
    52  
    53  		u = x10 + x6
    54  		x14 ^= bits.RotateLeft32(u, 7)
    55  		u = x14 + x10
    56  		x2 ^= bits.RotateLeft32(u, 9)
    57  		u = x2 + x14
    58  		x6 ^= bits.RotateLeft32(u, 13)
    59  		u = x6 + x2
    60  		x10 ^= bits.RotateLeft32(u, 18)
    61  
    62  		u = x15 + x11
    63  		x3 ^= bits.RotateLeft32(u, 7)
    64  		u = x3 + x15
    65  		x7 ^= bits.RotateLeft32(u, 9)
    66  		u = x7 + x3
    67  		x11 ^= bits.RotateLeft32(u, 13)
    68  		u = x11 + x7
    69  		x15 ^= bits.RotateLeft32(u, 18)
    70  
    71  		u = x0 + x3
    72  		x1 ^= bits.RotateLeft32(u, 7)
    73  		u = x1 + x0
    74  		x2 ^= bits.RotateLeft32(u, 9)
    75  		u = x2 + x1
    76  		x3 ^= bits.RotateLeft32(u, 13)
    77  		u = x3 + x2
    78  		x0 ^= bits.RotateLeft32(u, 18)
    79  
    80  		u = x5 + x4
    81  		x6 ^= bits.RotateLeft32(u, 7)
    82  		u = x6 + x5
    83  		x7 ^= bits.RotateLeft32(u, 9)
    84  		u = x7 + x6
    85  		x4 ^= bits.RotateLeft32(u, 13)
    86  		u = x4 + x7
    87  		x5 ^= bits.RotateLeft32(u, 18)
    88  
    89  		u = x10 + x9
    90  		x11 ^= bits.RotateLeft32(u, 7)
    91  		u = x11 + x10
    92  		x8 ^= bits.RotateLeft32(u, 9)
    93  		u = x8 + x11
    94  		x9 ^= bits.RotateLeft32(u, 13)
    95  		u = x9 + x8
    96  		x10 ^= bits.RotateLeft32(u, 18)
    97  
    98  		u = x15 + x14
    99  		x12 ^= bits.RotateLeft32(u, 7)
   100  		u = x12 + x15
   101  		x13 ^= bits.RotateLeft32(u, 9)
   102  		u = x13 + x12
   103  		x14 ^= bits.RotateLeft32(u, 13)
   104  		u = x14 + x13
   105  		x15 ^= bits.RotateLeft32(u, 18)
   106  	}
   107  	x0 += j0
   108  	x1 += j1
   109  	x2 += j2
   110  	x3 += j3
   111  	x4 += j4
   112  	x5 += j5
   113  	x6 += j6
   114  	x7 += j7
   115  	x8 += j8
   116  	x9 += j9
   117  	x10 += j10
   118  	x11 += j11
   119  	x12 += j12
   120  	x13 += j13
   121  	x14 += j14
   122  	x15 += j15
   123  
   124  	out[0] = byte(x0)
   125  	out[1] = byte(x0 >> 8)
   126  	out[2] = byte(x0 >> 16)
   127  	out[3] = byte(x0 >> 24)
   128  
   129  	out[4] = byte(x1)
   130  	out[5] = byte(x1 >> 8)
   131  	out[6] = byte(x1 >> 16)
   132  	out[7] = byte(x1 >> 24)
   133  
   134  	out[8] = byte(x2)
   135  	out[9] = byte(x2 >> 8)
   136  	out[10] = byte(x2 >> 16)
   137  	out[11] = byte(x2 >> 24)
   138  
   139  	out[12] = byte(x3)
   140  	out[13] = byte(x3 >> 8)
   141  	out[14] = byte(x3 >> 16)
   142  	out[15] = byte(x3 >> 24)
   143  
   144  	out[16] = byte(x4)
   145  	out[17] = byte(x4 >> 8)
   146  	out[18] = byte(x4 >> 16)
   147  	out[19] = byte(x4 >> 24)
   148  
   149  	out[20] = byte(x5)
   150  	out[21] = byte(x5 >> 8)
   151  	out[22] = byte(x5 >> 16)
   152  	out[23] = byte(x5 >> 24)
   153  
   154  	out[24] = byte(x6)
   155  	out[25] = byte(x6 >> 8)
   156  	out[26] = byte(x6 >> 16)
   157  	out[27] = byte(x6 >> 24)
   158  
   159  	out[28] = byte(x7)
   160  	out[29] = byte(x7 >> 8)
   161  	out[30] = byte(x7 >> 16)
   162  	out[31] = byte(x7 >> 24)
   163  
   164  	out[32] = byte(x8)
   165  	out[33] = byte(x8 >> 8)
   166  	out[34] = byte(x8 >> 16)
   167  	out[35] = byte(x8 >> 24)
   168  
   169  	out[36] = byte(x9)
   170  	out[37] = byte(x9 >> 8)
   171  	out[38] = byte(x9 >> 16)
   172  	out[39] = byte(x9 >> 24)
   173  
   174  	out[40] = byte(x10)
   175  	out[41] = byte(x10 >> 8)
   176  	out[42] = byte(x10 >> 16)
   177  	out[43] = byte(x10 >> 24)
   178  
   179  	out[44] = byte(x11)
   180  	out[45] = byte(x11 >> 8)
   181  	out[46] = byte(x11 >> 16)
   182  	out[47] = byte(x11 >> 24)
   183  
   184  	out[48] = byte(x12)
   185  	out[49] = byte(x12 >> 8)
   186  	out[50] = byte(x12 >> 16)
   187  	out[51] = byte(x12 >> 24)
   188  
   189  	out[52] = byte(x13)
   190  	out[53] = byte(x13 >> 8)
   191  	out[54] = byte(x13 >> 16)
   192  	out[55] = byte(x13 >> 24)
   193  
   194  	out[56] = byte(x14)
   195  	out[57] = byte(x14 >> 8)
   196  	out[58] = byte(x14 >> 16)
   197  	out[59] = byte(x14 >> 24)
   198  
   199  	out[60] = byte(x15)
   200  	out[61] = byte(x15 >> 8)
   201  	out[62] = byte(x15 >> 16)
   202  	out[63] = byte(x15 >> 24)
   203  }
   204  
   205  // genericXORKeyStream is the generic implementation of XORKeyStream to be used
   206  // when no assembly implementation is available.
   207  func genericXORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
   208  	var block [64]byte
   209  	var counterCopy [16]byte
   210  	copy(counterCopy[:], counter[:])
   211  
   212  	for len(in) >= 64 {
   213  		core(&block, &counterCopy, key, &Sigma)
   214  		for i, x := range block {
   215  			out[i] = in[i] ^ x
   216  		}
   217  		u := uint32(1)
   218  		for i := 8; i < 16; i++ {
   219  			u += uint32(counterCopy[i])
   220  			counterCopy[i] = byte(u)
   221  			u >>= 8
   222  		}
   223  		in = in[64:]
   224  		out = out[64:]
   225  	}
   226  
   227  	if len(in) > 0 {
   228  		core(&block, &counterCopy, key, &Sigma)
   229  		for i, v := range in {
   230  			out[i] = v ^ block[i]
   231  		}
   232  	}
   233  }
   234  

View as plain text