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
|
// test mp_get_int
|
||||||
printf("\n\nTesting: mp_get_int");
|
printf("\n\nTesting: mp_get_int");
|
||||||
for (i = 0; i < 1000; ++i) {
|
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 */
|
/* c = a AND b */
|
||||||
int mp_and(const mp_int *a, const mp_int *b, mp_int *c);
|
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 <--- */
|
/* ---> Basic arithmetic <--- */
|
||||||
|
|
||||||
|
/* b = ~a */
|
||||||
|
int mp_complement(const mp_int *a, mp_int *b);
|
||||||
|
|
||||||
/* b = -a */
|
/* b = -a */
|
||||||
int mp_neg(const mp_int *a, mp_int *b);
|
int mp_neg(const mp_int *a, mp_int *b);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user