How to decrypt a message using the Vigenere Cipher - encryption

Recently, I have been trying to educate myself on how to encrypt and decrypt using the Vigenere Cipher.
I have successfully encrypted the message and these are the steps I undertook to achieve encryption:
Encryption Key: Set
Message: Top secret
Step 1: Numerical representation of key is 18, 4, 19 (Using the table below)
Working Out:
Reminder:
P is the set of plaintext units
C is the set of ciphertext units
K is the set of keys
E: P x K -> C is the encryption function
D: C x K -> P is the decryption function
Plaintext: top secret
Ciphertext: ISIKIVJIM
Although I have managed to encrypt the message "top secret" I am struggling to decrypt messages using the Vigenere Cipher method using the numerical technique I used above. Can someone explain to me how I can decrypt lets say: ISIKIVJIM (the ciphertext from above) to its original plain text message which is "top secret".
Thanks.

As pointed out in the comments the decryption formula is : p = c - k mod 26, also note that we have to perform modular arithmetic so our answer for any input should belong in the range of 0 - 25, i.e if we get a negative number we can add 26(i.e the number we are taking modulo by) until we are within this range you can read more about this here :
https://en.wikipedia.org/wiki/Modular_arithmetic
So the decryption will be like :
L = 11 - 18 = -7 mod 26 = -7 + 26 = 19 = T
S = 18 - 4 = 14 mod 26 = 14 = O
I = 8 - 19 = -11 mod 26 = -11 + 26 = 15 = P
ans so on...
I have also written a c++ code : http://ideone.com/M3BAmq

I recently wrote a java program that encrypts and decrypts in Vigenere using bytes. You need to convert the plain text/ crypt text into byte array and pass it in.
public static byte [] encryptVigenere (byte [] pt, String key)
{
byte [] c_text = new byte [pt.length];
byte [] key_text = key.getBytes();
byte tmp;
int shift;
for (int i = 0, j = 0; i < pt.length; i++)
{
if (j >= key_text.length)
j = 0;
shift = key_text[j] - 65; //index of alphabet
tmp = (byte) (pt[i] + shift);
if (tmp > 'Z')
tmp = (byte) (pt[i] - (26-shift));
c_text[i] = tmp;
j++;
}
return c_text;
}
public static byte [] decryptVigenere (byte [] ct, String key)
{
byte [] p_text = new byte [ct.length];
byte [] key_text = key.getBytes();
byte tmp;
int shift;
for (int i = 0, j = 0; i < ct.length; i++)
{
if (j >= key_text.length)
j = 0;
shift = key_text[j] - 65; //index of alphabet
tmp = (byte) (ct[i] - shift);
if (tmp < 'A')
tmp = (byte) (ct[i] + (26-shift));
p_text[i] = tmp;
j++;
}
return p_text;
}

Related

What is missing from the AES Validation Standard Pseudocode for the Monte Carlo Tests?

