IUserRSA

 

     IUserRSA represents an RSA key pair. It includes the base integer N, the exponent of the one key E, and the exponent of the another      key D.

    

     A message M is another interger less than N.

    

     The following two equations hold.

                   

     M' = exp(M, E) mod N. ----(1)

 

     M = exp(M', D) mod N. ----(2)

 

 

To speed up the calculation, the private key may be represented as (p,q,r,s,u) where

 

     N = p * q where p, q are primes.

 

     r = D mod(p-1);

 

     s = D mod(q-1);

 

     u = inverse p mod q

 

     and the formula (2) is replaced with

    

     M = EXP(M',p,q,r,s,u) -----(3); ( the details of EXP is not relevent and can be found in a typical text book.)

    

     This means that the formula for public keys may be different from      the formula for the private key.

 

We can assign arbitrarily

    

          (E,N) as the public key and

         

          (D,N) as the private key which may be represented as (p,q,r,s,u).

 

For secrecy, the message M is encoded first with formula (1), and then decoded with formula (3) or (2).

 

For authentication, the compressed message M is first encoded with formula (3) or (2) and the decoded with formula (1).

 

In addition to the needed data for an RSA cryptosystem, each IUserRSA also contains a UserID and a KeyID. The UserID

is a NULL terminated string representing the name of the object. It can be anything you like. The KeyID is a NULL

terminated string which is the unique identifier of the object. It is normally generated by the method Generate. You may

assign a string to it with the method SetKeyID.

 

When to Implement

 

     This interface is implemented by UserCrypto.dll

    

Methods in Vtable Order

 

IUnknown methods

QueryInterface Returns pointers to supported interfaces.

AddRef Increments the reference count.

Release Decrements the reference count.     

    

IUserRSA Methods:

Clear      Clear all the parameters contained in IUserRSA.

 

Generate      Generate an RSA key

ExpModPublic      To calculate      M' = exp(M, E) mod N.

ExpModPrivate      To calculate M = exp(M', D) mod N or M = EXP(M',p,q,r,s,u)

 

LoadFile      Load from a file

SavePublicKey      Save the public key to a file

SavePrivateKey      Save the private key to a file

SaveBothKeys      Save the private key and the public key to a file

 

GetUserID      Get the UserID of the key

GetKeyID      Get the KeyID of the key

GetBase      Get the base integer of the key

GetPublicExp      Get the public exponent of the key

GetPrivateExp      Get the private exponent of the key

GetPrivateP      Get the prime P of the key

GetPrivateQ      Get the prime Q of the key

GetPrivateR      Get the integer R of the key

GetPrivateS Get the integer S of the key

GetPrivateU      Get the integer U of the key

SetUserID      Set the UserID of the key

SetKeyID      Set the KeyID of the key

SetBase      Set the base integer of the key

SetPublicExp      Set the public exponent of the key

SetPrivateExp      Set the private exponent of the key

SetPrivateP      Set the integer P of the key

SetPrivateQ      Set the integer Q of the key

SetPrivateR      Set the integer R of the key

SetPrivateS      Set the integer S of the key

SetPrivateU      Set the integer U of the key

 

Method Description:

 

1:STDMETHODIMP Clear()

 

     Clear all the parameters contained in IUserRSA.

 

Return: S_OK

 

   

 

2:STDMETHODIMP Generate(unsigned char * pUserName, int len)

 

     Generate an RSA key.

 

Return:

          S_OK if successful

          S_FALSE if not successful

 

Parameters

 

     pUserName: a NULL terminate string.

                  It is the name of the key.

                  You can set this to be anything you like.

                  Example:

                  "John", "abc", "MyKey"

    

     len: the length of the base of the RSA key in terms of DWORD.

          Example:

           16 indicates the length is 512 bits

           32 indicates the length is 1024 bits

           

          Minimum value of len is 5.

 

Note:

     The public exponent of the generated key is 65537 or 0x10001

 

 

3:STDMETHODIMP GetBaseLength(int * len)

 

     Get the length of the base of the RSA Key in terms of DWORDS

 

Return:

 

     Always S_OK

 

Parameters:

  

     len: an integer pointer to hold the length of the base.

 

Note:

 

     len = 16 indicates the base is of the length of 512 bits

    

4:STDMETHODIMP ExpModPublic(DWORD * pDataIn, int cInLen, DWORD *pDataOut, int *cOutLen)

 

     To calculate

         

          M' = exp(M, E) mod N. ----(1)

 

     where E is the public key contained in IUserRSA,

 

     N is the base of this IUserRSA,

 

     *pDateIn and cInlen form the M.

 

     *pDataOut and *cOutLen form the M'.

    

Return:

 

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pDataIn: A DWORD pointer. It represents a large integer.

     It is a Radix 0x100000000 integer.

     pDataIn[0] is the least significant digit.

 

     cInLen: It is the number of Radix 0x100000000 digits in

     pDataIn. It must be larger than 4.

     pDataIn[cInLen-1] is the most significant digit.

 

     Example:

 

     pDataIn can be

     ff11ff11 ff11ff11 ff11ff1 ff11ff11 ff11ff11

     and cInLen is 5.

 

 

     pDataOut: A DWORD pointer.

     pDataOut is the holder of the result of the calculation.

     pDataOut must point to a valid memory location. The user is

     responsible for memory allocation.

 

     cOutLen is an interger pointer.

     When input, it is the maximun number of DWORDs allocated for pDataOut.

     When output, it is the actual number of DWORDs significant in pDataOut.

    

Example C++ Code Segment:

    

     #include "UserCrypto_i.c"

     #include "UserCrypto.h"

 

     IUserRSA *pUserRSA;

    

     CoCreateInstance(CLSID_UserRSA,

     NULL,

     CLSCTX_INPROC_SERVER,

     IID_IUserRSA,

     (void **)&pUserRSA);

 

     pUserRSA->Generate((BYTE *)"NI",16);

     //

     // if you are using C , write as follows:

     // pUserRSA->lpVtbl->Generate((BYTE *)"NI",16);

     // This rule to convert a C++ statement to a C statement applies to

     // all the subsequent statements when interface pointers are involved.

     //

 

     int len;

     pUserRSA->GetBaseLength(&len);

 

     DWORD *pDataOut = (DWORD *)calloc(len, sizeof(DWORD));

 

     DWORD pDataIn[5] = {0xff11ff11, 0xff11ff11, Oxff11ff11, Oxff11ff11,0xff11ff11};

 

     int cOutLen;

     pUserRSA->GetBaseLength(&cOutLen);

     pUserRSA->ExpModPublic(pDataIn,5, pDataOut,&cOutLen);

 

     // Now, pDataOut contains the encoded data

 

     pUserRSA->Release();

 

 

 

5:STDMETHODIMP ExpModPrivate(DWORD * pDataIn, int cInLen, DWORD *pDataOut, int *cOutLen)

 

     To calculate

         

          M = exp(M', D) mod N. ----(2) or

          M = EXP(M',p,q,r,s,u) -----(3);

 

     where D is the private key contained in IUserRSA,

 

     N is the base of this IUserRSA,

 

     *pDateIn and cInlen form the M'.

 

     *pDataOut and *cOutLen form the M.

 

     If (p,q,r,s,u) is availabe in IUserRSA, formula (3) will be used

     automatically. Otherwise formula (2) will be used. Formula (3)

     is about twice as fast as formula (2).

 

Return:

 

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pDataIn: A DWORD pointer. It represents a large integer.

     It is a Radix 0x100000000 integer.

     pDataIn[0] is the least significant digit.

 

     cInLen: It is the number of Radix 0x100000000 digits in

     pDataIn. It must be larger than 4.

     pDataIn[cInLen-1] is the most significant digit.

 

     Example:

 

     pDataIn can be

     ff11ff11 ff11ff11 ff11ff1 ff11ff11 ff11ff11

     and cInLen is 5.

 

 

     pDataOut: A DWORD pointer.

     pDataOut is the holder of the result of the calculation.

     pDataOut must point tp a valid memory location. The user is

     responsible for memory allocation.

 

     cOutLen is an interger pointer.

     When input, it is the maximun number of DWORDs allocated for pDataOut.

     When output, it is the actual number of DWORDs significant in pDataOut.

    

Example C++ Code Segment:

    

     #include "UserCrypto_i.c"

     #include "UserCrypto.h"

 

     IUserRSA *pUserRSA;

    

     CoCreateInstance(CLSID_UserRSA,

     NULL,

     CLSCTX_INPROC_SERVER,

     IID_IUserRSA,

     (void **)&pUserRSA);

 

     pUserRSA->Generate((BYTE *)"NewImage",16);

 

     int len;

     pUserRSA->GetBaseLength(&len);

 

     DWORD *pDataOut = (DWORD *)calloc(len, sizeof(DWORD));

 

     DWORD pDataIn[5] = {0xff11ff11, 0xff11ff11, Oxff11ff11, Oxff11ff11,0xff11ff11};

 

     int cOutLen;

     pUserRSA->GetBaseLength(&cOutLen);

     pUserRSA->ExpModPublic(pDataIn,5, pDataOut,&cOutLen);

 

     // Now, pDataOut contains the encoded data

 

     DWORD *pDataReturn = (DWORD *)calloc(len, sizeof(DWORD));

     int cReturnLen = len;

     pUserRSA->ExpModPublic(pDataOut,cOutLen, pDataReturn,&cReturnLen);

 

     // Now, pDataReturn should hold the same data as pDataIn

 

     pUserRSA->Release();

 

 

6:STDMETHODIMP LoadFile(unsigned char *pFileName)

 

     Load the parameters of IUserRSA from a file. The file must

     be generated by any of the methods:

          SavePublicKey. SavePrivateKey, SaveBothKeys

 

     pFileName points to an OLE compound file.

 

Return:

     S_OK if successful

     S_FALSE if not successful

 

Parameters:

 

     pFileName: the filename to be loaded.

 

Example C++ code segment:

 

     #include "UserCrypto_i.c"

     #include "UserCrypto.h"

 

     IUserRSA *pUserRSA;

    

     CoCreateInstance(CLSID_UserRSA,

     NULL,

     CLSCTX_INPROC_SERVER,

     IID_IUserRSA,

     (void **)&pUserRSA);

 

     char buf[25] = "c:\\MyKey.asy";

     pUserRSA->Load(buf);

 

     // now you can call other methods like ExpModPublic

     // or ExpModPrivate or GetBase

 

     pUserRSA->Release(); // finish up

 

7:STDMETHODIMP SavePublicKey(unsigned char *pFileName)

 

     Save the public key to a file

 

Return:

 

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pFileName: the filename to be saved.

 

Example C++ code segment:

 

     #include "UserCrypto_i.c"

     #include "UserCrypto.h"

 

     IUserRSA *pUserRSA;

    

     CoCreateInstance(CLSID_UserRSA,

     NULL,

     CLSCTX_INPROC_SERVER,

     IID_IUserRSA,

     (void **)&pUserRSA);

 

     pUserRSA->Generate("MyKey",16);

 

     char buf[25] = "c:\\MyKey.wky";

     pUserRSA->SavePublicKey(buf);

 

     pUserRSA->Release();

 

 

 

8:STDMETHODIMP SavePrivateKey(unsigned char *pFileName)

    

     Save the private key to a file

 

Return:

 

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pFileName: the filename to be saved.

 

 

    

9:STDMETHODIMP SaveBothKeys(unsigned char *pFileName)

 

     Save the private key and the public key to a file

 

Return:

 

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pFileName: the filename to be saved.

 

 

    

10.STDMETHODIMP GetUserID(unsigned char *pUserID, int *cLen)

 

     Get the UserID of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pUserID: pointer to an unsigned array. It must be allocated.

                It can be NULL.

 

     cLen: If pUserID is not NULL, it is the maximum length of pUserID when input, and

            the actual length when output.

            If pUserID is NULL, it holds the return value of the actual length.

 

Example C++ code segment

 

     #include "UserCrypto_i.c"

     #include "UserCrypto.h"

 

     IUserRSA *pUserRSA;

    

     CoCreateInstance(CLSID_UserRSA,

     NULL,

     CLSCTX_INPROC_SERVER,

     IID_IUserRSA,

     (void **)&pUserRSA);

 

     pUserRSA->Generate("MyKey",16);

 

     unsigned char *pUserID = NULL;

     int len;

     pUserRSA->GetUserID(NULL, &len); // len now holds the length of the UserID

     // if you are using C , write as follows:

     // pUserRSA->lpVtbl->GetUserID(NULL, &len);

     // This rule to convert a C++ statement to a C statement applies to

     // all the subsequent statements when interface pointers are involved.

     //

     pUserID = (unsigned char *)calloc(len + 1, 1);

     pUserRSA->GetUserID(pUserID, len); // pUserID now holds the NULL terminated string

                                                  // MyKey

 

     pUserRSA->Release();

 

 

11.STDMETHODIMP GetKeyID(unsigned char *pKeyID, int *cLen)

    

     Get the KeyID of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pKeyID: pointer to an unsigned array. It must be allocated.

                It can be NULL.

 

     cLen: If pUserID is not NULL, it is the maximum length of pKeyID when input, and

            the actual length when output.

            If pUserID is NULL, it holds the return value of the actual length.

 

Example C++ code segment:

 

     #include "UserCrypto_i.c"

     #include "UserCrypto.h"

 

     IUserRSA *pUserRSA;

    

     CoCreateInstance(CLSID_UserRSA,

     NULL,

     CLSCTX_INPROC_SERVER,

     IID_IUserRSA,

     (void **)&pUserRSA);

 

     pUserRSA->Generate("MyKey",16);

 

     unsigned char *pKeyID = NULL;

     int len;

     pUserRSA->GetUserID(NULL, &len); // len now holds the length of the KeyID

     // if you are using C , write as follows:

     // pUserRSA->lpVtbl->GetUserID(NULL, &len);

     // This rule to convert a C++ statement to a C statement applies to

     // all the subsequent statements when interface pointers are involved.

     //

     pKeyID = (unsigned char *)calloc(len + 1, 1);

     pUserRSA->GetKeyID(KeyID, len);

 

     pUserRSA->Release();

 

 

12.STDMETHODIMP GetBase(DWORD *pData, int *pLen)

 

     Get the base integer of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pData: pointer to an DWORD array. It must be allocated.

                It can be NULL.

 

     pLen: If pData is not NULL, it is the maximum length of pData when input, and

            the actual length when output.

            If pData is NULL, it holds the return value of the actual length.

 

Example C++ code segment:

 

     #include "UserCrypto_i.c"

     #include "UserCrypto.h"

 

     IUserRSA *pUserRSA;

    

     CoCreateInstance(CLSID_UserRSA,

     NULL,

     CLSCTX_INPROC_SERVER,

     IID_IUserRSA,

     (void **)&pUserRSA);

 

     pUserRSA->Generate("MyKey",16);

 

     unsigned char *pData = NULL;

     int len;

     pUserRSA->GetBase(NULL, &len); // len now holds the length of the KeyID

     // if you are using C , write as follows:

     // pUserRSA->lpVtbl->GetBase(NULL, &len);

     // This rule to convert a C++ statement to a C statement applies to

     // all the subsequent statements when interface pointers are involved.

     //

     pData = (unsigned char *)calloc(len, 4);

     pUserRSA->GetBase(pData, len);

 

     pUserRSA->Release();

 

 

13.STDMETHODIMP GetPublicExp(DWORD *pData, int *pLen)

 

     Get the public exponent of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pData: pointer to an DWORD array. It must be allocated.

                It can be NULL.

 

     pLen: If pData is not NULL, it is the maximum length of pData when input, and

            the actual length when output.

            If pData is NULL, it holds the return value of the actual length.

 

 

14.STDMETHODIMP GetPrivateExp(DWORD *pData, int *pLen)

 

     Get the private exponent of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pData: pointer to an DWORD array. It must be allocated.

                It can be NULL.

 

     pLen: If pData is not NULL, it is the maximum length of pData when input, and

            the actual length when output.

            If pData is NULL, it holds the return value of the actual length.

 

 

15.STDMETHODIMP GetPrivateP(DWORD *pData, int *pLen)

 

     Get the prime P of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pData: pointer to an DWORD array. It must be allocated.

                It can be NULL.

 

     pLen: If pData is not NULL, it is the maximum length of pData when input, and

            the actual length when output.

              If pData is NULL, it holds the return value of the actual length.

 

16.STDMETHODIMP GetPrivateQ(DWORD *pData, int *pLen)

 

     Get the prime Q of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pData: pointer to an DWORD array. It must be allocated.

                It can be NULL.

 

     pLen: If pData is not NULL, it is the maximum length of pData when input, and

            the actual length when output.

            If pData is NULL, it holds the return value of the actual length.

 

17.STDMETHODIMP GetPrivateR(DWORD *pData, /int *pLen)

 

     Get the integer R of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pData: pointer to an DWORD array. It must be allocated.

                It can be NULL.

 

     pLen: If pData is not NULL, it is the maximum length of pData when input, and

            the actual length when output.

            If pData is NULL, it holds the return value of the actual length.

 

18.STDMETHODIMP GetPrivateS(DWORD *pData, int *pLen)

 

     Get the integer S of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pData: pointer to an DWORD array. It must be allocated.

                It can be NULL.

 

     pLen: If pData is not NULL, it is the maximum length of pData when input, and

            the actual length when output.

            If pData is NULL, it holds the return value of the actual length.

                 

19.STDMETHODIMP GetPrivateU(DWORD *pData, int *pLen)

 

     Get the integer U of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pData: pointer to an DWORD array. It must be allocated.

                It can be NULL.

 

     pLen: If pData is not NULL, it is the maximum length of pData when input, and

            the actual length when output.

            If pData is NULL, it holds the return value of the actual length.

 

20.STDMETHODIMP SetUserID(unsigned char *pUserID, int cLen)

 

     Set the UserID of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pUserID: pointer to an unsigned char array. It must be allocated.

                

 

     cLen: it is the length of pUserID when input.

            .

 

21.STDMETHODIMP SetKeyID(unsigned int *pKeyID, int cLen)

 

     Set the KeyID of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pKeyID: pointer to an unsigned char array. It must be allocated.

                

 

     cLen: it is the length of pUserID when input.

 

22.STDMETHODIMP SetBase(DWORD *pData,int cLen)

 

     Set the base integer of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pData: pointer to a DWORD array. It must be allocated.

                

     cLen: it is the length of pData.

 

23.STDMETHODIMP SetPublicExp(DWORD *pData, int cLen)

 

     Set the public exponent of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pData: pointer to a DWORD array. It must be allocated.

                

     cLen: it is the length of pData.

 

24.STDMETHODIMP SetPrivateExp(DWORD *pData, int cLen)

 

     Set the private exponent of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pData: pointer to a DWORD array. It must be allocated.

                

     cLen: it is the length of pData.

 

25.STDMETHODIMP SetPrivateP(DWORD *pData, int cLen)

 

     Set the integer P of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pData: pointer to a DWORD array. It must be allocated.

                

     cLen: it is the length of pData.

 

26.STDMETHODIMP SetPrivateQ(DWORD *pData, int cLen)

 

     Set the integer Q of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pData: pointer to a DWORD array. It must be allocated.

                

     cLen: it is the length of pData.

 

 

27.STDMETHODIMP SetPrivateR(DWORD *pData, int cLen)

 

     Set the integer R of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pData: pointer to a DWORD array. It must be allocated.

                

     cLen: it is the length of pData.

 

28.STDMETHODIMP SetPrivateS(DWORD *pData, int cLen)

 

     Set the integer S of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pData: pointer to a DWORD array. It must be allocated.

                

     cLen: it is the length of pData.

    

29.STDMETHODIMP SetPrivateU(DWORD *pData, int cLen)

 

     Set the integer U of the key

 

Return:

    

     S_OK if successful

     S_FALSE if not successful     

 

Parameters:

 

     pData: pointer to a DWORD array. It must be allocated.

                

     cLen: it is the length of pData.