add mp_complement, mp_tc_div_2d, mp_tc_and, mp_tc_or, mp_tc_xor
This commit is contained in:
parent
bc685fd4a5
commit
eebbcf0644
26
bn_mp_complement.c
Normal file
26
bn_mp_complement.c
Normal file
@ -0,0 +1,26 @@
|
||||
#include "tommath_private.h"
|
||||
#ifdef BN_MP_COMPLEMENT_C
|
||||
/* LibTomMath, multiple-precision integer library -- Tom St Denis
|
||||
*
|
||||
* LibTomMath is a library that provides multiple-precision
|
||||
* integer arithmetic as well as number theoretic functionality.
|
||||
*
|
||||
* The library was designed directly after the MPI library by
|
||||
* Michael Fromberger but has been written from scratch with
|
||||
* additional optimizations in place.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*/
|
||||
|
||||
/* b = ~a */
|
||||
int mp_complement(const mp_int *a, mp_int *b)
|
||||
{
|
||||
int res = mp_neg(a, b);
|
||||
return res == MP_OKAY ? mp_sub_d(b, 1, b) : res;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ref: $Format:%D$ */
|
||||
/* git commit: $Format:%H$ */
|
||||
/* commit time: $Format:%ai$ */
|
90
bn_mp_tc_and.c
Normal file
90
bn_mp_tc_and.c
Normal file
@ -0,0 +1,90 @@
|
||||
#include "tommath_private.h"
|
||||
#ifdef BN_MP_TC_AND_C
|
||||
/* LibTomMath, multiple-precision integer library -- Tom St Denis
|
||||
*
|
||||
* LibTomMath is a library that provides multiple-precision
|
||||
* integer arithmetic as well as number theoretic functionality.
|
||||
*
|
||||
* The library was designed directly after the MPI library by
|
||||
* Michael Fromberger but has been written from scratch with
|
||||
* additional optimizations in place.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*/
|
||||
|
||||
/* two complement and */
|
||||
int mp_tc_and(const mp_int *a, const mp_int *b, mp_int *c)
|
||||
{
|
||||
int res = MP_OKAY, bits;
|
||||
int as = mp_isneg(a), bs = mp_isneg(b), s = 0;
|
||||
mp_int *mx = 0, _mx, acpy, bcpy;
|
||||
|
||||
if (as || bs) {
|
||||
bits = MAX(mp_count_bits(a), mp_count_bits(b));
|
||||
res = mp_init_set_int(&_mx, 1);
|
||||
if (res != MP_OKAY) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
mx = &_mx;
|
||||
res = mp_mul_2d(mx, bits + 1, mx);
|
||||
if (res != MP_OKAY) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (as) {
|
||||
res = mp_init(&acpy);
|
||||
if (res != MP_OKAY) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
res = mp_add(mx, a, &acpy);
|
||||
if (res != MP_OKAY) {
|
||||
mp_clear(&acpy);
|
||||
goto end;
|
||||
}
|
||||
a = &acpy;
|
||||
}
|
||||
if (bs) {
|
||||
res = mp_init(&bcpy);
|
||||
if (res != MP_OKAY) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
res = mp_add(mx, b, &bcpy);
|
||||
if (res != MP_OKAY) {
|
||||
mp_clear(&bcpy);
|
||||
goto end;
|
||||
}
|
||||
b = &bcpy;
|
||||
}
|
||||
}
|
||||
|
||||
res = mp_and(a, b, c);
|
||||
s = as & bs;
|
||||
|
||||
if (s && res == MP_OKAY) {
|
||||
res = mp_sub(c, mx, c);
|
||||
}
|
||||
|
||||
end:
|
||||
if (a == &acpy) {
|
||||
mp_clear(&acpy);
|
||||
}
|
||||
|
||||
if (b == &bcpy) {
|
||||
mp_clear(&bcpy);
|
||||
}
|
||||
|
||||
if (mx == &_mx) {
|
||||
mp_clear(mx);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ref: $Format:%D$ */
|
||||
/* git commit: $Format:%H$ */
|
||||
/* commit time: $Format:%ai$ */
|
36
bn_mp_tc_div_2d.c
Normal file
36
bn_mp_tc_div_2d.c
Normal file
@ -0,0 +1,36 @@
|
||||
#include "tommath_private.h"
|
||||
#ifdef BN_MP_TC_DIV_2D_C
|
||||
/* LibTomMath, multiple-precision integer library -- Tom St Denis
|
||||
*
|
||||
* LibTomMath is a library that provides multiple-precision
|
||||
* integer arithmetic as well as number theoretic functionality.
|
||||
*
|
||||
* The library was designed directly after the MPI library by
|
||||
* Michael Fromberger but has been written from scratch with
|
||||
* additional optimizations in place.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*/
|
||||
|
||||
/* two complement right shift */
|
||||
int mp_tc_div_2d(const mp_int *a, int b, mp_int *c)
|
||||
{
|
||||
int res;
|
||||
if (!mp_isneg(a)) {
|
||||
return mp_div_2d(a, b, c, 0);
|
||||
}
|
||||
|
||||
res = mp_add_d(a, 1, c);
|
||||
if (res != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = mp_div_2d(c, b, c, 0);
|
||||
return res == MP_OKAY ? mp_sub_d(c, 1, c) : res;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ref: $Format:%D$ */
|
||||
/* git commit: $Format:%H$ */
|
||||
/* commit time: $Format:%ai$ */
|
90
bn_mp_tc_or.c
Normal file
90
bn_mp_tc_or.c
Normal file
@ -0,0 +1,90 @@
|
||||
#include "tommath_private.h"
|
||||
#ifdef BN_MP_TC_OR_C
|
||||
/* LibTomMath, multiple-precision integer library -- Tom St Denis
|
||||
*
|
||||
* LibTomMath is a library that provides multiple-precision
|
||||
* integer arithmetic as well as number theoretic functionality.
|
||||
*
|
||||
* The library was designed directly after the MPI library by
|
||||
* Michael Fromberger but has been written from scratch with
|
||||
* additional optimizations in place.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*/
|
||||
|
||||
/* two complement or */
|
||||
int mp_tc_or(const mp_int *a, const mp_int *b, mp_int *c)
|
||||
{
|
||||
int res = MP_OKAY, bits;
|
||||
int as = mp_isneg(a), bs = mp_isneg(b), s = 0;
|
||||
mp_int *mx = 0, _mx, acpy, bcpy;
|
||||
|
||||
if (as || bs) {
|
||||
bits = MAX(mp_count_bits(a), mp_count_bits(b));
|
||||
res = mp_init_set_int(&_mx, 1);
|
||||
if (res != MP_OKAY) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
mx = &_mx;
|
||||
res = mp_mul_2d(mx, bits + 1, mx);
|
||||
if (res != MP_OKAY) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (as) {
|
||||
res = mp_init(&acpy);
|
||||
if (res != MP_OKAY) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
res = mp_add(mx, a, &acpy);
|
||||
if (res != MP_OKAY) {
|
||||
mp_clear(&acpy);
|
||||
goto end;
|
||||
}
|
||||
a = &acpy;
|
||||
}
|
||||
if (bs) {
|
||||
res = mp_init(&bcpy);
|
||||
if (res != MP_OKAY) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
res = mp_add(mx, b, &bcpy);
|
||||
if (res != MP_OKAY) {
|
||||
mp_clear(&bcpy);
|
||||
goto end;
|
||||
}
|
||||
b = &bcpy;
|
||||
}
|
||||
}
|
||||
|
||||
res = mp_or(a, b, c);
|
||||
s = as | bs;
|
||||
|
||||
if (s && res == MP_OKAY) {
|
||||
res = mp_sub(c, mx, c);
|
||||
}
|
||||
|
||||
end:
|
||||
if (a == &acpy) {
|
||||
mp_clear(&acpy);
|
||||
}
|
||||
|
||||
if (b == &bcpy) {
|
||||
mp_clear(&bcpy);
|
||||
}
|
||||
|
||||
if (mx == &_mx) {
|
||||
mp_clear(mx);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ref: $Format:%D$ */
|
||||
/* git commit: $Format:%H$ */
|
||||
/* commit time: $Format:%ai$ */
|
90
bn_mp_tc_xor.c
Normal file
90
bn_mp_tc_xor.c
Normal file
@ -0,0 +1,90 @@
|
||||
#include "tommath_private.h"
|
||||
#ifdef BN_MP_TC_XOR_C
|
||||
/* LibTomMath, multiple-precision integer library -- Tom St Denis
|
||||
*
|
||||
* LibTomMath is a library that provides multiple-precision
|
||||
* integer arithmetic as well as number theoretic functionality.
|
||||
*
|
||||
* The library was designed directly after the MPI library by
|
||||
* Michael Fromberger but has been written from scratch with
|
||||
* additional optimizations in place.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*/
|
||||
|
||||
/* two complement xor */
|
||||
int mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c)
|
||||
{
|
||||
int res = MP_OKAY, bits;
|
||||
int as = mp_isneg(a), bs = mp_isneg(b), s = 0;
|
||||
mp_int *mx = 0, _mx, acpy, bcpy;
|
||||
|
||||
if (as || bs) {
|
||||
bits = MAX(mp_count_bits(a), mp_count_bits(b));
|
||||
res = mp_init_set_int(&_mx, 1);
|
||||
if (res != MP_OKAY) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
mx = &_mx;
|
||||
res = mp_mul_2d(mx, bits + 1, mx);
|
||||
if (res != MP_OKAY) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (as) {
|
||||
res = mp_init(&acpy);
|
||||
if (res != MP_OKAY) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
res = mp_add(mx, a, &acpy);
|
||||
if (res != MP_OKAY) {
|
||||
mp_clear(&acpy);
|
||||
goto end;
|
||||
}
|
||||
a = &acpy;
|
||||
}
|
||||
if (bs) {
|
||||
res = mp_init(&bcpy);
|
||||
if (res != MP_OKAY) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
res = mp_add(mx, b, &bcpy);
|
||||
if (res != MP_OKAY) {
|
||||
mp_clear(&bcpy);
|
||||
goto end;
|
||||
}
|
||||
b = &bcpy;
|
||||
}
|
||||
}
|
||||
|
||||
res = mp_xor(a, b, c);
|
||||
s = as ^ bs;
|
||||
|
||||
if (s && res == MP_OKAY) {
|
||||
res = mp_sub(c, mx, c);
|
||||
}
|
||||
|
||||
end:
|
||||
if (a == &acpy) {
|
||||
mp_clear(&acpy);
|
||||
}
|
||||
|
||||
if (b == &bcpy) {
|
||||
mp_clear(&bcpy);
|
||||
}
|
||||
|
||||
if (mx == &_mx) {
|
||||
mp_clear(mx);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ref: $Format:%D$ */
|
||||
/* git commit: $Format:%H$ */
|
||||
/* commit time: $Format:%ai$ */
|
121
demo/demo.c
121
demo/demo.c
@ -261,6 +261,127 @@ int main(void)
|
||||
}
|
||||
}
|
||||
|
||||
// test mp_complement
|
||||
printf("\n\nTesting: mp_complement");
|
||||
for (i = 0; i < 1000; ++i) {
|
||||
int l = (rand() * rand() + 1) * (rand() % 1 ? -1 : 1);
|
||||
mp_set_int(&a, labs(l));
|
||||
if (l < 0)
|
||||
mp_neg(&a, &a);
|
||||
mp_complement(&a, &b);
|
||||
|
||||
l = ~l;
|
||||
mp_set_int(&c, labs(l));
|
||||
if (l < 0)
|
||||
mp_neg(&c, &c);
|
||||
|
||||
if (mp_cmp(&b, &c) != MP_EQ) {
|
||||
printf("\nmp_complement() bad result!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// test mp_tc_div_2d
|
||||
printf("\n\nTesting: mp_tc_div_2d");
|
||||
for (i = 0; i < 1000; ++i) {
|
||||
int l, m;
|
||||
|
||||
l = (rand() * rand() + 1) * (rand() % 1 ? -1 : 1);
|
||||
mp_set_int(&a, labs(l));
|
||||
if (l < 0)
|
||||
mp_neg(&a, &a);
|
||||
|
||||
m = rand() % 32;
|
||||
|
||||
mp_set_int(&d, labs(l >> m));
|
||||
if ((l >> m) < 0)
|
||||
mp_neg(&d, &d);
|
||||
|
||||
mp_tc_div_2d(&a, m, &b);
|
||||
if (mp_cmp(&b, &d) != MP_EQ) {
|
||||
printf("\nmp_tc_div_2d() bad result!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// test mp_tc_xor
|
||||
printf("\n\nTesting: mp_tc_or");
|
||||
for (i = 0; i < 1000; ++i) {
|
||||
int l, m;
|
||||
|
||||
l = (rand() * rand() + 1) * (rand() % 1 ? -1 : 1);
|
||||
mp_set_int(&a, labs(l));
|
||||
if (l < 0)
|
||||
mp_neg(&a, &a);
|
||||
|
||||
m = (rand() * rand() + 1) * (rand() % 1 ? -1 : 1);
|
||||
mp_set_int(&b, labs(m));
|
||||
if (m < 0)
|
||||
mp_neg(&b, &b);
|
||||
|
||||
mp_set_int(&d, labs(l ^ m));
|
||||
if ((l ^ m) < 0)
|
||||
mp_neg(&d, &d);
|
||||
|
||||
mp_tc_xor(&a, &b, &c);
|
||||
if (mp_cmp(&c, &d) != MP_EQ) {
|
||||
printf("\nmp_tc_xor() bad result!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// test mp_tc_or
|
||||
printf("\n\nTesting: mp_tc_or");
|
||||
for (i = 0; i < 1000; ++i) {
|
||||
int l, m;
|
||||
|
||||
l = (rand() * rand() + 1) * (rand() % 1 ? -1 : 1);
|
||||
mp_set_int(&a, labs(l));
|
||||
if (l < 0)
|
||||
mp_neg(&a, &a);
|
||||
|
||||
m = (rand() * rand() + 1) * (rand() % 1 ? -1 : 1);
|
||||
mp_set_int(&b, labs(m));
|
||||
if (m < 0)
|
||||
mp_neg(&b, &b);
|
||||
|
||||
mp_set_int(&d, labs(l | m));
|
||||
if ((l | m) < 0)
|
||||
mp_neg(&d, &d);
|
||||
|
||||
mp_tc_or(&a, &b, &c);
|
||||
if (mp_cmp(&c, &d) != MP_EQ) {
|
||||
printf("\nmp_tc_or() bad result!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// test mp_tc_and
|
||||
printf("\n\nTesting: mp_tc_and");
|
||||
for (i = 0; i < 1000; ++i) {
|
||||
int l, m;
|
||||
|
||||
l = (rand() * rand() + 1) * (rand() % 1 ? -1 : 1);
|
||||
mp_set_int(&a, labs(l));
|
||||
if (l < 0)
|
||||
mp_neg(&a, &a);
|
||||
|
||||
m = (rand() * rand() + 1) * (rand() % 1 ? -1 : 1);
|
||||
mp_set_int(&b, labs(m));
|
||||
if (m < 0)
|
||||
mp_neg(&b, &b);
|
||||
|
||||
mp_set_int(&d, labs(l & m));
|
||||
if ((l & m) < 0)
|
||||
mp_neg(&d, &d);
|
||||
|
||||
mp_tc_and(&a, &b, &c);
|
||||
if (mp_cmp(&c, &d) != MP_EQ) {
|
||||
printf("\nmp_tc_and() bad result!");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// test mp_get_int
|
||||
printf("\n\nTesting: mp_get_int");
|
||||
for (i = 0; i < 1000; ++i) {
|
||||
|
15
tommath.h
15
tommath.h
@ -292,8 +292,23 @@ int mp_or(const mp_int *a, const mp_int *b, mp_int *c);
|
||||
/* c = a AND b */
|
||||
int mp_and(const mp_int *a, const mp_int *b, mp_int *c);
|
||||
|
||||
/* c = a XOR b (two complement) */
|
||||
int mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c);
|
||||
|
||||
/* c = a OR b (two complement) */
|
||||
int mp_tc_or(const mp_int *a, const mp_int *b, mp_int *c);
|
||||
|
||||
/* c = a AND b (two complement) */
|
||||
int mp_tc_and(const mp_int *a, const mp_int *b, mp_int *c);
|
||||
|
||||
/* right shift (two complement) */
|
||||
int mp_tc_div_2d(const mp_int *a, int b, mp_int *c);
|
||||
|
||||
/* ---> Basic arithmetic <--- */
|
||||
|
||||
/* b = ~a */
|
||||
int mp_complement(const mp_int *a, mp_int *b);
|
||||
|
||||
/* b = -a */
|
||||
int mp_neg(const mp_int *a, mp_int *b);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user