#include <Arduino.h>
void add32(uint8_t *r, const uint8_t *a, const uint8_t *b);
void sub(uint8_t *r, const uint8_t *a, const uint8_t *b, uint8_t *borrow);
void mul32_mod25519(const uint8_t* a, const uint8_t* b, uint8_t* result);
void mod25519(uint8_t* result, const uint8_t* tempResult);
void mod25519_exchange_32(uint8_t* r, const uint8_t* original, uint8_t borrow);
void exchange(uint8_t *r, const uint8_t *original, uint8_t borrow);
void add32_mod25519(const uint8_t* a, const uint8_t* b, uint8_t* result);
void sub32_mod25519(const uint8_t *a, const uint8_t *b, uint8_t *result);
void twosComplement(uint8_t *num);
void cswap(uint8_t* swap, uint8_t* value1, uint8_t* value0, uint8_t* p);
void fe25519_invert(uint8_t *result, const uint8_t *input);
const uint8_t p[32] = {0xED, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}; // Define the prime number ((2^55)-19) using little endain method
void setup()
{
Serial.begin(9600); //-------------------> you have to activate this if you want to implement this code in a real Microcontroller
uint8_t Xg[32] = {0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t Zg[32] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t X1[32] = {0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t Z1[32] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t X0[32] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t Z0[32] = {0x00};
uint8_t x_Affine[32] = {0x00};
uint8_t scalar[32] = {0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t temp_scalar[32] = {0x00};
uint8_t A24[32] = {0x42, 0xDB, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t swap[32] = {0x00};
uint8_t current_bit[32] = {0x00};
uint8_t A[32] = {0x00};
uint8_t AA[32] = {0x00};
uint8_t B[32] = {0x00};
uint8_t BB[32] = {0x00};
uint8_t E[32] = {0x00};
uint8_t C[32] = {0x00};
uint8_t CC[32] = {0x00};
uint8_t D[32] = {0x00};
uint8_t DD[32] = {0x00};
uint8_t DA[32] = {0x00};
uint8_t CB[32] = {0x00};
uint8_t addDACB[32] = {0x00};
uint8_t subDACB[32] = {0x00};
uint8_t A24E[32] = {0x00};
memcpy(temp_scalar, scalar, 32);
for (int i = 254; i >= 0; i--) // note when i=255, this means that we use 256-bits (32 byte) to represent the scalar
{
Serial.print(" ============================================================> Start of Iteration number = ");
Serial.println(i);
memcpy(scalar, temp_scalar, 32); // The idea of this is to reset the vaule of scalar to original value with each iteration, so the code can shift it i number to the right
// shifting the scalar to get the current bit ----------> for (int j = 32; j > 0; j--) {current_bit [j] = (scalar [j] >> i) & 1;}
//-----> The for j loop is for doing -------> current_bit = (scalar >> i) & 1;----------------------------------------------------------------------------------------------------------------------
for (int k = i; k > 0; k--) //Note that we want the Most Significant bit of the Most Significant Byte (The first bit from the left), So we shifted the scalar 255 times, 254 times, 253 times, ... etc.
{
uint8_t carry = 0;
for (int j = 31; j >= 0; j--)
{
uint8_t temp = scalar[j];
scalar[j] = (carry << 7) | (scalar[j] >> 1);
carry = temp;
}
}
current_bit[0] = scalar[0] & 0x01; //Note that we want the Most Significant bit al the Most Significant Byte (The first bit from the left), So we shifted the scalar 255 times, 254 times, 253 times, ... etc.
Serial.print("=======> current_bit = ");
for (int j = 31; j >= 0; j--)
{
Serial.print(current_bit[j], HEX);
Serial.print(" ");
}
Serial.println("");
//------------------------swap = swap ^ current_bit;------------------------------------------------------------------------------------------
for (int j = 31; j >= 0; j--)
{
swap[j] = swap[j] ^ current_bit[j];
}
Serial.println("---------------------------------------Points Before the cswap:--------------------------------------------------------");
Serial.print("R0 = ( ");
for (int j = 31; j >= 0; j--)
{
Serial.print(X0[j], HEX);
Serial.print(" ");
}
Serial.print(": ");
for (int j = 31; j >= 0; j--)
{
Serial.print(Z0[j], HEX);
Serial.print(" ");
}
Serial.println(")");
Serial.print("R1 = ( ");
for (int j = 31; j >= 0; j--)
{
Serial.print(X1[j], HEX);
Serial.print(" ");
}
Serial.print(": ");
for (int j = 31; j >= 0; j--)
{
Serial.print(Z1[j], HEX);
Serial.print(" ");
}
Serial.println(")");
cswap(swap, X1, X0, p);
cswap(swap, Z1, Z0, p);
Serial.print("-----> swap = ");
for (int j = 31; j >= 0; j--)
{
Serial.print(swap[j], BIN);
Serial.print(" ");
}
Serial.println(" ");
Serial.println(" ---------------------------------------Points After the cswap:-------------------------------------------------------- ");
Serial.print("R0 = ( ");
for (int j = 31; j >= 0; j--)
{
Serial.print(X0[j], HEX);
Serial.print(" ");
}
Serial.print(": ");
for (int j = 31; j >= 0; j--)
{
Serial.print(Z0[j], HEX);
Serial.print(" ");
}
Serial.println(")");
Serial.print("R1 = ( ");
for (int j = 31; j >= 0; j--)
{
Serial.print(X1[j], HEX);
Serial.print(" ");
}
Serial.print(": ");
for (int j = 31; j >= 0; j--)
{
Serial.print(Z1[j], HEX);
Serial.print(" ");
}
Serial.println(")");
//----------------swap = current_bit
memcpy(swap, current_bit, 32);
add32_mod25519(X0, Z0, A); //----> A = (X0 + Z0) % p;
mul32_mod25519(A, A, AA); // AA = (A*A) % p;
sub32_mod25519(X0, Z0, B); // B = (X0 - Z0) % p;
mul32_mod25519(B, B, BB); // BB = (B*B) % p;
sub32_mod25519(AA, BB, E); // E = (AA - BB)%p;
add32_mod25519(X1, Z1, C);// C = (X1 + Z1) % p;
mul32_mod25519(C, C, CC); // CC = (C*C) % p;
sub32_mod25519(X1, Z1, D); // D = (X1 - Z1) % p;
mul32_mod25519(D, D, DD); // DD = (D*D) % p;
mul32_mod25519(D, A, DA); // DA = (D*A) % p;
mul32_mod25519(C, B, CB); // CB = (C*B) % p;
add32_mod25519(DA, CB, addDACB);
mul32_mod25519(addDACB, addDACB, X1);
sub32_mod25519(DA, CB, subDACB);
mul32_mod25519(subDACB, subDACB, subDACB);
mul32_mod25519(Xg, subDACB, Z1);
mul32_mod25519(AA, BB, X0); // X0 = (AA * BB) % p;
//Z0 = (E * (BB + (A24 * E))) % p;
mul32_mod25519(A24, E, A24E); //A24E = (A24 * E) % p;
add32_mod25519(BB, A24E, Z0); //Z0 = (BB + A24E) % p;
mul32_mod25519(E, Z0, Z0); //Z0 = (E * Z0) % p;
// Print the points over the Serial screen
Serial.println(" -------> Print the points over the Serial screen :");
Serial.print("R0 = (");
for (int j = 31; j >= 0; j--)
{
Serial.print(X0[j], HEX);
Serial.print(" ");
}
Serial.print(" : ");
for (int j = 31; j >= 0; j--)
{
Serial.print(Z0[j], HEX);
Serial.print(" ");
}
Serial.println(")");
Serial.print("R1 = (");
for (int j = 31; j >= 0; j--)
{
Serial.print(X1[j], HEX);
Serial.print(" ");
}
Serial.print(" : ");
for (int j = 31; j >= 0; j--)
{
Serial.print(Z1[j], HEX);
Serial.print(" ");
}
Serial.println(")");
Serial.print(" ============================================================> END Iteration number = ");
Serial.println(i);
}
// --------------------------------
Serial.println("*************************************** The Last Exchange, by Gods will *************************************** ");
//--------------- X1, X0 = cswap(swap, X1, X0, p) -----------------
cswap(swap, X1, X0, p); // ValuePair Exchange1 = cswap(swap, X1, X0, p);
// --------------- Z1, Z0 = cswap(swap, Z1, Z0, p) -----------------
cswap(swap, Z1, Z0, p); // ValuePair Exchange2 = cswap(swap, Z1, Z0, p);
// --------------------------------
// --------------------------------
Serial.println("---------- ");
Serial.println("Points After the last cswap: ");
Serial.println(" ");
Serial.print("R0 = (");
for (int j = 31; j >= 0; j--)
{
Serial.print(X0[j], HEX);
Serial.print(" ");
}
Serial.print(" : ");
for (int j = 31; j >= 0; j--)
{
Serial.print(Z0[j], HEX);
Serial.print(" ");
}
Serial.println(" ");
Serial.println(" ");
Serial.print("R1 = (");
for (int j = 31; j >= 0; j--)
{
Serial.print(X1[j], HEX);
Serial.print(" ");
}
Serial.print(" : ");
for (int j = 31; j >= 0; j--)
{
Serial.print(Z1[j], HEX);
Serial.print(" ");
}
Serial.println(" ");
Serial.println(" ");
//--------------------------------
Serial.print("Z0 before inverinting its bytes to save them using Little endain method = ");
for (int j = 31; j >= 0; j--)
{
Serial.print(Z0[j], HEX);
Serial.print(" ");
}
Serial.println(" ");
fe25519_invert(Z0, Z0);
Serial.print("The multiplicative inverse of Z0 =");
for (int j = 31; j >= 0; j--)
{
Serial.print(Z0[j], HEX);
Serial.print(" ");
}
Serial.println(" ");
mul32_mod25519(X0, Z0, x_Affine); // Perform multiplication modulo
Serial.print(" x_Affine = ");
for (int j = 31; j >= 0; j--)
{
Serial.print(x_Affine[j], HEX);
Serial.print(" ");
}
Serial.println(" ");
Serial.print("The result point is R0 = (");
for (int j = 31; j >= 0; j--)
{
Serial.print(X0[j], HEX);
Serial.print(" ");
}
Serial.print(" : ");
for (int j = 31; j >= 0; j--)
{
Serial.print(Z0[j], HEX);
Serial.print(" ");
}
Serial.println(" ");
Serial.println(" ");
}
void loop()
{
// put your main code here, to run repeatedly:
}
//===================================================================================Functions============================================================================================================
// Function for conditional swap
void cswap(uint8_t* swap, uint8_t* value1, uint8_t* value0, uint8_t* p)
{
uint8_t dummy[32]; //dummy should be 32 byte because if you note that all the add, sub, or multiplication done with modulo operation at the end
sub32_mod25519(value1, value0, dummy); // ----> dummy = value1 - value0;
mul32_mod25519(swap, dummy, dummy); // -----> dummy = swap * (value1 - value0) = swap * dummy;
sub32_mod25519(value1, dummy, value1); // ----------> value1 = (value1 - dummy) %p
add32_mod25519(value0, dummy, value0); // -----> value0 = (value0 + dummy) %p
return (value1, value0); // ----> return (value1, value2)
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------
// Function to add two 32-byte numbers
void add32(uint8_t *r, const uint8_t *a, const uint8_t *b)
{
uint16_t carry = 0;
for (int i = 0; i < 32; i++)
{
uint16_t sum = (uint16_t)a[i] + (uint16_t)b[i] + carry;
r[i] = sum & 0xFF; // Store the lower 8 bits in the result
carry = (sum >> 8) & 1; // Carry is the upper 8 bits
}
r[32] = carry; // Store the final carry in the next byte
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------
// Multiplication of two 32-byte numbers followed by modulus
void mul32_mod25519(const uint8_t* a, const uint8_t* b, uint8_t* result)
{
int carry = 0;
uint8_t tempResult[64] = {0}; // Temporary result array to store 512-bit number after multiplication
for (int i = 0; i < 32; ++i)
{
int carry = 0;
for (int j = 0; j < 32; ++j)
{
int index = i + j;
long product = (long)a[i] * (long)b[j] + (long)tempResult[index] + (long)carry;
tempResult[index] = product & 0xFF;
carry = (product >> 8) & 0xFF;
}
tempResult[i + 32] = (carry + tempResult[i + 32]) & 0xFF;
}
uint8_t Result_mod[32] = {0};
mod25519(Result_mod, tempResult);
memcpy(result, Result_mod, 32);
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
// Multiply the high part by 38
void mod25519_multiply_32(uint8_t* result, const uint8_t* a, uint8_t b, uint16_t& carry)
{
for (int i = 0; i < 32; i++)
{
uint16_t mul = a[i] * b + carry;
result[i] = mul & 0xFF;
carry = mul >> 8;
}
}
void mod25519_add_32(uint8_t* result, const uint8_t* a, uint16_t& carry)
{
for (int i = 0; i < 32; i++)
{
uint32_t sum = result[i] + a[i] + carry;
result[i] = sum & 0xFF;
carry = sum >> 8;
}
}
void mod25519_sub_32(uint8_t* r, const uint8_t* a, const uint8_t* b, uint8_t* borrow)
{
*borrow = 0;
for (int i = 0; i < 32; i++)
{
uint16_t temp = (uint16_t)a[i] - b[i] - *borrow;
r[i] = temp & 0xFF;
*borrow = (temp >> 8) & 1;
}
}
// Exchange numbers consist of 32 byte
void mod25519_exchange_32(uint8_t* r, const uint8_t* original, uint8_t borrow)
{
uint8_t mask = -borrow;
uint8_t inv_mask = ~mask;
for (int i = 0; i < 32; i++)
{
r[i] = (r[i] & inv_mask) | (original[i] & mask);
}
}
//-------------------------------------------------------Modulo-mod25519 function---------------------------------------------------------------------------------------------------
void mod25519(uint8_t* result, const uint8_t* tempResult)
{
uint8_t high[32];
uint8_t low[32];
uint8_t mod25519_originalResult[32];
uint8_t borrow = 0;
uint16_t carry = 0;
// Divide tempResult into high and low parts
memcpy(high, tempResult + 32, 32);
memcpy(low, tempResult, 32);
// Multiply high part by 38
mod25519_multiply_32(result, high, 38, carry);
// Propagate carry
for (int k = 0; k < 2; k++)
{
uint32_t carryProduct = carry * 38;
uint32_t tempSum = 0;
for (int i = 0; i < 32; i++)
{
tempSum += result[i] + (carryProduct & 0xFF);
result[i] = tempSum & 0xFF;
carryProduct >>= 8;
tempSum >>= 8;
}
carry = tempSum;
}
// Add low part
mod25519_add_32(result, low, carry);
// Final carry propagation
uint32_t carryProduct = carry * 38;
carry = 0;
for (int i = 0; i < 32; i++)
{
uint32_t sum = result[i] + (carryProduct & 0xFF) + carry;
result[i] = sum & 0xFF;
carryProduct >>= 8;
carry = sum >> 8;
}
// Save original result
memcpy(mod25519_originalResult, result, 32);
// Perform subtraction and exchange to ensure result is within range
mod25519_sub_32(result, result, p, &borrow);
mod25519_exchange_32(result, mod25519_originalResult, borrow);
memcpy(mod25519_originalResult, result, 32);
mod25519_sub_32(result, result, p, &borrow);
mod25519_exchange_32(result, mod25519_originalResult, borrow);
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------
// Exchange numbers consist of 64 byte
void exchange(uint8_t *r, const uint8_t *original, uint8_t borrow)
{
uint8_t mask = -borrow; // All 1s if borrow is 1, all 0s otherwise
uint8_t inv_mask = ~mask; // Inverse of the mask
for (int i = 0; i < 64; i++)
{
r[i] = (r[i] & mask) | (original[i] & inv_mask);
}
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------
// Addition followed by modulus operation
void add32_mod25519(const uint8_t* a, const uint8_t* b, uint8_t* result)
{
uint8_t tempResult[64] = {0}; // Temporary array to store 256-bit number after addition
add32(tempResult, a, b);
mod25519(result, tempResult);
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------
// New subtraction process with additional steps for 64-byte numbers
void sub32_mod25519(const uint8_t *a, const uint8_t *b, uint8_t *result)
{
uint8_t tempResult[64] = {0};
uint8_t borrow1;
// Extend the 32-byte arrays to 64-byte arrays
uint8_t extendedA[64] = {0};
uint8_t extendedB[64] = {0};
memcpy(extendedA, a, 32);
memcpy(extendedB, b, 32);
sub(tempResult, extendedA, extendedB, &borrow1); // Subtract the numbers
uint8_t originalResult[64];
memcpy(originalResult, tempResult, 64);
twosComplement(tempResult); // If negative, get the positive equivalent
uint8_t subtracter[64] = {0xED, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t borrow2;
sub(tempResult, subtracter, tempResult, &borrow2);
exchange(tempResult, originalResult, borrow1);
mod25519(result, tempResult);
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------
// Function for two's complement
void twosComplement(uint8_t *num)
{
uint8_t carry = 1;
for (int i = 0; i < 64; i++)
{
num[i] = ~num[i]; // Invert bits
uint16_t temp = num[i] + carry;
num[i] = temp & 0xFF;
carry = (temp >> 8) & 1;
}
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//Subtraction Function
void sub(uint8_t *r, const uint8_t *a, const uint8_t *b, uint8_t *borrow)
{
*borrow = 0;
for (int i = 0; i < 64; i++)
{
uint16_t temp = (uint16_t)a[i] - b[i] - *borrow;
r[i] = temp & 0xFF;
*borrow = (temp >> 8) & 1;
}
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------
// Function to find multiplicative inverse
void fe25519_invert(uint8_t *result, const uint8_t *input)
{
uint8_t x_exp_2[32], x_exp_11[32], x2_exp_10[32], x2_exp_50[32], x2_exp_100[32], x2_exp_200[32], temp0[32], temp1[32];
unsigned char i;
mul32_mod25519(input, input, x_exp_2); // 1.x_exp_2 = input^2
Serial.print("1. x_exp_2 = input^2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(x_exp_2[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(x_exp_2, x_exp_2, temp1); // 2.temp1 = x_exp_2^2 = input^4
Serial.print("2. temp1 = x_exp_2^2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp1[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp1, temp1, temp0); // 3.temp0 = temp1^2 = input^8
Serial.print("3. temp0 = temp1^2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp0[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp0, input, x2_exp_10); // 4. x2_exp_10 = temp0 * input
Serial.print("4. x2_exp_10 = temp0 * input = ");
for (int i = 0; i < 32; i++)
{
Serial.print(x2_exp_10[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(x2_exp_10, x_exp_2, x_exp_11); // 5. x_exp_11 = x2_exp_10 * x_exp_2
Serial.print("5. x_exp_11 = x2_exp_10 * x_exp_2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(x_exp_11[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(x_exp_11, x_exp_11, temp0); // 6. temp0 = x_exp_11 ^ 2
Serial.print("6. temp0 = x_exp_11 ^ 2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp0[i], HEX); Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp0, x2_exp_10, x2_exp_10); // 7. x2_exp_10 = temp0 * x2_exp_10
Serial.print("7. x2_exp_10 = temp0 * x2_exp_10 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(x2_exp_10[i], HEX); Serial.print(" ");
}
Serial.println();
mul32_mod25519(x2_exp_10, x2_exp_10, temp0); // 8. temp0 = x2_exp_10 ^ 2
Serial.print("8. temp0 = x2_exp_10^2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp0[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp0, temp0, temp1); // 9. temp1 = temp0^2
Serial.print("9. temp1 = temp0^2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp1[i], HEX); Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp1, temp1, temp0); // 10. temp0 = temp1^2
Serial.print("10. temp0 = temp1^2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp0[i], HEX); Serial.print(" ");
}
Serial.println();
//----------------------------------
mul32_mod25519(temp0, temp0, temp1); // 11. temp1 = temp0^2
Serial.print("11. temp1 = temp0^2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp1[i], HEX); Serial.print(" ");
}
Serial.println();
//----------------------------------
mul32_mod25519(temp1, temp1, temp0); // 12. temp0 = temp1^2
Serial.print("12. temp0 = temp1^2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp0[i], HEX); Serial.print(" ");
}
Serial.println();
//--------------------------------
mul32_mod25519(temp0, x2_exp_10, x2_exp_10); // 13. x2_exp_10 = temp0 * x2_exp_10
Serial.print("13. x2_exp_10: ");
for (int i = 0; i < 32; i++)
{
Serial.print(x2_exp_10[i], HEX); Serial.print(" ");
}
Serial.println();
//----------------------------------
mul32_mod25519(x2_exp_10, x2_exp_10, temp0); // 14. temp0 = x2_exp_10^2
Serial.print("14. temp0 (x2_exp_10^2): ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp0[i], HEX);
Serial.print(" ");
}
Serial.println();
//----------------------------------
mul32_mod25519(temp0, temp0, temp1); // 15. temp1 = temp0^2
Serial.print("15. temp1 (temp0^2): ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp1[i], HEX);
Serial.print(" ");
}
Serial.println();
Serial.println(" =======================================> Start of the first for loop : ");
for (i = 2; i < 10; i += 2)
{
mul32_mod25519(temp1, temp1, temp0); // 16. temp0 = temp1^2
Serial.print("16. temp0 (iteration ");
Serial.print(i);
Serial.print("): ");
for (int j = 0; j < 32; j++)
{
Serial.print(temp0[j], HEX); Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp0, temp0, temp1); // 16. temp1 = temp0^2
Serial.print("16. temp1 (iteration ");
Serial.print(i);
Serial.print("): ");
for (int j = 0; j < 32; j++)
{
Serial.print(temp1[j], HEX); Serial.print(" ");
}
Serial.println();
}
Serial.println(" =======================================> End of the first for loop : ");
mul32_mod25519(temp1, x2_exp_10, x2_exp_50); // 17. x2_exp_50 = temp1 * x2_exp_10
Serial.print("17. x2_exp_50: ");
for (int i = 0; i < 32; i++)
{
Serial.print(x2_exp_50[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(x2_exp_50, x2_exp_50, temp0); // 18. temp0 = x2_exp_50^2
Serial.print("18. temp0 = x2_exp_50^2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp0[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp0, temp0, temp1); // 19. temp1 = temp0^2
Serial.print("19. temp1 = temp0^2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp1[i], HEX);
Serial.print(" ");
}
Serial.println();
Serial.println(" =======================================> Start of the Second for loop : ");
for (i = 2; i < 20; i += 2)
{
mul32_mod25519(temp1, temp1, temp0); // 20. temp0 = temp1^2
Serial.print("20. temp0 (iteration ");
Serial.print(i);
Serial.print("): ");
for (int j = 0; j < 32; j++)
{
Serial.print(temp0[j], HEX); Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp0, temp0, temp1); // 20. temp1 = temp0 ^2
Serial.print("20. temp1 (iteration ");
Serial.print(i);
Serial.print("): ");
for (int j = 0; j < 32; j++)
{
Serial.print(temp1[j], HEX);
Serial.print(" ");
}
Serial.println();
}
Serial.println(" =======================================> End of the Second for loop ========= ");
mul32_mod25519(temp1, x2_exp_50, temp0); // 21. temp0 = temp1 * x2_exp_50
Serial.print("21. x2_exp_100: ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp0[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp0, temp0, temp1); // 22. temp1 = temp0^2
Serial.print("22. temp1 = temp0^2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp1[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp1, temp1, temp0); // 23. temp1 = temp0^2
Serial.print("23. temp0 = temp1^2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp0[i], HEX);
Serial.print(" ");
}
Serial.println();
Serial.println(" =======================================> Start of the third for loop : ");
for (i = 2; i < 10; i += 2)
{
mul32_mod25519(temp0, temp0, temp1); // 24. temp1 = temp0^2
Serial.print("24. temp1 (iteration ");
Serial.print(i);
Serial.print("): ");
for (int j = 0; j < 32; j++)
{
Serial.print(temp1[j], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp1, temp1, temp0); // 24. temp0 = temp1^2
Serial.print("24. temp0 (iteration ");
Serial.print(i);
Serial.print("): ");
for (int j = 0; j < 32; j++)
{
Serial.print(temp0[j], HEX);
Serial.print(" ");
}
Serial.println();
}
Serial.println(" =======================================> End of the third for loop ========= ");
mul32_mod25519(temp0, x2_exp_10, x2_exp_50); // 25. x2_exp_50 = temp0 * x2_exp_10
Serial.print("25. x2_exp_50 = temp0 * x2_exp_10 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(x2_exp_50[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(x2_exp_50, x2_exp_50, temp0); // 26. temp0 = x2_exp_50 ^ 2
Serial.print("26. temp0 = x2_exp_10 ^ 2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp0[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp0, temp0, temp1); // 27. temp1 = temp0 ^ 2
Serial.print("27. temp1 = temp0 ^ 2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp1[i], HEX);
Serial.print(" ");
}
Serial.println();
Serial.println(" =======================================> Start of the fourth for loop : ");
for (i = 2; i < 50; i += 2)
{
mul32_mod25519(temp1, temp1, temp0); // 28. temp0 = temp1 ^ 2
Serial.print("28. temp0 (iteration ");
Serial.print(i);
Serial.print("): ");
for (int j = 0; j < 32; j++)
{
Serial.print(temp0[j], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp0, temp0, temp1); // 28. temp1 = temp0 ^ 2
Serial.print("28. temp1 (iteration ");
Serial.print(i);
Serial.print("): ");
for (int j = 0; j < 32; j++)
{
Serial.print(temp1[j], HEX); Serial.print(" ");
}
Serial.println();
}
Serial.println(" =======================================> End of the fourth for loop ===============");
mul32_mod25519(temp1, x2_exp_50, x2_exp_100); // 29. x2_exp_100 = temp1 * x2_exp_50
Serial.print("29. x2_exp_100 = temp1 * x2_exp_50 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(x2_exp_100[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(x2_exp_100, x2_exp_100, temp1); // 30. temp1 = x2_exp_100 ^ 2
Serial.print("30. temp1 = x2_exp_100 ^ 2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp1[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp1, temp1, temp0); // 31. temp0 = temp1 ^ 2
Serial.print("31. temp0 = temp1 ^ 2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp0[i], HEX);
Serial.print(" ");
}
Serial.println();
Serial.println(" =======================================> Start of the fifth for loop : ");
for (i = 2; i < 100; i += 2)
{
mul32_mod25519(temp0, temp0, temp1); // 32. temp1 = temp0 ^ 2
Serial.print("32. temp1 (iteration ");
Serial.print(i);
Serial.print("): ");
for (int j = 0; j < 32; j++)
{
Serial.print(temp1[j], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp1, temp1, temp0); // 32. temp0 = temp1 ^ 2
Serial.print("32. temp0 (iteration ");
Serial.print(i);
Serial.print("): ");
for (int j = 0; j < 32; j++)
{
Serial.print(temp0[j], HEX);
Serial.print(" ");
}
Serial.println();
}
Serial.println(" =======================================> End of the fifth for loop ========= ");
mul32_mod25519(temp0, x2_exp_100, temp1); // 33. temp1 = temp0 * x2_exp_100
Serial.print("33. temp1 = temp0 * x2_exp_100 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp1[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp1, temp1, temp0); // 34. temp0 = temp1 ^2
Serial.print("34. temp0 = temp1 ^2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp0[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp0, temp0, temp1); // 35. temp1 = temp0 ^2
Serial.print("35. temp1 = temp0 ^2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp1[i], HEX);
Serial.print(" ");
}
Serial.println();
Serial.println(" =======================================> Start of the 6'th for loop : ");
for (i = 2; i < 50; i += 2)
{
mul32_mod25519(temp1, temp1, temp0); // 36. temp0 = temp1 ^2
Serial.print("36. temp0 (iteration ");
Serial.print(i);
Serial.print("): ");
for (int j = 0; j < 32; j++)
{
Serial.print(temp0[j], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp0, temp0, temp1); // 36. temp1 = temp0 ^2
Serial.print("36. temp1 (iteration ");
Serial.print(i);
Serial.print("): ");
for (int j = 0; j < 32; j++)
{
Serial.print(temp1[j], HEX);
Serial.print(" ");
}
Serial.println();
}
Serial.println(" =======================================> End of the 6'th for loop : ");
mul32_mod25519(temp1, x2_exp_50, temp0); // 37. temp0 = temp1 * x2_exp_50
Serial.print("37. temp0 = temp1 * x2_exp_50 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp0[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp0, temp0, temp1); // 38. temp1 = temp0 ^ 2
Serial.print("38. temp1 = temp0 ^ 2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp1[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp1, temp1, temp0); // 39. temp0 = temp1 ^ 2
Serial.print("39. temp0 = temp1 ^ 2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp0[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp0, temp0, temp1); // 40. temp1 = temp0 ^ 2
Serial.print("40. temp1 = temp0 ^ 2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp1[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp1, temp1, temp0); // 41. temp0 = temp1 ^ 2
Serial.print("41. temp1 = temp0 ^ 2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp0[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp0, temp0, temp1); // 42. temp1 = temp0 ^ 2
Serial.print("42. temp1 = temp0 ^ 2 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(temp1[i], HEX);
Serial.print(" ");
}
Serial.println();
mul32_mod25519(temp1, x_exp_11, result); // 43. result = temp1 * x_exp_11 = input^(2^255 - 21)
Serial.print("43. result = temp1 * x_exp_11 = ");
for (int i = 0; i < 32; i++)
{
Serial.print(result[i], HEX);
Serial.print(" ");
}
Serial.println();
}