#include <iostream>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <inttypes.h>
#include <functional>
#include "BigInteger.h"
#include "Integer.h"
const char* secretMessage =
"b3bb321dd5ba49a6dc3003d47d769e0b8001154fb7e785c567e68986"
"cf6caadd1f57c8f0b5bd33553ab25b519f8f59637d2913e21ba6c2c4"
"f8cc1e4b933507191352acbbbca4774b82471bd052dfd9f95f17e644"
"cd0efdfbe692ea54d78fcdb79e6aa6ae9d6c100d7dd1f72bb68ae8e7"
"2fe3886e90aa89268c5c8eb961df316b568acd8c1e78cb20ec1ebd3e"
"ef01828e271093a9c83380b62187f2a92f0d191ba463307de661c5ad"
"0ac229cc347d8dd932a639dc1d724a707d2f5528ca75005a126877e9"
"b58e7e139854dae90e43dcdfb3d2373f412aafa2e1a977addc9be9a8"
"c1e959af236dcd42e76f1fefd577c6211f7b033da9c2b683f131a7c7"
"0d96038b";
const char* publicModulus =
"C595751A3ECF23F251F42D53053E2A88B195F79FAA370EBDA69D4C0E"
"8535E9DCBD1A28CD726CB097504B041807FB0755228B180F4EC82907"
"2BF716A4DD0948917B09308509916A7AB1F4D5C2D65444284FB734AB"
"7F161AE2FACC6962EC0CF12559BD81E34E945B8A5BDE6276EAD96F7B"
"1ECBE0BFD1D8266261AF6C6CF6D72F0962002FC774A0FB43C5A7EA3E"
"FFBFC5EF95703CB408BA414E0C280611F03A8423C3A5A827D49B8CB8"
"5E92513C7A68870701B16D0511EE1A8EA1998A519DAA3BFFCB926236"
"D94658C57E413B49E8F7881B7000DF05655487E9B0D9D82F077EEC1F"
"8533816D074AE6B347430C5F3F98E5350A0A3121B243ED1C1CFA9408"
"BA64E00D";
const char* publicExponent = "010001";
template <typename T>
void rsa_test(bool debug)
{
printf("\nRSA test:\n");
T data(secretMessage);
T exponent(publicExponent);
T modulus(publicModulus);
T result = T::ExpMod(data, exponent, modulus);
size_t siz = result.Size();
if (debug)
{
printf("\ndata: "); data.Print();
printf("\nexponent: "); exponent.Print();
printf("\nmodulus: "); modulus.Print();
printf("\nresult: "); result.Print();
printf("\nsize: %i", int(siz));
}
printf("\nmessage: \n");
for (size_t i = 0; i < siz; i++)
{
unsigned int val = result[siz-1-i];
if (isprint(val) || isspace(val))
printf("%c", val);
}
printf("\n");
}
uint64_t TestCaseValues[] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x40, 0x4F, 0x50, 0x5F, 0x60, 0x6F, 0x70, 0x7F, 0x80, 0x81, 0xE0, 0xEF, 0xF0, 0xF1, 0xF2,
0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x100, 0x101, 0x102,
0x103, 0x104, 0x105, 0x1FF, 0x200, 0x201, 0x2FF, 0x300, 0x301, 0xFFF, 0x1000, 0x1001, 0xFFFF,
0x10000, 0x10001, 0x7FFFF, 0x80000, 0x80001, 0x87654, 0x8FFFF, 0x90000, 0xFFFFF, 0xFFFFFFF,
0x10000000, 0xFFFFFFFF, 0x20000000, 0x12345678
};
template <typename T>
uint64_t TestMultiply(uint64_t a_a, uint64_t a_b)
{
T a = a_a;
T b = a_b;
T c = a * b;
printf("\n 0x%" PRIX64 " x 0x%" PRIX64 " = 0x%" PRIX64 " ", (uint64_t)a, (uint64_t)b, (uint64_t)c);
return (uint64_t)c;
}
void RunTest()//std::function<uint64_t(uint64_t, uint64_t)> a_f1, std::function<uint64_t(uint64_t, uint64_t)> a_f2)
{
for (uint64_t i: TestCaseValues)
{
for (uint64_t j: TestCaseValues)
{
//uint64_t a = a_f1(i,j);
//uint64_t b = a_f2(i,j);
uint64_t a = TestMultiply<BigInteger>(i, j);
uint64_t b = TestMultiply<uint64_t>(i, j);
if (a != b)
{
printf("Test failure: %llx x %llx = %llx (actual: %llx)\n", i, j, a, b);
}
assert(a == b);
}
}
}
template <typename T>
void number_tests()
{
const char* testBase =
"7e2f50f7fa486c1dd51a37702a537df093cf3c11d9475599b1ce281eceb8cfcd3f67746a24edaf7e21c06571c0188f269f8d9803fc294273adbfc486b9e9683fb58c5b0c23b1212c95f2d533ceb0d515db9ef19f617aef39304ac130a2097fd870281d32b0d509c3b7023685c4ca70f90d9a77e780c5b62670fbb8d2997adf011a6eedcacb7386acebeebaafa89b18403b5d48519d0b8e82791e9d9e1c99a63d771c9b167918118d1a0847c897e266b2d9a0e8ad21b373f59da21619c7ed8397b13d5345b4dbaf0c754d2b26c498f304cac31ae7bc45b6ce225642446db7951c94aa868d74c77d849546b8ddb11524bd6a4c1c3f11d357550db51e7fe84c51dd069610704972b83e228f7d96736e6b91f60beea507ec55f38ddddae388fb244f0fa2c1b966ce3d1be8cc03aec9ff0abc73b85f95fc41b65ce9400d94089066af6cbbe24624c0a822b40864530da91598daeb38a15fdc723b83cf6646d2739fc5c7e9fa64cbfb6234a406343396066acad9474e4e55ccd22111d65ab95edfc8212e6f1ef2a8e3394a504269ca57035bf849f402bc1751b6b8029efe71e6a5cd608fc2d1e4fdbdb152f9bdd5129bd3c3830869065613b10a6a427c32c6b6b5e45dc880a9388b0541df42683494fea04a43c639f1fd4df7eb877e38123062e19825abfffce6a4d73dba14583d310818edc17f64ded888fa38dae9c7705e44f08d79";
const char* testModulus =
//"C5"
"C595751A3ECF23F251F42D53053E2A88B195F79FAA370EBDA69D4C0E"
"8535E9DCBD1A28CD726CB097504B041807FB0755228B180F4EC82907"
"2BF716A4DD0948917B09308509916A7AB1F4D5C2D65444284FB734AB"
"7F161AE2FACC6962EC0CF12559BD81E34E945B8A5BDE6276EAD96F7B"
"1ECBE0BFD1D8266261AF6C6CF6D72F0962002FC774A0FB43C5A7EA3E"
"FFBFC5EF95703CB408BA414E0C280611F03A8423C3A5A827D49B8CB8"
"5E92513C7A68870701B16D0511EE1A8EA1998A519DAA3BFFCB926236"
"D94658C57E413B49E8F7881B7000DF05655487E9B0D9D82F077EEC1F"
"8533816D074AE6B347430C5F3F98E5350A0A3121B243ED1C1CFA9408"
"BA64E00D";
//printf("\n result = %s", std::string(T::ExpMod(T(secretMessage), T(publicExponent), T(publicModulus))).c_str());
printf("\n result = %s", std::string((T(testBase) % T(testModulus))).c_str());
//printf("\n 0x123456789623FF %% 0x1F2354321 = %llx", 0xF1F2F3456789623FFULL % 0x1F2354321);
return;
printf("\n \"0\" = %s", std::string(T("0")).c_str());
printf("\n \"1\" = %s", std::string(T("1")).c_str());
printf("\n \"00\" = %s", std::string(T("00")).c_str());
printf("\n \"01\" = %s", std::string(T("01")).c_str());
printf("\n \"10\" = %s", std::string(T("10")).c_str());
printf("\n \"1020\" = %s", std::string(T("1020")).c_str());
printf("\n 0x00 = %s", std::string(T(uint64_t(0x00ULL))).c_str());
printf("\n 0x01 = %s", std::string(T(0x01ULL)).c_str());
printf("\n 0x10 = %s", std::string(T(0x10ULL)).c_str());
printf("\n 0x1020 = %s", std::string(T(0x1020ULL)).c_str());
/*
printf("\n \"0\" = %llx", uint64_t(T("0")));
printf("\n \"1\" = %llx", uint64_t(T("1")));
printf("\n \"00\" = %llx", uint64_t(T("00")));
printf("\n \"01\" = %llx", uint64_t(T("01")));
printf("\n \"10\" = %llx", uint64_t(T("10")));
printf("\n 0x00 = %llx", uint64_t(T(uint64_t(0x00ULL))));
printf("\n 0x01 = %llx", uint64_t(T(0x01ULL)));
printf("\n 0x10 = %llx", uint64_t(T(0x10ULL)));
return;
*/
printf("\n 0x10001 x 0xFFFFFFFF = %llx", uint64_t(T(0x10001) * T(0xFFFFFFFF)));
printf("\n 0x10001 x 0xFFFFFFFF = %llx", 0x10001ULL*0xFFFFFFFFULL);
printf("\n 0x10001 x 0x20000000 = %llx", uint64_t(T(0x10001) * T(0x20000000)));
printf("\n 0x10001 x 0x20000000 = %llx", 0x10001ULL*0x20000000ULL);
printf("\n 0x10001 x 0x00000000 = %llx", uint64_t(T(0x10001) * T(uint64_t(0x00000000))));
printf("\n 0x10001 x 0x00000000 = %llx", 0x10001ULL*0x00000000ULL);
printf("\n 0x10001 x 0x00000001 = %llx", uint64_t(T(0x10001) * T(0x00000001)));
printf("\n 0x10001 x 0x00000001 = %llx", 0x10001ULL*0x00000001ULL);
printf("\n 0x10001 x 0x00000002 = %llx", uint64_t(T(0x10001) * T(0x00000002)));
printf("\n 0x10001 x 0x00000002 = %llx", 0x10001ULL*0x00000002ULL);
// RunTest();//TestMultiply<T>, TestMultiply<uint64_t>);
// need helper to print out in reverse order or be able to convert back to an int
// then can make a set of unit tests which can be compared against normal int math results
printf("\n 0x40512F x 0x03 = "); T(T(0x40512F) * T(0x03)).Print();
printf("\n 0x40512F x 0x03 = %llx", 0x40512FLL*0x03LL);
printf("\n 0x40512F x 0x03 = "); T(T("03") * T("40512F")).Print();
printf("\n 0x40512F x 0x03 = %llx", 0x40512FLL*0x03LL);
T a("012F"); // reverse endian order
T b("FF");
T d = a;
d -= b;
printf("\n 0x012F - 0xFF = "); d.Print();
printf("\n %x - %x = %x", 0x012F, 0xFF, 0x012F-0xFF);
T bmod("03");
T bexp("02");
T bdat("1234");
printf("\nbmod: "); bmod.Print();
printf("\nbexp: "); bexp.Print();
printf("\nbdat: "); bdat.Print();
printf("\n");
T bdst;
bdst = T::ExpMod(bdat, bexp, bmod);
printf("\n 0x1234 ^ 0x2 %% 0x3 = "); bdst.Print();
printf("\n %x ^ %x %% %x = %x", 0x1234, 0x2, 0x3, 0x1234*0x1234 % 0x3);
bdst = bdat;
bdst = bdat % T("07");
printf("\n 0x1234 %% 0x0007 = "); bdst.Print();
printf("\n %x %% %x = %x", 0x1234, 0x0007, 0x1234 % 0x0007);
bdst = bdat;
bdst = bdat / T("07");
printf("\n 0x1234 / 0x0007 = "); bdst.Print();
printf("\n %x / %x = %x", 0x1234, 0x0007, 0x1234 / 0x0007);
bdst = bdat;
bdst -= bmod;
printf("\n 0x1234 - 0x3 = "); bdst.Print();
printf("\n %x - %x = %x", 0x1234, 0x3, 0x1234 - 0x3);
bdst = bdat;
bdst += bmod;
printf("\n 0x1234 + 0x3 = "); bdst.Print();
printf("\n %x + %x = %x", 0x1234, 0x3, 0x1234 + 0x3);
bdat = T("31234");
bdst = bdat;
bdst >>= 0xA;//bmod;
printf("\n 0x31234 >> 0xA = "); bdst.Print();
printf("\n %x >> %x = %x", 0x31234, 0xA, 0x31234 >> 0xA);
//printf("\n %x << %x = %x", 0x1234, 0x3, 0x1234 << 0x3);
bdst = bdat;
bdst <<= 0xA;//bmod;
printf("\n 0x31234 << 0xA = "); bdst.Print();
printf("\n %x << %x = %x", 0x31234, 0xA, 0x31234 << 0xA);
//printf("\n %x << %x = %x", 0x1234, 0x3, 0x1234 << 0x3);
printf("\n");
}
int main(int argc, char* argv[])
{
if (argc != 3)
{
printf("Usage: %s [A|B] loops\n", argv[0]);
return -1;
}
std::string arg = argv[1];
int loops = atoi(argv[2]);
for (int i = 0; i < loops; i++)
{
rsa_test<uint2048_t>(false);
}
//rsa_test<BigInteger>();
/*
if (arg == "A")
number_tests<BigInteger>();
if (arg == "B")
number_tests<uint2048_t>();
*/
return 0;
}