diff --git a/mpint.c b/mpint.c index 8b72382f..fa33121b 100644 --- a/mpint.c +++ b/mpint.c @@ -692,6 +692,38 @@ void mp_sub_into(mp_int *r, mp_int *a, mp_int *b) mp_add_masked_into(r->w, r->nw, a, b, ~(BignumInt)0, ~(BignumInt)0, 1); } +void mp_and_into(mp_int *r, mp_int *a, mp_int *b) +{ + for (size_t i = 0; i < r->nw; i++) { + BignumInt aword = mp_word(a, i), bword = mp_word(b, i); + r->w[i] = aword & bword; + } +} + +void mp_or_into(mp_int *r, mp_int *a, mp_int *b) +{ + for (size_t i = 0; i < r->nw; i++) { + BignumInt aword = mp_word(a, i), bword = mp_word(b, i); + r->w[i] = aword | bword; + } +} + +void mp_xor_into(mp_int *r, mp_int *a, mp_int *b) +{ + for (size_t i = 0; i < r->nw; i++) { + BignumInt aword = mp_word(a, i), bword = mp_word(b, i); + r->w[i] = aword ^ bword; + } +} + +void mp_bic_into(mp_int *r, mp_int *a, mp_int *b) +{ + for (size_t i = 0; i < r->nw; i++) { + BignumInt aword = mp_word(a, i), bword = mp_word(b, i); + r->w[i] = aword & ~bword; + } +} + static void mp_cond_negate(mp_int *r, mp_int *x, unsigned yes) { BignumCarry carry = yes; diff --git a/mpint.h b/mpint.h index 45409b30..e05f1dab 100644 --- a/mpint.h +++ b/mpint.h @@ -197,6 +197,14 @@ mp_int *mp_add(mp_int *x, mp_int *y); mp_int *mp_sub(mp_int *x, mp_int *y); mp_int *mp_mul(mp_int *x, mp_int *y); +/* + * Bitwise operations. + */ +void mp_and_into(mp_int *r, mp_int *a, mp_int *b); +void mp_or_into(mp_int *r, mp_int *a, mp_int *b); +void mp_xor_into(mp_int *r, mp_int *a, mp_int *b); +void mp_bic_into(mp_int *r, mp_int *a, mp_int *b); + /* * Addition, subtraction and multiplication with one argument small * enough to fit in a C integer. For mp_mul_integer_into, it has to be diff --git a/test/cryptsuite.py b/test/cryptsuite.py index 1b9d78d2..1fac8596 100755 --- a/test/cryptsuite.py +++ b/test/cryptsuite.py @@ -367,6 +367,23 @@ class mpint(MyTestBase): self.assertEqual(int(mp_div(n, d)), q) self.assertEqual(int(mp_mod(n, d)), r) + def testBitwise(self): + p = 0x3243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e + e = 0x2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d9045190 + x = mp_new(nbits(p)) + + mp_and_into(x, p, e) + self.assertEqual(int(x), p & e) + + mp_or_into(x, p, e) + self.assertEqual(int(x), p | e) + + mp_xor_into(x, p, e) + self.assertEqual(int(x), p ^ e) + + mp_bic_into(x, p, e) + self.assertEqual(int(x), p & ~e) + def testInversion(self): # Test mp_invert_mod_2to. testnumbers = [(mp_copy(n),n) for n in fibonacci_scattered() diff --git a/testcrypt.h b/testcrypt.h index c326059a..ae99b51b 100644 --- a/testcrypt.h +++ b/testcrypt.h @@ -37,6 +37,10 @@ FUNC3(void, mp_mul_into, val_mpint, val_mpint, val_mpint) FUNC2(val_mpint, mp_add, val_mpint, val_mpint) FUNC2(val_mpint, mp_sub, val_mpint, val_mpint) FUNC2(val_mpint, mp_mul, val_mpint, val_mpint) +FUNC3(void, mp_and_into, val_mpint, val_mpint, val_mpint) +FUNC3(void, mp_or_into, val_mpint, val_mpint, val_mpint) +FUNC3(void, mp_xor_into, val_mpint, val_mpint, val_mpint) +FUNC3(void, mp_bic_into, val_mpint, val_mpint, val_mpint) FUNC3(void, mp_add_integer_into, val_mpint, val_mpint, uint) FUNC3(void, mp_sub_integer_into, val_mpint, val_mpint, uint) FUNC3(void, mp_mul_integer_into, val_mpint, val_mpint, uint)