mirror of
https://github.com/thunderbrewhq/common.git
synced 2025-12-12 03:02:29 +00:00
feat(biginteger): add big integer function suite
This commit is contained in:
parent
7ef7db7824
commit
ca7b7c3bc6
3 changed files with 296 additions and 0 deletions
87
common/BigInteger.cpp
Normal file
87
common/BigInteger.cpp
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
#include "common/BigInteger.hpp"
|
||||||
|
#include <cstring>
|
||||||
|
#include <storm/Big.hpp>
|
||||||
|
|
||||||
|
void BigIntegerAdd(void* a, void* b, void* c) {
|
||||||
|
SBigAdd(static_cast<BigData*>(a), static_cast<BigData*>(b), static_cast<BigData*>(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BigIntegerAddInt(void* a, void* b, uint32_t c) {
|
||||||
|
BigData* c_;
|
||||||
|
SBigNew(&c_);
|
||||||
|
SBigFromUnsigned(c_, c);
|
||||||
|
|
||||||
|
SBigAdd(static_cast<BigData*>(a), static_cast<BigData*>(b), c_);
|
||||||
|
|
||||||
|
SBigDel(c_);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t BigIntegerBitLen(void* num) {
|
||||||
|
uint32_t len;
|
||||||
|
SBigBitLen(static_cast<BigData*>(num), &len);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t BigIntegerCmp(void* a, void* b) {
|
||||||
|
return SBigCompare(static_cast<BigData*>(a), static_cast<BigData*>(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t BigIntegerCmpInt(void* a, uint32_t b) {
|
||||||
|
BigData* b_;
|
||||||
|
SBigNew(&b_);
|
||||||
|
SBigFromUnsigned(b_, b);
|
||||||
|
|
||||||
|
auto result = SBigCompare(static_cast<BigData*>(a), b_);
|
||||||
|
|
||||||
|
SBigDel(b_);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BigIntegerFree(void* num) {
|
||||||
|
SBigDel(static_cast<BigData*>(num));
|
||||||
|
}
|
||||||
|
|
||||||
|
void* BigIntegerFromBytes(const uint8_t* data, uint32_t bytes) {
|
||||||
|
BigData* num;
|
||||||
|
SBigNew(&num);
|
||||||
|
SBigFromBinary(num, data, bytes);
|
||||||
|
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* BigIntegerFromInt(uint32_t val) {
|
||||||
|
BigData* num;
|
||||||
|
SBigNew(&num);
|
||||||
|
SBigFromUnsigned(num, val);
|
||||||
|
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BigIntegerMod(void* a, void* b, void* c) {
|
||||||
|
SBigMod(static_cast<BigData*>(a), static_cast<BigData*>(b), static_cast<BigData*>(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BigIntegerModExp(void* a, void* b, void* c, void* d) {
|
||||||
|
SBigPowMod(static_cast<BigData*>(a), static_cast<BigData*>(b), static_cast<BigData*>(c), static_cast<BigData*>(d));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BigIntegerMul(void* a, void* b, void* c) {
|
||||||
|
SBigMul(static_cast<BigData*>(a), static_cast<BigData*>(b), static_cast<BigData*>(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BigIntegerSub(void* a, void* b, void* c) {
|
||||||
|
SBigSub(static_cast<BigData*>(a), static_cast<BigData*>(b), static_cast<BigData*>(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t BigIntegerToBytes(void* num, uint8_t* bytes, uint32_t maxBytes) {
|
||||||
|
uint32_t copiedBytes;
|
||||||
|
SBigToBinaryBuffer(static_cast<BigData*>(num), bytes, maxBytes, &copiedBytes);
|
||||||
|
|
||||||
|
if (maxBytes > copiedBytes) {
|
||||||
|
memset(&bytes[copiedBytes], 0, maxBytes - copiedBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return copiedBytes;
|
||||||
|
}
|
||||||
32
common/BigInteger.hpp
Normal file
32
common/BigInteger.hpp
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef COMMON_BIG_INTEGER_HPP
|
||||||
|
#define COMMON_BIG_INTEGER_HPP
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
void BigIntegerAdd(void* a, void* b, void* c);
|
||||||
|
|
||||||
|
void BigIntegerAddInt(void* a, void* b, uint32_t c);
|
||||||
|
|
||||||
|
uint32_t BigIntegerBitLen(void* num);
|
||||||
|
|
||||||
|
int32_t BigIntegerCmp(void* a, void* b);
|
||||||
|
|
||||||
|
int32_t BigIntegerCmpInt(void* a, uint32_t b);
|
||||||
|
|
||||||
|
void BigIntegerFree(void* num);
|
||||||
|
|
||||||
|
void* BigIntegerFromBytes(const uint8_t* bytes, uint32_t len);
|
||||||
|
|
||||||
|
void* BigIntegerFromInt(uint32_t val);
|
||||||
|
|
||||||
|
void BigIntegerMod(void* a, void* b, void* c);
|
||||||
|
|
||||||
|
void BigIntegerModExp(void* a, void* b, void* c, void* d);
|
||||||
|
|
||||||
|
void BigIntegerMul(void* a, void* b, void* c);
|
||||||
|
|
||||||
|
void BigIntegerSub(void* a, void* b, void* c);
|
||||||
|
|
||||||
|
uint32_t BigIntegerToBytes(void* num, uint8_t* bytes, uint32_t maxBytes);
|
||||||
|
|
||||||
|
#endif
|
||||||
177
test/BigInteger.cpp
Normal file
177
test/BigInteger.cpp
Normal file
|
|
@ -0,0 +1,177 @@
|
||||||
|
#include "common/BigInteger.hpp"
|
||||||
|
#include "test/Test.hpp"
|
||||||
|
|
||||||
|
TEST_CASE("BigIntegerAdd", "[biginteger]") {
|
||||||
|
SECTION("adds 0x10 to 0xFFFFFFFF") {
|
||||||
|
auto a = BigIntegerFromInt(0);
|
||||||
|
auto b = BigIntegerFromInt(0xFFFFFFFF);
|
||||||
|
auto c = BigIntegerFromInt(0x10);
|
||||||
|
|
||||||
|
BigIntegerAdd(a, b, c);
|
||||||
|
|
||||||
|
uint64_t a_;
|
||||||
|
BigIntegerToBytes(a, reinterpret_cast<uint8_t*>(&a_), sizeof(a_));
|
||||||
|
|
||||||
|
CHECK(a_ == 0x10000000F);
|
||||||
|
|
||||||
|
BigIntegerFree(a);
|
||||||
|
BigIntegerFree(b);
|
||||||
|
BigIntegerFree(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("BigIntegerAddInt", "[biginteger]") {
|
||||||
|
SECTION("adds 0x10 to 0xFFFFFFFF") {
|
||||||
|
auto a = BigIntegerFromInt(0);
|
||||||
|
auto b = BigIntegerFromInt(0xFFFFFFFF);
|
||||||
|
|
||||||
|
BigIntegerAddInt(a, b, 0x10);
|
||||||
|
|
||||||
|
uint64_t a_;
|
||||||
|
BigIntegerToBytes(a, reinterpret_cast<uint8_t*>(&a_), sizeof(a_));
|
||||||
|
|
||||||
|
CHECK(a_ == 0x10000000F);
|
||||||
|
|
||||||
|
BigIntegerFree(a);
|
||||||
|
BigIntegerFree(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("BigIntegerBitLen", "[biginteger]") {
|
||||||
|
SECTION("returns bit length of 0x1234567890") {
|
||||||
|
uint64_t bytes = 0x1234567890;
|
||||||
|
auto num = BigIntegerFromBytes(reinterpret_cast<uint8_t*>(&bytes), sizeof(bytes));
|
||||||
|
|
||||||
|
CHECK(BigIntegerBitLen(num) == 37);
|
||||||
|
|
||||||
|
BigIntegerFree(num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("BigIntegerCmp", "[biginteger]") {
|
||||||
|
SECTION("compares 10 and 1") {
|
||||||
|
auto a = BigIntegerFromInt(10);
|
||||||
|
auto b = BigIntegerFromInt(1);
|
||||||
|
|
||||||
|
CHECK(BigIntegerCmp(a, b) == 1);
|
||||||
|
|
||||||
|
BigIntegerFree(a);
|
||||||
|
BigIntegerFree(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("BigIntegerCmpInt", "[biginteger]") {
|
||||||
|
SECTION("compares 10 and 1") {
|
||||||
|
auto a = BigIntegerFromInt(10);
|
||||||
|
auto b = 1;
|
||||||
|
|
||||||
|
CHECK(BigIntegerCmpInt(a, b) == 1);
|
||||||
|
|
||||||
|
BigIntegerFree(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("BigIntegerFromBytes", "[biginteger]") {
|
||||||
|
SECTION("creates new biginteger from bytes") {
|
||||||
|
uint64_t bytes = 0x1234567890;
|
||||||
|
auto num = BigIntegerFromBytes(reinterpret_cast<uint8_t*>(&bytes), sizeof(bytes));
|
||||||
|
|
||||||
|
uint64_t num_;
|
||||||
|
BigIntegerToBytes(num, reinterpret_cast<uint8_t*>(&num_), sizeof(num_));
|
||||||
|
|
||||||
|
CHECK(num_ == 0x1234567890);
|
||||||
|
|
||||||
|
BigIntegerFree(num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("BigIntegerFromInt", "[biginteger]") {
|
||||||
|
SECTION("creates new biginteger from integer") {
|
||||||
|
auto num = BigIntegerFromInt(4);
|
||||||
|
|
||||||
|
uint32_t num_;
|
||||||
|
BigIntegerToBytes(num, reinterpret_cast<uint8_t*>(&num_), sizeof(num_));
|
||||||
|
|
||||||
|
CHECK(num_ == 4);
|
||||||
|
|
||||||
|
BigIntegerFree(num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("BigIntegerMod", "[biginteger]") {
|
||||||
|
SECTION("mods 7 by 4") {
|
||||||
|
auto a = BigIntegerFromInt(0);
|
||||||
|
auto b = BigIntegerFromInt(7);
|
||||||
|
auto c = BigIntegerFromInt(4);
|
||||||
|
|
||||||
|
BigIntegerMod(a, b, c);
|
||||||
|
|
||||||
|
uint32_t a_;
|
||||||
|
BigIntegerToBytes(a, reinterpret_cast<uint8_t*>(&a_), sizeof(a_));
|
||||||
|
|
||||||
|
CHECK(a_ == 3);
|
||||||
|
|
||||||
|
BigIntegerFree(a);
|
||||||
|
BigIntegerFree(b);
|
||||||
|
BigIntegerFree(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("BigIntegerModExp", "[biginteger]") {
|
||||||
|
SECTION("takes 256 to the 8th power and mods the result by 999") {
|
||||||
|
auto a = BigIntegerFromInt(0);
|
||||||
|
auto b = BigIntegerFromInt(256);
|
||||||
|
auto c = BigIntegerFromInt(8);
|
||||||
|
auto d = BigIntegerFromInt(999);
|
||||||
|
|
||||||
|
BigIntegerModExp(a, b, c, d);
|
||||||
|
|
||||||
|
uint32_t a_;
|
||||||
|
BigIntegerToBytes(a, reinterpret_cast<uint8_t*>(&a_), sizeof(a_));
|
||||||
|
|
||||||
|
CHECK(a_ == 160);
|
||||||
|
|
||||||
|
BigIntegerFree(a);
|
||||||
|
BigIntegerFree(b);
|
||||||
|
BigIntegerFree(c);
|
||||||
|
BigIntegerFree(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("BigIntegerMul", "[biginteger]") {
|
||||||
|
SECTION("multiplies 0xFFFFFFFF and 0x100") {
|
||||||
|
auto a = BigIntegerFromInt(0);
|
||||||
|
auto b = BigIntegerFromInt(0xFFFFFFFF);
|
||||||
|
auto c = BigIntegerFromInt(0x100);
|
||||||
|
|
||||||
|
BigIntegerMul(a, b, c);
|
||||||
|
|
||||||
|
uint64_t a_;
|
||||||
|
BigIntegerToBytes(a, reinterpret_cast<uint8_t*>(&a_), sizeof(a_));
|
||||||
|
|
||||||
|
CHECK(a_ == 0xFFFFFFFF00);
|
||||||
|
|
||||||
|
BigIntegerFree(a);
|
||||||
|
BigIntegerFree(b);
|
||||||
|
BigIntegerFree(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("BigIntegerSub", "[biginteger]") {
|
||||||
|
SECTION("subtracts 0xFF from 0xFFFF") {
|
||||||
|
auto a = BigIntegerFromInt(0);
|
||||||
|
auto b = BigIntegerFromInt(0xFFFF);
|
||||||
|
auto c = BigIntegerFromInt(0xFF);
|
||||||
|
|
||||||
|
BigIntegerSub(a, b, c);
|
||||||
|
|
||||||
|
uint32_t a_;
|
||||||
|
BigIntegerToBytes(a, reinterpret_cast<uint8_t*>(&a_), sizeof(a_));
|
||||||
|
|
||||||
|
CHECK(a_ == 0xFF00);
|
||||||
|
|
||||||
|
BigIntegerFree(a);
|
||||||
|
BigIntegerFree(b);
|
||||||
|
BigIntegerFree(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue