git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/crypto/chacha/chacha_generic.go (about)

     1  // Copyright (c) 2016 Andreas Auernhammer. All rights reserved.
     2  // Use of this source code is governed by a license that can be
     3  // found in the LICENSE file.
     4  
     5  package chacha
     6  
     7  import (
     8  	"encoding/binary"
     9  )
    10  
    11  func xorKeyStreamGeneric(dst, src []byte, block, state *[64]byte, rounds int) int {
    12  	for len(src) >= 64 {
    13  		chachaGeneric(block, state, rounds)
    14  
    15  		for i, v := range block {
    16  			dst[i] = src[i] ^ v
    17  		}
    18  		src = src[64:]
    19  		dst = dst[64:]
    20  	}
    21  
    22  	n := len(src)
    23  	if n > 0 {
    24  		chachaGeneric(block, state, rounds)
    25  		for i, v := range src {
    26  			dst[i] = v ^ block[i]
    27  		}
    28  	}
    29  	return n
    30  }
    31  
    32  func chachaGeneric(dst *[64]byte, state *[64]byte, rounds int) {
    33  	v00 := binary.LittleEndian.Uint32(state[0:])
    34  	v01 := binary.LittleEndian.Uint32(state[4:])
    35  	v02 := binary.LittleEndian.Uint32(state[8:])
    36  	v03 := binary.LittleEndian.Uint32(state[12:])
    37  	v04 := binary.LittleEndian.Uint32(state[16:])
    38  	v05 := binary.LittleEndian.Uint32(state[20:])
    39  	v06 := binary.LittleEndian.Uint32(state[24:])
    40  	v07 := binary.LittleEndian.Uint32(state[28:])
    41  	v08 := binary.LittleEndian.Uint32(state[32:])
    42  	v09 := binary.LittleEndian.Uint32(state[36:])
    43  	v10 := binary.LittleEndian.Uint32(state[40:])
    44  	v11 := binary.LittleEndian.Uint32(state[44:])
    45  	v12 := binary.LittleEndian.Uint32(state[48:])
    46  	v13 := binary.LittleEndian.Uint32(state[52:])
    47  	v14 := binary.LittleEndian.Uint32(state[56:])
    48  	v15 := binary.LittleEndian.Uint32(state[60:])
    49  
    50  	s00, s01, s02, s03, s04, s05, s06, s07 := v00, v01, v02, v03, v04, v05, v06, v07
    51  	s08, s09, s10, s11, s12, s13, s14, s15 := v08, v09, v10, v11, v12, v13, v14, v15
    52  
    53  	for i := 0; i < rounds; i += 2 {
    54  		v00 += v04
    55  		v12 ^= v00
    56  		v12 = (v12 << 16) | (v12 >> 16)
    57  		v08 += v12
    58  		v04 ^= v08
    59  		v04 = (v04 << 12) | (v04 >> 20)
    60  		v00 += v04
    61  		v12 ^= v00
    62  		v12 = (v12 << 8) | (v12 >> 24)
    63  		v08 += v12
    64  		v04 ^= v08
    65  		v04 = (v04 << 7) | (v04 >> 25)
    66  		v01 += v05
    67  		v13 ^= v01
    68  		v13 = (v13 << 16) | (v13 >> 16)
    69  		v09 += v13
    70  		v05 ^= v09
    71  		v05 = (v05 << 12) | (v05 >> 20)
    72  		v01 += v05
    73  		v13 ^= v01
    74  		v13 = (v13 << 8) | (v13 >> 24)
    75  		v09 += v13
    76  		v05 ^= v09
    77  		v05 = (v05 << 7) | (v05 >> 25)
    78  		v02 += v06
    79  		v14 ^= v02
    80  		v14 = (v14 << 16) | (v14 >> 16)
    81  		v10 += v14
    82  		v06 ^= v10
    83  		v06 = (v06 << 12) | (v06 >> 20)
    84  		v02 += v06
    85  		v14 ^= v02
    86  		v14 = (v14 << 8) | (v14 >> 24)
    87  		v10 += v14
    88  		v06 ^= v10
    89  		v06 = (v06 << 7) | (v06 >> 25)
    90  		v03 += v07
    91  		v15 ^= v03
    92  		v15 = (v15 << 16) | (v15 >> 16)
    93  		v11 += v15
    94  		v07 ^= v11
    95  		v07 = (v07 << 12) | (v07 >> 20)
    96  		v03 += v07
    97  		v15 ^= v03
    98  		v15 = (v15 << 8) | (v15 >> 24)
    99  		v11 += v15
   100  		v07 ^= v11
   101  		v07 = (v07 << 7) | (v07 >> 25)
   102  		v00 += v05
   103  		v15 ^= v00
   104  		v15 = (v15 << 16) | (v15 >> 16)
   105  		v10 += v15
   106  		v05 ^= v10
   107  		v05 = (v05 << 12) | (v05 >> 20)
   108  		v00 += v05
   109  		v15 ^= v00
   110  		v15 = (v15 << 8) | (v15 >> 24)
   111  		v10 += v15
   112  		v05 ^= v10
   113  		v05 = (v05 << 7) | (v05 >> 25)
   114  		v01 += v06
   115  		v12 ^= v01
   116  		v12 = (v12 << 16) | (v12 >> 16)
   117  		v11 += v12
   118  		v06 ^= v11
   119  		v06 = (v06 << 12) | (v06 >> 20)
   120  		v01 += v06
   121  		v12 ^= v01
   122  		v12 = (v12 << 8) | (v12 >> 24)
   123  		v11 += v12
   124  		v06 ^= v11
   125  		v06 = (v06 << 7) | (v06 >> 25)
   126  		v02 += v07
   127  		v13 ^= v02
   128  		v13 = (v13 << 16) | (v13 >> 16)
   129  		v08 += v13
   130  		v07 ^= v08
   131  		v07 = (v07 << 12) | (v07 >> 20)
   132  		v02 += v07
   133  		v13 ^= v02
   134  		v13 = (v13 << 8) | (v13 >> 24)
   135  		v08 += v13
   136  		v07 ^= v08
   137  		v07 = (v07 << 7) | (v07 >> 25)
   138  		v03 += v04
   139  		v14 ^= v03
   140  		v14 = (v14 << 16) | (v14 >> 16)
   141  		v09 += v14
   142  		v04 ^= v09
   143  		v04 = (v04 << 12) | (v04 >> 20)
   144  		v03 += v04
   145  		v14 ^= v03
   146  		v14 = (v14 << 8) | (v14 >> 24)
   147  		v09 += v14
   148  		v04 ^= v09
   149  		v04 = (v04 << 7) | (v04 >> 25)
   150  	}
   151  
   152  	v00 += s00
   153  	v01 += s01
   154  	v02 += s02
   155  	v03 += s03
   156  	v04 += s04
   157  	v05 += s05
   158  	v06 += s06
   159  	v07 += s07
   160  	v08 += s08
   161  	v09 += s09
   162  	v10 += s10
   163  	v11 += s11
   164  	v12 += s12
   165  	v13 += s13
   166  	v14 += s14
   167  	v15 += s15
   168  
   169  	s12++
   170  	binary.LittleEndian.PutUint32(state[48:], s12)
   171  	if s12 == 0 { // indicates overflow
   172  		s13++
   173  		binary.LittleEndian.PutUint32(state[52:], s13)
   174  	}
   175  
   176  	binary.LittleEndian.PutUint32(dst[0:], v00)
   177  	binary.LittleEndian.PutUint32(dst[4:], v01)
   178  	binary.LittleEndian.PutUint32(dst[8:], v02)
   179  	binary.LittleEndian.PutUint32(dst[12:], v03)
   180  	binary.LittleEndian.PutUint32(dst[16:], v04)
   181  	binary.LittleEndian.PutUint32(dst[20:], v05)
   182  	binary.LittleEndian.PutUint32(dst[24:], v06)
   183  	binary.LittleEndian.PutUint32(dst[28:], v07)
   184  	binary.LittleEndian.PutUint32(dst[32:], v08)
   185  	binary.LittleEndian.PutUint32(dst[36:], v09)
   186  	binary.LittleEndian.PutUint32(dst[40:], v10)
   187  	binary.LittleEndian.PutUint32(dst[44:], v11)
   188  	binary.LittleEndian.PutUint32(dst[48:], v12)
   189  	binary.LittleEndian.PutUint32(dst[52:], v13)
   190  	binary.LittleEndian.PutUint32(dst[56:], v14)
   191  	binary.LittleEndian.PutUint32(dst[60:], v15)
   192  }
   193  
   194  // func hChaCha20Generic(out *[32]byte, nonce *[16]byte, key *[32]byte) {
   195  // 	v00 := sigma[0]
   196  // 	v01 := sigma[1]
   197  // 	v02 := sigma[2]
   198  // 	v03 := sigma[3]
   199  // 	v04 := binary.LittleEndian.Uint32(key[0:])
   200  // 	v05 := binary.LittleEndian.Uint32(key[4:])
   201  // 	v06 := binary.LittleEndian.Uint32(key[8:])
   202  // 	v07 := binary.LittleEndian.Uint32(key[12:])
   203  // 	v08 := binary.LittleEndian.Uint32(key[16:])
   204  // 	v09 := binary.LittleEndian.Uint32(key[20:])
   205  // 	v10 := binary.LittleEndian.Uint32(key[24:])
   206  // 	v11 := binary.LittleEndian.Uint32(key[28:])
   207  // 	v12 := binary.LittleEndian.Uint32(nonce[0:])
   208  // 	v13 := binary.LittleEndian.Uint32(nonce[4:])
   209  // 	v14 := binary.LittleEndian.Uint32(nonce[8:])
   210  // 	v15 := binary.LittleEndian.Uint32(nonce[12:])
   211  
   212  // 	for i := 0; i < 20; i += 2 {
   213  // 		v00 += v04
   214  // 		v12 ^= v00
   215  // 		v12 = (v12 << 16) | (v12 >> 16)
   216  // 		v08 += v12
   217  // 		v04 ^= v08
   218  // 		v04 = (v04 << 12) | (v04 >> 20)
   219  // 		v00 += v04
   220  // 		v12 ^= v00
   221  // 		v12 = (v12 << 8) | (v12 >> 24)
   222  // 		v08 += v12
   223  // 		v04 ^= v08
   224  // 		v04 = (v04 << 7) | (v04 >> 25)
   225  // 		v01 += v05
   226  // 		v13 ^= v01
   227  // 		v13 = (v13 << 16) | (v13 >> 16)
   228  // 		v09 += v13
   229  // 		v05 ^= v09
   230  // 		v05 = (v05 << 12) | (v05 >> 20)
   231  // 		v01 += v05
   232  // 		v13 ^= v01
   233  // 		v13 = (v13 << 8) | (v13 >> 24)
   234  // 		v09 += v13
   235  // 		v05 ^= v09
   236  // 		v05 = (v05 << 7) | (v05 >> 25)
   237  // 		v02 += v06
   238  // 		v14 ^= v02
   239  // 		v14 = (v14 << 16) | (v14 >> 16)
   240  // 		v10 += v14
   241  // 		v06 ^= v10
   242  // 		v06 = (v06 << 12) | (v06 >> 20)
   243  // 		v02 += v06
   244  // 		v14 ^= v02
   245  // 		v14 = (v14 << 8) | (v14 >> 24)
   246  // 		v10 += v14
   247  // 		v06 ^= v10
   248  // 		v06 = (v06 << 7) | (v06 >> 25)
   249  // 		v03 += v07
   250  // 		v15 ^= v03
   251  // 		v15 = (v15 << 16) | (v15 >> 16)
   252  // 		v11 += v15
   253  // 		v07 ^= v11
   254  // 		v07 = (v07 << 12) | (v07 >> 20)
   255  // 		v03 += v07
   256  // 		v15 ^= v03
   257  // 		v15 = (v15 << 8) | (v15 >> 24)
   258  // 		v11 += v15
   259  // 		v07 ^= v11
   260  // 		v07 = (v07 << 7) | (v07 >> 25)
   261  // 		v00 += v05
   262  // 		v15 ^= v00
   263  // 		v15 = (v15 << 16) | (v15 >> 16)
   264  // 		v10 += v15
   265  // 		v05 ^= v10
   266  // 		v05 = (v05 << 12) | (v05 >> 20)
   267  // 		v00 += v05
   268  // 		v15 ^= v00
   269  // 		v15 = (v15 << 8) | (v15 >> 24)
   270  // 		v10 += v15
   271  // 		v05 ^= v10
   272  // 		v05 = (v05 << 7) | (v05 >> 25)
   273  // 		v01 += v06
   274  // 		v12 ^= v01
   275  // 		v12 = (v12 << 16) | (v12 >> 16)
   276  // 		v11 += v12
   277  // 		v06 ^= v11
   278  // 		v06 = (v06 << 12) | (v06 >> 20)
   279  // 		v01 += v06
   280  // 		v12 ^= v01
   281  // 		v12 = (v12 << 8) | (v12 >> 24)
   282  // 		v11 += v12
   283  // 		v06 ^= v11
   284  // 		v06 = (v06 << 7) | (v06 >> 25)
   285  // 		v02 += v07
   286  // 		v13 ^= v02
   287  // 		v13 = (v13 << 16) | (v13 >> 16)
   288  // 		v08 += v13
   289  // 		v07 ^= v08
   290  // 		v07 = (v07 << 12) | (v07 >> 20)
   291  // 		v02 += v07
   292  // 		v13 ^= v02
   293  // 		v13 = (v13 << 8) | (v13 >> 24)
   294  // 		v08 += v13
   295  // 		v07 ^= v08
   296  // 		v07 = (v07 << 7) | (v07 >> 25)
   297  // 		v03 += v04
   298  // 		v14 ^= v03
   299  // 		v14 = (v14 << 16) | (v14 >> 16)
   300  // 		v09 += v14
   301  // 		v04 ^= v09
   302  // 		v04 = (v04 << 12) | (v04 >> 20)
   303  // 		v03 += v04
   304  // 		v14 ^= v03
   305  // 		v14 = (v14 << 8) | (v14 >> 24)
   306  // 		v09 += v14
   307  // 		v04 ^= v09
   308  // 		v04 = (v04 << 7) | (v04 >> 25)
   309  // 	}
   310  
   311  // 	binary.LittleEndian.PutUint32(out[0:], v00)
   312  // 	binary.LittleEndian.PutUint32(out[4:], v01)
   313  // 	binary.LittleEndian.PutUint32(out[8:], v02)
   314  // 	binary.LittleEndian.PutUint32(out[12:], v03)
   315  // 	binary.LittleEndian.PutUint32(out[16:], v12)
   316  // 	binary.LittleEndian.PutUint32(out[20:], v13)
   317  // 	binary.LittleEndian.PutUint32(out[24:], v14)
   318  // 	binary.LittleEndian.PutUint32(out[28:], v15)
   319  // }