Blog Entry © Monday, March 9, 2026, by James Pate Williams, Jr. Testing a Translation of My C# Advanced Encryption Standard (AES) to the Programming Language C

Blog Entry © Friday, February 27, 2026, by James Pate Williams, Jr., C Pseudorandom Bit Generators and Four Statistical Tests

Blog Entry (c) Monday, February 24, 2026, by James Pate Williams, Jr. TDES Verification

I wrote my Triple-DES C source code a number of years ago. Today, I verified my Cipher Block Chaining version using the NIST online reference document:

CBC-TDES (Encryption)

Key1 is
01234567 89ABCDEF
Key2 is
23456789 ABCDEF01
Key3 is
456789AB CDEF0123
IV is
F69F2445 DF4F9B17

Block #1
Plaintext 6BC1BEE2 2E409F96
InputBlock 9D5E9AA7 F10F0481
OutputBlock 2079C3D5 3AA763E1
Ciphertext 2079C3D5 3AA763E1

Block #2
Plaintext E93D7E11 7393172A
InputBlock C944BDC4 493474CB
OutputBlock 93B79E25 69AB5262
Ciphertext 93B79E25 69AB5262

Block #3
Plaintext AE2D8A57 1E03AC9C
InputBlock 3D9A1472 77A8FEFE
OutputBlock 51657048 1F25B50F
Ciphertext 51657048 1F25B50F

Block #4
Plaintext 9EB76FAC 45AF8E51
InputBlock CFD21FE4 5A8A3B5E
OutputBlock 73C0BDA8 5C8E0DA7
Ciphertext 73C0BDA8 5C8E0DA7

CBC-TDES (Decryption)

Key1 is
01234567 89ABCDEF
Key2 is
23456789 ABCDEF01
Key3 is
456789AB CDEF0123
IV is
F69F2445 DF4F9B17

Block #1
Ciphertext 2079C3D5 3AA763E1
InputBlock 2079C3D5 3AA763E1
OutputBlock 9D5E9AA7 F10F0481
Plaintext 6BC1BEE2 2E409F96
Block #2
Ciphertext 93B79E25 69AB5262
InputBlock 93B79E25 69AB5262
OutputBlock C944BDC4 493474CB
Plaintext E93D7E11 7393172A
Block #3
Ciphertext 51657048 1F25B50F
InputBlock 51657048 1F25B50F
OutputBlock 3D9A1472 77A8FEFE
Plaintext AE2D8A57 1E03AC9C
Block #4
Ciphertext 73C0BDA8 5C8E0DA7
InputBlock 73C0BDA8 5C8E0DA7
OutputBlock CFD21FE4 5A8A3B5E
Plaintext 9EB76FAC 45AF8E51

D:\Triple_DES_CBC\Triple_DES_CBC\Release\Triple_DES_CBC.exe (process 43728) exited with code 0 (0x0).
Press any key to close this window . . .

Blog Entry (c) Sunday, February 22, 2026, by James Pate Williams, Jr. A Little Test C Program Source Code and Results

Back in February 2016 I created a C# program to test my bit-orientated implementation of SHA-3 using the algorithms in NIST FIPS 202. Today I finished my C implementation, and I created a Win32 64-bit test application. Reference: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf

See Algorithm 10 of FIPS 202:

Enter a hex string
a32e
Enter n
14
H = 10 3 2 14
S = 1 1 0 0 0 1 0 1 0 1 1 1 0 1

D:\FIPS202Algorithm10\x64\Release\FIPS202Algorithm10.exe (process 38932) exited with code 0 (0x0).
Press any key to close this window . . .

// FIPS202Algorithm10.c
// James Pate Williams, Jr.
// Copyright Sunday, February
// 22, 2026 See FIPS 202
// Algorithm 10

#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char gHexStr[2048];
int gBinaryStr[8];
int gH[2048], gh[1024];
int gT[8 * 1024 + 7];
int gTruncN[1024];
int gS[1024];

static void ToBinary(int hex)
{
    int count = 0;

    while (hex > 0)
    {
        gBinaryStr[count++] = hex & 1;
        hex >>= 1;
    }

    for (int i = count; i < 8; i++)
        gBinaryStr[i] = 0;
}

static void Trunc(int X[], int n)
{
    for (int i = 0; i < n; i++)
        gTruncN[i] = X[i];
}

