Skip to content

Commit

Permalink
feat: starting work on AES-128 (#32)
Browse files Browse the repository at this point in the history
* aes comments

* vanilla aes start

* Base the key_size based on number of rounds

* Removed unused comment

* Clarified the math for key_size

* rounds 13 -> 9, and some comments

---------

Co-authored-by: KaiGeffen <geffenkai@gmail.com>
  • Loading branch information
0xJepsen and KaiGeffen authored Aug 10, 2024
1 parent 74a3562 commit d18e42f
Show file tree
Hide file tree
Showing 30 changed files with 737 additions and 26 deletions.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,40 @@ pragma circom 2.0.0;
include "aes_256_encrypt.circom";
include "helper_functions.circom";

/// AES-256 CTR template
/// We will need to change this to AES-128 CTR
/// Which means we will need to change the aes_256_encrypt.circom to aes_128_encrypt.circom
template AES256CTR(n_bits)
{
var msg_len = n_bits/8;
signal input in[n_bits];
signal input ctr[128];
/// TODO(WJ 2024-08-09): change to correct key bytes
/// Question: 1920 / 8 = 240? why is there key 16 bits less than the input size?
/// niavely it should be 128 * 8 = 1240 bits?
signal input ks[1920];

/// output is amount of input bits
signal output out[n_bits];

/// What is EK?
var EK[128];
var p_index = 0, c_index = 0;
var ctr_t[128] = ctr;
var out_t[msg_len][8];

/// iterator varirables
var i, j, k, l;

/// components for 16 bit blocks
component aes_256_encrypt_1[msg_len/16];
component xor_1[msg_len/16][4][4][32];
component num2bits_1[msg_len/16];
component bits2num_1[msg_len/16];

for(i=0; i<msg_len/16; i++)
{
/// for each block encrypt with aes;
aes_256_encrypt_1[i] = AES256Encrypt();
for(j=0; j<128; j++) aes_256_encrypt_1[i].in[j] <== ctr_t[j];

Expand Down Expand Up @@ -60,4 +72,4 @@ template AES256CTR(n_bits)
for(k=0; k<8; k++) ctr_t[j*8+k] = num2bits_1[i].out[j*8+7-k];
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ template AES_256_CTR_TEST(n_bits_msg, n_bits_aad) {
// populate tag for counter
var TAG[128];
for(i=0; i<128; i++) TAG[i] = CT[msg_len*8+i];

// populate counter
var CTR[128];
for(i=0; i<128; i++) CTR[i] = TAG[i];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,68 +5,93 @@ include "aes_emulation_tables.circom";
include "aes_emulation.circom";
include "helper_functions.circom";


/// AES-256 Encrypt template
/// We will need to change this to AES-128 Encrypt
/// Which means we will need to change the key size to 128
/// And the number of rounds to 10

template AES256Encrypt()
{
signal input in[128];
signal input ks[1920];
signal output out[128];
/// Input is 128 bit of plaintext
signal input in[128]; // ciphertext
/// Key schedule is 1920 bits
signal input ks[1920]; // key bits Not sure why it's 1920 (240 bytes)
/// Output is 128 bit of ciphertext
signal output out[128]; // plaintext

var ks_index = 0;

/// TODO(WJ 2024-08-09): what are these?
/// 4 x 32 mattrix of field elements
var s[4][32], t[4][32];

var i,j,k,l,m;

component xor_1[4][32];

for(i=0; i<4; i++)
/// state initialization, might have to do with key size being 240byte rather 256byte
for(i=0; i<4; i++) // adding round key
{
for(j=0; j<32; j++)
{
xor_1[i][j] = XOR();
xor_1[i][j].a <== in[i*32+j];
xor_1[i][j].b <== ks[(i+ks_index)*32+j];
/// example sequece [[0..31],[33..64]
/// i see so they are 32 bit chunks
/// Then XOR each chuck with parts of the keys
xor_1[i][j].a <== in[i*32+j]; // plaintext
xor_1[i][j].b <== ks[(i+ks_index)*32+j]; // key schedule

s[i][j] = xor_1[i][j].out;
}
}

ks_index += 4;

component xor_2[13][4][3][32];
component bits2num_1[13][4][4];
component num2bits_1[13][4][4];
component xor_3[13][4][32];

for(i=0; i<13; i++)

/// 14 rounds of encryption TODO(WJ 2024-08-09): Change this to 10 rounds to fit AES-128
for(i=0; i<13; i++) // 13 iterations maybe one extra at the end or happened to generate the key above?
{
for(j=0; j<4; j++)
/// 5 steps in each round
/// Step 1: SubBytes
/// Step 2: ShiftRows:
/// Step 3: MixColumns
/// Step 4: AddRoundKeys
///
for(j=0; j<4; j++) // 4 iterations
{
for(k=0; k<4; k++)
for(k=0; k<4; k++) // 4 iterations // COLUMN MIXING ALGORITHM
{
/// initialize trace space for 13x4x4 uses of bits2num and num2bit
bits2num_1[i][j][k] = Bits2Num(8);
num2bits_1[i][j][k] = Num2Bits(32);
/// 0 - 3 based on sum of index j and k
/// grabbing 1 x 32 bit row from state (top to bottom)
var s_tmp[32] = s[(j+k)%4];

/// big endian indexing through the bits to num
for(l=0; l<8; l++) bits2num_1[i][j][k].in[l] <== s_tmp[k*8+7-l];

/// I think this is the sbox lookup, not sure any more
num2bits_1[i][j][k].in <-- emulated_aesenc_enc_table(k, bits2num_1[i][j][k].out);

if(k==0)
if(k==0) // first row unchanged (not shifted)
{
for(l=0; l<4; l++)
{
for(m=0; m<8; m++)
{
{ // setting up one part of a xor
xor_2[i][j][k][l*8+m] = XOR();
xor_2[i][j][k][l*8+m].a <== num2bits_1[i][j][k].out[l*8+7-m];
}
}
}
else if(k<3)
else if(k<3) // 2nd, 3rd rows are shifted by 1, 2 respectively (clever indexing here is how they do this)
{
for(l=0; l<4; l++)
for(l=0; l<4; l++) // 4
{
for(m=0; m<8; m++)
for(m=0; m<8; m++) // 8 -> 32 bits = 1 row of state
{
xor_2[i][j][k-1][l*8+m].b <== num2bits_1[i][j][k].out[l*8+7-m];

Expand All @@ -75,6 +100,7 @@ template AES256Encrypt()
}
}
}
/// Thought 1: is this maybe just copying memory?
else
{
for(l=0; l<4; l++)
Expand All @@ -90,7 +116,6 @@ template AES256Encrypt()
}
}
}

for(j=0; j<4; j++)
{
for(l=0; l<32; l++)
Expand All @@ -100,7 +125,7 @@ template AES256Encrypt()
}
}
ks_index += 4;
}
} // end of round

component bits2num_2[16];
var s_bytes[16];
Expand All @@ -115,6 +140,7 @@ template AES256Encrypt()
}
}

/// Row shifting and substitution
component row_shifting = EmulatedAesencRowShifting();
component sub_bytes = EmulatedAesencSubstituteBytes();
for(i=0; i<16; i++) row_shifting.in[i] <== s_bytes[i];
Expand All @@ -134,7 +160,7 @@ template AES256Encrypt()

component xor_4[4][32];

for(i=0; i<4; i++)
for(i=0; i<4; i++) // final key XOR?
{
for(j=0; j<32; j++)
{
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ pragma circom 2.0.0;

include "aes_emulation_tables.circom";

/// template or row shifting
template EmulatedAesencRowShifting()
{

/// Opperating on 16 bits at a time
signal input in[16];
signal output out[16];

Expand All @@ -29,6 +32,8 @@ template EmulatedAesencRowShifting()
for(var i=0; i<16; i++) out[i] <== in[byte_order[i]];
}

/// Template for S-Box using the aes_encoding_rijndael_sbox
/// https://en.wikipedia.org/wiki/Rijndael_S-box
template EmulatedAesencSubstituteBytes()
{
signal input in[16];
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// Copyright © 2022, Electron Labs
pragma circom 2.0.0;

include "./lib_circuits/bitify.circom";
include "./lib_circuits/gates.circom";
include "./lib_circuits/comparators.circom";
include "../lib_circuits/bitify.circom";
include "../lib_circuits/gates.circom";
include "../lib_circuits/comparators.circom";

template BitwiseRightShift(n, r) {
signal input in[n];
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit d18e42f

Please sign in to comment.