#include "crypto_verify_32.h" #include "crypto_pow_inv25519.h" #include "crypto_powbatch.h" #include "fe25519.h" #define MAXTODO 8 static const unsigned char zerobytes[32] = {0}; static const fe25519_10l_dense zero = {{0,0,0,0,0}}; static const fe25519_10l_dense one = {{1,0,0,0,0}}; void crypto_powbatch(unsigned char *q,const unsigned char *p,long long batch) { fe25519_10l_dense tmp[MAXTODO+MAXTODO-1]; /* for todo=1: p0 */ /* for todo=2: p0p1, p0, p1 */ /* for todo=3: p0p1p2, p0p1, p0, p1, p2 */ int zeroflag[MAXTODO]; unsigned char s[32]; fe25519 x; while (batch > 0) { long long todo = MAXTODO; if (batch < todo) todo = batch; batch -= todo; for (long long pos = 0;pos < todo;++pos) { fe25519_unpack(&x,p); fe25519_4l_to_10l_dense(&tmp[todo-1+pos],&x); p += 32; fe25519_10l_dense_to_4l(&x,&tmp[todo-1+pos]); fe25519_pack(s,&x); zeroflag[pos] = 1+crypto_verify_32(s,zerobytes); fe25519_cmov(&tmp[todo-1+pos],&one,zeroflag[pos]); if (pos > 0) fe25519_mul(&tmp[todo-1-pos],&tmp[todo-pos],&tmp[todo-1+pos]); } fe25519_10l_dense_to_4l(&x,&tmp[0]); fe25519_pack(s,&x); crypto_pow_inv25519(s,s); fe25519_unpack(&x,s); fe25519_4l_to_10l_dense(&tmp[0],&x); for (long long pos = todo-1;pos > 0;--pos) { fe25519_mul(&tmp[todo-pos],&tmp[todo-pos],&tmp[todo-1-pos]); fe25519_cmov(&tmp[todo-pos],&zero,zeroflag[pos]); fe25519_10l_dense_to_4l(&x,&tmp[todo-pos]); fe25519_pack(q+32*pos,&x); fe25519_mul(&tmp[todo-pos],&tmp[todo-1+pos],&tmp[todo-1-pos]); } fe25519_cmov(&tmp[todo-1],&zero,zeroflag[0]); fe25519_10l_dense_to_4l(&x,&tmp[todo-1]); fe25519_pack(q,&x); q += 32*todo; } }