static void Algorithm10(int m, int n)
{
    for (int i = 0; i < m; i++)
    {
        gh[i] = 16 * gH[2 * i] + gH[2 * i + 1];
    }

    for (int i = 0; i < m; i++)
    {
        ToBinary(gh[i]);

        for (int j = 0; j < 8; j++)
            gT[8 * i + j] = gBinaryStr[j];
    }

    Trunc(gT, n);

    for (int i = 0; i < n; i++)
        gS[i] = gTruncN[i];
}

static void HexToBinary(int m, int n)
{
    int m2 = m + m;

    printf_s("H = ");

    for (int i = 0; i < m2; i++)
    {
        int digit = 0;

        if (gHexStr[i] >= '0' && gHexStr[i] <= '9')
            digit = gHexStr[i] - '0';
        else if (gHexStr[i] >= 'a' && gHexStr[i] <= 'f')
            digit = gHexStr[i] - 'a' + 10;
        else if (gHexStr[i] >= 'A' && gHexStr[i] <= 'F')
            digit = gHexStr[i] - 'A' + 10;

        gH[i] = digit;

        printf_s("% d ", gH[i]);
    }

    printf_s("\r\n");
    Algorithm10(m, n);
}

int main()
{
    int n = 0;
    printf_s("Enter a hex string\r\n");
    scanf_s("%s", gHexStr, 128);
    printf_s("Enter n\r\n");
    scanf_s("%d", &n);
    int m = (int)strlen(gHexStr);

    HexToBinary(m / 2, n);

    printf_s("S = ");

    for (int i = 0; i < n; i++)
        printf_s("%d ", gS[i]);

    printf_s("\r\n");
    return 0;
}

Blog Entry © Friday, February 20, 2026, by James Pate Williams, Jr., Wayback C# SHA-3 Test Application Results

Preliminary NIST FIPS 203 Results © Monday, February 16, 2026, by James Pate Williams, Jr. C Implementation

References:

  1. Module-Lattice-Based Key-Encapsulation Mechanism Standard
  2. Number-theoretic transform (integer DFT)
  3. chap2.pdf Chapter 2 of the Handbook of Applied Cryptography

I have two versions of the code using C long integers and another variant using Professor Emeritus Arjen K. Lenstra’s C Free Large Integer Package (lip).

Testing NIST BitRev
Primitive root = 17
Length = 7
n = 256
n / 2 = 128
q = 3329
BitRev(0) = 1
BitRev(1) = 1729
BitRev(2) = 2580
BitRev(3) = 3289
BitRev(4) = 2642
BitRev(5) = 630
BitRev(6) = 1897
BitRev(7) = 848
Testing NIST NTT
f[0] = 4 fhat[0] = 257
f[1] = 1 fhat[1] = 95
f[2] = 4 fhat[2] = 308
f[3] = 2 fhat[3] = 232
f[4] = 1 fhat[4] = 90
f[5] = 3 fhat[5] = 657
f[6] = 5 fhat[6] = 34
f[7] = 6 fhat[7] = 366
Testing NIST NTT^-1
fhat[0] = 257 copf[0] = 4
fhat[1] = 95 copf[1] = 1
fhat[2] = 308 copf[2] = 4
fhat[3] = 232 copf[3] = 2
fhat[4] = 90 copf[4] = 1
fhat[5] = 657 copf[5] = 3
fhat[6] = 34 copf[6] = 5
fhat[7] = 366 copf[7] = 6
Testing NIST NTT Multiplication
g[0] = 6 ghat[0] = 518 copg[0] = 6
g[1] = 1 ghat[1] = 661 copg[1] = 1
g[2] = 8 ghat[2] = 492 copg[2] = 8
g[3] = 0 ghat[3] = 339 copg[3] = 0
g[4] = 3 ghat[4] = 583 copg[4] = 3
g[5] = 3 ghat[5] = 91 copg[5] = 3
g[6] = 9 ghat[6] = 450 copg[6] = 9
g[7] = 8 ghat[7] = 259 copg[7] = 8
fhat[0] = 257 ghat[0] = 518 hhat[0] = 102
fhat[1] = 95 ghat[1] = 661 hhat[1] = 362
fhat[2] = 308 ghat[2] = 492 hhat[2] = 392
fhat[3] = 232 ghat[3] = 339 hhat[3] = 504
fhat[4] = 90 ghat[4] = 583 hhat[4] = 150
fhat[5] = 657 ghat[5] = 91 hhat[5] = 208
fhat[6] = 34 ghat[6] = 450 hhat[6] = 196
fhat[7] = 366 ghat[7] = 259 hhat[7] = 545

