Black Lives Matter. Support the Equal Justice Initiative.

Source file src/crypto/md5/gen.go

Documentation: crypto/md5

     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  //go:build ignore
     6  // +build ignore
     7  
     8  // This program generates md5block.go
     9  // Invoke as
    10  //
    11  //	go run gen.go -output md5block.go
    12  
    13  package main
    14  
    15  import (
    16  	"bytes"
    17  	"flag"
    18  	"go/format"
    19  	"log"
    20  	"os"
    21  	"strings"
    22  	"text/template"
    23  )
    24  
    25  var filename = flag.String("output", "md5block.go", "output file name")
    26  
    27  func main() {
    28  	flag.Parse()
    29  
    30  	var buf bytes.Buffer
    31  
    32  	t := template.Must(template.New("main").Funcs(funcs).Parse(program))
    33  	if err := t.Execute(&buf, data); err != nil {
    34  		log.Fatal(err)
    35  	}
    36  
    37  	data, err := format.Source(buf.Bytes())
    38  	if err != nil {
    39  		log.Fatal(err)
    40  	}
    41  	err = os.WriteFile(*filename, data, 0644)
    42  	if err != nil {
    43  		log.Fatal(err)
    44  	}
    45  }
    46  
    47  type Data struct {
    48  	a, b, c, d string
    49  	Shift1     []int
    50  	Shift2     []int
    51  	Shift3     []int
    52  	Shift4     []int
    53  	Table1     []uint32
    54  	Table2     []uint32
    55  	Table3     []uint32
    56  	Table4     []uint32
    57  }
    58  
    59  var funcs = template.FuncMap{
    60  	"dup":     dup,
    61  	"relabel": relabel,
    62  	"rotate":  rotate,
    63  	"idx":     idx,
    64  	"seq":     seq,
    65  }
    66  
    67  func dup(count int, x []int) []int {
    68  	var out []int
    69  	for i := 0; i < count; i++ {
    70  		out = append(out, x...)
    71  	}
    72  	return out
    73  }
    74  
    75  func relabel(s string) string {
    76  	return strings.NewReplacer("arg0", data.a, "arg1", data.b, "arg2", data.c, "arg3", data.d).Replace(s)
    77  }
    78  
    79  func rotate() string {
    80  	data.a, data.b, data.c, data.d = data.d, data.a, data.b, data.c
    81  	return "" // no output
    82  }
    83  
    84  func idx(round, index int) int {
    85  	v := 0
    86  	switch round {
    87  	case 1:
    88  		v = index
    89  	case 2:
    90  		v = (1 + 5*index) & 15
    91  	case 3:
    92  		v = (5 + 3*index) & 15
    93  	case 4:
    94  		v = (7 * index) & 15
    95  	}
    96  	return v
    97  }
    98  
    99  func seq(i int) []int {
   100  	s := make([]int, i)
   101  	for i := range s {
   102  		s[i] = i
   103  	}
   104  	return s
   105  }
   106  
   107  var data = Data{
   108  	a:      "a",
   109  	b:      "b",
   110  	c:      "c",
   111  	d:      "d",
   112  	Shift1: []int{7, 12, 17, 22},
   113  	Shift2: []int{5, 9, 14, 20},
   114  	Shift3: []int{4, 11, 16, 23},
   115  	Shift4: []int{6, 10, 15, 21},
   116  
   117  	// table[i] = int((1<<32) * abs(sin(i+1 radians))).
   118  	Table1: []uint32{
   119  		// round 1
   120  		0xd76aa478,
   121  		0xe8c7b756,
   122  		0x242070db,
   123  		0xc1bdceee,
   124  		0xf57c0faf,
   125  		0x4787c62a,
   126  		0xa8304613,
   127  		0xfd469501,
   128  		0x698098d8,
   129  		0x8b44f7af,
   130  		0xffff5bb1,
   131  		0x895cd7be,
   132  		0x6b901122,
   133  		0xfd987193,
   134  		0xa679438e,
   135  		0x49b40821,
   136  	},
   137  	Table2: []uint32{
   138  		// round 2
   139  		0xf61e2562,
   140  		0xc040b340,
   141  		0x265e5a51,
   142  		0xe9b6c7aa,
   143  		0xd62f105d,
   144  		0x2441453,
   145  		0xd8a1e681,
   146  		0xe7d3fbc8,
   147  		0x21e1cde6,
   148  		0xc33707d6,
   149  		0xf4d50d87,
   150  		0x455a14ed,
   151  		0xa9e3e905,
   152  		0xfcefa3f8,
   153  		0x676f02d9,
   154  		0x8d2a4c8a,
   155  	},
   156  	Table3: []uint32{
   157  		// round3
   158  		0xfffa3942,
   159  		0x8771f681,
   160  		0x6d9d6122,
   161  		0xfde5380c,
   162  		0xa4beea44,
   163  		0x4bdecfa9,
   164  		0xf6bb4b60,
   165  		0xbebfbc70,
   166  		0x289b7ec6,
   167  		0xeaa127fa,
   168  		0xd4ef3085,
   169  		0x4881d05,
   170  		0xd9d4d039,
   171  		0xe6db99e5,
   172  		0x1fa27cf8,
   173  		0xc4ac5665,
   174  	},
   175  	Table4: []uint32{
   176  		// round 4
   177  		0xf4292244,
   178  		0x432aff97,
   179  		0xab9423a7,
   180  		0xfc93a039,
   181  		0x655b59c3,
   182  		0x8f0ccc92,
   183  		0xffeff47d,
   184  		0x85845dd1,
   185  		0x6fa87e4f,
   186  		0xfe2ce6e0,
   187  		0xa3014314,
   188  		0x4e0811a1,
   189  		0xf7537e82,
   190  		0xbd3af235,
   191  		0x2ad7d2bb,
   192  		0xeb86d391,
   193  	},
   194  }
   195  
   196  var program = `// Copyright 2013 The Go Authors. All rights reserved.
   197  // Use of this source code is governed by a BSD-style
   198  // license that can be found in the LICENSE file.
   199  
   200  // Code generated by go run gen.go -output md5block.go; DO NOT EDIT.
   201  
   202  package md5
   203  
   204  import (
   205  	"encoding/binary"
   206  	"math/bits"
   207  )
   208  
   209  func blockGeneric(dig *digest, p []byte) {
   210  	// load state
   211  	a, b, c, d := dig.s[0], dig.s[1], dig.s[2], dig.s[3]
   212  
   213  	for i := 0; i <= len(p)-BlockSize; i += BlockSize {
   214  		// eliminate bounds checks on p
   215  		q := p[i:]
   216  		q = q[:BlockSize:BlockSize]
   217  
   218  		// save current state
   219  		aa, bb, cc, dd := a, b, c, d
   220  
   221  		// load input block
   222  		{{range $i := seq 16 -}}
   223  			{{printf "x%x := binary.LittleEndian.Uint32(q[4*%#x:])" $i $i}}
   224  		{{end}}
   225  
   226  		// round 1
   227  		{{range $i, $s := dup 4 .Shift1 -}}
   228  			{{printf "arg0 = arg1 + bits.RotateLeft32((((arg2^arg3)&arg1)^arg3)+arg0+x%x+%#08x, %d)" (idx 1 $i) (index $.Table1 $i) $s | relabel}}
   229  			{{rotate -}}
   230  		{{end}}
   231  	
   232  		// round 2
   233  		{{range $i, $s := dup 4 .Shift2 -}}
   234  			{{printf "arg0 = arg1 + bits.RotateLeft32((((arg1^arg2)&arg3)^arg2)+arg0+x%x+%#08x, %d)" (idx 2 $i) (index $.Table2 $i) $s | relabel}}
   235  			{{rotate -}}
   236  		{{end}}
   237  	
   238  		// round 3
   239  		{{range $i, $s := dup 4 .Shift3 -}}
   240  			{{printf "arg0 = arg1 + bits.RotateLeft32((arg1^arg2^arg3)+arg0+x%x+%#08x, %d)" (idx 3 $i) (index $.Table3 $i) $s | relabel}}
   241  			{{rotate -}}
   242  		{{end}}
   243  	
   244  		// round 4
   245  		{{range $i, $s := dup 4 .Shift4 -}}
   246  			{{printf "arg0 = arg1 + bits.RotateLeft32((arg2^(arg1|^arg3))+arg0+x%x+%#08x, %d)" (idx 4 $i) (index $.Table4 $i) $s | relabel}}
   247  			{{rotate -}}
   248  		{{end}}
   249  
   250  		// add saved state
   251  		a += aa
   252  		b += bb
   253  		c += cc
   254  		d += dd
   255  	}
   256  
   257  	// save state
   258  	dig.s[0], dig.s[1], dig.s[2], dig.s[3] = a, b, c, d
   259  }
   260  `
   261  

View as plain text