knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.path = "man/figures/README-",
  out.width = "100%"
)

HOQCenc is an R package containing routines for encryption and decryption of character strings and files. The main function is xcode that encrypts an input string by executing a number of operations (specified by argument trans) when argument ed='e'. When ed='d' is specified decryption will be done by executing the operations in reversed order.

Installation

You can install this version from GitHub with:

# install.packages("devtools")
devtools::install_github("HanOostdijk/HOQCenc",build_vignettes=TRUE) 
library(HOQCenc)

Example

In the Details section more examples are given and some background. In this first example we show:

key <- "1VerySecretKey"
message1 <- "Line 1 of a two-line message!\nAs expected a second line."
message2 <- "Line 1 of a two-line message.\nAs expected a second line." 

(s <- xcode(message1,key=key,ed='e',trans='cscvp')) # encrypt message1
xcode(s,key=key,ed='d',trans='cscvp')               # show result of decryption
xcode(message2,key=key,ed='e',trans='cscvp')        # encrypt message2

Details {#details}

Key and alphabet

When we specify key='' an ordered set is constructed consisting of the lower and upper case letters, the digits 0 till 9 and the space and the # character. This ordered set is our 'alphabet': all operations will work only with this set with the exception of the e operation that converts our standard symbols to this new alphabet.
When we use the key 1VerySecretKey the characters in this key will be inserted in this set before the others so that the following ordered set will be constructed:

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] "1"  "V"  "e"  "r"  "y"  "S"  "c"  "t" 
[2,] "K"  "a"  "b"  "d"  "f"  "g"  "h"  "i" 
[3,] "j"  "k"  "l"  "m"  "n"  "o"  "p"  "q" 
[4,] "s"  "u"  "v"  "w"  "x"  "z"  "A"  "B" 
[5,] "C"  "D"  "E"  "F"  "G"  "H"  "I"  "J" 
[6,] "L"  "M"  "N"  "O"  "P"  "Q"  "R"  "T" 
[7,] "U"  "W"  "X"  "Y"  "Z"  "0"  "2"  "3" 
[8,] "4"  "5"  "6"  "7"  "8"  "9"  " "  "#" 

In almost all operations (but not the e, s and f operation) this 'alphabet' will be used.

Operations {#operations}

The following operations are defined (we describe only what happens in case of encryption because for decryption the reversed action is performed):

The encryption characteristics of these operations are the following:

So it is advised to combine several options as e.g. done in the example below

key <- "1VerySecretKey"

# small differences in text lead to similar outcomes with simple trans
xcode("abcdefghijklmnopqrstuwvxyz",key=key,ed='e',trans='p')
xcode("1bcdefghijklmnopqrstuwvxyz",key=key,ed='e',trans='p')
xcode("abcdefghijklmnopqrstuwvxy1",key=key,ed='e',trans='p')
xcode("ABabcdefghijklmnopqrstuwvxy1",key=key,ed='e',trans='p')

# small differences in text lead to unrelated outcomes with complex trans
xcode("abcdefghijklmnopqrstuwvxyz",key=key,ed='e',trans='cscvp')
xcode("1bcdefghijklmnopqrstuwvxyz",key=key,ed='e',trans='cscvp')
xcode("abcdefghijklmnopqrstuwvxy1",key=key,ed='e',trans='cscvp')
xcode("ABabcdefghijklmnopqrstuwvxy1",key=key,ed='e',trans='cscvp')

The e operation

Most of the operations used in the xcode function are working only at the 64 characters of our ordered set of the lower and upper case letters, the digits 0 till 9 and the space and the # character. The e operation:

Because the e operation is necessary for most cases it is always prefixed to the list of operations that is specified in the trans argument.

xcode('Deze #!',key='',ed='e',trans='')
xcode('example!',key='',ed='e',trans='')
xcode('example!',key='',ed='e',trans='p')
xcode('example!',key='',ed='e',trans='a')

Only when the noe argument is explicitly set to TRUE this is not done.

xcode('example!',key='',ed='e',trans='',noe=T)
xcode('example!',key='',ed='e',trans='p',noe=T)
xcode('example ',key='',ed='e',trans='p',noe=T) # but with space instead of !
xcode('example ',key='',ed='e',trans='a',noe=T)

The p operation

With the p operation a Playfair transformation is done that acts on pairs of characters. With key='' the following 'alphabet' is used

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] "a"  "b"  "c"  "d"  "e"  "f"  "g"  "h" 
[2,] "i"  "j"  "k"  "l"  "m"  "n"  "o"  "p" 
[3,] "q"  "r"  "s"  "t"  "u"  "v"  "w"  "x" 
[4,] "y"  "z"  "A"  "B"  "C"  "D"  "E"  "F" 
[5,] "G"  "H"  "I"  "J"  "K"  "L"  "M"  "N" 
[6,] "O"  "P"  "Q"  "R"  "S"  "T"  "U"  "V" 
[7,] "W"  "X"  "Y"  "Z"  "0"  "1"  "2"  "3" 
[8,] "4"  "5"  "6"  "7"  "8"  "9"  " "  "#" 

and therefore "ex" is converted to "hu' because 'h' and 'u' lie on the opposite corner of the rectangle though 'e' and 'x'. Special cases:

Advantage of Playfair is that a frequency distribution on character level makes little sense because the method works on pairs of characters.

xcode('example ',key='',ed='e',trans='p',noe=T)
xcode("hueiimg8",key='',ed='d',trans='p',noe=T)

