cao-0.1.1: backend_lib/C_generic/CAO_sbits.cpp
/* CAO Compiler
Copyright (C) 2014 Cryptography and Information Security Group, HASLab - INESC TEC and Universidade do Minho
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "CAO_sbits.h"
CAO_RES CAO_sbits_decl(CAO_sbits * b, const int s)
{
CAO_sbits_s *_b = (CAO_sbits_s *) malloc(sizeof(CAO_sbits_s));
_b->size = s;
_b->value = new ZZ;
*b = _b;
return CAO_OK;
}
CAO_RES CAO_sbits_init(CAO_sbits b, const char *val)
{
CAO_sbits_s *_b = (CAO_sbits_s *) b;
*(_b->value) = to_ZZ(val);
// b = _b;
return CAO_OK;
}
CAO_RES CAO_sbits_assign(CAO_sbits r, CAO_sbits b)
{
CAO_sbits_s *_r = (CAO_sbits_s *) r;
CAO_sbits_s *_b = (CAO_sbits_s *) b;
ZZ *zr = _r->value;
ZZ *zb = _b->value;
(*zr) = (*zb);
return CAO_OK;
}
CAO_RES CAO_sbits_clone(CAO_sbits * b, CAO_sbits a)
{
CAO_sbits_s *_a = (CAO_sbits_s *) a;
CAO_sbits_decl(b, _a->size);
CAO_sbits_assign(*b, a);
return CAO_OK;
}
CAO_bool _CAO_sbits_equal(CAO_sbits i, CAO_sbits j)
{
CAO_sbits_s *_i = (CAO_sbits_s *) i;
CAO_sbits_s *_j = (CAO_sbits_s *) j;
ZZ *zi = _i->value;
ZZ *zj = _j->value;
CAO_bool r = ((*zi) == (*zj));
return r;
}
CAO_bool _CAO_sbits_nequal(CAO_sbits i, CAO_sbits j)
{
CAO_sbits_s *_i = (CAO_sbits_s *) i;
CAO_sbits_s *_j = (CAO_sbits_s *) j;
ZZ *zi = _i->value;
ZZ *zj = _j->value;
CAO_bool r = !((*zi) == (*zj));
return r;
}
CAO_RES CAO_sbits_or(CAO_sbits r, CAO_sbits i, CAO_sbits j)
{
CAO_sbits_s *_r = (CAO_sbits_s *) r;
CAO_sbits_s *_i = (CAO_sbits_s *) i;
CAO_sbits_s *_j = (CAO_sbits_s *) j;
ZZ *zr = _r->value;
ZZ *zi = _i->value;
ZZ *zj = _j->value;
*zr = (*zi) | (*zj);
return CAO_OK;
}
CAO_RES CAO_sbits_and(CAO_sbits r, CAO_sbits i, CAO_sbits j)
{
CAO_sbits_s *_r = (CAO_sbits_s *) r;
CAO_sbits_s *_i = (CAO_sbits_s *) i;
CAO_sbits_s *_j = (CAO_sbits_s *) j;
ZZ *zr = _r->value;
ZZ *zi = _i->value;
ZZ *zj = _j->value;
*zr = (*zi) & (*zj);
return CAO_OK;
}
CAO_RES CAO_sbits_xor(CAO_sbits r, CAO_sbits i, CAO_sbits j)
{
CAO_sbits_s *_r = (CAO_sbits_s *) r;
CAO_sbits_s *_i = (CAO_sbits_s *) i;
CAO_sbits_s *_j = (CAO_sbits_s *) j;
ZZ *zr = _r->value;
ZZ *zi = _i->value;
ZZ *zj = _j->value;
*zr = (*zi) ^ (*zj);
return CAO_OK;
}
CAO_RES CAO_sbits_not(CAO_sbits r, CAO_sbits i)
{
long j;
CAO_sbits_s *_r = (CAO_sbits_s *) r;
CAO_sbits_s *_i = (CAO_sbits_s *) i;
ZZ *zr = _r->value;
ZZ *zi = _i->value;
*zr = *zi;
for (j = 0; j < _i->size; j++)
{
SwitchBit(*zr, j);
}
return CAO_OK;
}
CAO_RES CAO_sbits_shift_up(CAO_sbits r, CAO_sbits i, CAO_rint e)
{
CAO_sbits_s *_r = (CAO_sbits_s *) r;
CAO_sbits_s *_i = (CAO_sbits_s *) i;
ZZ base;
ZZ *zr = _r->value;
ZZ *zi = _i->value;
int si = _i->size;
power(base, 2, si);
*zr = ((*zi) << e) % base;
return CAO_OK;
}
CAO_RES CAO_sbits_shift_down(CAO_sbits r, CAO_sbits i, CAO_rint e)
{
CAO_sbits_s *_r = (CAO_sbits_s *) r;
CAO_sbits_s *_i = (CAO_sbits_s *) i;
ZZ base;
ZZ *zi = _i->value;
ZZ *zr = _r->value;
*zr = (*zi) >> e;
return CAO_OK;
}
CAO_RES CAO_sbits_rot_up(CAO_sbits r, CAO_sbits i, CAO_rint e)
{
CAO_sbits_s *_r = (CAO_sbits_s *) r;
CAO_sbits_s *_i = (CAO_sbits_s *) i;
ZZ a, base, upper;
ZZ *zr = _r->value;
ZZ *zi = _i->value;
int si = _i->size;
power(base, 2, si);
a = *zi << e;
upper = a / base;
a = a % base;
*zr = a + upper;
return CAO_OK;
}
CAO_RES CAO_sbits_rot_down(CAO_sbits r, CAO_sbits i, CAO_rint e)
{
CAO_sbits_s *_r = (CAO_sbits_s *) r;
CAO_sbits_s *_i = (CAO_sbits_s *) i;
ZZ a, base, lower;
ZZ *zi = _i->value;
ZZ *zr = _r->value;
power(base, 2, e);
lower = *zi % base;
a = *zi / base;
lower = lower * base;
*zr = a + lower;
return CAO_OK;
}
CAO_RES CAO_sbits_select(CAO_sbits r, CAO_sbits b, CAO_rint e)
{
CAO_sbits_s *_r = (CAO_sbits_s *) r;
CAO_sbits_s *_b = (CAO_sbits_s *) b;
ZZ *zb = _b->value;
ZZ *zr = _r->value;
long _bit = bit(*zb, e);
*zr = _bit;
return CAO_OK;
}
CAO_RES CAO_sbits_set(CAO_sbits r, CAO_sbits b, CAO_rint e)
{
CAO_sbits_s *_r = (CAO_sbits_s *) r;
CAO_sbits_s *_b = (CAO_sbits_s *) b;
ZZ *zb = _b->value;
ZZ *zr = _r->value;
if (bit(*zr, e) != bit(*zb, 0))
{
SwitchBit(*zr, e);
}
return CAO_OK;
}
CAO_RES CAO_sbits_range_select(CAO_sbits r, CAO_sbits b, CAO_rint e, CAO_rint j)
{
CAO_sbits_s *_r = (CAO_sbits_s *) r;
CAO_sbits_s *_b = (CAO_sbits_s *) b;
ZZ a, base, lower;
ZZ *zb = _b->value;
ZZ *zr = _r->value;
int ns = j - e + 1;
power(base, 2, ns);
a = (*zb) >> e;
lower = a % base;
*zr = lower;
return CAO_OK;
}
CAO_RES CAO_sbits_range_set(CAO_sbits r, CAO_sbits b, CAO_rint e, CAO_rint j)
{
CAO_sbits_s *_r = (CAO_sbits_s *) r;
CAO_sbits_s *_b = (CAO_sbits_s *) b;
ZZ a, base, lower;
ZZ *zb = _b->value;
ZZ *zr = _r->value;
int ns = j - e + 1;
power(base, 2, e);
lower = *zr % base;
a = (*zr) >> (j + 1);
a <<= ns;
a += *zb;
a <<= e;
*zr = a + lower;
return CAO_OK;
}
CAO_RES CAO_sbits_concat(CAO_sbits r, CAO_sbits a, CAO_sbits b)
{
CAO_sbits_s *_r = (CAO_sbits_s *) r;
CAO_sbits_s *_a = (CAO_sbits_s *) a;
CAO_sbits_s *_b = (CAO_sbits_s *) b;
ZZ nval, base;
ZZ *zr = _r->value;
ZZ *za = _a->value;
ZZ *zb = _b->value;
int sa = _a->size;
power(base, 2, sa);
nval = (*zb) * base;
*zr = nval + *za;
return CAO_OK;
}
CAO_RES CAO_sbits_dump(CAO_sbits b)
{
CAO_sbits_s *_b = (CAO_sbits_s *) b;
int size = _b->size;
ZZ *val = _b->value;
cout << "sbits[" << size << "] = " << (*val) << "\n";
return CAO_OK;
}
CAO_RES CAO_sbits_dispose(CAO_sbits a)
{
CAO_sbits_s *_a = (CAO_sbits_s *) a;
delete(_a->value);
free(_a);
return CAO_OK;
}
CAO_RES CAO_sbits_cast_int(CAO_int b, CAO_sbits a)
{
CAO_sbits_s *_a = (CAO_sbits_s *) a;
ZZ base;
ZZ *_b = (ZZ *) b;
power(base, 2, _a->size);
*_b = *_a->value - base;
return CAO_OK;
}
CAO_RES CAO_int_cast_sbits(CAO_sbits b, CAO_int a)
{
CAO_sbits_s *_b = (CAO_sbits_s *) b;
ZZ base;
ZZ *_a = (ZZ *) a;
power(base, 2, _b->size);
if (sign(*_a) == -1)
{
*_b->value = base + (*_a);
}
else
{
*_b->value = *_a;
}
*_b->value = (*_b->value) % base;
return CAO_OK;
}
CAO_RES CAO_sbits_cast_sbits(CAO_sbits b, CAO_sbits a)
{
CAO_sbits_s *_b = (CAO_sbits_s *) b;
CAO_sbits_s *_a = (CAO_sbits_s *) a;
ZZ base;
power(base, 2, _b->size);
*_b->value = *_a->value % base;
return CAO_OK;
}