I'm trying to use the prescribed validation procedure for AES-128 in CBC mode, as defined in the NIST AESAVS standard. One of the more important parts of the test suite is the Monte Carlo test, which provides an algorithm for generating many 10000 pseudorandom tests cases such that it is unlikely that a hardcoded circuit could fake AES. The algorithm pseudocode therein appears to be taking some liberties with variable scope and definition, so I am hoping someone could help me fill in the missing information to interpret this correctly.
The verbatim algorithm for the 128-bit key case is as follows:
Key[0] = Key
IV[0] = IV
PT[0] = PT
For i = 0 to 99
Output Key[i]
Output IV[i]
Output PT[0]
For j = 0 to 999
If ( j=0 )
CT[j] = AES(Key[i], IV[i], PT[j])
PT[j+1] = IV[i]
Else
CT[j] = AES(Key[i], PT[j])
PT[j+1] = CT[j-1]
Output CT[j]
Key[i+1] = Key[i] xor CT[j]
IV[i+1] = CT[j]
PT[0] = CT[j-1]
For the above pseudocode, starting with these initial values:
Key = 9dc2c84a37850c11699818605f47958c
IV = 256953b2feab2a04ae0180d8335bbed6
PT = 2e586692e647f5028ec6fa47a55a2aab
The first three iterations of the outer loop should output:
KEY = 9dc2c84a37850c11699818605f47958c
IV = 256953b2feab2a04ae0180d8335bbed6
PLAINTEXT = 2e586692e647f5028ec6fa47a55a2aab
CIPHERTEXT = 1b1ebd1fc45ec43037fd4844241a437f
KEY = 86dc7555f3dbc8215e6550247b5dd6f3
IV = 1b1ebd1fc45ec43037fd4844241a437f
PLAINTEXT = c1b77ed52521525f0a4ba341bdaf51d9
CIPHERTEXT = bf43583a665fa45fdee831243a16ea8f
KEY = 399f2d6f95846c7e808d6100414b3c7c
IV = bf43583a665fa45fdee831243a16ea8f
PLAINTEXT = 7cbeea19157ec7bbf6289e2dff5e8ee4
CIPHERTEXT = 5464e1900f81e06f67139456da25fc09
It looks like we are using j outside of the inner loop, which I believe is the source of the confusion. I had originally assumed that this meant whatever the final value of the ciphertext CT was (CT[999]), which would lead me to believe that the plaintext for the next outer loop PT[0] is initialized to CT[998]. However, this interpretation doesn't match the expected outputs given.
I also thought that maybe brackets are not indicating an array of values here, but rather they represent the time steps relative to now. However, this also makes referencing j outside of the loop confusing. If the loop has expired, then is i or j the current time?
Am I missing some crucial step here? Is there a typo (there is no errata in the document)?
Could anyone with some experience on the matter comment on the appropriate interpretation?
Some months ago I tried to get the AES CBC MonteCarlo running on Java. I encountered the same problems but in the end I could find a complete and running solution that meets the official NIST vector results.
Before I start - your inital test vector seems to be an own vector but not the one provided by NIST - here is the link to the official NIST-website with all AES testvectors:
NIST-Website: https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/Block-Ciphers Montecarlo testvectors: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/aes/aesmct.zip
My test will start with these data:
[ENCRYPT]
COUNT = 0
KEY = 8809e7dd3a959ee5d8dbb13f501f2274
IV = e5c0bb535d7d54572ad06d170a0e58ae
PLAINTEXT = 1fd4ee65603e6130cfc2a82ab3d56c24
CIPHERTEXT = b127a5b4c4692d87483db0c3b0d11e64
and the function uses a "double" byte array for the inner and outer loop. I do not present the complete sourcode here on SO but the complete code is available in my GitHub repository https://github.com/java-crypto/Known_Answer_Tests with many other tests and test vector files. The encryption/decryption has to be done with NoPadding - don't use AES in default mode as in most
cases it would run with PKCS#5/#7 padding.
If you like you can run the code online (reduced to AES CBC 128 MonteCarlo) here: https://repl.it/#javacrypto/AesCbcMonteCarloTest#Main.java
The program will run the complete encryption and decryption test and does an additional cross-check (means the encryption result is checked
by a decryption and vice versa).
As it is some months ago that I took care of this I'm just offering my solution in Java code - hopefully it helps you in
your understanding of the NIST test procedure.
public static byte[] aes_cbc_mct_encrypt(byte[] PLAINTEXT, byte[] KEYinit, byte[] IVinit) throws Exception {
int i = 0; // outer loop
int j = 0; // inner loop
byte[][] KEY = new byte[101][128];
byte[][] IV = new byte[1001][128];
byte[][] PT = new byte[1001][128]; // plaintext
byte[][] CT = new byte[1001][128]; // ciphertext
byte[] CTsave = new byte[256]; // nimmt den letzten ct fuer nutzung als neuen iv auf
// init
int KEYLENGTH = KEYinit.length * 8;
KEY[0] = KEYinit;
IV[0] = IVinit;
PT[0] = PLAINTEXT;
for (i = 0; i < 100; i++) {
for (j = 0; j < 1000; j++) {
if (j == 0) {
CT[j] = aes_cbc_encrypt(PT[j], KEY[i], IV[i]);
CTsave = CT[j]; // sicherung fuer naechsten iv
PT[j + 1] = IV[i];
} else {
IV[i] = CTsave;
CT[j] = aes_cbc_encrypt(PT[j], KEY[i], IV[i]);
CTsave = CT[j];
PT[j + 1] = CT[j - 1];
}
}
j = j - 1; // correction of loop counter
if (KEYLENGTH == 128) {
KEY[i + 1] = xor(KEY[i], CT[j]);
}
if (KEYLENGTH == 192) {
KEY[i + 1] = xor192(KEY[i], CT[j - 1], CT[j]);
}
if (KEYLENGTH == 256) {
KEY[i + 1] = xor256(KEY[i], CT[j - 1], CT[j]);
}
IV[i + 1] = CT[j];
PT[0] = CT[j - 1];
ctCalculated[i] = CT[j].clone();
}
return CT[j];
}
public static byte[] xor(byte[] a, byte[] b) {
// nutzung in der mctCbcEncrypt und mctCbcDecrypt methode
byte[] result = new byte[Math.min(a.length, b.length)];
for (int i = 0; i < result.length; i++) {
result[i] = (byte) (((int) a[i]) ^ ((int) b[i]));
}
return result;
}
public static byte[] aes_cbc_encrypt(byte[] plaintextByte, byte[] keyByte, byte[] initvectorByte) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, BadPaddingException, IllegalBlockSizeException {
byte[] ciphertextByte = null;
SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
IvParameterSpec ivKeySpec = new IvParameterSpec(initvectorByte);
Cipher aesCipherEnc = Cipher.getInstance("AES/CBC/NOPADDING");
aesCipherEnc.init(Cipher.ENCRYPT_MODE, keySpec, ivKeySpec);
ciphertextByte = aesCipherEnc.doFinal(plaintextByte);
return ciphertextByte;
}

