YULL ENCRYPTION PRO


Operational Notes

File Handling with Yull Console

There are two ways Yull handles files; Yull options file and Command Line

There are four file parameters in the Options file:

ENCRYPTSOURCEDIR= 
DECRYPTOUTPUTDIR= 
DECRYPTSOURCEDIR= 
ENCRYPTOUTPUTDIR= 

If these are used, then Yull will attempt to construct a Fully Qualfied Path from the simple file name on the command line, like this:

ENCRYPTSOURCEDIR=R:\documents\

yull in=resume.docx @yulloptions

With these two elements, Yull will look for "resume.docx" in R:\documents. So R:\documents\resume.docx will be the Fully Qualfied Path name of the file.

If the "in" file on the Yull command line contains a folder or a drive specification, Yull will ignore the corresponding file parameter in the Options file.

So regardless of the value of ENCRYPTSOURCEDIR, if the command line is like this: yull in=documents\resume.docx @yulloptions

Yull will just look for resume.docx within the documents folder relative to where Yull.exe was invoked. So if you are on:

R:\tools

and use

yull in=documents\resume.docx @yulloptions

Yull will look for resume.docx in r:\tools\documents

If the "in" parameter is a directory + a file spec (even a wildcard spec), like:

yull in=source\resume.docx

yull will look for the file resume.docx the "source" subfolder in the same folder from which Yull was invoked (not from where Yull is located).

To recap:

If the "in" parameter is just a file spec like "resume.docx", then Yull will look for it in ENCRYPTSOURCEDIR\resume.docx.

If the "in" parameter is a FQP or a folder+file, Yull will look for it relative to where Yull is invoked.

Because of Yull's options and what it does, one needs to be certain that the filespec passed to Yull is accurate. Relative paths or folders should be avoided.

Use Fully qualified paths and be safe.

Here's an example:

s:\files>yull in=temp\aaa @yulloptions
**********************************************************
Yull Data Encryption Version 1.47.0
 Copyright (c) 2010-2016 Ronald Gans. All rights reserved.
**********************************************************
Yull is starting: 9/27/2016 9:01:48 PM
Command line: in=temp\aaa @yulloptions
Error parsing input variables: Could not find a part of the path 's:\files\source\TEMP\AAA'.

Because the Yulloptions file has ENCRYPTSOURCEDIR=s:\files\source

s:\files>yull in=s:\files\temp\aaa @yulloptions
**********************************************************
Yull Data Encryption Version 1.47.0
 Copyright (c) 2010-2016 Ronald Gans. All rights reserved.
**********************************************************
Yull is starting: 9/27/2016 9:02:07 PM
Command line: in=s:\files\temp\aaa @yulloptions
.....................
Encrypting s:\files\TEMP\AAA to s:\files\output\AAA 

Because the "in" parameter is a fully qualified path name.

Issue with Console Version 1.42

While you cannot encrypt or decrypt a 0-length file, the GUI app YullG handles this gracefully. The console app does not. Instead, it will abend with a cryptic message of "Object variable not set". This will be fixed in the next version.

Issue with Version 1.40

When using YullG, if you DO NOT preview the files but simply input a path into the SOURCE field and attempt to ENCRYPT or DECRYPT the app will emit an exception:

If you press Continue you can continue on without issue but you must use the preview grid.

This issue is fixed in 1.42, which is now available on the Try It Out page. 1.42 is NOT compatible with previous versions, so files encrypted with 1.40 cannot be decrypted with 1.42 and visa versa.

Again, this does not impact encryption and the work around is to use the preview grids.

New for Version 1.40 (August 21, 2015)

I added new encryption routines for Version 140 (both vesions Yull Console and YullG will be at the same version from now on).

These routines take a byte array, separate out the upper and lower nibbles and do ROL and ROR on the nibbles.

Normally, ROR and ROR (ROtate Right and ROtate Left), rotate the bits in a byte one position left or right. So, if the byte is:

197 (0xC4, 0b11000101)

and you perform ROL on it, the resulting byte is

0b10001011 or 139 in decimal.

Here's the original byte;

11000101

SO, rotating the bits one position left gets you:

10001011

Where the leftmost 1 swings around to the first position (the rightmost position) and everything else moves one position left.

