diff --git a/aes/hash.go b/aes/hash.go index 654f9ff..6e7c3a8 100644 --- a/aes/hash.go +++ b/aes/hash.go @@ -57,21 +57,21 @@ func HashAes1Rx4(input []byte, output *[64]byte) { for input_ptr := 0; input_ptr < len(input); input_ptr += 64 { in := (*[4][4]uint32)(unsafe.Pointer(unsafe.SliceData(input[input_ptr:]))) - soft_aesenc(&states[0], &in[0]) - soft_aesdec(&states[1], &in[1]) - soft_aesenc(&states[2], &in[2]) - soft_aesdec(&states[3], &in[3]) + aesenc(&states[0], &in[0]) + aesdec(&states[1], &in[1]) + aesenc(&states[2], &in[2]) + aesdec(&states[3], &in[3]) } - soft_aesenc(&states[0], &keys.AesHash1R_XKeys[0]) - soft_aesdec(&states[1], &keys.AesHash1R_XKeys[0]) - soft_aesenc(&states[2], &keys.AesHash1R_XKeys[0]) - soft_aesdec(&states[3], &keys.AesHash1R_XKeys[0]) + aesenc(&states[0], &keys.AesHash1R_XKeys[0]) + aesdec(&states[1], &keys.AesHash1R_XKeys[0]) + aesenc(&states[2], &keys.AesHash1R_XKeys[0]) + aesdec(&states[3], &keys.AesHash1R_XKeys[0]) - soft_aesenc(&states[0], &keys.AesHash1R_XKeys[1]) - soft_aesdec(&states[1], &keys.AesHash1R_XKeys[1]) - soft_aesenc(&states[2], &keys.AesHash1R_XKeys[1]) - soft_aesdec(&states[3], &keys.AesHash1R_XKeys[1]) + aesenc(&states[0], &keys.AesHash1R_XKeys[1]) + aesdec(&states[1], &keys.AesHash1R_XKeys[1]) + aesenc(&states[2], &keys.AesHash1R_XKeys[1]) + aesdec(&states[3], &keys.AesHash1R_XKeys[1]) copy(output[:], (*[64]byte)(unsafe.Pointer(&states))[:]) } @@ -95,10 +95,10 @@ func FillAes1Rx4(state *[64]byte, output []byte) { states := (*[4][4]uint32)(unsafe.Pointer(state)) for outptr := 0; outptr < len(output); outptr += len(state) { - soft_aesdec(&states[0], &keys.AesGenerator1R_Keys[0]) - soft_aesenc(&states[1], &keys.AesGenerator1R_Keys[1]) - soft_aesdec(&states[2], &keys.AesGenerator1R_Keys[2]) - soft_aesenc(&states[3], &keys.AesGenerator1R_Keys[3]) + aesdec(&states[0], &keys.AesGenerator1R_Keys[0]) + aesenc(&states[1], &keys.AesGenerator1R_Keys[1]) + aesdec(&states[2], &keys.AesGenerator1R_Keys[2]) + aesenc(&states[3], &keys.AesGenerator1R_Keys[3]) copy(output[outptr:], state[:]) } @@ -116,25 +116,25 @@ func FillAes4Rx4(state [64]byte, output []byte) { states := (*[4][4]uint32)(unsafe.Pointer(&state)) for outptr := 0; outptr < len(output); outptr += len(state) { - soft_aesdec(&states[0], &keys.AesGenerator4R_Keys[0]) - soft_aesenc(&states[1], &keys.AesGenerator4R_Keys[0]) - soft_aesdec(&states[2], &keys.AesGenerator4R_Keys[4]) - soft_aesenc(&states[3], &keys.AesGenerator4R_Keys[4]) + aesdec(&states[0], &keys.AesGenerator4R_Keys[0]) + aesenc(&states[1], &keys.AesGenerator4R_Keys[0]) + aesdec(&states[2], &keys.AesGenerator4R_Keys[4]) + aesenc(&states[3], &keys.AesGenerator4R_Keys[4]) - soft_aesdec(&states[0], &keys.AesGenerator4R_Keys[1]) - soft_aesenc(&states[1], &keys.AesGenerator4R_Keys[1]) - soft_aesdec(&states[2], &keys.AesGenerator4R_Keys[5]) - soft_aesenc(&states[3], &keys.AesGenerator4R_Keys[5]) + aesdec(&states[0], &keys.AesGenerator4R_Keys[1]) + aesenc(&states[1], &keys.AesGenerator4R_Keys[1]) + aesdec(&states[2], &keys.AesGenerator4R_Keys[5]) + aesenc(&states[3], &keys.AesGenerator4R_Keys[5]) - soft_aesdec(&states[0], &keys.AesGenerator4R_Keys[2]) - soft_aesenc(&states[1], &keys.AesGenerator4R_Keys[2]) - soft_aesdec(&states[2], &keys.AesGenerator4R_Keys[6]) - soft_aesenc(&states[3], &keys.AesGenerator4R_Keys[6]) + aesdec(&states[0], &keys.AesGenerator4R_Keys[2]) + aesenc(&states[1], &keys.AesGenerator4R_Keys[2]) + aesdec(&states[2], &keys.AesGenerator4R_Keys[6]) + aesenc(&states[3], &keys.AesGenerator4R_Keys[6]) - soft_aesdec(&states[0], &keys.AesGenerator4R_Keys[3]) - soft_aesenc(&states[1], &keys.AesGenerator4R_Keys[3]) - soft_aesdec(&states[2], &keys.AesGenerator4R_Keys[7]) - soft_aesenc(&states[3], &keys.AesGenerator4R_Keys[7]) + aesdec(&states[0], &keys.AesGenerator4R_Keys[3]) + aesenc(&states[1], &keys.AesGenerator4R_Keys[3]) + aesdec(&states[2], &keys.AesGenerator4R_Keys[7]) + aesenc(&states[3], &keys.AesGenerator4R_Keys[7]) copy(output[outptr:], state[:]) } diff --git a/aes/round_amd64.go b/aes/round_amd64.go new file mode 100644 index 0000000..6be0afe --- /dev/null +++ b/aes/round_amd64.go @@ -0,0 +1,33 @@ +//go:build amd64 && !purego + +package aes + +import ( + _ "git.gammaspectra.live/P2Pool/go-randomx/v2/asm" + "golang.org/x/sys/cpu" + _ "unsafe" +) + +//go:linkname hard_aesdec git.gammaspectra.live/P2Pool/go-randomx/v2/asm.aesdec +func hard_aesdec(state *[4]uint32, key *[4]uint32) + +//go:linkname hard_aesenc git.gammaspectra.live/P2Pool/go-randomx/v2/asm.aesenc +func hard_aesenc(state *[4]uint32, key *[4]uint32) + +var supportsAES = cpu.X86.HasAES + +func aesenc(state *[4]uint32, key *[4]uint32) { + if supportsAES { + hard_aesenc(state, key) + } else { + soft_aesenc(state, key) + } +} + +func aesdec(state *[4]uint32, key *[4]uint32) { + if supportsAES { + hard_aesdec(state, key) + } else { + soft_aesdec(state, key) + } +} diff --git a/aes/round_generic.go b/aes/round_generic.go new file mode 100644 index 0000000..396cbb1 --- /dev/null +++ b/aes/round_generic.go @@ -0,0 +1,11 @@ +//go:build !amd64 || purego + +package aes + +func aesenc(state *[4]uint32, key *[4]uint32) { + soft_aesenc(state, key) +} + +func aesdec(state *[4]uint32, key *[4]uint32) { + soft_aesdec(state, key) +} diff --git a/asm/aes.go b/asm/aes.go new file mode 100644 index 0000000..698bc4c --- /dev/null +++ b/asm/aes.go @@ -0,0 +1,11 @@ +//go:build amd64 && !purego + +package asm + +func AESRoundEncrypt(state *[4]uint32, key *[4]uint32) { + aesenc(state, key) +} + +func AESRoundDecrypt(state *[4]uint32, key *[4]uint32) { + aesdec(state, key) +} diff --git a/asm/aes_amd64.go b/asm/aes_amd64.go new file mode 100644 index 0000000..8e7b982 --- /dev/null +++ b/asm/aes_amd64.go @@ -0,0 +1,9 @@ +//go:build amd64 && !purego + +package asm + +//go:noescape +func aesenc(state *[4]uint32, key *[4]uint32) + +//go:noescape +func aesdec(state *[4]uint32, key *[4]uint32) diff --git a/asm/aes_amd64.s b/asm/aes_amd64.s new file mode 100644 index 0000000..3a09f95 --- /dev/null +++ b/asm/aes_amd64.s @@ -0,0 +1,23 @@ +//go:build amd64 && !purego + +#include "textflag.h" + +TEXT ·aesenc(SB),NOSPLIT|NOFRAME,$0-16 + MOVQ state+0(FP), AX + MOVQ key+8(FP), BX + MOVUPS 0(AX), X0 + MOVUPS 0(BX), X1 + AESENC X1, X0 + MOVUPS X0, 0(AX) + MOVUPS X1, 0(BX) + RET + +TEXT ·aesdec(SB),NOSPLIT|NOFRAME,$0-16 + MOVQ state+0(FP), AX + MOVQ key+8(FP), BX + MOVUPS 0(AX), X0 + MOVUPS 0(BX), X1 + AESDEC X1, X0 + MOVUPS X0, 0(AX) + MOVUPS X1, 0(BX) + RET diff --git a/asm/aes_noasm.go b/asm/aes_noasm.go new file mode 100644 index 0000000..3f4006b --- /dev/null +++ b/asm/aes_noasm.go @@ -0,0 +1,11 @@ +//go:build !amd64 || purego + +package asm + +func AESRoundEncrypt(state *[4]uint32, key *[4]uint32) { + panic("not implemented") +} + +func AESRoundDecrypt(state *[4]uint32, key *[4]uint32) { + panic("not implemented") +}