package main import ( "crypto/sha1" "encoding/binary" "encoding/hex" "fmt" "strings" ) var rom = []byte{ 0xA9, 0x16, 0x20, 0xC9, 0xFC, 0x85, 0x2E, 0x20, 0xFA, 0xFC, 0xA0, 0x24, 0x20, 0xFD, 0xFC, 0xB0, 0xF9, 0x20, 0xFD, 0xFC, 0xA0, 0x3B, 0x20, 0xEC, 0xFC, 0x81, 0x3C, 0x45, 0x2E, 0x85, 0x2E, 0x20, 0xBA, 0xFC, 0xA0, 0x35, 0x90, 0xF0, 0x20, 0xEC, 0xFC, 0xC5, 0x2E, 0xF0, 0x0D, 0xA9, 0xC5, 0x20, 0xED, 0xFD, 0xA9, 0xD2, 0x20, 0xED, 0xFD, 0x20, 0xED, 0xFD, 0xA9, 0x87, 0x4C, 0xED, 0xFD, 0xA5, 0x48, 0x48, 0xA5, 0x45, 0xA6, 0x46, 0xA4, 0x47, 0x28, 0x60, 0x85, 0x45, 0x86, 0x46, 0x84, 0x47, 0x08, 0x68, 0x85, 0x48, 0xBA, 0x86, 0x49, 0xD8, 0x60, 0x20, 0x84, 0xFE, 0x20, 0x2F, 0xFB, 0x20, 0x93, 0xFE, 0x20, 0x89, 0xFE, 0xD8, 0x20, 0x3A, 0xFF, 0xA9, 0xAA, 0x85, 0x33, 0x20, 0x67, 0xFD, 0x20, 0xC7, 0xFF, 0x20, 0xA7, 0xFF, 0x84, 0x34, 0xA0, 0x17, 0x88, 0x30, 0xE8, 0xD9, 0xCC, 0xFF, 0xD0, 0xF8, 0x20, 0xBE, 0xFF, 0xA4, 0x34, 0x4C, 0x73, 0xFF, 0xA2, 0x03, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x26, 0x3E, 0x26, 0x3F, 0xCA, 0x10, 0xF8, 0xA5, 0x31, 0xD0, 0x06, 0xB5, 0x3F, 0x95, 0x3D, 0x95, 0x41, 0xE8, 0xF0, 0xF3, 0xD0, 0x06, 0xA2, 0x00, 0x86, 0x3E, 0x86, 0x3F, 0xB9, 0x00, 0x02, 0xC8, 0x49, 0xB0, 0xC9, 0x0A, 0x90, 0xD3, 0x69, 0x88, 0xC9, 0xFA, 0xB0, 0xCD, 0x60, 0xA9, 0xFE, 0x48, 0xB9, 0xE3, 0xFF, 0x48, 0xA5, 0x31, 0xA0, 0x00, 0x84, 0x31, 0x60, 0xBC, 0xB2, 0xBE, 0xB2, 0xEF, 0xC4, 0xB2, 0xA9, 0xBB, 0xA6, 0xA4, 0x06, 0x95, 0x07, 0x02, 0x05, 0xF0, 0x00, 0xEB, 0x93, 0xA7, 0xC6, 0x99, 0xB2, 0xC9, 0xBE, 0xC1, 0x35, 0x8C, 0xC4, 0x96, 0xAF, 0x17, 0x17, 0x2B, 0x1F, 0x83, 0x7F, 0x5D, 0xCC, 0xB5, 0xFC, 0x17, 0x17, 0xF5, 0x03, 0xFB, 0x03, 0x62, 0xFA, 0x59, 0xFF, } func main() { // print40s(tobytes(expand(pad(rom[:0x37])))) fmt.Printf("%X\n", sha1.Sum(rom[:0])) // fmt.Printf("%X\n", shasum(rom[:0])) // fmt.Printf("%X\n", sha1.Sum(rom[:0x37])) fmt.Printf("%X\n", shasum(rom[:0x37])) fmt.Printf("%X\n", sha1.Sum(rom[:0x100])) // fmt.Printf("%X\n", shasum(rom[:0x100])) } func print40s(in []byte) { for i := 0; i < len(in); i += 20 { end := i + 20 if end > len(in) { end = len(in) } fmt.Println(strings.ToUpper(hex.EncodeToString(in[i:end]))) } fmt.Printf("length: %d 0x%x\n", len(in), len(in)) } func pad(in []byte) []byte { out := make([]byte, len(in)) copy(out, in) out = append(out, 0x80) for len(out)%64 != 56 { out = append(out, 0) } l := uint64(len(in)) << 3 for i := uint(0); i < 8; i++ { out = append(out, byte(l>>(56-8*i))) } return out } func tobytes(in []uint32) []byte { out := make([]byte, len(in)*4) for i, w := range in { binary.BigEndian.PutUint32(out[i*4:], w) } return out } func expand(in []byte) []uint32 { if len(in) != 64 { panic(fmt.Sprintf("expand() expects 64-byte slices as input; got %d", len(in))) } var w [80]uint32 for i := 0; i < 16; i++ { w[i] = binary.BigEndian.Uint32(in[i*4:]) } for i := 16; i < 80; i++ { w[i] = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16] w[i] = w[i]<<1 + w[i]>>31 } return w[:] } func shasum(in []byte) [20]byte { h0 := uint32(0x67452301) h1 := uint32(0xEFCDAB89) h2 := uint32(0x98BADCFE) h3 := uint32(0x10325476) h4 := uint32(0xC3D2E1F0) in2 := pad(in) _ = in2 _ = h0 _ = h1 _ = h2 _ = h3 _ = h4 for j := 0; j < len(in2); j += 64 { w := expand(in2[j : j+64]) if len(w) != 80 { panic(fmt.Sprintf("expand should return 80 words; got %d", len(w))) } a := h0 b := h1 c := h2 d := h3 e := h4 var f, k uint32 for i, wi := range w { switch { case i <= 19: f = d ^ (b & (c ^ d)) k = 0x5A827999 case i <= 39: f = b ^ c ^ d k = 0x6ED9EBA1 case i <= 59: f = (b & c) | (d & (b | c)) k = 0x8F1BBCDC default: f = b ^ c ^ d k = 0xCA62C1D6 } temp := ((a << 5) | (a >> 27)) + f + e + k + wi e = d d = c c = (b << 30) | (b >> 2) b = a a = temp } h0 += a h1 += b h2 += c h3 += d h4 += e } var result [20]byte binary.BigEndian.PutUint32(result[0:], h0) binary.BigEndian.PutUint32(result[4:], h1) binary.BigEndian.PutUint32(result[8:], h2) binary.BigEndian.PutUint32(result[12:], h3) binary.BigEndian.PutUint32(result[16:], h4) return result }