The s and f operations

The s (shuffle) operation shuffles the characters in such a way that 0123456789abcdef is translated to 0f2d4b6987a5c3e1 and the f (flip) operation flips the characters in such a way that 0123456789abcdef is translated to fedcba9876543210.

xcode('0123456789abcdef',key='',ed='e',trans='s',noe=T)
xcode('0123456789abcdef',key='',ed='e',trans='f',noe=T)

The v operation

The v (Vigenère) operation shifts the i-th character a number of places in the 'alphabet'. That number is determined by the position of the i-th letter in the 'alphabet'. In the first example the 'alphabet' is ABCabcdef ... and therefore the shifts for the letters 'a', 'b' etc. are 4, 5 etc. resulting in '4', '6' etc. In the second example the 'alphabet' is abcdef ... and therefore the shifts for the letters 'a', 'b' etc. are 1, 2 etc. resulting in '1', '3' etc.

xcode('0123456789abcdef',key='ABC',ed='e',trans='v',noe=T)
xcode('0123456789abcdef',key='abc',ed='e',trans='v',noe=T)

The c operation

The c operation shifts the first character a number of places in the 'alphabet'. That number is again determined by the position of the first letter in the 'alphabet'. In the first example the 'alphabet' is abcdef ... and therefore the shifts for the letter 'a' is 1 resulting in '1' . The shift for the next position is therefore determined by the position of '1' in the 'alphabet' and that is 44. So the next position (the '1') is shifted by 44 positions in the 'alphabet' resulting in 'R' . And so on ... The main advantage of this method is that the encryption of a character is determined by all of its predecessors. The weak point is that only the position of the 'a' in the 'alphabet' has to be guessed or tried by brute force and this is very easy. So this method should never be used on its own.

xcode('0123456789abcdef',key='abc',ed='e',trans='c',noe=T)

The a operation

The a uses the digest::AES function with the mode='ECB' method. The method works in blocks of 16 characters: blocks that are identical with the exception of one character will be encrypted to very unrelated results. However if a block occurs more than once, each block is identically encrypted. So also this method should never be used on its own.

xcode('0123456789abcdef',key='abc',ed='e',trans='a',noe=T)
xcode('1123456789abcdef',key='abc',ed='e',trans='a',noe=T)
xcode('0123456789abcdee',key='abc',ed='e',trans='a',noe=T)

xcode('0123456789abcdef0123456789abcdef',key='abc',ed='e',trans='a',noe=T)

The h operation

The h uses the Hill transformation. The method works in blocks of 4 characters: blocks that are identical with the exception of one character will be encrypted to very unrelated results. Each character is transformed to its rank in the ordered set. A linear transformation is then done on these four numbers by applying a matrix multiplication and the resulting numbers (modulo 64) are used as rank numbers in the ordered set to determine the four output characters. The matrix used is a fixed matrix. The examples show (again) that it is necessary to combine this operation with other ones to make it more safe.

xcode('0123456789abcdef',key='abc',ed='e',trans='h',noe=T)
xcode('1123456789abcdef',key='abc',ed='e',trans='h',noe=T)
xcode('0123456789abcdee',key='abc',ed='e',trans='h',noe=T)

xcode('0123456789abcdef0123456789abcdef',key='abc',ed='e',trans='h',noe=T)

Encrypting raw vectors

The xcode function can also handle raw vectors

text     <- "this will be raw text"
(textraw  <- charToRaw(text))
(s<-xcode(textraw,key='abc',ed='e',trans='cscp'))
(s<-xcode(s,key='abc',ed='d',trans='cscp'))
rawToChar(s) 

Reading and writing files

To ease reading and writing of files with and without encryption four functions are defined:

To demonstrate the various possibilities we first define text to work on and generate the name of a test file:

text     <- "This is a 21st century example of an English text."
textraw  <- charToRaw(text)

tfile <- tempfile(pattern = "file", tmpdir = tempdir(), fileext = ".txt")

Example of working with asci text (remember that the encrypted text is always asci):

# write asci with encoding
write_enc_ascfile(text,tfile,encode=T)
# read without decoding
(read_enc_ascfile(tfile,decode=F))
# read with decoding
(read_enc_ascfile(tfile,decode=T))

Again asci text but now using the binary mode functions:

# write asci in binary mode with encoding
write_enc_binfile(text,tfile,encode=T)
# read without decoding and no raw -> character conversion
(read_enc_binfile(tfile,decode=F,raw2char=F))
# read without decoding and with raw -> character conversion
(read_enc_binfile(tfile,decode=F,raw2char=T))
# read with decoding and no raw -> character conversion
(read_enc_binfile(tfile,decode=T))

Now with binary data and therefore the write_enc_binfile and read_enc_binfile functions must be used:

# write raw text binary mode with encoding
write_enc_binfile(textraw,tfile,encode=T)
# read without decoding and no raw -> character conversion
(read_enc_binfile(tfile,decode=F,raw2char=F))
# read without decoding and with raw -> character conversion
(read_enc_binfile(tfile,decode=F,raw2char=T))
# read with decoding and no raw -> character conversion
(read_enc_binfile(tfile,decode=T,raw2char=F))
# read with decoding and with raw -> character conversion
(read_enc_binfile(tfile,decode=T,raw2char=T))


HanOostdijk/HOQCenc documentation built on Dec. 17, 2021, 10:28 p.m.