From 37de1f5cac06a145af01d9379b257800f50a2e5c Mon Sep 17 00:00:00 2001 From: Zellyn Hunter Date: Wed, 28 Sep 2016 22:43:49 -0400 Subject: [PATCH] shasum: working for 0x0, 0x37, or 0x100 ROM bytes --- shasum/shasum.a | 113 +++++++++++++++++++++++++++++------------------ shasum/shasum.go | 98 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 160 insertions(+), 51 deletions(-) diff --git a/shasum/shasum.a b/shasum/shasum.a index 1280351..e743f1f 100644 --- a/shasum/shasum.a +++ b/shasum/shasum.a @@ -7,7 +7,7 @@ ;; 06-09 ;; EB-EF ;; FA-FD - + !addr SRC = $06 !addr DST = $08 !addr INPUT = $eb @@ -17,13 +17,13 @@ !addr PRBYTE = $FDDA !addr COUT = $FDED - + h0: !32 0 ; return value (hash) h1: !32 0 h2: !32 0 h3: !32 0 h4: !32 0 -h5: +h5: ml: !32 0, 0 ; message length w: !fill 64, 0 w_next: !fill 64, 0 @@ -43,7 +43,7 @@ kh4: !be32 $C3D2E1F0 k1: !be32 $5A827999 ; k = constants k2: !be32 $6ED9EBA1 k3: !be32 $8F1BBCDC -k4: !be32 $CA62C1D6 +k4: !be32 $CA62C1D6 !macro cp32 .source, .target { lda .source @@ -82,19 +82,27 @@ prbytes: adc #$ff bne - rts - -main: - ;; Test PRBYTES - ;; lda #kh0 - ;; sta SRC+1 - ;; lda #8 - ;; jsr prbytes - ;; LDA #$8D - ;; jsr COUT - ;; Test shasum +main: + ;; Test shasum "" + lda #0 + sta INPUT + lda #$ff + sta INPUT+1 + lda #0 + sta LENGTH+1 + lda #0 ; da39a3ee5e6b4b0d3255bfef95601890afd80709 + sta LENGTH + jsr shasum + + ; lda #$8d + ; jsr COUT + + +setSRC h0 + lda #(h5-h0) + jsr prbytes + + ;; Test shasum ROM[:0x37] lda #0 sta INPUT lda #$ff @@ -102,17 +110,34 @@ main: lda #0 sta LENGTH+1 lda #$37 ; 863ec5335a92b8289e4b1e5cbf646689fe81134b - lda #0 ; da39a3ee5e6b4b0d3255bfef95601890afd80709 sta LENGTH jsr shasum - lda #$8d - jsr COUT + ; lda #$8d + ; jsr COUT +setSRC h0 lda #(h5-h0) jsr prbytes + + ;; Test shasum ROM[:0x100] + lda #0 + sta INPUT + lda #$ff + sta INPUT+1 + lda #1 + sta LENGTH+1 + lda #0 ; F0282F962EC20651431D385E813F6E0904F8F812 + sta LENGTH + jsr shasum + ; lda #$8d + ; jsr COUT + + +setSRC h0 + lda #(h5-h0) + jsr prbytes + rts shasum: @@ -155,7 +180,7 @@ shasum: sta LENGTH+1 ora LENGTH beq .msgdone - + .loop lda (INPUT),y sta w,y iny @@ -172,12 +197,12 @@ shasum: sta INPUT bcc + inc INPUT+1 - + + inc LENGTH bne .loop inc LENGTH+1 bne .loop - + .msgdone: lda #$80 sta w,y @@ -210,15 +235,15 @@ shasum: ;;; do_chunk processes a chunk of input. It burns A,X,Y,TMP1,TMP2. do_chunk: ;; Copy a..e from h0..h4 - + ldy #(f-a-1) - lda h0,y sta a,y dey bpl - - + ldy #0 ; y is index into w - + ;; First 20: k1 +cp32 k1, k @@ -298,6 +323,7 @@ kind1: jsr and32 +setSRC d jsr xor32 + jmp common kind2: sty TMP1 @@ -310,11 +336,12 @@ kind2: jsr xor32 +setSRC b jsr xor32 + jmp common kind3: sty TMP1 stx TMP2 - ;; f = (b and c) or (d and (b or c)) + ;; f = (b and c) or (d and (b or c)) +setSRC c +setDST f jsr cp32 @@ -337,9 +364,11 @@ common: +setSRC a jsr cp32 jsr rol8 + jsr ror1 jsr ror1 jsr ror1 + +setSRC f jsr add32 +setSRC e @@ -358,10 +387,6 @@ common: sta SRC+1 jsr add32 - ;; Print out w[i] - lda #4 - jsr prbytes - ;; e = d +setSRC d +setDST e @@ -378,17 +403,17 @@ common: jsr cp32 jsr ror1 jsr ror1 - + ;; b = a +setSRC a +setDST b jsr cp32 - + ;; a = temp +setSRC temp +setDST a jsr cp32 - + ldy TMP1 ldx TMP2 iny @@ -435,14 +460,14 @@ fill: sta w,x dex bpl - - + ldy #0 rts ;;; 32-bit, big-endian math routines. ;;; Result goes in DST. Second operand (if any) ;;; comes from SRC. - + ;; Rotate-left DST. Burns a,y. rol1: ldy #0 @@ -462,12 +487,16 @@ ror1: lda (DST),y ror ldy #0 + php - lda (DST),y + plp ror + php sta (DST),y iny cpy #4 bne - + plp rts ;; Xor SRC into DST. Burns a,y. @@ -522,19 +551,19 @@ or32: ;; Rotate DST right by 8 bits. Burns a,x,y. rol8: ldy #0 - lda (SRC),y + lda (DST),y tax - iny - lda (SRC),y + lda (DST),y dey - sta (SRC),y + sta (DST),y iny cpy #3 bne - txa - sta (SRC),y + sta (DST),y rts - + !eof TODOs [X] Routine to print n hex bytes (address, length (byte)) @@ -548,5 +577,5 @@ Needed arithmetic routines for sha1sum: - [X] xor32 - [X] ROL1 - [X] ROR1 -- [ ] ROL5 --> ROL8, (ROR1,ROR1,ROR1) -- [ ] ROL30 --> (ROR1,ROR1) +- [X] ROL5 --> ROL8, (ROR1,ROR1,ROR1) +- [X] ROL30 --> (ROR1,ROR1) diff --git a/shasum/shasum.go b/shasum/shasum.go index 923b9e0..19ff80c 100644 --- a/shasum/shasum.go +++ b/shasum/shasum.go @@ -44,9 +44,13 @@ var rom = []byte{ } func main() { - print40s(expand(pad(rom[:0x37]))) - fmt.Printf("%x\n", sha1.Sum(rom[:0x37])) - fmt.Printf("%x\n", sha1.Sum(rom[:0])) + // 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) { @@ -74,7 +78,18 @@ func pad(in []byte) []byte { return out } -func expand(in []byte) []byte { +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:]) @@ -85,9 +100,74 @@ func expand(in []byte) []byte { w[i] = w[i]<<1 + w[i]>>31 } - out := make([]byte, len(w)*4) - for i, wi := range w { - binary.BigEndian.PutUint32(out[i*4:], wi) - } - return out + 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 }