#include "bee2/core/util.h"
#include "bee2/math/pp.h"
#include "bee2/math/ww.h"
#include "belt_lcl.h"
void beltBlockAddBitSizeU32(u32 block[4], size_t count)
{
register u32 carry = (u32)count << 3;
#if (B_PER_S < 32)
carry = (block[0] += carry) < carry;
carry = (block[1] += carry) < carry;
carry = (block[2] += carry) < carry;
block[3] += carry;
#else
register size_t t = count >> 29;
carry = (block[0] += carry) < carry;
if ((block[1] += carry) < carry)
block[1] = (u32)t;
else
carry = (block[1] += (u32)t) < (u32)t;
t >>= 16, t >>= 16;
if ((block[2] += carry) < carry)
block[2] = (u32)t;
else
carry = (block[2] += (u32)t) < (u32)t;
t >>= 16, t >>= 16;
block[3] += carry;
block[3] += (u32)t;
CLEAN(t);
#endif
CLEAN(carry);
}
void beltHalfBlockAddBitSizeW(word block[W_OF_B(64)], size_t count)
{
register word carry = (word)count << 3;
#if (B_PER_W == 16)
register size_t t = count >> 13;
carry = (block[0] += carry) < carry;
if ((block[1] += carry) < carry)
block[1] = (word)t;
else
carry = (block[1] += (word)t) < (word)t;
t >>= 8, t >>= 8;
if ((block[2] += carry) < carry)
block[2] = (word)t;
else
carry = (block[2] += (word)t) < (word)t;
t >>= 8, t >>= 8;
block[3] += carry;
block[3] += (word)t;
#elif (B_PER_W == 32)
register size_t t = count;
carry = (block[0] += carry) < carry;
t >>= 15, t >>= 14;
block[1] += carry;
block[1] += (u32)t;
CLEAN(t);
#elif (B_PER_W == 64)
block[0] += carry;
#else
#error "Unsupported word size"
#endif CLEAN(carry);
}
void beltPolyMul(word c[], const word a[], const word b[], void* stack)
{
const size_t n = W_OF_B(128);
word* prod = (word*)stack;
stack = prod + 2 * n;
ppMul(prod, a, n, b, n, stack);
ppRedBelt(prod);
wwCopy(c, prod, n);
}
size_t beltPolyMul_deep()
{
const size_t n = W_OF_B(128);
return O_OF_W(2 * n) + ppMul_deep(n, n);
}
void beltBlockMulC(u32 block[4])
{
register u32 t = ~((block[3] >> 31) - U32_1) & 0x00000087;
block[3] = (block[3] << 1) ^ (block[2] >> 31);
block[2] = (block[2] << 1) ^ (block[1] >> 31);
block[1] = (block[1] << 1) ^ (block[0] >> 31);
block[0] = (block[0] << 1) ^ t;
CLEAN(t);
}