Support x86_64 aesenc/aesdec and roundtrip mode
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing

This commit is contained in:
DataHoarder 2024-04-18 10:47:29 +02:00
parent ef069318b9
commit 14a10f544f
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk
7 changed files with 273 additions and 35 deletions

View file

@ -57,21 +57,12 @@ 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])
aesroundtrip_encdec(&states, in)
}
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])
aesroundtrip_encdec1(&states, &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])
aesroundtrip_encdec1(&states, &keys.AesHash1R_XKeys[1])
copy(output[:], (*[64]byte)(unsafe.Pointer(&states))[:])
}
@ -95,15 +86,37 @@ 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])
aesroundtrip_decenc(states, &keys.AesGenerator1R_Keys)
copy(output[outptr:], state[:])
}
}
var fillAes4Rx4Keys0 = [4][4]uint32{
keys.AesGenerator4R_Keys[0],
keys.AesGenerator4R_Keys[0],
keys.AesGenerator4R_Keys[4],
keys.AesGenerator4R_Keys[4],
}
var fillAes4Rx4Keys1 = [4][4]uint32{
keys.AesGenerator4R_Keys[1],
keys.AesGenerator4R_Keys[1],
keys.AesGenerator4R_Keys[5],
keys.AesGenerator4R_Keys[5],
}
var fillAes4Rx4Keys2 = [4][4]uint32{
keys.AesGenerator4R_Keys[2],
keys.AesGenerator4R_Keys[2],
keys.AesGenerator4R_Keys[6],
keys.AesGenerator4R_Keys[6],
}
var fillAes4Rx4Keys3 = [4][4]uint32{
keys.AesGenerator4R_Keys[3],
keys.AesGenerator4R_Keys[3],
keys.AesGenerator4R_Keys[7],
keys.AesGenerator4R_Keys[7],
}
// FillAes4Rx4 used to generate final program
func FillAes4Rx4(state [64]byte, output []byte) {
if len(output)%len(state) != 0 {
@ -116,25 +129,10 @@ 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])
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])
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])
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])
aesroundtrip_decenc(states, &fillAes4Rx4Keys0)
aesroundtrip_decenc(states, &fillAes4Rx4Keys1)
aesroundtrip_decenc(states, &fillAes4Rx4Keys2)
aesroundtrip_decenc(states, &fillAes4Rx4Keys3)
copy(output[outptr:], state[:])
}

75
aes/round_amd64.go Normal file
View file

@ -0,0 +1,75 @@
//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)
//go:linkname hard_aesroundtrip_decenc git.gammaspectra.live/P2Pool/go-randomx/v2/asm.aesroundtrip_decenc
func hard_aesroundtrip_decenc(states *[4][4]uint32, keys *[4][4]uint32)
//go:linkname hard_aesroundtrip_encdec git.gammaspectra.live/P2Pool/go-randomx/v2/asm.aesroundtrip_encdec
func hard_aesroundtrip_encdec(states *[4][4]uint32, keys *[4][4]uint32)
//go:linkname hard_aesroundtrip_encdec1 git.gammaspectra.live/P2Pool/go-randomx/v2/asm.aesroundtrip_encdec1
func hard_aesroundtrip_encdec1(states *[4][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)
}
}
func aesroundtrip_decenc(states *[4][4]uint32, keys *[4][4]uint32) {
if supportsAES {
hard_aesroundtrip_decenc(states, keys)
} else {
aesdec(&states[0], &keys[0])
aesenc(&states[1], &keys[1])
aesdec(&states[2], &keys[2])
aesenc(&states[3], &keys[3])
}
}
func aesroundtrip_encdec(states *[4][4]uint32, keys *[4][4]uint32) {
if supportsAES {
hard_aesroundtrip_encdec(states, keys)
} else {
aesenc(&states[0], &keys[0])
aesdec(&states[1], &keys[1])
aesenc(&states[2], &keys[2])
aesdec(&states[3], &keys[3])
}
}
func aesroundtrip_encdec1(states *[4][4]uint32, key *[4]uint32) {
if supportsAES {
hard_aesroundtrip_encdec1(states, key)
} else {
aesenc(&states[0], key)
aesdec(&states[1], key)
aesenc(&states[2], key)
aesdec(&states[3], key)
}
}

