S Lazy-H
  • Home
  • About
  • Posts
  • Contact
  • Slide Rules
  • A Biker’s Tale

Casual Cryptography Using R, Part 3

ciphers
R Programming
Author

Sam Hutchins

Published

March 20, 2024

Well, this post carries on in the vein of this first post and this second post, but simplifies to the point where only the Curve25519 (Diffe-Hellman) encryption is noted, and covers a different aspect of the same.

In those posts, there was a separate level of obfuscation added to the program and it only covered symmetric encryption. This post will simplify the process and introduce asymmetric encryption.

In the other posts, symmetric encryption was used as in this code snippet:

safer::save_object(z,conn=fileName,key=pass) # encrypt and save

What is the difference between asymmetric and symmetric encryption?

  • Asymmetric or public key cryptography is the form of encryption that involves using public and private keys for encryption and decryption. In asymmetric encryption, the sender uses the public key to encode the information in a non-readable form, which can only be decrypted or read with a secret key. In sending encrypted data from the public key scheme, the receiver needs a secret key to access the encrypted data.
  • Symmetric encryption, also dubbed single key encryption, is the type of encryption where a single key can be used to encrypt and decrypt information. In this form of encryption, the receiver uses an agreed shared secret key to decrypt the encrypted data.

The symmetric key can be either a string or a raw object/vector. For asymmetric encryption, another element is required as so:

encrypt_object(object, key = "pass", pkey = NULL, ascii = FALSE)

In this case, both the key (private) and pkey (public) must be a raw object/vector. To make the process easier, we will generate both the private and public keys at the same time using keypair() instead of keygen() as below:

Code
library(safer)
alice <- keypair() #keypair(seed=NULL) for random seed
bob <- keypair() #keypair(seed=NULL) for random seed

The safer library also loads the sodium library, which does all the heavy lifting. The above code will generate a structure that looks similar to this:

List of 3
 $ public_key : raw [1:32] c1 de e7 1d ...
 $ private_key: raw [1:32] 75 b3 b8 ff ...
 $ seed       : raw [1:32] 5e 50 2a c1 ...

Note the format of the two keys as raw, which is the required format for asymmetric encryption. As the seed=NULL, a random seed is produced each time the keypair() function is executed. So, we now have a private and public key in raw format like this, respectively:

 [1] 75 b3 b8 ff 40 90 a0 33 94 63 22 e5 68 87 e3 62 1d ec c5 2f bc 9f 29 bf 60 c8 d7 95 e5 3c 1f 51
 [1] c1 de e7 1d c6 9b 13 fc aa f0 ed e0 7a 04 1b 68 85 7b 38 75 ac 5a a6 a9 20 72 ea 7a a9 f2 6b 21

Now we have the keys we need for the asymmetric encryption. Let’s say we have the following phrase:

Code
a <- "This is the phrase we wish to encrypt."

We now take that variable (a) and encrypt it into another string variable, where Bob is sending to Alice, like so:

Code
b <- encrypt_string(a,key=bob$private_key,pkey=alice$public_key)

This produces the following Curve25519 encrypted variable:

[1] "gFlduni98lOEB9hzi7Nc1nzkF37UQ4wKC05rnEmZEsOMdxFRXHG61ClftSxpOE/bkZAd5yvU"

One thing to note is if Bob attempts to use only his keys to decrypt, an error is generated, and the phrase is not decrypted. This means both the sender and recipient each must use their respective keys. This is demonstrated as below, where Alice decrypts the message as such:

Code
c <- decrypt_string(b,key=alice$private_key,pkey=bob$public_key)

Now, can Bob decrypt his own message? To check, we reverse the keys as so:

Code
d <- decrypt_string(b,key=bob$private_key,pkey=alice$public_key)

This should show both decryptions (c, d) as the same phrase:

[1] "This is the phrase we wish to encrypt."
[1] "This is the phrase we wish to encrypt."

Now we know the process was successful. The short R program to do the above is:

Code
library(safer) # 'sodium' interface for encryption/decryption

# generate private and public asymmetric key pairs for Bob and Alice
alice <- keypair() #keypair(seed=NULL) for random seed
bob <- keypair() #keypair(seed=NULL) for random seed

a <- readline(prompt="Enter phrase: ") # text string input

b <- encrypt_string(a,key=bob$private_key,pkey=alice$public_key)
writeLines("\nEncrypted string by Bob:")
show(b)

c <- decrypt_string(b,key=alice$private_key,pkey=bob$public_key)
writeLines("\nDecrypted string by Alice:")
show(c)

d <- decrypt_string(b,key=bob$private_key,pkey=alice$public_key)
writeLines("\nDecrypted string by Bob:")
show(d)

Loading the safer library automatically loads the accessed sodium library functions as noted earlier. Note the readline() function to input the phrase you wish to encrypt. Of course, Bob and Alice would do their part at their own location, and only distribute the public part of their respective keys.

And that about wraps up this little series on cryptography. Have a great day, and I pray you know Jesus as your personal Lord and Savior!

© S Lazy-H 2019 - 2025