#include <iostream>
//#include <endian.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <inttypes.h>
// #include "bignum.h"
#include "BigInteger/BigInteger.h"
extern "C" {
//#include "tfm.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";
unsigned int hexCharToInt(unsigned char ch)
{
unsigned int c = tolower(ch);
if (c >= 'a')
return c - 'a' + 10;
return c - '0';
}
#if 0
uint8_t bnCreateFromString(BN* bn, const char* str)
{
int len = strlen(str);
int byteLen = len / 2;
bn->nbytes = byteLen - 1;
bn->data = (uint8_t*)malloc((int)byteLen+2);
if (!bn->data)
return 0;
for (int i = 0; i < byteLen; i++)
{
int val = 0;
val = hexCharToInt(str[i * 2 +1]);
val |= hexCharToInt(str[i * 2]) << 4;
//val = hexCharToInt(str[(len - 1) - i * 2]);
//val |= hexCharToInt(str[(len - 2) - i * 2]) << 4;
bn->data[i] = val;
}
return 1;
}
void printBigNum(const char* name, BN* bn)
{
printf("%s", name);
for (int i = 0; i <= bn->nbytes; i++)
printf("%02X ", bn->data[i]);
printf("\n");
}
void fpCreateFromString(fp_int* n, const char* str)
{
int len = strlen(str);
char* writable = (char*)memcpy(malloc(len + 1), str, len + 1);
//fp_reverse((unsigned char*)writable, len);
fp_read_radix(n, writable, 16);
free(writable);
//fp_reverse(s.c_str(), s.length());
//fp_read_radix(n, (char*)s.c_str(), 16);
}
void rsa_test()
{
fp_int d, e, n, c, m, e_m;
/* read in the parameters */
fpCreateFromString(&m, secretMessage);
fpCreateFromString(&e, publicExponent);
fpCreateFromString(&n, publicModulus);
/* test it */
fp_exptmod(&m, &e, &n, &e_m);
char buf[512];
memset(buf, 0, 512);
fp_toradix_n(&e_m, buf, 16, 512);
//printf("text = %s\n", buf);
for (int i = 0; i < 256; i++)
{
unsigned int val = 0;
val = hexCharToInt(buf[i * 2 + 1]) << 4;
val |= hexCharToInt(buf[i * 2 + 2]);
if (isprint(val) || isspace(val))
printf("%c", val);
}
printf("res: ");
for (int i = 0; i < 512; i++)
{
printf("%c", buf[i]);
}
}
#endif
void bignum_tests()
{
// TODO: need some helpers to reverse the order, construct from an int
// 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
BigInteger a = 0x40512F; // reverse endian order
BigInteger b = 0xE1E30F;
BigInteger c = a * b;
printf("\n %" PRIx64 " x %" PRIx64 " = %" PRIx64 " ", (uint64_t)a, (uint64_t)b, (uint64_t)c);
printf("\n %x x %x = %llx", 0x40512F, 0xE1E30F, 0x40512FLL*0xE1E30FLL);
printf("\n 0x40512F x 0x03 = "); BigInteger(BigInteger(0x40512F) * BigInteger(0x03)).Print();
printf("\n 0x40512F x 0x03 = %llx", 0x40512FLL*0x03LL);
printf("\n 0x40512F x 0x03 = "); BigInteger(BigInteger("03") * BigInteger("40512F")).Print();
printf("\n 0x40512F x 0x03 = %llx", 0x40512FLL*0x03LL);
a = BigInteger("012F"); // reverse endian order
b = BigInteger("FF");
BigInteger d = a;
d -= b;
printf("\n 0x012F - 0xFF = "); d.Print();
printf("\n %x - %x = %x", 0x012F, 0xFF, 0x012F-0xFF);
BigInteger bmod("03");
BigInteger bexp("02");
BigInteger bdat("1234");
printf("\nbmod: "); bmod.Print();
printf("\nbexp: "); bexp.Print();
printf("\nbdat: "); bdat.Print();
printf("\n");
BigInteger bdst;
bdst = BigInteger::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 % BigInteger("07");
printf("\n 0x1234 %% 0x0007 = "); bdst.Print();
printf("\n %x %% %x = %x", 0x1234, 0x0007, 0x1234 % 0x0007);
bdst = bdat;
bdst = bdat / BigInteger("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);
bdst = bdat;
bdst >>= 3;//bmod;
printf("\n 0x1234 >> 0x3 = "); bdst.Print();
printf("\n %x >> %x = %x", 0x1234, 0x3, 0x1234 >> 0x3);
//printf("\n %x << %x = %x", 0x1234, 0x3, 0x1234 << 0x3);
bdst = bdat;
bdst <<= 3;//bmod;
printf("\n 0x1234 << 0x3 = "); bdst.Print();
printf("\n %x << %x = %x", 0x1234, 0x3, 0x1234 << 0x3);
//printf("\n %x << %x = %x", 0x1234, 0x3, 0x1234 << 0x3);
printf("\n");
}
void rsa_test2()
{
BigInteger bmod(publicModulus);
BigInteger bexp(publicExponent);
BigInteger bdat(secretMessage);
printf("\nbmod: "); bmod.Print();
printf("\nbexp: "); bexp.Print();
printf("\nbdat: "); bdat.Print();
printf("\n");
BigInteger bdst = BigInteger::ExpMod(bdat, bexp, bmod);
printf("\nbdst: "); bdst.Print();
printf("\n");
size_t siz = bdst.Size();
printf("\nbdst size: %i\n", int(siz));
for (size_t i = 0; i < siz; i++)
{
unsigned int val = bdst[siz-1-i];
//printf("%x ", val);
if (isprint(val) || isspace(val))
printf("%c", val);
}
}
/*
void rsa_test3()
{
BN bdst,bdat,bexp,bmod;
bnCreateFromString(&bmod, publicModulus);
printBigNum("bmod: ", &bmod);
bnCreateFromString(&bexp, publicExponent);
printBigNum("bexp: ", &bexp);
bnCreateFromString(&bdat, secretMessage);
printBigNum("bdat: ", &bdat);
//bnCreate(&bdat,21,bunenc);
//bnCreate(&bexp,3,bpublicExponent);
//bnCreate(&bmod,128,bmodulus);
bnExpMod(&bdst, &bdat, &bexp, &bmod);
printBigNum("bdst: ", &bdst);
}
*/
int main()
{
bignum_tests();
//rsa_test();
rsa_test2();
//rsa_test3();
// const char* paypal_pub_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3EdI1EOw/+ft6uywdUHi5P4CyIqCl5u31m88yuixkRHVYLGe/NLC8wjzOHkeN6kKjrdCMXhDcBK2CFnTKKptJdwmj25o3Kj3uqscN+jEzGaIy0hRvnFZ2FGr6MdQxMLI0xkC1fFiU22TCuwEJydxKtTQl";
return 0;
}