32
aes/round_generic.go Normal file
View file

@ -0,0 +1,32 @@
//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)
}
func aesroundtrip_decenc(states *[4][4]uint32, keys *[4][4]uint32) {
aesdec(&states[0], &keys[0])
aesenc(&states[1], &keys[1])
aesdec(&states[2], &keys[2])
aesenc(&states[3], &keys[3])
}
func aesroundtrip_encdec(states *[4][4]uint32, keys *[4][4]uint32) {
aesenc(&states[0], &keys[0])
aesdec(&states[1], &keys[1])
aesenc(&states[2], &keys[2])
aesdec(&states[3], &keys[3])
}
func aesroundtrip_encdec1(states *[4][4]uint32, key *[4]uint32) {
aesenc(&states[0], key)
aesdec(&states[1], key)
aesenc(&states[2], key)
aesdec(&states[3], key)
}

11
asm/aes.go Normal file
View file

@ -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)
}

18
asm/aes_amd64.go Normal file
View file

@ -0,0 +1,18 @@
//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)
//go:noescape
func aesroundtrip_decenc(states *[4][4]uint32, keys *[4][4]uint32)
//go:noescape
func aesroundtrip_encdec(states *[4][4]uint32, keys *[4][4]uint32)
//go:noescape
func aesroundtrip_encdec1(states *[4][4]uint32, key *[4]uint32)

93
asm/aes_amd64.s Normal file
View file

@ -0,0 +1,93 @@
//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)
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)
RET
TEXT ·aesroundtrip_decenc(SB),NOSPLIT|NOFRAME,$0-16
MOVQ states+0(FP), AX
MOVQ keys+8(FP), BX
MOVUPS 0(AX), X0
MOVUPS 0(BX), X1
MOVUPS 16(AX), X2
MOVUPS 16(BX), X3
MOVUPS 32(AX), X4
MOVUPS 32(BX), X5
MOVUPS 48(AX), X6
MOVUPS 48(BX), X7
AESDEC X1, X0
AESENC X3, X2
AESDEC X5, X4
AESENC X7, X6
MOVUPS X0, 0(AX)
MOVUPS X2, 16(AX)
MOVUPS X4, 32(AX)
MOVUPS X6, 48(AX)
RET
TEXT ·aesroundtrip_encdec(SB),NOSPLIT|NOFRAME,$0-16
MOVQ states+0(FP), AX
MOVQ keys+8(FP), BX
MOVUPS 0(AX), X0
MOVUPS 0(BX), X1
MOVUPS 16(AX), X2
MOVUPS 16(BX), X3
MOVUPS 32(AX), X4
MOVUPS 32(BX), X5
MOVUPS 48(AX), X6
MOVUPS 48(BX), X7
AESENC X1, X0
AESDEC X3, X2
AESENC X5, X4
AESDEC X7, X6
MOVUPS X0, 0(AX)
MOVUPS X2, 16(AX)
MOVUPS X4, 32(AX)
MOVUPS X6, 48(AX)
RET
TEXT ·aesroundtrip_encdec1(SB),NOSPLIT|NOFRAME,$0-16
MOVQ states+0(FP), AX
MOVQ key+8(FP), BX
MOVUPS 0(BX), X0
MOVUPS 0(AX), X1
MOVUPS 16(AX), X2
MOVUPS 32(AX), X3
MOVUPS 48(AX), X4
AESENC X0, X1
AESDEC X0, X2
AESENC X0, X3
AESDEC X0, X4
MOVUPS X1, 0(AX)
MOVUPS X2, 16(AX)
MOVUPS X3, 32(AX)
MOVUPS X4, 48(AX)
RET

11
asm/aes_noasm.go Normal file
View file

@ -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")
}