github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/common/crypto/internal/chacha_core_gen.go (about)

     1  //go:build generate
     2  // +build generate
     3  
     4  package main
     5  
     6  import (
     7  	"fmt"
     8  	"log"
     9  	"os"
    10  )
    11  
    12  func writeQuarterRound(file *os.File, a, b, c, d int) {
    13  	add := "x%d+=x%d\n"
    14  	xor := "x=x%d^x%d\n"
    15  	rotate := "x%d=(x << %d) | (x >> (32 - %d))\n"
    16  
    17  	fmt.Fprintf(file, add, a, b)
    18  	fmt.Fprintf(file, xor, d, a)
    19  	fmt.Fprintf(file, rotate, d, 16, 16)
    20  
    21  	fmt.Fprintf(file, add, c, d)
    22  	fmt.Fprintf(file, xor, b, c)
    23  	fmt.Fprintf(file, rotate, b, 12, 12)
    24  
    25  	fmt.Fprintf(file, add, a, b)
    26  	fmt.Fprintf(file, xor, d, a)
    27  	fmt.Fprintf(file, rotate, d, 8, 8)
    28  
    29  	fmt.Fprintf(file, add, c, d)
    30  	fmt.Fprintf(file, xor, b, c)
    31  	fmt.Fprintf(file, rotate, b, 7, 7)
    32  }
    33  
    34  func writeChacha20Block(file *os.File) {
    35  	fmt.Fprintln(file, `
    36  func ChaCha20Block(s *[16]uint32, out []byte, rounds int) {
    37    var x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15 = s[0],s[1],s[2],s[3],s[4],s[5],s[6],s[7],s[8],s[9],s[10],s[11],s[12],s[13],s[14],s[15]
    38  	for i := 0; i < rounds; i+=2 {
    39      var x uint32
    40      `)
    41  
    42  	writeQuarterRound(file, 0, 4, 8, 12)
    43  	writeQuarterRound(file, 1, 5, 9, 13)
    44  	writeQuarterRound(file, 2, 6, 10, 14)
    45  	writeQuarterRound(file, 3, 7, 11, 15)
    46  	writeQuarterRound(file, 0, 5, 10, 15)
    47  	writeQuarterRound(file, 1, 6, 11, 12)
    48  	writeQuarterRound(file, 2, 7, 8, 13)
    49  	writeQuarterRound(file, 3, 4, 9, 14)
    50  	fmt.Fprintln(file, "}")
    51  	for i := 0; i < 16; i++ {
    52  		fmt.Fprintf(file, "binary.LittleEndian.PutUint32(out[%d:%d], s[%d]+x%d)\n", i*4, i*4+4, i, i)
    53  	}
    54  	fmt.Fprintln(file, "}")
    55  	fmt.Fprintln(file)
    56  }
    57  
    58  func main() {
    59  	file, err := os.OpenFile("chacha_core.generated.go", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0o644)
    60  	if err != nil {
    61  		log.Fatalf("Failed to generate chacha_core.go: %v", err)
    62  	}
    63  	defer file.Close()
    64  
    65  	fmt.Fprintln(file, "package internal")
    66  	fmt.Fprintln(file)
    67  	fmt.Fprintln(file, "import \"encoding/binary\"")
    68  	fmt.Fprintln(file)
    69  	writeChacha20Block(file)
    70  }