Newer
Older
Import / applications / MakePDF / Security / BigInteger / tests.cpp
#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;
}