RSA decryption primitive (SP800-56B) using OpenSSL

I'm trying to implement RSA decryption primitive using OpenSSL (Refer https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Br2.pdf; section 7.1.2.1).
Here is my code:
BIGNUM *m = NULL, *n = NULL, *d = NULL, *c = NULL;
RSA *rsa = NULL;
int isValid = -1;
n = BN_bin2bn(N, 256, n);
d = BN_bin2bn(D, 256, d);
c = BN_bin2bn(ciphertext, 256, d);
rsa = RSA_new();
if (c == NULL || n == NULL || d == NULL)
printf("\n\nC,N,D is NULL, BN_bin2bn() failed!!\n\n");
isValid = BN_mod_exp(m, c, d, n, rsa);
RSA_free(rsa);
BN_free(n); BN_free(d); BN_free(m);
My inputs are shown below:
N : bff722714050aebb23a9bd018c3e9ba26a47f53816eeac7e10543958702d9265c8d67784fe03c07bfceac05e7f2a434971dfa2a5ea461893450ced52fcb3f143a85fb3a9194417ff220258840a3359a104079ccd201afec091bab6587d4cfe0b95bba34ef74a70b392a92a93f026c9bed41eb4ec80452492a2ad524e6b0333c5787b34ee941829020bb75ee5dd216b3734823ddd547d50f8a7e711f8a24fd7dbc0bd2f062ccaba98cdbf62c15d2521b39ce44c53125604493e482ae35f945c4efff1d01414b0aad33de77b020ea4aedf3d88171fe51b22881bc70c639f8b6f1b5a70ed39aa121a8f44887dcbbfce29e1e508d1b0f0666693b476d81faa6a18bd
D : a13aec8eba3a09c7dc18404b0083c52c10a00771e8b0e5e7abc751b2d9e52cc4987ea93be62d3889eacf306b2ddb4d506e782a9fb7b8d0034147ae3cb94a59253e51c3100fcc856b2021603ee66262b13e3536998291a9ce0b980a7720267e693485b890265b3b75578505e1e31e70ebfa3520385333bf97f9522183039658efd9b09fc0bd67a7d3c32e23adada71320ada2135f1d06a9144033ff9e0037a3b7ed1f5729b6db5f02470ecdde9eb2d97c759c73d13889bae550ab97205b67ce2f91eefb487f18c19bc6dd8831a43b0d699c771e1a9c55a1d5d2ae975691789b5c0a814c4f5e3d6a8e9e5f75419194b2d7dfe06700f6891cae8b712b3af1f9ec71
C : 534d1f57d948cac580b88b922bc47bc3d64c8cd1262bbf0944b99833ec94d072c1a1496be44d47a9c419dc403855a4b1cb2bb30e56e0cc5fd557d34373d785dbe70d67e30355fc228a353b05432a40874ba84253af5cc52d3ab4118e8ca1e28e6c9c610760e753f87a15912774ccb80b00ca21e85926143c1ed8385a607c4e55fa531f1f208bb3f23bc0c4eff4c272068f9939157bc61f5427cc32f017ef31f6363c8a736ec984da763ebea5eb94d83fa31d70223ec5503cfd97e598d883f43aca5e884b702a2f76d298659181cb5180e25faf56c9aa0ebe49413b9acbbefde95ec102ee4e351a8ff8d5a3fbdcee448ff466dffb45fdc0a0b3d31b3d192bb5cb
From the documentation, m can be derived by doing:
m = (c^d) mod n
I use the OpenSSL function BN_mod_exp() to do this. (Refer: https://www.openssl.org/docs/man1.1.0/man3/BN_mod_exp.html). I've followed the usage example of this function from : https://github.com/openssl/openssl/blob/master/test/bntest.c but still see the following error.
Can someone please tell me if they see anything wrong with what I've done!
I've made sure I copied values correctly and freed them after use.
Thanks in advance!
Update: I've passed in NULL arg as the fifth arg to BN_mod_exp function:
BN_mod_exp(m, c, d, n, NULL);
I still see an error, slightly different to the previous one. Initially I had the fifth arg as NULL but that gave me this error which is why I passed in NULL.
Shown the output after passing NULL below:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff792fd39 in fips_bn_ctx_start (ctx=0x0) at bn_ctx.c:261
261 if(ctx->err_stack || ctx->too_many)
(gdb) bt
#0 0x00007ffff792fd39 in fips_bn_ctx_start (ctx=0x0) at bn_ctx.c:261
#1 0x00007ffff7932a55 in fips_bn_mod_exp_mont (rr=0x0, a=0x6a9b30, p=0x6a9b30, m=0x6a99c0, ctx=0x0, in_mont=0x0) at bn_exp.c:417
#2 0x00007ffff79320f0 in fips_bn_mod_exp (r=0x0, a=0x6a9b30, p=0x6a9b30, m=0x6a99c0, ctx=0x0) at bn_exp.c:237
Datatypes of N, D and ciphertext:
unsigned char N[512];
unsigned char D[512];
unsigned char ciphertext[512];

android hexToByteArray signed to unsigned

I've got the following function to make a conversion from a Hex String to a Byte array. Then, I calculate the Checksum:
private String CalcChecksum (String message) {
/**Get string's bytes*/
//byte[] bytes = DatatypeConverter.parseHexBinary(message.replaceAll("\\s","")).getBytes();
message = message.replaceAll("\\s","");
byte[] bytes = hexToByteArray(message);
byte b_checksum = 0;
for (int byte_index = 0; byte_index < bytes.length; byte_index++) {
b_checksum += bytes[byte_index];
}
int d_checksum = b_checksum; //Convert byte to int(2 byte)
int c2_checksum = 256 - d_checksum; //Hacer complemento a 2
String hexString = Integer.toHexString(c2_checksum); //Convertir el entero (decimal) a hexadecimal
return hexString;
}
public static byte[] hexToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16));
}
return data;
}
Making some test, for example for the hex value "e0", the hexToByteArray is getting the value "-32". So the final returning value in the CalcChecksum is "17a".
What I need is to get unsigned values in the hexToByteArray function. This is because i need to send the Checksum in a hexString to a MCU where the Checksum is calculated with unsigned values, so isntead of get the "-32" value, it gets "224" and the final hex value is "7a" instead of "17a".
i think that doing some kind of conversion like when the byte result is a negative value, do something like 255 + "negative value" + 1. This will convert "-32" into "224".
The problem is that i'm trying to do it, but i'm having some errors making the conversions between bytes, int, etc...
So, how could i do?
For the moment, I think that this can be the solution.
Just including in the CalcChecksum function the next code after int d_checksum = b_checksum;:
if (d_checksum < 0) {
d_checksum = 255 + d_checksum + 1;
}