D:\NISTFIPS203\x64\Release\NISTFIPS203.exe (process 26656) exited with code 0 (0x0).
Press any key to close this window . . .

Blog Entry Wednesday, July 10, 2024, © James Pate Williams, Jr. My Dual Interests in Cryptography and Number Theory

I became fascinated with secret key cryptography as a child. Later, as an adult, in around 1979, I started creating crude symmetric cryptographic algorithms. I became further enthralled with cryptography and number theory in 1996 upon reading Applied CryptographySecond EditionProtocolsAlgorithmsand Source Code in C by Bruce Schneier and later the Handbook of Applied Cryptography by Alfred J. Menezes, Paul C. van Oorschot, and Scott A. Vanstone. After implementing many of the algorithms in both tomes, I communicated my results to two of the authors namely Bruce Schneier and Professor Alfred J. Menezes. In 1997 I developed a website devoted to constraint satisfaction problems and their solutions, cryptography, and number theory. I posted legal C and C++ source code. Professor Menezes advertised my website along with his treatise. See the following blurb:

In the spirit of my twin scientific infatuations, I offer yet another C integer factoring implementation utilizing the Free Large Integer Package (known more widely as lip) which was created by Arjen K. Lenstra (now a Professor Emeritus). This implementation includes Henri Cohen’s Trial Division algorithm, the Brent-Cohen-Pollard rho method, the Cohen-Pollard p – 1 stage 1 method, and the Lenstra lip Elliptic Curve Method. If I can get the proper authorization, I will later post the source code.

total time required for initialization: 0.056000 seconds
enter number below:
2^111+2
== Menu ==
1 Trial Division
2 Pollard-Brent-Cohen rho
3 p - 1 Pollard-Cohen
4 Lenstra's Elliptic Curve Method
5 Pollard-Lenstra rho
1
2596148429267413814265248164610050
number is composite
factors:
total time required factoring: 0.014000 seconds:
2
5 ^ 2
41
397
2113
enter number below:
0
total time required for initialization: 0.056000 seconds
enter number below:
2^111+2
== Menu ==
1 Trial Division
2 Pollard-Brent-Cohen rho
3 p - 1 Pollard-Cohen
4 Lenstra's Elliptic Curve Method
5 Pollard-Lenstra rho
2
2596148429267413814265248164610050
number is composite
factors:
total time required factoring: 1.531000 seconds:
2
5 ^ 2
41
397
2113
415878438361
3630105520141
enter number below:
0
total time required for initialization: 0.055000 seconds
enter number below:
2^111+2
== Menu ==
1 Trial Division
2 Pollard-Brent-Cohen rho
3 p - 1 Pollard-Cohen
4 Lenstra's Elliptic Curve Method
5 Pollard-Lenstra rho
3
2596148429267413814265248164610050
number is composite
factors:
total time required factoring: 0.066000 seconds:
2
5 ^ 2
41
838861
415878438361
3630105520141
enter number below:
0
total time required for initialization: 0.056000 seconds
enter number below:
2^111+2
== Menu ==
1 Trial Division
2 Pollard-Brent-Cohen rho
3 p - 1 Pollard-Cohen
4 Lenstra's Elliptic Curve Method
5 Pollard-Lenstra rho
4
2596148429267413814265248164610050
number is composite
factors:
total time required factoring: 0.013000 seconds:
2
5
205
838861
415878438361
3630105520141
enter number below:
0

Five Stream Ciphers Created from Five Pseudorandom Number Generators Built Using the Tests of FIPS 140-1 by James Pate Williams, BA, BS, MSwE, PhD

The five pseudorandom number generators are:

  1. Triple-AES based ANSI X9.17 PRNG
  2. Triple-DES based ANSI x9.17 PRNG
  3. RSA based PRNG
  4. Micali-Schnorr PRNG
  5. Blum-Blum-Shub PRNG

Five stream ciphers were created using 1 to 5. Screenshots of the C# application follow:

sc aessc dessc rsasc mssc bbs

The pass phrase optimally should consist of 147 ASCII characters. If the number of pass phrase ASCII characters is less than 147 then more random ASCII characters are added using the standard C# pseudorandom number generator seeded with the parameter named Seed. The user defined parameter k is used by RSA, Micali-Schnorr, and Blum-Blum-Shub pseudorandom number generators. It is the approximate bit length of the large composite number composed of two large probable prime numbers. The real key lengths of all the stream ciphers is about 1024-bits for 1, 3, 4, and 5 and 296-bits for 2. I’d strongly suggest using 1 and/or 5.