ROR is the opposite.

ROL and ROR are heavily used in encryption routines because they are reversible.

BUT one thing about them is that they operate on the entire byte. Now, a byte, which is 8 bits, can be viewed as two nibbles, an upper and a lower one. Each nibble is 4 bits.

SO, for our byte 197:

11000101

The upper nibble is 1100 and the lower nibble is 0101.

Joined together they are 1100 0101.

My new routines operate on these independently. So, newROL for this byte is:

1001 1010.

The leftmost 1 for the upper nibble 1100 becomes the right most position of the nibble and everything else moves left one, to get 1001. And the same with the lower nibble. Then the byte is reassembled. This decouples encryption from dealing with whole bytes, opening up a much larger encryption space.

Another routine does ROL on the Upper Nibble and ROL on the Lower and visa versa for decryption.

Here is the code for this:

void doROLOnArray(ref byte[] inB)
{
    byte m; byte top; byte bottom;
    for (int i = 0; i < inB.Length; i++)
    {
        bottom = (byte)(inB[i] & 15);
        top = (byte)(inB[i] & 240);
        m = 0;
        if ((bottom & (1 << 3)) != 0) m = 1;
        bottom = (byte)(((bottom << 1) | m) & 15);

        m = 0;
        if ((top & (1 << 7)) != 0) m = 1;
        m = (byte)(m << 4);
        top = (byte)(((top<< 1) | m) & 240);
        inB[i] = (byte)(top | bottom);
    }

}


doROROnArray is similar, of course.

the point of it is to manipulate arrays of bytes in unpredictable ways. Now what's unpredictable for me might be very predictable for a large computer (or arrays of GPUs, say). But if the data encryption mechanism is decoupled from operating on the byte level, then we have added an enormous level of complexity.

These functions are in some ways inspired by my functions rotateArrayLeftAsBits (and RightAsBits) where an array of bytes is treated as an array of bits, so for that ROR and ROL operate on the array level, not on the byte level.

YullG Menu: Show User Info

This is no longer used. Nothing will happen when you click on that menu setting. It will be eliminated in the next benign release.

YullG Menu: Help->About

This is out of date. It will be fixed in the next benign release.

Yull's Speed

At the PLANK level (which is the fastest pre-set level), YULL encrypted and decrypted a 12288 byte file 928,952 times:

**********************************************************
Yull Data Encryption Version 1.38
 Copyright (c) 2010-2015 Ronald Gans. All rights reserved.
**********************************************************
Yull is starting: 7/26/2015 2:38:07 PM
Command linc: in=256 @yulloptions

....................

Encrypting c:\test\source\256 to C:\Users\MarshaTest\AppData\Local\YullEncryption\encrypts\256.OUT
*****ENCRYPT ENDS********
total number of encrypts=928952
number of encrypts per byte=75
Total RunTime (hours:minutes:seconds:milliseconds)=00:00:00.665
Yull took less than a second to run.
There were 384 reads.
There were a total of 1055 rounds.
Average rounds per read = 2
Approx. Speed per round in milliseconds = 0.6309
File Conversion Speed: Bytes Per Second (approx) = 18460
Yull ends.
Parameters:
Source file=c:\test\source\256
Output file=C:\Users\MarshaTest\AppData\Local\YullEncryption\encrypts\256.OUT
Output Dir=C:\Users\MarshaTest\AppData\Local\YullEncryption\encrypts
Output Dir Decrypt=c:\test\final
Key file=
Key Size=1024
MinRounds=1
MaxRounds=6
Encryption Level: PLANK
MaxBuffSize=35
MinBuffSize=20
OVERWRITEMODE=OVERWRITE
ReadOrder=40
UseDefaultFolder=False
UseDefaultKey=True
Yull Decides Buff Size=True
Yull Decides Dummy Data=True
Please note these parameters as they are needed to decrypt the file.

From this we can see that YULL put the file 256, which is in the SAMPLESOURCEFILES folder through 928,952 encrypt routines and that took 0.665 seconds to complete.
This is the options file used:

ENCRYPTSOURCEDIR=C:\test\source
DECRYPTOUTPUTDIR="C:\test\final
LEVEL=PLANK
YULLDECIDESDUMMYDATA
USEDEFAULTKEY
--ASKFORKEY
--key=X:\keys\myfirstkey.mmm
--THE KEY CAN BE NAMED ANYTHING
--ASKFORPDATA
USEDEFAULTFOLDERFORENCRYPTOUTPUT
USEDEFAULTFOLDERFORDECRYPTSOURCE
OVERWRITEMODE=OVERWRITE
ENCRYPTEXTENSION=OUT
MAXROUNDS=6
MINROUNDS=1
MAXBUFFSIZE=35
MINBUFFSIZE=20
READORDER=40
DATAGRIDDEFAULT=INCLUDE
PDATA=IT'S GREAT TO KNOW YOUR DATA IS SAFE

As there were 384 reads, there was a ROUNDSARRAY containing 384 elements, each one is a ROUND value between 1 and 6 (which are the values in MAXROUNDS and MINROUNDS).
Unlike AES (Rijndael), which hsa a fixed set of rounds (14) ,Yull uses a variable number. This adds greatly to the difficulty (read: impossibility) of force decrypting a Yull file. You would have to try most (or all) of the different variations of numbers between 1 and 6, 384 times. How big a number is that? 6.4577*10298 OR:
645773392949699126328439748662074583024741
0998717229789957502979735322525075668960411
1626460390641633159649534609612137904713841
2574828248928774492836510605926581205117350
93840882656958557833491103105045282969599547
2333731580987199457291770438912472752234178
18878146964206925075429654641156550557696


I'm pretty sure this is a ridiculously large number. Yet another way Yull's encryption puts it way beyond brute force decryption.

Note also the output size of the file 256 is now larger:

 Directory of C:\Users\MarshaTest\AppData\Local\YullEncryption\encrypts

07/26/2015  02:38 PM            23,424 256.OUT
               1 File(s)         23,424 bytes
               0 Dir(s)  819,763,044,352 bytes free

So YULL added 11,136 bytes of dummy data. This dummy data (which is created by a call to RNGCryptoServices) is sprinkled throughout each of the reads. Let's change the MAXBUFFSIZE to 100. So now when we run the same YULL command linc:
Yull IN=256 @yulloptions

we get:


**********************************************************
Yull Data Encryption Version 1.38
 Copyright (c) 2010-2015 Ronald Gans. All rights reserved.
**********************************************************
Yull is starting: 7/26/2015 1:55:08 PM
Command linc: in=256 @yulloptions

....................

Encrypting c:\test\source\256 to C:\Users\MarshaTest\AppData\Local\YullEncryption\encrypts\256.OUT
*****ENCRYPT ENDS********
total number of encrypts=2752505
number of encrypts per byte=223
Total RunTime (hours:minutes:seconds:milliseconds)=00:00:02.146
There were 123 reads.
There were a total of 352 rounds.
Average rounds per read = 2
Approx. Speed per round in milliseconds = 6.0979
File Conversion Speed: Bytes Per Second (approx) = 5724
Yull ends.
Parameters:
Source file=C:\test\source\256
Output file=C:\Users\MarshaTest\AppData\Local\YullEncryption\encrypts\256.OUT
Output Dir=C:\Users\MarshaTest\AppData\Local\YullEncryption\encrypts
Output Dir Decrypt=c:\test\final
Key file=
Key Size=1024
MinRounds=1
MaxRounds=6
Encryption Level: PLANK
MaxBuffSize=100
MinBuffSize=20
OVERWRITEMODE=OVERWRITE
ReadOrder=40
UseDefaultFolder=False
UseDefaultKey=True
Yull Decides Buff Size=True
Yull Decides Dummy Data=True
Please note these parameters as they are needed to decrypt the file.

and we can see now YULL took 2.146 seconds to encrypt the 12288 byte file but there were 2,752,505 encrypts versus the previous 777,125 encrypts. Quite a bit slower but many more encrypts.
If we crank it up to MaxRounds=50, MinRounds=20 (just taking random numbers) and keep the same MAXBUFFER size of 100 we will get this:


**********************************************************
Yull Data Encryption Version 1.38
 Copyright (c) 2010-2015 Ronald Gans. All rights reserved.