Cipher Feedback mode c++ implementation

HI I am tiring to implement a CFB with DES. I think i am able to encrypt using with CFB but how can I decrypt?? My main issue is CFB code for encrypting using CFB correct ??. Due to the restriction I have, I am unable to use other library.
for (int i = 0; i < VecMSG.size(); i++) {
DESEncrypt(IV, Key);
stringstream str;
str << bitset < 32 > (V[0]); //First 32 bits convert to string
str << bitset < 32 > (V[1]); //Second 32 bits covert to string and join with the first
VText2 = VText = str.str(); //Store in 2 different strings
VText = VText.substr(0, 5); //Take the most significant first 5 bits in the form of
str.str("");
bitset < 2 > mybits(VText); //covert to bits
bitset < 2 > mybits2(VecMSG[i]); //covert plaintext bits from string to bits
str << (mybits ^= mybits2); //XOR with and convert to string
VecCipher.push_back(str.str()); //Store in a different vector
str.str("");
VText2 = VText2.substr(5) + VecCipher[i]; //Remove the first 5 bits and join ciphertext to the end
V[0] = (unsigned int)VText2.substr(0,32).c_str();
V[1] = (unsigned int)VText2.substr(32).c_str();
}

Encrypt the message NEED HELP by translating the letters into numbers..answer is UTTQ CTOA...how?

Encrypt the message NEED HELP by translating the letters into numbers, applying the
encryption function f (p) = (3p + 7) mod 26, and then translating the numbers back into
letters.
Ans: Encrypted form: UTTQ CTOA.
could someone please explain to me how they got this answer
first you have to assign a number to each letter:
A = 0; B = 1; C = 2 ....
then you apply the function to the numbers you get and convert it back to letters:
N would be 13, so 13 * 3 = 39, + 7 = 46
then mod 26 = 20
converting back, 20 = U
If you do it on all the letters of your sentence you'll have the encrypted form
and here the C# code to do this:
private static string encrypt(string s)
{
char[] tmp = new char[s.Length];
int i = 0;
foreach (char c in s)
{
tmp[i] = (char)((((c - 'A') * 3 + 7) % 26) + 'A');
i++;
}
return new string(tmp);
}
and here your decrypt function (ok this one is messy but works):
private static string decrypt(string s)
{
string res = s;
for (int i = 0; i < 5; i++)
res = encrypt(res);
return res;
}

Resources