Tests of Six Pseudorandom Number Generators (PRNGs) Using the Now Superseded FIPS 140-1 by James Pate Williams, Jr. BA, BS, MSwE, PhD

This blog explores six pseudorandom number generators which are enumerated as follows:

  1. Standard C# PRNG
  2. Triple-AES PRNG
  3. Triple-DES PRNG
  4. RSA Based PRNG
  5. Micali-Schnorr PRNG
  6. Blum-Blum-Shub PRNG

PT 00PT 01PT 02PT 03PT 04PT 05

Here is the order in terms of run-times from the fastest to the slowest: 1, 2, 3, 6, 5, 4.

 

PRNG Tests Using the Now Superseded FIPS 140-1 by James Pate Williams, Jr., BA, BS, MSwE, PhD

This blog post is dedicated to Section 5.3.1 ANSI X9.17 generator page 173 with 5.11 Algorithm and Section 5.4.4 Five basic tests pages 181-183 especially 5.32 Note of the Handbook of Applied Cryptography by Alfred J. Menezes, Paul C. van Oorschot, and Scott A. Vanstone. I developed a PRNG test program for three PRNGs namely, Triple-AES, Triple-DES, and the C# built-in PRNG.

Each time an algorithm is run a randomly generated key is generated based on the time of day and the C# built-in PRNG with a key space of 2147483647 possible seeds. Triple-AES requires a 147 7-bit ASCII key and part of a similar key is used to construct the 296-bit Triple-DES key material. Now onto my C# Windows Forms application’s screenshots.

PRNGTests AES Key

PRNG Tests AES

PRNG Tests DES Key

PRNG Tests DES

PRNG Tests C#

PRNG Tests Other AES

PRNG Tests Other AES Data

PRNG Tests Other DES Key

PRNG Tests Other DES Data

PRNG Tests Other C#

We use the five basic statistical tests of Chapter 5 Section 5.4.4 which are as follows:

  1. Monobit Test also Known as the Single Bit Frequency Test
  2. Serial Test also as the Two-Bit Frequency of Occurrence Test
  3. Poker Test
  4. Runs Test (Not to be confused with Montezuma’s Revenge)
  5. Autocorrelation Test

Below is a copy of a recent email of mine concerning Secret Key Exchange or Distribution:

The linchpin and point of greatest vulnerability in any secret key cryptographic system is the key exchange mechanism. Now suppose that we are living in a post quantum computer world. This means that traditional public key cryptosystems such as RSA (integer factorization problem based) and elliptic curve public key cryptography (discrete logarithm problem based) are effectively broken. That implies that any public key based cryptographic key exchange is compromised over communication channels where Eve, the classical eavesdropper, is listening in on the key exchange between Alice and Bob. Quantum cryptography over fiber optic channels allows the communication endpoints to detect the eavesdropper and thus abort a potentially compromised key exchange. However, quantum cryptography is not readily available everywhere on the vast Internet. The rest of this email missive is devoted to other more exotic means of secret key exchange.

Human to human key exchange is optimal provided that all human beings in the loop are trustworthy. A good way to exchange secret keys is via a diplomatic courier with a diplomatic pouch and the key bits are concealed by a steganographic means.

Now suppose an adversary of an English speaking and reading country has two agents or human intelligence operatives that have infiltrated the country. Further both agents have the same 1024-bit seeded pseudorandom number generator-based stream cipher on their desktops and/or laptops for secure communications. That means they must somehow pass 147 secret 7-bit printable ASCII characters of information between one another for each quasi-one-time pad message. Each character represents 7 bits of the key and there are 5 bits left over after construction of each key. Also, suppose an actual face-to-face meeting between the two spies is inadvisable. Enter the text based social media or library book code. Now suppose the two spies are connected to one another via Facebook but are afraid to use text messaging for direct key exchange or clandestine communication. The solution is to use a shared Facebook page of text to construct the secret key. One spy shares a Facebook post containing at least 147 English characters and the other spy looks up the post. Both spies cut and paste the first 147 English characters of the post into a key constructing application. Voila, now both spies can communicate using their handy dandy stream cipher and email and/or cell phone text messaging of encrypted data in the form of three-digit decimal numbers. An alternative key exchange could be by the classic and readily available book code. Assume both spies have access to the same library, but not concurrent access. Both somehow agree to go and copy 147 characters from the same book in the library’s reference section. They write down the passage and take it home to enter the text into the key generator. Again, we have a means of clandestine key exchange.