RSA Test program problem

Help
joesmith
2004-08-18
2004-08-21
  • joesmith

    joesmith - 2004-08-18

    Hi,
    I am trying to test the testrsa.c program. I have made some modifications

    #include <stdio.h>

    #include "rsa.h"
    #include "rsakp.h"
    #include "mp.h"

    static const char* rsa_n  = "bbf82f090682ce9c2338ac2b9da871f7368d07eed41043a440d6b6f07454f51fb8dfbaaf035c02ab61ea48ceeb6fcd4876ed520d60e1ec4619719d8a5b8b807fafb8e0a3dfc737723ee6b4b7d93a2584ee6a649d060953748834b2454598394ee0aab12d7b61a51f527a9a41f6c1687fe2537298ca2a8f5946f8e5fd091dbdcb";
    static const char* rsa_e  = "11";
    static const char* rsa_p  = "eecfae81b1b9b3c908810b10a1b5600199eb9f44aef4fda493b81a9e3d84f632124ef0236e5d1e3b7e28fae7aa040a2d5b252176459d1f397541ba2a58fb6599";
    static const char* rsa_q  = "c97fb1f027f453f6341233eaaad1d9353f6c42d08866b1d05a0f2035028b9d869840b41666b42e92ea0da3b43204b5cfce3352524d0416a5a441e700af461503";
    static const char* rsa_d1 = "54494ca63eba0337e4e24023fcd69a5aeb07dddc0183a4d0ac9b54b051f2b13ed9490975eab77414ff59c1f7692e9a2e202b38fc910a474174adc93c1f67c981";
    static const char* rsa_d2 = "471e0290ff0af0750351b7f878864ca961adbd3a8a7e991c5c0556a94c3146a7f9803f8f6f8ae342e931fd8ae47a220d1b99a495849807fe39f9245a9836da3d";
    static const char* rsa_c  = "b06c4fdabb6301198d265bdbae9423b380f271f73453885093077fcd39e2119fc98632154f5883b167a967bf402b4e9e2e0f9656e698ea3666edfb25798039f7";

    static const char* rsa_m  = "d436e99569fd32a7c8a05bbc90d32c49";

    // Fixed value verification
    int main()
    {
        int failures = 0,i;

        rsakp keypair;
        mpnumber m, cipher, decipher;
       
          // Initialize the key pair
        rsakpInit(&keypair);

          // Set all the values in the MP library
        mpbsethex(&keypair.n, rsa_n);
        mpnsethex(&keypair.e, rsa_e);
        mpbsethex(&keypair.p, rsa_p);
        mpbsethex(&keypair.q, rsa_q);
        mpnsethex(&keypair.dp, rsa_d1);
        mpnsethex(&keypair.dq, rsa_d2);
        mpnsethex(&keypair.qi, rsa_c);

        mpnzero(&m);
        mpnzero(&cipher);
        mpnzero(&decipher);

          mpnsethex(&m, rsa_m);

          printf("Plaintext \n");
          for(i=0;i<m.size;i++)
          printf("%x ",m.data[i]);
               

        // It's safe to cast the keypair to a public key
          // Encrypting using the public key
        rsapub(&keypair.n, &keypair.e, &m, &cipher);
           

          printf("\nCiphertext \n");
          for(i=0;i<cipher.size;i++)
          printf("%x ",cipher.data[i]);

               
          // Decrypt using the chinese remainder theorm
          rsapricrt(&keypair.n, &keypair.p, &keypair.q, &keypair.dp, &keypair.dq, &keypair.qi, &cipher, &decipher);
       

          printf("\nRecovered Plaintext \n");
          for(i=0;i<decipher.size;i++)
          printf("%x ",decipher.data[i]);

               mpnfree(&decipher);
        mpnfree(&cipher);
        mpnfree(&m);

        rsakpFree(&keypair);
       
    }

    But when I print the hex message and the recovered message I only see alternate 4 characters of the hex number.
    Any suggestions?

    Joe

     
    • Bob Deblier

      Bob Deblier - 2004-08-19

      Please use mpprint and mpprintln functions to output mpnumber variables.

       
      • joesmith

        joesmith - 2004-08-19

        Hi,

        Thanks for the advice. It worked. But now I've taken one step forward by substituing my set of development keys into the system. They are binary so I deduced that I should use the binary version of the key assignment functions mpbsetbin and mpnsetbin. I would expect that I should be able to encrypt and decrypt just as the original example did. However the decrypt doesn't really resemble the clear text. Here's my code:

        #include <stdio.h>

        #include "rsa.h"

        #include "rsakp.h"

        #include "mp.h"

        typedef unsigned short int UInt16;

        static void byteSwap( UInt16 *srcAddr, unsigned long nbytes ){

        int i;

        int size;

        size=nbytes/2;

        for( i=0; i<size; i++, srcAddr++ ){

        *srcAddr = (*srcAddr << 8) | (*srcAddr >> 8);

        }

        }

        typedef unsigned long DWORD;

        typedef unsigned char BYTE;

        static DWORD dwExponent = 65537;

        static DWORD cbModulus = 128;

        static BYTE pbModulus[] = {

        0xc3, 0xc1, 0x3a, 0xac, 0x5b, 0xdf, 0xba, 0xb1, 0x7a, 0x96, 0x0d, 0x54, 0x06, 0x1b, 0xd2, 0xbd,

        0x1b, 0x1a, 0x05, 0xf8, 0xa1, 0x55, 0xcb, 0x16, 0xb9, 0x8d, 0x00, 0x2c, 0x59, 0x86, 0xa3, 0x73,

        0x3b, 0xa8, 0xeb, 0x72, 0xd3, 0xe8, 0x31, 0x80, 0xa9, 0x80, 0xbb, 0xd9, 0x28, 0x2f, 0x30, 0x68,

        0x57, 0x24, 0x64, 0xb6, 0xab, 0x65, 0xea, 0x8e, 0xa4, 0x57, 0x43, 0xae, 0x2b, 0xba, 0xa3, 0xe4,

        0xe8, 0xf2, 0x77, 0x4d, 0xb8, 0x0b, 0x66, 0xd9, 0xd7, 0x7d, 0x51, 0xae, 0x96, 0x5f, 0x87, 0x55,

        0x47, 0xc5, 0x90, 0x5d, 0xa2, 0x72, 0x02, 0xa0, 0xb8, 0xde, 0x4e, 0x97, 0x9a, 0x2b, 0x16, 0xb8,

        0x1f, 0xb3, 0xae, 0x81, 0xe6, 0xa8, 0x95, 0xff, 0x04, 0x65, 0x6e, 0x01, 0x86, 0xb2, 0xd5, 0xc5,

        0x06, 0x8d, 0x5e, 0x2c, 0x84, 0xd2, 0xed, 0xd6, 0xfa, 0x9f, 0x0b, 0xe1, 0x1c, 0x3c, 0x8d, 0x81 };

        static DWORD cbP = 64;

        //Prime number 1

        static BYTE pbP[] = {0xf1, 0xc7, 0x5f, 0x0b, 0x0a, 0xdd, 0x96, 0xfb, 0x63, 0xb7, 0xb0, 0xa4, 0xcd, 0x57, 0xa0, 0xc1,0xa0, 0x41, 0xb5, 0x5b, 0x4a, 0x9d, 0x12, 0x8f, 0x4b, 0xe3, 0x4c, 0x12, 0xa6, 0x46, 0xa2, 0x61,0xad, 0xfe, 0x3f, 0x16, 0x8e, 0x68, 0x92, 0x96, 0x07, 0x70, 0x16, 0xbd, 0x43, 0x46, 0xba, 0xfe,0xc7, 0xa2, 0x0b, 0x9d, 0x17, 0xec, 0x66, 0xf7, 0x79, 0x28, 0xa1, 0x7b, 0x7d, 0xbb, 0x2d, 0xc1 };

        static DWORD cbQ = 64;

        //Prime number 2

        static BYTE pbQ[] = {0xcf, 0x44, 0xd7, 0xda, 0xe7, 0x69, 0x69, 0x8c, 0xda, 0x78, 0x54, 0x91, 0xca, 0x00, 0xbd, 0xdb,0xf4, 0x1f, 0x93, 0x43, 0x29, 0xa4, 0x43, 0xf3, 0x95, 0xb3, 0xb7, 0x3c, 0xd1, 0xa3, 0xfa, 0x75,0x5e, 0xbc, 0x46, 0x07, 0x38, 0xe0, 0x37, 0xa3, 0xa7, 0x34, 0x36, 0xc2, 0x0b, 0x12, 0x6b, 0x30,0xa6, 0xb7, 0x41, 0x9d, 0x27, 0xff, 0xd1, 0xc9, 0xea, 0x39, 0xb0, 0x07, 0x40, 0x20, 0xcf, 0xc1 };

        static DWORD cbDP = 64;

        // prime exponent 1

        static BYTE pbDP[] = {0xa8, 0xb3, 0x13, 0xfe, 0x00, 0x76, 0xdd, 0x02, 0x4b, 0x71, 0xc0, 0x2f, 0x3d, 0x98, 0x06, 0xf3,0x13, 0x7e, 0xc5, 0xac, 0x0d, 0x43, 0xcb, 0xcf, 0x70, 0x84, 0x08, 0x70, 0x7a, 0xd4, 0x8e, 0x38,0xd9, 0xce, 0xac, 0xf6, 0x70, 0x27, 0x47, 0x20, 0xa7, 0xcf, 0xee, 0x0d, 0xe1, 0x03, 0x59, 0x36,0xac, 0xd4, 0xc4, 0x85, 0xb8, 0x4b, 0x9b, 0x0c, 0xd1, 0xdd, 0x27, 0xcf, 0xa2, 0xcb, 0x18, 0x01 };

        static DWORD cbDQ = 64;

        // prime exponent 2

        static BYTE pbDQ[] = {0x4f, 0x97, 0x32, 0x04, 0x5f, 0x44, 0x7d, 0x41, 0x97, 0x4b, 0x09, 0xbe, 0x8a, 0x01, 0x4a, 0xe6,0xc1, 0x91, 0xb6, 0x6c, 0xdd, 0xfa, 0xb4, 0x15, 0x3f, 0x71, 0x29, 0x75, 0xf3, 0x52, 0xb2, 0x84,0x8b, 0x82, 0x64, 0xa9, 0xb5, 0x4f, 0x74, 0x4e, 0x25, 0x90, 0xc9, 0x4e, 0x2e, 0x0e, 0x3e, 0x97,0x0a, 0x0d, 0xe8, 0xe6, 0x3e, 0x4b, 0xdf, 0xf5, 0x57, 0x3a, 0x1b, 0xbc, 0x4d, 0x05, 0xcc, 0x81 };

        static DWORD cbInverseQ = 64;

        // coeficient

        static BYTE pbInverseQ[] = {0x40, 0x71, 0x13, 0x1a, 0x4d, 0x55, 0xc2, 0x8d, 0x93, 0x8d, 0x9d, 0x1c, 0x5e, 0xf0, 0x20, 0x4a,0xa2, 0xef, 0x3a, 0x38, 0x9e, 0xf1, 0x56, 0xe9, 0x26, 0x3f, 0xf7, 0x89, 0x9d, 0x58, 0x69, 0x88,0x83, 0x6f, 0x38, 0x29, 0xf2, 0x3a, 0xab, 0x70, 0xd2, 0x8a, 0xb6, 0xb8, 0x95, 0x24, 0xa5, 0xb7,0xb9, 0x61, 0x2d, 0x72, 0x2b, 0xb3, 0xea, 0x61, 0xfb, 0xc5, 0x6b, 0x58, 0xe9, 0xd5, 0x6c, 0x24 };

        static DWORD cbD = 128;

        // private exp

        static BYTE pbD[] = {0x74, 0x1b, 0xb0, 0x89, 0x7b, 0x15, 0x00, 0xcf, 0x34, 0x3e, 0xbc, 0x39, 0x12, 0x46, 0x7e, 0x80,0xdc, 0x0a, 0x5b, 0x70, 0x55, 0x81, 0x65, 0xac, 0x5c, 0xf2, 0x5d, 0x1f, 0xf1, 0x1a, 0x02, 0xe8,0xde, 0x82, 0x1a, 0xe5, 0x48, 0xfb, 0x78, 0x21, 0x30, 0x68, 0xc3, 0x02, 0xd2, 0xea, 0xea, 0x73,0x78, 0xfc, 0x85, 0x20, 0x34, 0x19, 0x87, 0x3e, 0x84, 0x0b, 0x9e, 0x81, 0x38, 0x3e, 0xc3, 0xe6,0x80, 0x4b, 0xf9, 0xf7, 0x93, 0x3e, 0x22, 0xd2, 0x53, 0x73, 0x9d, 0xdf, 0xae, 0xcc, 0xb8, 0x41,0xfd, 0x8d, 0x85, 0x60, 0xc8, 0x2c, 0xe6, 0x69, 0xec, 0xbe, 0xc4, 0xd0, 0x4c, 0x40, 0xa2, 0x09,0xf6, 0x0f, 0x03, 0x95, 0xf7, 0x66, 0x02, 0x9f, 0x51, 0x75, 0xf3, 0xaa, 0x49, 0x72, 0x28, 0xcb,0x3a, 0x33, 0xe7, 0xb9, 0x4b, 0x54, 0xec, 0x23, 0x9a, 0x48, 0xd2, 0xe2, 0x16, 0x68, 0x80, 0x01 };

        static unsigned char testCipherText[] = {0xb9, 0x17, 0x41, 0x41, 0x48, 0x4d, 0x5f, 0x05, 0x51, 0x91, 0x93, 0x4f, 0x54, 0xfa, 0xc4, 0x69,0xad, 0x75, 0x47, 0xb5, 0x1b, 0xfa, 0x35, 0x0b, 0xee, 0xef, 0x00, 0xc6, 0x8d, 0xe1, 0x92, 0x9b,0x64, 0x04, 0x16, 0xd8, 0xa1, 0xd2, 0xb7, 0xeb, 0xcd, 0x2e, 0xec, 0x30, 0x4e, 0xb2, 0x91, 0x92,0x50, 0xb6, 0x42, 0xfb, 0xf0, 0x66, 0xa8, 0x57, 0x23, 0xe3, 0x40, 0x05, 0x0d, 0xe9, 0x74, 0x92,0x6d, 0x7d, 0x60, 0x66, 0x6f, 0xaf, 0x4d, 0xef, 0xed, 0xf1, 0x3a, 0x38, 0x98, 0x58, 0x5c, 0x62,0xc9, 0x79, 0xc0, 0xa1, 0xf0, 0xef, 0xbd, 0x39, 0xac, 0x6c, 0x84, 0xda, 0x15, 0x0a, 0x24, 0xfb,0xed, 0xcf, 0x89, 0x01, 0x47, 0x80, 0xa2, 0x56, 0x85, 0x66, 0xde, 0x3d, 0x15, 0x02, 0x03, 0x1e,0x85, 0xb9, 0x5c, 0x0f, 0xdf, 0x95, 0x3d, 0x4d, 0x3a, 0xc4, 0xfc, 0x9f, 0x56, 0x5b, 0x6f, 0xb3 };

        static const char* rsa_m = "d436e99569fd32a7c8a05bbc90d32c49";

        void swapEm(void)

        {

        byteSwap((UInt16 *)pbModulus,cbModulus);

        byteSwap((UInt16 *)&dwExponent,sizeof(dwExponent));

        byteSwap((UInt16 *)pbD,cbD);

        byteSwap((UInt16 *)pbP,cbP);

        byteSwap((UInt16 *)pbQ,cbQ);

        byteSwap((UInt16 *)pbDP,cbDP);

        byteSwap((UInt16 *)pbDQ,cbDQ);

        byteSwap((UInt16 *)pbInverseQ,cbInverseQ);

        }

        int main(void)

        {

        int failures = 0,i;

        int len;

        char *c;

        rsakp keypair;

        mpnumber m, cipher, decipher;

        // Initialize the key pair

        rsakpInit(&keypair);

        // do we have to swap key bytes?

        swapEm();

        mpbsetbin(&keypair.n, pbModulus,cbModulus);

        mpnsetbin(&keypair.e, (const byte *)&dwExponent, sizeof(dwExponent));

        mpbsetbin(&keypair.p, pbP, cbP);

        mpbsetbin(&keypair.q, pbQ, cbQ);

        mpnsetbin(&keypair.dp, pbDP, cbDP);

        mpnsetbin(&keypair.dq, pbDQ, cbDQ);

        mpnsetbin(&keypair.qi, pbInverseQ, cbInverseQ);

        mpnsetbin(&keypair.d, pbD, cbD);

        mpnzero(&m);

        mpnzero(&cipher);

        mpnzero(&decipher);

        mpnsethex(&m, rsa_m);

        mpprintln(m.size, m.data);

        // Encrypt message using the RSA public key

        rsapub(&keypair.n, &keypair.e, &m, &cipher);

        // Decrypt ciphertext using the chinese remainder theorm

        rsapricrt(&keypair.n, &keypair.p, &keypair.q, &keypair.dp, &keypair.dq, &keypair.qi, &cipher, &decipher);

        // Output the deciphered message in hex format

        printf("\nRecovered Plaintext \n");

        mpprintln(decipher.size, decipher.data);

        mpnfree(&decipher);

        mpnfree(&cipher);

        mpnfree(&m);

        rsakpFree(&keypair);

        }

        Any Suggestions?

        Also,the byte arrays are shown in network order and I have a little endian system. Should I be swaping bytes within words? Or bytes and 16-bit words?

        Thanks ,

        Joe

         
    • Bob Deblier

      Bob Deblier - 2004-08-21

      It's an almost classical endian-mistake. The mp[nb]setbin routines take bytes as input, and hence need no endian-swapping. Only for your public exponent do you use an endian-dependent encoding. On a little-endian machine this will have the following result:
      - if you swap everything, all variables but 'e' will be wrong
      - if you swap nothing, variable 'e' will be wrong

      For your code to work properly on any machine, substitute your initialization of the public exponent with:

          static DWORD cbExponent = 3;
                                                                                                                                                  
          static byte pbExponent[] = {
          0x01, 0x00, 0x01
          };

      and:

          mpnsetbin(&keypair.e, pbExponent, cbExponent);

      I've tested this on my little-endian x86-64.

      Sincerely,

      Bob Deblier

       

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.





No, thanks