BLAKE2をPythonから

Sourceforge.JP Magazine の記事BLAKE2 というものが載ってたので,ctypesの練習がてら書いてみた.

Makefile:

:::makefile
CC=gcc
CFLAGS=-shared -std=c99 -O3 -march=native -Wall -fPIC -fopenmp -I../sse -I/usr/include/python2.7
LIBS=
#FILES=blake2sum.c ../ref/blake2b-ref.c ../ref/blake2s-ref.c ../ref/blake2bp-ref.c ../ref/blake2sp-ref.c 
FILES=../sse/blake2b.c ../sse/blake2s.c ../sse/blake2bp.c ../sse/blake2sp.c 
all: $(FILES)
    $(CC) $(FILES) $(CFLAGS) $(LIBS) -o pyblake2.so

clean:
    rm -f pyblake2.so

blake2.py:

:::python
from ctypes import *
pyblake = CDLL("./pyblake2.so")
BLAKE2S_BLOCKBYTES = 64
BLAKE2S_OUTBYTES = 32
class blake2s_state(Structure):
    _pack_ = 64
    _fields_ = [
        ("h", c_uint32 * 8),
        ("t", c_uint32 * 2),
        ("f", c_uint32 * 2),
        ("buf", c_uint8 * 2 * BLAKE2S_BLOCKBYTES),
        ("buflen", c_size_t),
        ("last_node", c_uint8),
    ]
S = blake2s_state()
pyblake.blake2s_init(pointer(S), BLAKE2S_OUTBYTES);
buffer_length = 32768
buf = (c_ubyte * buffer_length)(*map(ord, list("abc\n")))
buf[4] = 0
pyblake.blake2s_update(pointer(S), buf, 4)
resstream = (c_ubyte * BLAKE2S_OUTBYTES)()
pyblake.blake2s_final(pointer(S), resstream, BLAKE2S_OUTBYTES);
print "".join(["%02x" % x for x in resstream])

落としてきたBLAKE2のソースを解凍してそれっぽい感じに配置してみて下さい.

:::sh
$ echo abc > input
$ ./b2sum -a blake2s input
e6a9ebf5e152e6f140779805687cf2ad5e67408f5bfddbbdf4ee85d5c2e09f9e input
$ ../pythonapi
$ python blake2.py
e6a9ebf5e152e6f140779805687cf2ad5e67408f5bfddbbdf4ee85d5c2e09f9e