【发布时间】:2014-08-13 04:42:43
【问题描述】:
我正在为 libsodium 例程 crypto_aead_chacha20poly1305_encrypt 在 PySodium 中编写一个 ctypes 包装器,该例程定义为:
def crypto_aead_chacha20poly1305_encrypt(message,
ad,
nonce,
key):
mlen = ctypes.c_ulonglong(len(message))
adlen = ctypes.c_ulonglong(len(ad))
c = ctypes.create_string_buffer(mlen.value+16L)
clen = ctypes.c_ulonglong(0)
sodium.crypto_aead_chacha20poly1305_encrypt(c,
clen,
message,
mlen,
ad,
adlen,
None,
nonce,
key)
return c.raw
我的测试司机是:
from pysodium import crypto_aead_chacha20poly1305_encrypt
from bitstring import BitStream
key = BitStream(hex="4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007")
nonce = BitStream(hex="cd7cf67be39c794a")
ad = BitStream(hex="87e229d4500845a079c0")
msg = BitStream(hex="86d09974840bded2a5ca")
print(key)
print(nonce)
print(ad)
print(msg)
m = crypto_aead_chacha20poly1305_encrypt(message=msg.bytes,
ad=ad.bytes,
nonce=nonce.bytes,
key=key.bytes)
edata = BitStream(bytes=m)
print(edata)
令我惊讶的是(这是我第一次使用 libsodium 或 PySodium 或 ctypes)它在 AMD x86_64 系统上运行顺利。不幸的是,当我将所有内容都移植到 RaspberryPi (ARMv6) 上时,事情就被取消了。我对它运行了gdb python-gdb,可以看到堆栈跟踪:
阅读 FFI 实际上做了什么我不得不认为,由于某种原因,当 ctypes 将数据传递给 FFI 时,它会在此过程中被损坏。我已经搜索过,试图找出在 Pi/ARM 平台上 ctypes/FFI 等是否存在一些已知问题,但一直空白。如果这是我的实际绑定代码,我很想知道为什么它在 x86_64 与 ARM 上的行为正确。
最后,我对使用 ctypes 替代品的建议持开放态度(尽管对 SWIG 并不疯狂,如果需要的话)。
【问题讨论】:
-
您可能应该尝试设置显式
argtypes(和restype,但这并不重要,尤其是对于返回int的函数)。当您不确定您创建的值是错误的还是错误的签名时,调试这些问题已经够难的了…… -
供参考,这里是the docs for the function。乍一看,您似乎掌握了正确的类型……
-
最后一件事:根据Bindings for other languages,libsodium 有两组不同的 Python 绑定。你两个都试过了吗?它们是否缺少您需要的功能,或者它们没有在 RPi 上运行,或者......?
-
感谢
argtypes的提示,我去看看。我看了一眼其他 Python 绑定,它们完全是在旧版本的libsodium上,但我已经提出了一个问题请求,希望我可以与他们合作更新它。 -
如果他们都使用
ctypes,也许对方的来源有一些可以提供帮助的想法,即使你不能直接使用它?
标签: python raspberry-pi ctypes ffi