examples/sha1: single block
This commit is contained in:
124
examples/sha1/asm.go
Normal file
124
examples/sha1/asm.go
Normal file
@@ -0,0 +1,124 @@
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
. "github.com/mmcloughlin/avo/build"
|
||||
. "github.com/mmcloughlin/avo/operand"
|
||||
"github.com/mmcloughlin/avo/reg"
|
||||
)
|
||||
|
||||
func main() {
|
||||
TEXT("block", "func(h *[5]uint32, m []byte)")
|
||||
h := Mem{Base: Load(Param("h"), GP64v())}
|
||||
m := Mem{Base: Load(Param("m").Base(), GP64v())}
|
||||
|
||||
// Store message values on the stack.
|
||||
w := AllocLocal(64)
|
||||
W := func(r int) Mem { return w.Idx((r % 16) * 4) }
|
||||
|
||||
// Load initial hash.
|
||||
h0, h1, h2, h3, h4 := GP32v(), GP32v(), GP32v(), GP32v(), GP32v()
|
||||
|
||||
MOVL(h.Idx(0), h0)
|
||||
MOVL(h.Idx(4), h1)
|
||||
MOVL(h.Idx(8), h2)
|
||||
MOVL(h.Idx(12), h3)
|
||||
MOVL(h.Idx(16), h4)
|
||||
|
||||
// Initialize registers.
|
||||
a, b, c, d, e := GP32v(), GP32v(), GP32v(), GP32v(), GP32v()
|
||||
|
||||
MOVL(h0, a)
|
||||
MOVL(h1, b)
|
||||
MOVL(h2, c)
|
||||
MOVL(h3, d)
|
||||
MOVL(h4, e)
|
||||
|
||||
// Generate round updates.
|
||||
quarter := []struct {
|
||||
F func(reg.Register, reg.Register, reg.Register) reg.Register
|
||||
K uint32
|
||||
}{
|
||||
{choose, 0x5a827999},
|
||||
{xor, 0x6ed9eba1},
|
||||
{majority, 0x8f1bbcdc},
|
||||
{xor, 0xca62c1d6},
|
||||
}
|
||||
|
||||
for r := 0; r < 80; r++ {
|
||||
q := quarter[r/20]
|
||||
|
||||
// Load message value.
|
||||
u := GP32v()
|
||||
if r < 16 {
|
||||
MOVL(m.Idx(4*r), u)
|
||||
BSWAPL(u)
|
||||
} else {
|
||||
MOVL(W(r-3), u)
|
||||
XORL(W(r-8), u)
|
||||
XORL(W(r-14), u)
|
||||
XORL(W(r-16), u)
|
||||
ROLL(Imm(1), u)
|
||||
}
|
||||
MOVL(u, W(r))
|
||||
|
||||
// Compute the next state register.
|
||||
t := GP32v()
|
||||
MOVL(a, t)
|
||||
ROLL(Imm(5), t)
|
||||
ADDL(q.F(b, c, d), t)
|
||||
ADDL(e, t)
|
||||
ADDL(Imm(q.K), t)
|
||||
ADDL(u, t)
|
||||
|
||||
// Update registers.
|
||||
ROLL(Imm(30), b)
|
||||
a, b, c, d, e = t, a, b, c, d
|
||||
}
|
||||
|
||||
// Final add.
|
||||
ADDL(a, h0)
|
||||
ADDL(b, h1)
|
||||
ADDL(c, h2)
|
||||
ADDL(d, h3)
|
||||
ADDL(e, h4)
|
||||
|
||||
// Store results back.
|
||||
MOVL(h0, h.Idx(0))
|
||||
MOVL(h1, h.Idx(4))
|
||||
MOVL(h2, h.Idx(8))
|
||||
MOVL(h3, h.Idx(12))
|
||||
MOVL(h4, h.Idx(16))
|
||||
RET()
|
||||
|
||||
Generate()
|
||||
}
|
||||
|
||||
func choose(b, c, d reg.Register) reg.Register {
|
||||
r := GP32v()
|
||||
MOVL(d, r)
|
||||
XORL(c, r)
|
||||
ANDL(b, r)
|
||||
XORL(d, r)
|
||||
return r
|
||||
}
|
||||
|
||||
func xor(b, c, d reg.Register) reg.Register {
|
||||
r := GP32v()
|
||||
MOVL(b, r)
|
||||
XORL(c, r)
|
||||
XORL(d, r)
|
||||
return r
|
||||
}
|
||||
|
||||
func majority(b, c, d reg.Register) reg.Register {
|
||||
t, r := GP32v(), GP32v()
|
||||
MOVL(b, t)
|
||||
ORL(c, t)
|
||||
ANDL(d, t)
|
||||
MOVL(b, r)
|
||||
ANDL(c, r)
|
||||
ORL(t, r)
|
||||
return r
|
||||
}
|
||||
1341
examples/sha1/sha1.s
Normal file
1341
examples/sha1/sha1.s
Normal file
File diff suppressed because it is too large
Load Diff
26
examples/sha1/sha1_test.go
Normal file
26
examples/sha1/sha1_test.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package sha1
|
||||
|
||||
import (
|
||||
"log"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
//go:generate go run asm.go -out sha1.s -stubs stub.go
|
||||
|
||||
func TestEmptyString(t *testing.T) {
|
||||
h := [...]uint32{0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0}
|
||||
m := make([]byte, 64)
|
||||
m[0] = 0x80
|
||||
|
||||
block(&h, m)
|
||||
|
||||
expect := [...]uint32{0xda39a3ee, 0x5e6b4b0d, 0x3255bfef, 0x95601890, 0xafd80709}
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
log.Printf("h[%d] = %08x", i, h[i])
|
||||
}
|
||||
if !reflect.DeepEqual(expect, h) {
|
||||
t.Fatal("incorrect hash")
|
||||
}
|
||||
}
|
||||
5
examples/sha1/stub.go
Normal file
5
examples/sha1/stub.go
Normal file
@@ -0,0 +1,5 @@
|
||||
// Code generated by command: go run asm.go -out sha1.s -stubs stub.go. DO NOT EDIT.
|
||||
|
||||
package sha1
|
||||
|
||||
func block(h *[5]uint32, m []byte)
|
||||
Reference in New Issue
Block a user