Cython中的AES-NI内置函数?

3

2
类似于 pycrypto AESNI.c 这样的东西? - J.J. Hakala
@J.J.Hakala 然后提供示例代码并将其作为答案。 - ArekBulski
1个回答

2
你应该可以像在Cython中定义普通的C函数一样定义内在函数。类似于以下代码:
cdef extern from "emmintrin.h": # I'm going off the microsoft documentation for where the headers are
    # define the datatype as an opaque type
    ctypedef struct __m128i:
        pass

    __m128i _mm_set_epi32 (int i3, int i2, int i1, int i0)

cdef extern from "wmmintrin.h":
    __m128i _mm_aesdec_si128(__m128i v,__m128i rkey)

# then in some Cython function
def f():
   cdef __m128i v = _mm_set_epi32(1,2,3,4)
   cdef __m128i key = _mm_set_epi32(5,6,7,8)
   cdef __m128i result = _mm_aesdec_si128(v,key)

如何将此应用于 bytes 数组?首先,您需要获取 bytes 数组的 char*。然后,使用 range 进行迭代(注意不要越界)即可。

# assuming you already have an __m128i key
cdef __m128i v
cdef char* array = python_bytes_array # auto conversion
cdef int i, j

# you NEED to ensure that the byte array has a length divisible by
# 16, otherwise you'll probably get a segmentation fault.
for i in range(0,len(python_bytes_array),16):
    # go over in chunks of 16
    v = _mm_set_epi8(array[i+15],array[i+14],array[i+13],
            # etc... fill in the rest 
            array[i+1], array[i])

    cdef __m128 result = _mm_aesdec_si128(v,key)

    # write back to the same place?
    for j in range(16):
        array[i+j] = _mm_extract_epi8(result,j)

能否生成一个循环,而不需要在每次迭代中内部调用大量函数来解码数组?如果不能,那么您可能需要编写编码/解码C函数。 - Peter Cordes
看起来很棒。现在我该如何将其应用于字节(Python 3)对象? - ArekBulski
1
使用 _mm_extract_epi8 16 次看起来很糟糕。如果你幸运的话,它可能会编译成单个非对齐存储,但如果不行,它将是一些令人讨厌的膨胀代码。 - Peter Cordes
1
@PeterCordes 我同意!我相信它可以更快地完成。我只是想回答原始问题“如何在Cython中使用AES-NI指令?”我很高兴承认,有效地使用这些指令(甚至知道它们实际上是做什么的……)超出了我的知识范围。 - DavidW
1
@ThomasAhle 我认为删除 x。我不知道当初为什么要加上它,但我怀疑那是个错误。没有 x 对我来说编译(并且有意义)。 - DavidW
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接