本例摘自标准库 AES package,它使用汇编充分利用Intel的对AES的硬件支持,通过调用 AES-NI CPU 指令来实现。 它可以执行 AES算法的”循环”(round)加密和解密。 |
|
package aes
|
|
|
func encryptBlockAsm(nr int, xk *uint32, dst, src *byte)
|
#include "textflag.h"
|
|
本例设计AES算法的一些术语,翻译的比较勉强,如有错误,欢迎指正。
如你所见, 参数和返回结果的整体长度被忽略了, |
TEXT ·encryptBlockAsm(SB),NOSPLIT,$0
MOVQ nr+0(FP), CX
MOVQ xk+8(FP), AX
MOVQ dst+16(FP), DX
MOVQ src+24(FP), BX
|
|
MOVUPS 0(AX), X1
MOVUPS 0(BX), X0
ADDQ $16, AX // next round key
PXOR X1, X0
|
AES 接受各种变长的key:128位、192位、256位。这三种变长都接受一个不同数量的round。我们通过比较 |
SUBQ $12, CX
JE Lenc196
JB Lenc128
Lenc256:
|
一轮的处理总是使用相同的方式。相应的128位round key被加载到128位 SSE 寄存器中( |
MOVUPS 0(AX), X1
AESENC X1, X0
MOVUPS 16(AX), X1
AESENC X1, X0
ADDQ $32, AX // next round keys
|
AES-256 比 AES-196 要多两轮,所以当前两个操作做完后,很自然继续 AES-192的分支。 |
Lenc196:
MOVUPS 0(AX), X1
AESENC X1, X0
MOVUPS 16(AX), X1
AESENC X1, X0
ADDQ $32, AX
|
同样的道理前面两个case还要执行这个分支。 |
Lenc128:
MOVUPS 0(AX), X1
AESENC X1, X0
MOVUPS 16(AX), X1
AESENC X1, X0
MOVUPS 32(AX), X1
AESENC X1, X0
MOVUPS 48(AX), X1
AESENC X1, X0
MOVUPS 64(AX), X1
AESENC X1, X0
MOVUPS 80(AX), X1
AESENC X1, X0
MOVUPS 96(AX), X1
AESENC X1, X0
MOVUPS 112(AX), X1
AESENC X1, X0
MOVUPS 128(AX), X1
AESENC X1, X0
MOVUPS 144(AX), X1
AESENCLAST X1, X0
MOVUPS X0, 0(DX)
RET
|
下一个例子: Sqrt.