...

Source file src/crypto/md5/gen.go

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

View as plain text