#ifndef __BLS12_381_ASM_BYTES_H__
#define __BLS12_381_ASM_BYTES_H__
static inline void bytes_zero(unsigned char *a, size_t num)
{
size_t i;
for (i = 0; i < num; i++)
a[i] = 0;
}
static inline void limbs_from_be_bytes(limb_t *restrict ret,
const unsigned char *in, size_t n)
{
limb_t limb = 0;
while(n--) {
limb <<= 8;
limb |= *in++;
ret[n / sizeof(limb_t)] = limb;
}
}
static inline void be_bytes_from_limbs(unsigned char *out, const limb_t *in,
size_t n)
{
limb_t limb;
while(n--) {
limb = in[n / sizeof(limb_t)];
*out++ = (unsigned char)(limb >> (8 * (n % sizeof(limb_t))));
}
}
static inline void limbs_from_le_bytes(limb_t *restrict ret,
const unsigned char *in, size_t n)
{
limb_t limb = 0;
while(n--) {
limb <<= 8;
limb |= in[n];
ret[n / sizeof(limb_t)] = limb;
}
}
static inline void le_bytes_from_limbs(unsigned char *out, const limb_t *in,
size_t n)
{
const union {
long one;
char little;
} is_endian = { 1 };
limb_t limb;
size_t i, j, r;
if ((uptr_t)out == (uptr_t)in && is_endian.little)
return;
r = n % sizeof(limb_t);
n /= sizeof(limb_t);
for(i = 0; i < n; i++) {
for (limb = in[i], j = 0; j < sizeof(limb_t); j++, limb >>= 8)
*out++ = (unsigned char)limb;
}
if (r) {
for (limb = in[i], j = 0; j < r; j++, limb >>= 8)
*out++ = (unsigned char)limb;
}
}
static inline char hex_from_nibble(unsigned char nibble)
{
int mask = (9 - (nibble &= 0xf)) >> 31;
return (char)(nibble + ((('a'-10) & mask) | ('0' & ~mask)));
}
static unsigned char nibble_from_hex(char c)
{
int mask, ret;
mask = (('a'-c-1) & (c-1-'f')) >> 31;
ret = (10 + c - 'a') & mask;
mask = (('A'-c-1) & (c-1-'F')) >> 31;
ret |= (10 + c - 'A') & mask;
mask = (('0'-c-1) & (c-1-'9')) >> 31;
ret |= (c - '0') & mask;
mask = ((ret-1) & ~mask) >> 31;
ret |= 16 & mask;
return (unsigned char)ret;
}
static void bytes_from_hexascii(unsigned char *ret, size_t sz, const char *hex)
{
size_t len;
unsigned char b = 0;
if (hex[0]=='0' && (hex[1]=='x' || hex[1]=='X'))
hex += 2;
for (len = 0; len<2*sz && nibble_from_hex(hex[len])<16; len++) ;
bytes_zero(ret, sz);
while(len--) {
b <<= 4;
b |= nibble_from_hex(*hex++);
if (len % 2 == 0)
ret[len / 2] = b;
}
}
static void limbs_from_hexascii(limb_t *ret, size_t sz, const char *hex)
{
size_t len;
limb_t limb = 0;
if (hex[0]=='0' && (hex[1]=='x' || hex[1]=='X'))
hex += 2;
for (len = 0; len<2*sz && nibble_from_hex(hex[len])<16; len++) ;
vec_zero(ret, sz);
while(len--) {
limb <<= 4;
limb |= nibble_from_hex(*hex++);
if (len % (2*sizeof(limb_t)) == 0)
ret[len / (2*sizeof(limb_t))] = limb;
}
}
#endif