**********************************************************
Yull is starting: 7/26/2015 1:59:45 PM
Command linc: in=256 @yulloptions

....................

Encrypting C:\test\source\256 to C:\Users\MarshaTest\AppData\Local\YullEncryption\encrypts\256.OUT
*****ENCRYPT ENDS********
total number of encrypts=41001525
number of encrypts per byte=3336
Total RunTime (hours:minutes:seconds:milliseconds)=00:00:33.994
There were 123 reads.
There were a total of 5109 rounds.
Average rounds per read = 41
Approx. Speed per round in milliseconds = 6.6539
File Conversion Speed: Bytes Per Second (approx) = 361
Yull ends.
Parameters:
Source file=C:\test\source\256
Output file=C:\Users\MarshaTest\AppData\Local\YullEncryption\encrypts\256.OUT
Output Dir=C:\Users\MarshaTest\AppData\Local\YullEncryption\encrypts
Output Dir Decrypt=c:\test\final
Key file=
Key Size=1024
MinRounds=20
MaxRounds=50
Encryption Level: PLANK
MaxBuffSize=100
MinBuffSize=20
OVERWRITEMODE=OVERWRITE
ReadOrder=40
UseDefaultFolder=False
UseDefaultKey=True
Yull Decides Buff Size=True
Yull Decides Dummy Data=True
Please note these parameters as they are needed to decrypt the file.

and we can see now YULL takes 33.994 seconds but does 41,001,525 encrypts.
How much is too much? I don't know. My gut tells me that PLANK is sufficient for everything but if you really want to be 99.9999999% safe, use MAX (one of the presets) or do your own.
Play around with YULL. See what you get.

Programmatically outputting data as Excel

I had to write a program which saved data as Excel files. I looked around a lot and perhaps just didn't do the right searches because I just couldn't find anything in one place. So I amalgamated this from various sites. I hope it is useful. It is for a C# program:

using Microsoft.Office.Interop.Excel;


add it as a reference as well

(or the Microsoft.Excel 14.0 (or 12.0) object library

And declare these variables:

Microsoft.Office.Interop.Excel.Worksheet excelWorkSheet; Microsoft.Office.Interop.Excel.Workbook excelWorkBook;

I used a function to instantiate the new Excel objects, but you don't have to:


private bool createExcel()
{
    try
    {
        Microsoft.Office.Interop.Excel.Application excelApplication =
			new Microsoft.Office.Interop.Excel.Application();
        excelWorkBook = excelApplication.Workbooks.Add();
        excelWorkSheet = excelWorkBook.Sheets.Add();
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error creating Excel objects: " + ex.Message);
        return false;

    }
    return true;
}


Bold the headers (which are typically the first row):


excelWorkSheet.Cells[1, 1].EntireRow.Font.Bold = true;


create your delimited list of header cells:


for (int i = 0; i<columnCount; i++)
{
   excelWorkSheet.Cells[1, i + 1] = getHeaderData(i); //just a suggestion;
}


and the same with the regular data:


for (int i 0; i<columnCount; i++)
{
   excelWorkSheet.Cells[rowCount, i + 1] = getColumnData(i); //just a suggestion;
}

and when done:


private void btnSaveAs_Click_1(object sender, EventArgs e)
{
  using (SaveFileDialog dialog = new SaveFileDialog())
     {
         dialog.Filter = "xlsx files (*.xlsx)|*.xlsx|All files (*.*)|*.*";
         dialog.FilterIndex = 2;
         dialog.RestoreDirectory = true;
	try {
         if (dialog.ShowDialog() == DialogResult.OK)
		 {
             Cursor.Current = Cursors.WaitCursor;
             excelWorkSheet.SaveAs(dialog.FileName);
			 //if you don't close it off and get rid of
			 //the Excel object, the saved file will be
			 //locked (in use) and you will have
			 //Excel.EXEs on your system
             excelWorkBook.Close();
             excelWorkSheet = null;
             Cursor.Current = Cursors.Default;
         }
	} //end try
	catch (Exception ex)
    {
        MessageBox.Show("Error saving Excel file: " + ex.Message);
        return;
    }

  } //end using

} //end function


And that's it. It's that easy!