diff --git a/storm/Big.cpp b/storm/Big.cpp index aec9930..5200602 100644 --- a/storm/Big.cpp +++ b/storm/Big.cpp @@ -7,6 +7,10 @@ void SBigAdd(BigData* a, BigData* b, BigData* c) { Add(a->Primary(), b->Primary(), c->Primary()); } +void SBigAnd(BigData* a, BigData* b, BigData* c) { + And(a->Primary(), b->Primary(), c->Primary()); +} + void SBigBitLen(BigData* num, uint32_t* len) { auto& buffer = num->Primary(); buffer.Trim(); diff --git a/storm/Big.hpp b/storm/Big.hpp index aa2f9fb..b820545 100644 --- a/storm/Big.hpp +++ b/storm/Big.hpp @@ -6,6 +6,8 @@ void SBigAdd(BigData* a, BigData* b, BigData* c); +void SBigAnd(BigData* a, BigData* b, BigData* c); + void SBigBitLen(BigData* num, uint32_t* len); int32_t SBigCompare(BigData* a, BigData* b); diff --git a/storm/big/Ops.cpp b/storm/big/Ops.cpp index 36e76a7..01563e2 100644 --- a/storm/big/Ops.cpp +++ b/storm/big/Ops.cpp @@ -22,6 +22,15 @@ void Add(BigBuffer& a, const BigBuffer& b, const BigBuffer& c) { a.SetCount(i); } +void And(BigBuffer& a, const BigBuffer& b, const BigBuffer& c) { + uint32_t i = 0; + for (; b.IsUsed(i) || c.IsUsed(i); i++) { + a[i] = c[i] & b[i]; + } + + a.SetCount(i); +} + int32_t Compare(const BigBuffer& a, const BigBuffer& b) { int32_t result = 0; diff --git a/storm/big/Ops.hpp b/storm/big/Ops.hpp index d2b1b11..d153f5d 100644 --- a/storm/big/Ops.hpp +++ b/storm/big/Ops.hpp @@ -9,6 +9,8 @@ void Add(BigBuffer& a, const BigBuffer& b, uint32_t c); void Add(BigBuffer& a, const BigBuffer& b, const BigBuffer& c); +void And(BigBuffer& a, const BigBuffer& b, const BigBuffer& c); + int32_t Compare(const BigBuffer& a, const BigBuffer& b); void Div(BigBuffer& a, uint32_t* b, const BigBuffer& c, uint64_t d); diff --git a/test/Big.cpp b/test/Big.cpp index f4cad15..8b66f57 100644 --- a/test/Big.cpp +++ b/test/Big.cpp @@ -92,6 +92,42 @@ TEST_CASE("SBigAdd", "[big]") { } } +TEST_CASE("SBigAnd", "[big]") { + BigDataTest a; + BigDataTest b; + BigDataTest c; + + SECTION("overwrites output") { + SBigFromUnsigned(a, 123456); + SBigFromUnsigned(b, 0); + SBigFromUnsigned(c, 0); + + SBigAnd(a, b, c); + + CHECK(a->Primary().Count() == 1); + CHECK(a->Primary()[0] == 0); + } + + SECTION("performs bitwise and on large nums") { + uint8_t data[] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 31, 12, 13, 14, 15 + }; + uint8_t data2[] = { + 0, 0, 0, 6, 6, 0, 6, 0, 0, 6, 0xFF, 6, 0, 6, 0 + }; + SBigFromBinary(b, data, sizeof(data)); + SBigFromBinary(c, data2, sizeof(data2)); + + SBigAnd(a, b, c); + + CHECK(a->Primary().Count() == 4); + CHECK(a->Primary()[0] == 0x04000000); + CHECK(a->Primary()[1] == 0x00060004); + CHECK(a->Primary()[2] == 0x041F0200); + CHECK(a->Primary()[3] == 0x00000600); + } +} + TEST_CASE("SBigBitLen", "[big]") { SECTION("returns bit length of 1") { BigData* num; diff --git a/test/Test.cpp b/test/Test.cpp index 14d382f..9f59f24 100644 --- a/test/Test.cpp +++ b/test/Test.cpp @@ -1,2 +1,8 @@ #define CATCH_CONFIG_MAIN #include "test/Test.hpp" +#include "storm/Big.hpp" + + +BigDataTest::BigDataTest() { SBigNew(&num); } +BigDataTest::~BigDataTest() { SBigDel(num); } + diff --git a/test/Test.hpp b/test/Test.hpp index da3dbbd..25f37c1 100644 --- a/test/Test.hpp +++ b/test/Test.hpp @@ -1 +1,17 @@ #include "vendor/catch-2.13.10/catch.hpp" + +class BigData; + +// Fixture for repetitive handling of BigData objects. +struct BigDataTest { + using BigDataPtr=BigData*; + + BigData *num; + + BigDataTest(); + ~BigDataTest(); + + BigData **operator &() { return # } + operator BigDataPtr() const { return num; } + BigData *operator->() const { return num; } +}; diff --git a/test/big/Ops.cpp b/test/big/Ops.cpp index 8a8abf1..a003b46 100644 --- a/test/big/Ops.cpp +++ b/test/big/Ops.cpp @@ -68,6 +68,42 @@ TEST_CASE("Add", "[big]") { } } +TEST_CASE("And", "[big]") { + BigDataTest a; + BigDataTest b; + BigDataTest c; + + SECTION("overwrites output") { + SBigFromUnsigned(a, 123456); + SBigFromUnsigned(b, 0); + SBigFromUnsigned(c, 0); + + And(a->Primary(), b->Primary(), c->Primary()); + + CHECK(a->Primary().Count() == 1); + CHECK(a->Primary()[0] == 0); + } + + SECTION("performs bitwise and on large nums") { + uint8_t data[] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 31, 12, 13, 14, 15 + }; + uint8_t data2[] = { + 0, 0, 0, 6, 6, 0, 6, 0, 0, 6, 0xFF, 6, 0, 6, 0 + }; + SBigFromBinary(b, data, sizeof(data)); + SBigFromBinary(c, data2, sizeof(data2)); + + And(a->Primary(), b->Primary(), c->Primary()); + + CHECK(a->Primary().Count() == 4); + CHECK(a->Primary()[0] == 0x04000000); + CHECK(a->Primary()[1] == 0x00060004); + CHECK(a->Primary()[2] == 0x041F0200); + CHECK(a->Primary()[3] == 0x00000600); + } +} + TEST_CASE("Compare", "[big]") { SECTION("compares 0 and 1") { BigData* a;