125 lines
2.0 KiB
Go
125 lines
2.0 KiB
Go
// +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(Register, Register, Register) 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 Register) Register {
|
|
r := GP32v()
|
|
MOVL(d, r)
|
|
XORL(c, r)
|
|
ANDL(b, r)
|
|
XORL(d, r)
|
|
return r
|
|
}
|
|
|
|
func xor(b, c, d Register) Register {
|
|
r := GP32v()
|
|
MOVL(b, r)
|
|
XORL(c, r)
|
|
XORL(d, r)
|
|
return r
|
|
}
|
|
|
|
func majority(b, c, d Register) 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
|
|
}
|