Support x86_64 aesenc/aesdec and roundtrip mode
This commit is contained in:
parent
ef069318b9
commit
14a10f544f
68
aes/hash.go
68
aes/hash.go
|
@ -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
75
aes/round_amd64.go
Normal 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
32
aes/round_generic.go
Normal 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
11
asm/aes.go
Normal 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
18
asm/aes_amd64.go
Normal 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
93
asm/aes_amd64.s
Normal 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
11
asm/aes_noasm.go
Normal 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")
|
||||
}
|
Loading…
Reference in a new issue