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:
 
 
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.