I have broken down coco's code into three components (keygen, encrypter, decrypter) independent of each other to help get my head around this fascinating algorithm

its mainly based on coco's SelfTest() routine which demonstrates the full process.
Thanks again to coco and wilbert for some awesome code!!!
Keygen (Alice) - saves the three key components:
Code: Select all
IncludeFile("cc2rsa.pbi")
Procedure RSASaveKeys(SavePath.s, *K.Cc2RSA::RSAKeyPair)
hFile = CreateFile(#PB_Any, SavePath+"rsakey-e-pub.dat") ;Public-only
If hFile
WriteData(hFile, *K\PublicExponent, BigInt::NumberSize(*K\PublicExponent))
CloseFile(hFile)
EndIf
hFile = CreateFile(#PB_Any, SavePath+"rsakey-n-pub.dat") ;Public/shared
If hFile
WriteData(hFile, *K\Modulus, BigInt::NumberSize(*K\Modulus))
CloseFile(hFile)
EndIf
hFile = CreateFile(#PB_Any, SavePath+"rsakey-d-prv.dat") ;Private-only
If hFile
WriteData(hFile, *K\SecretExponent, BigInt::NumberSize(*K\SecretExponent))
CloseFile(hFile)
EndIf
EndProcedure
Procedure GenerateAndSaveKeys(KeyPath.s)
Protected.Cc2RSA::RSAKeyPair K
Protected.BigInt::BigInt data1, data2
If Cc2RSA::GenerateKeyPair(K)
Debug "e: " + BigInt::GetHex(K\PublicExponent)
Debug "n: " + BigInt::GetHex(K\Modulus)
Debug "d: " + BigInt::GetHex(K\SecretExponent)
RSASaveKeys(KeyPath, @K)
Else
Debug "GenerateKeyPair() failed"
EndIf
EndProcedure
Define KeyPath.s = GetPathPart(ProgramFilename())
GenerateAndSaveKeys(KeyPath)
Debug "DONE. Saved to " + KeyPath
Encrypter (Bob) - reads the public key and shared modulus, and encrypts a buffer which it saves to a file:
Code: Select all
IncludeFile("cc2rsa.pbi")
Procedure LoadPublicKey(KeyPath.s, *K.Cc2RSA::RSAKeyPair)
*tmpbuf = AllocateMemory($10000)
hFile = ReadFile(#PB_Any, KeyPath+"rsakey-n-pub.dat")
If hFile
*K\KeySize = Lof(hFile)*8 ;set keysize (eg. 1024, 2048, 4096)
If *K\KeySize % 512 <> 0: MessageRequester("WARNING", "Keysize not multiple of 512"): EndIf
ReadData(hFile, *tmpbuf, Lof(hFile))
BigInt::LoadValue(*k\Modulus, *tmpbuf, Lof(hFile))
CloseFile(hFile)
EndIf
hFile = ReadFile(#PB_Any, KeyPath+"rsakey-e-pub.dat")
If hFile
ReadData(hFile, *tmpbuf, Lof(hFile))
BigInt::LoadValue(*k\PublicExponent, *tmpbuf, Lof(hFile))
CloseFile(hFile)
EndIf
FreeMemory(*tmpbuf)
EndProcedure
Procedure RSAEncrypt(*K.Cc2RSA::RSAKeyPair, *data, datalen.i, *dataout.BigInt::BigInt)
Protected.BigInt::BigInt data1
BigInt::LoadValue(data1, *data, datalen)
If Cc2RSA::RSAProcessRaw(*dataout, data1, *K)
Debug "RSAProcessRaw SUCCESS"
Else
Debug "RSAProcessRaw FAIL"
EndIf
EndProcedure
Procedure SaveBigInt(*bigint.BigInt::BigInt, sFile.s)
hFile = CreateFile(#PB_Any, sFile)
If hFile
WriteData(hFile, *bigint, BigInt::NumberSize(*bigint))
CloseFile(hFile)
EndIf
EndProcedure
Define KeyPath.s = GetPathPart(ProgramFilename())
Define K.Cc2RSA::RSAKeyPair
Define encdata.BigInt::BigInt
LoadPublicKey(KeyPath, @K)
Debug "n: " + BigInt::GetHex(K\Modulus)
Debug "e: " + BigInt::GetHex(K\PublicExponent)
Debug "Encrypting..."
sMsg.s = "secret!"
RSAEncrypt(K, @sMsg, Len(sMsg), encdata)
SaveBigInt(encdata, KeyPath+"rsa-encrypted.dat")
Decrypter (Alice) - reads private key and shared modulus, reads the encrypted buffer from file, and decrypts it:
Code: Select all
IncludeFile("cc2rsa.pbi")
Procedure LoadPrivateKey(KeyPath.s, *K.Cc2RSA::RSAKeyPair)
*tmpbuf = AllocateMemory($10000)
hFile = ReadFile(#PB_Any, KeyPath+"rsakey-n-pub.dat")
If hFile
*K\KeySize = Lof(hFile)*8 ;set keysize (eg. 1024, 2048, 4096)
If *K\KeySize % 512 <> 0: MessageRequester("WARNING", "Keysize not multiple of 512"): EndIf
ReadData(hFile, *tmpbuf, Lof(hFile))
BigInt::LoadValue(*k\Modulus, *tmpbuf, Lof(hFile))
CloseFile(hFile)
EndIf
hFile = ReadFile(#PB_Any, KeyPath+"rsakey-d-prv.dat")
If hFile
ReadData(hFile, *tmpbuf, Lof(hFile))
BigInt::LoadValue(*k\SecretExponent, *tmpbuf, Lof(hFile))
CloseFile(hFile)
EndIf
FreeMemory(*tmpbuf)
EndProcedure
Procedure RSADecrypt(*K.Cc2RSA::RSAKeyPair, *data, datalen.i, *dataout.BigInt::BigInt)
Protected.BigInt::BigInt data1
BigInt::LoadValue(data1, *data, datalen)
If Cc2RSA::RSAProcessRaw(*dataout, data1, *K, 1)
Debug "RSAProcessRaw SUCCESS"
Else
Debug "RSAProcessRaw FAIL"
EndIf
EndProcedure
Procedure SaveBigInt(*bigint.BigInt::BigInt, sFile.s)
hFile = CreateFile(#PB_Any, sFile)
If hFile
WriteData(hFile, *bigint, BigInt::NumberSize(*bigint))
CloseFile(hFile)
EndIf
EndProcedure
Define KeyPath.s = GetPathPart(ProgramFilename())
Define K.Cc2RSA::RSAKeyPair
Define encdata.BigInt::BigInt
LoadPrivateKey(KeyPath, @K)
Debug "n: " + BigInt::GetHex(K\Modulus)
Debug "d: " + BigInt::GetHex(K\SecretExponent)
hFile = ReadFile(#PB_Any, KeyPath+"rsa-encrypted.dat")
If hFile
buflen = Lof(hFile)
*buf = AllocateMemory(buflen)
ReadData(hFile, *buf, buflen)
BigInt::LoadValue(encdata, *buf, buflen)
CloseFile(hFile)
Debug "Decrypting..."
RSADecrypt(K, *buf, buflen, encdata)
ShowMemoryViewer(encdata, BigInt::NumberSize(encdata))
Else
Debug "Couldnt read rsa-encrypted.dat"
EndIf