github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/crypto/md5/gen.go (about)

     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  // +build ignore
     6  
     7  // This program generates md5block.go
     8  // Invoke as
     9  //
    10  //	go run gen.go [-full] |gofmt >md5block.go
    11  //
    12  // The -full flag causes the generated code to do a full
    13  // (16x) unrolling instead of a 4x unrolling.
    14  
    15  package main
    16  
    17  import (
    18  	"flag"
    19  	"log"
    20  	"os"
    21  	"strings"
    22  	"text/template"
    23  )
    24  
    25  func main() {
    26  	flag.Parse()
    27  
    28  	t := template.Must(template.New("main").Funcs(funcs).Parse(program))
    29  	if err := t.Execute(os.Stdout, data); err != nil {
    30  		log.Fatal(err)
    31  	}
    32  }
    33  
    34  type Data struct {
    35  	a, b, c, d string
    36  	Shift1     []int
    37  	Shift2     []int
    38  	Shift3     []int
    39  	Shift4     []int
    40  	Table1     []uint32
    41  	Table2     []uint32
    42  	Table3     []uint32
    43  	Table4     []uint32
    44  	Full       bool
    45  }
    46  
    47  var funcs = template.FuncMap{
    48  	"dup":     dup,
    49  	"relabel": relabel,
    50  	"rotate":  rotate,
    51  }
    52  
    53  func dup(count int, x []int) []int {
    54  	var out []int
    55  	for i := 0; i < count; i++ {
    56  		out = append(out, x...)
    57  	}
    58  	return out
    59  }
    60  
    61  func relabel(s string) string {
    62  	return strings.NewReplacer("a", data.a, "b", data.b, "c", data.c, "d", data.d).Replace(s)
    63  }
    64  
    65  func rotate() string {
    66  	data.a, data.b, data.c, data.d = data.d, data.a, data.b, data.c
    67  	return "" // no output
    68  }
    69  
    70  func init() {
    71  	flag.BoolVar(&data.Full, "full", false, "complete unrolling")
    72  }
    73  
    74  var data = Data{
    75  	a:      "a",
    76  	b:      "b",
    77  	c:      "c",
    78  	d:      "d",
    79  	Shift1: []int{7, 12, 17, 22},
    80  	Shift2: []int{5, 9, 14, 20},
    81  	Shift3: []int{4, 11, 16, 23},
    82  	Shift4: []int{6, 10, 15, 21},
    83  
    84  	// table[i] = int((1<<32) * abs(sin(i+1 radians))).
    85  	Table1: []uint32{
    86  		// round 1
    87  		0xd76aa478,
    88  		0xe8c7b756,
    89  		0x242070db,
    90  		0xc1bdceee,
    91  		0xf57c0faf,
    92  		0x4787c62a,
    93  		0xa8304613,
    94  		0xfd469501,
    95  		0x698098d8,
    96  		0x8b44f7af,
    97  		0xffff5bb1,
    98  		0x895cd7be,
    99  		0x6b901122,
   100  		0xfd987193,
   101  		0xa679438e,
   102  		0x49b40821,
   103  	},
   104  	Table2: []uint32{
   105  		// round 2
   106  		0xf61e2562,
   107  		0xc040b340,
   108  		0x265e5a51,
   109  		0xe9b6c7aa,
   110  		0xd62f105d,
   111  		0x2441453,
   112  		0xd8a1e681,
   113  		0xe7d3fbc8,
   114  		0x21e1cde6,
   115  		0xc33707d6,
   116  		0xf4d50d87,
   117  		0x455a14ed,
   118  		0xa9e3e905,
   119  		0xfcefa3f8,
   120  		0x676f02d9,
   121  		0x8d2a4c8a,
   122  	},
   123  	Table3: []uint32{
   124  		// round3
   125  		0xfffa3942,
   126  		0x8771f681,
   127  		0x6d9d6122,
   128  		0xfde5380c,
   129  		0xa4beea44,
   130  		0x4bdecfa9,
   131  		0xf6bb4b60,
   132  		0xbebfbc70,
   133  		0x289b7ec6,
   134  		0xeaa127fa,
   135  		0xd4ef3085,
   136  		0x4881d05,
   137  		0xd9d4d039,
   138  		0xe6db99e5,
   139  		0x1fa27cf8,
   140  		0xc4ac5665,
   141  	},
   142  	Table4: []uint32{
   143  		// round 4
   144  		0xf4292244,
   145  		0x432aff97,
   146  		0xab9423a7,
   147  		0xfc93a039,
   148  		0x655b59c3,
   149  		0x8f0ccc92,
   150  		0xffeff47d,
   151  		0x85845dd1,
   152  		0x6fa87e4f,
   153  		0xfe2ce6e0,
   154  		0xa3014314,
   155  		0x4e0811a1,
   156  		0xf7537e82,
   157  		0xbd3af235,
   158  		0x2ad7d2bb,
   159  		0xeb86d391,
   160  	},
   161  }
   162  
   163  var program = `
   164  // DO NOT EDIT.
   165  // Generate with: go run gen.go{{if .Full}} -full{{end}} | gofmt >md5block.go
   166  
   167  // +build !amd64,!386,!arm
   168  
   169  package md5
   170  
   171  import (
   172  	"unsafe"
   173  	"runtime"
   174  )
   175  
   176  {{if not .Full}}
   177  	var t1 = [...]uint32{
   178  	{{range .Table1}}{{printf "\t%#x,\n" .}}{{end}}
   179  	}
   180  	
   181  	var t2 = [...]uint32{
   182  	{{range .Table2}}{{printf "\t%#x,\n" .}}{{end}}
   183  	}
   184  	
   185  	var t3 = [...]uint32{
   186  	{{range .Table3}}{{printf "\t%#x,\n" .}}{{end}}
   187  	}
   188  	
   189  	var t4 = [...]uint32{
   190  	{{range .Table4}}{{printf "\t%#x,\n" .}}{{end}}
   191  	}
   192  {{end}}
   193  
   194  const x86 = runtime.GOARCH == "amd64" || runtime.GOARCH == "386"
   195  
   196  var littleEndian bool
   197  
   198  func init() {
   199  	x := uint32(0x04030201)
   200  	y := [4]byte{0x1, 0x2, 0x3, 0x4}
   201  	littleEndian = *(*[4]byte)(unsafe.Pointer(&x)) == y
   202  }
   203  
   204  func block(dig *digest, p []byte) {
   205  	a := dig.s[0]
   206  	b := dig.s[1]
   207  	c := dig.s[2]
   208  	d := dig.s[3]
   209  	var X *[16]uint32
   210  	var xbuf [16]uint32
   211  	for len(p) >= chunk {
   212  		aa, bb, cc, dd := a, b, c, d
   213  
   214  		// This is a constant condition - it is not evaluated on each iteration.
   215  		if x86 {
   216  			// MD5 was designed so that x86 processors can just iterate
   217  			// over the block data directly as uint32s, and we generate
   218  			// less code and run 1.3x faster if we take advantage of that.
   219  			// My apologies.
   220  			X = (*[16]uint32)(unsafe.Pointer(&p[0]))
   221  		} else if littleEndian && uintptr(unsafe.Pointer(&p[0]))&(unsafe.Alignof(uint32(0))-1) == 0 {
   222  			X = (*[16]uint32)(unsafe.Pointer(&p[0]))
   223  		} else {
   224  			X = &xbuf
   225  			j := 0
   226  			for i := 0; i < 16; i++ {
   227  				X[i&15] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24
   228  				j += 4
   229  			}
   230  		}
   231  
   232  		{{if .Full}}
   233  			// Round 1.
   234  			{{range $i, $s := dup 4 .Shift1}}
   235  				{{index $.Table1 $i | printf "a += (((c^d)&b)^d) + X[%d] + %d" $i | relabel}}
   236  				{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
   237  				{{rotate}}
   238  			{{end}}
   239  	
   240  			// Round 2.
   241  			{{range $i, $s := dup 4 .Shift2}}
   242  				{{index $.Table2 $i | printf "a += (((b^c)&d)^c) + X[(1+5*%d)&15] + %d" $i | relabel}}
   243  				{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
   244  				{{rotate}}
   245  			{{end}}
   246  	
   247  			// Round 3.
   248  			{{range $i, $s := dup 4 .Shift3}}
   249  				{{index $.Table3 $i | printf "a += (b^c^d) + X[(5+3*%d)&15] + %d" $i | relabel}}
   250  				{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
   251  				{{rotate}}
   252  			{{end}}
   253  	
   254  			// Round 4.
   255  			{{range $i, $s := dup 4 .Shift4}}
   256  				{{index $.Table4 $i | printf "a += (c^(b|^d)) + X[(7*%d)&15] + %d" $i | relabel}}
   257  				{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
   258  				{{rotate}}
   259  			{{end}}
   260  		{{else}}
   261  			// Round 1.
   262  			for i := uint(0); i < 16; {
   263  				{{range $s := .Shift1}}
   264  					{{printf "a += (((c^d)&b)^d) + X[i&15] + t1[i&15]" | relabel}}
   265  					{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
   266  					i++
   267  					{{rotate}}
   268  				{{end}}
   269  			}
   270  	
   271  			// Round 2.
   272  			for i := uint(0); i < 16; {
   273  				{{range $s := .Shift2}}
   274  					{{printf "a += (((b^c)&d)^c) + X[(1+5*i)&15] + t2[i&15]" | relabel}}
   275  					{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
   276  					i++
   277  					{{rotate}}
   278  				{{end}}
   279  			}
   280  	
   281  			// Round 3.
   282  			for i := uint(0); i < 16; {
   283  				{{range $s := .Shift3}}
   284  					{{printf "a += (b^c^d) + X[(5+3*i)&15] + t3[i&15]" | relabel}}
   285  					{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
   286  					i++
   287  					{{rotate}}
   288  				{{end}}
   289  			}
   290  	
   291  			// Round 4.
   292  			for i := uint(0); i < 16; {
   293  				{{range $s := .Shift4}}
   294  					{{printf "a += (c^(b|^d)) + X[(7*i)&15] + t4[i&15]" | relabel}}
   295  					{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
   296  					i++
   297  					{{rotate}}
   298  				{{end}}
   299  			}
   300  		{{end}}
   301  
   302  		a += aa
   303  		b += bb
   304  		c += cc
   305  		d += dd
   306  
   307  		p = p[chunk:]
   308  	}
   309  
   310  	dig.s[0] = a
   311  	dig.s[1] = b
   312  	dig.s[2] = c
   313  	dig.s[3] = d
   314  }
   315  `