1 (edited by solamnic 2023-06-21 14:34:45)

Topic: Curve25519, Secp256R1 time measurement on STM32F410

Hi all,

For those who have little time; I'm reviewing the run times of a couple of elliptic curves on the stm32F410. But I'm not sure about the code I wrote and the results.

Long version; I tried to create a code block that generates key pair with curve25519 and key exchange for elliptic curve diffie hellman. I also tried key generation and signing with ED25519 and secp256r1. My goal was to find out how long it takes for these functions to work, so to do some kind of test.  I will write the values I got during debug below. I am also sharing the code below. I used three different math configuration settings on the STM32f410.

1. Fast (stack) Math ()
2. Single Precision C Math (only common curves/key size)
3. Single Precision ASM Cortex -M3+ Math

  • The measurements I got from this test seemed a bit strange to me. Isn't curve25519 supposed to do faster operations? But secp256r1 rendered faster.

  • What could I be missing?

  • What should I do to get more accurate results?

  • İn fast (stack) math I got 4383 mili second for curve25519 key generation. Is it possible or sensible?

By the way , I created a timer in code, also I used an oscilloscope.

STM32CubeIDE: 1.12.1
Target Reference: STM32F410RBTx
Firmware Package Name: STM32Cube FW_F4 V1.27.1
WolfSSL: wolfSSL.I-CUBE-wolfSSL.5.6.0


The code:


/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file           : main.c
 * @brief          : Main program body
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2023 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stm32f4xx.h"
#include "wolfssl/options.h"
#include "wolfssl/wolfcrypt/random.h"
#include "wolfssl/wolfcrypt/settings.h"
#include "wolfssl/wolfcrypt/ed25519.h"
#include "wolfssl/wolfcrypt/curve25519.h"
#include "wolfssl/wolfcrypt/error-crypt.h"
#include "wolfssl/internal.h"
#include <wolfssl/wolfcrypt/ecc.h>
#include "wolfssl/wolfcrypt/kyber.h"
#include "wolfssl/wolfcrypt/ext_kyber.h"
#define ECC_256_BIT_FIELD 32 // 256-bit curve field
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
RNG_HandleTypeDef hrng;

TIM_HandleTypeDef htim6;

UART_HandleTypeDef huart2;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_RNG_Init(void);
static void MX_TIM6_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  MX_RNG_Init();
  MX_TIM6_Init();
  /* USER CODE BEGIN 2 */

    printf(" \n");
    printf("Starting...\n");
    printf(" \n");

    //Begin- Variables
    int generateRandomNumberResult;
    int curve25519InitResultForIOT;
    int curve25519InitResultForRemote;
    int curve25519KeyResultForIOT;
    int curve25519KeyResultForRemote;
    int controlPublicForIOT;
    int controlPublicForRemote;
    int generateSecredSharedResultForIOT;
    int generateSecredSharedResultForRemote;
    int controlSecretShared;
    uint32_t timer; // timer for code
    WC_RNG rng;
    curve25519_key keyPairCurve25519IOT; //->Curve25519
    curve25519_key keyPairCurve25519Remote; //->Curve25519
    byte publicKeyForIOT[CURVE25519_PUB_KEY_SIZE] = { 0 };
    byte publicKeyForRemote[CURVE25519_PUB_KEY_SIZE] = { 0 };
    byte secretSharedForIOT[CURVE25519_KEYSIZE] = { 0 };
    byte secretSharedForRemote[CURVE25519_KEYSIZE] = { 0 };
    word32 secredSharedLength = 0;
    //------------------------
    ed25519_key keyPairED25519IOT; //->ED25519 Curve
    ed25519_key keyPairED25519Remote; //->ED25519 Curve
    int ed25519InitResult;
    int ed25519GenerateKeyResultForIOT;
    int ed25519GenerateKeyResultForRemote;
    int ed25519SigningResult;
    //----------------------
    ecc_key keyPairSecp256r1IOT; //->Secp256R1
    ecc_key keyPairSecp256r1REMOTE; //->Secp256R1
    byte sharedSecretSecp26r1[32] = { };
    int secredSharedGenerationResultForIOT;
    //End-

    //Begin- ready for oscilloscope
    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 1);
    HAL_Delay(1);
    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 0);
    HAL_Delay(1);
    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 1);
    HAL_Delay(1);
    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 0);
    HAL_Delay(1);
    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 1);
    HAL_Delay(1);
    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 0);
    HAL_Delay(1);
    //End-


    printf("--------Curve25519------ \n");

    //Create random
    generateRandomNumberResult = wc_InitRng(&rng);

    //Begin- Init
    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 1);
    HAL_TIM_Base_Start(&htim6);
    curve25519InitResultForIOT = wc_curve25519_init(&keyPairCurve25519IOT);
    timer = TIM6->CNT;
    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 0);
    HAL_TIM_Base_Stop(&htim6);
    TIM6->CNT = 0;

    printf("wc_curve25519_init for IOT: \n");
    printf("%d", timer);
    printf(" \n");

    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 1);
    HAL_TIM_Base_Start(&htim6);
    curve25519InitResultForRemote = wc_curve25519_init(
            &keyPairCurve25519Remote);
    timer = TIM6->CNT;
    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 0);
    HAL_TIM_Base_Stop(&htim6);
    TIM6->CNT = 0;

    printf("wc_curve25519_init for Remote: \n");
    printf("%d", timer);
    printf(" \n");
    //End- Init

    //Begin- Genereate Key Pairs
    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 1);
    HAL_TIM_Base_Start(&htim6);
    curve25519KeyResultForIOT = wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE,
            &keyPairCurve25519IOT);
    timer = TIM6->CNT;
    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 0);
    HAL_TIM_Base_Stop(&htim6);
    TIM6->CNT = 0;

    printf("wc_curve25519_make_key for IOT: \n");
    printf("%d", timer);
    printf(" \n");

    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 1);
    HAL_TIM_Base_Start(&htim6);
    curve25519KeyResultForRemote = wc_curve25519_make_key(&rng,
            CURVE25519_KEYSIZE, &keyPairCurve25519Remote);
    timer = TIM6->CNT;
    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 0);
    HAL_TIM_Base_Stop(&htim6);
    TIM6->CNT = 0;

    printf("wc_curve25519_make_key for Remote: \n");
    printf("%d", timer);
    printf(" \n");
    //End-

    //Control from Key Pairs
    controlPublicForIOT = wc_curve25519_make_pub(CURVE25519_PUB_KEY_SIZE,
            publicKeyForIOT, CURVE25519_KEYSIZE, keyPairCurve25519IOT.k);
    controlPublicForRemote = wc_curve25519_make_pub(CURVE25519_PUB_KEY_SIZE,
            publicKeyForRemote, CURVE25519_KEYSIZE, keyPairCurve25519Remote.k);

    printf(" \n");
    printf("Key pairs are ready... \n");
    printf(" \n");
    printf(" \n");

    //Print Private Key
    printf("Private Key for IOT: \n");
    for (int i = 0; i < CURVE25519_KEYSIZE; i++) {
        printf("%02x", keyPairCurve25519IOT.k[i]);
    }
    printf(" \n");
    printf(" \n");

    //Print Public Key
    printf("Public Key for IOT: \n");
    for (int i = 0; i < CURVE25519_PUB_KEY_SIZE; i++) {
        printf("%02x", keyPairCurve25519IOT.p.point[i]);
    }
    printf(" \n");
    printf(" \n");

    //Check both public key creations  are OK for IOT
    printf("Public Key from Private Key Of IOT :\n");
    for (int i = 0; i < CURVE25519_PUB_KEY_SIZE; i++) {
        printf("%02x", publicKeyForIOT[i]);
    }
    printf(" \n");
    printf(" \n");
    printf("-------------- \n");

    //Print Private Key
    printf("Private Key for Remote: \n");
    for (int i = 0; i < CURVE25519_KEYSIZE; i++) {
        printf("%02x", keyPairCurve25519Remote.k[i]);
    }
    printf(" \n");
    printf(" \n");

    //Print Public Key
    printf("Public Key for Remote: \n");
    for (int i = 0; i < CURVE25519_PUB_KEY_SIZE; i++) {
        printf("%02x", keyPairCurve25519Remote.p.point[i]);
    }
    printf(" \n");
    printf(" \n");

    //Check both public key creations  are OK for Remote
    printf("Public Key from Private Key Of Remote :\n");
    for (int i = 0; i < CURVE25519_PUB_KEY_SIZE; i++) {
        printf("%02x", publicKeyForRemote[i]);
    }
    printf(" \n");
    printf(" \n");
    printf("-------------- \n");

    secredSharedLength = ECC_256_BIT_FIELD;

    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 1);
    HAL_TIM_Base_Start(&htim6);
    generateSecredSharedResultForIOT = wc_curve25519_shared_secret(
            &keyPairCurve25519IOT, &keyPairCurve25519Remote, secretSharedForIOT,
            &secredSharedLength);
    timer = TIM6->CNT;
    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 0);
    HAL_TIM_Base_Stop(&htim6);
    TIM6->CNT = 0;

    printf("wc_curve25519_shared_secret for IOT: \n");
    printf("%d", timer);
    printf(" \n");
    printf(" \n");

    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 1);
    HAL_TIM_Base_Start(&htim6);
    generateSecredSharedResultForRemote = wc_curve25519_shared_secret(
            &keyPairCurve25519Remote, &keyPairCurve25519IOT,
            secretSharedForRemote, &secredSharedLength);
    timer = TIM6->CNT;
    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 0);
    HAL_TIM_Base_Stop(&htim6);
    TIM6->CNT = 0;

    printf("wc_curve25519_shared_secret for Remote: \n");
    printf("%d", timer);
    printf(" \n");
    printf(" \n");

    printf("Secret Shared for IOT: \n");
    for (int i = 0; i < sizeof(secretSharedForIOT); i++) {
        printf("%02x", secretSharedForIOT[i]);
    }
    printf(" \n");
    printf(" \n");

    printf("Secret Shared for Remote: \n");
    for (int i = 0; i < sizeof(secretSharedForRemote); i++) {
        printf("%02x", secretSharedForRemote[i]);
    }
    printf(" \n");
    printf(" \n");

    controlSecretShared = memcmp(secretSharedForIOT, secretSharedForRemote,
            secredSharedLength);
    printf(" \n");
    printf(" \n");

    wc_FreeRng(&rng);
    wc_curve25519_free(&keyPairCurve25519IOT);
    wc_curve25519_free(&keyPairCurve25519Remote);

    /* export
     byte pub[32];
     byte priv[32];
     int pubSz;
     int privSz;
     int exportResult = wc_curve25519_export_key_raw(&keyPairCurve25519IOT, priv, &privSz, pub, &pubSz);
     */

    printf("--------ED25519------ \n");
    generateRandomNumberResult = wc_InitRng(&rng); // initialize random number generator
    if (generateRandomNumberResult != 0) {
        printf("Error in generating random for Ed25519.\n");
        return -1;
    }

    ed25519InitResult = wc_ed25519_init(&keyPairED25519IOT);

    //IOT Key Pair
    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 1);
    HAL_TIM_Base_Start(&htim6);
    ed25519GenerateKeyResultForIOT = wc_ed25519_make_key(&rng, ED25519_KEY_SIZE,
            &keyPairED25519IOT);
    timer = TIM6->CNT;
    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 0);
    HAL_TIM_Base_Stop(&htim6);
    TIM6->CNT = 0;

    printf("wc_edcurve25519_make_Key for IOT: \n");
    printf("%d", timer);
    printf(" \n");

    if (ed25519GenerateKeyResultForIOT != 0) {
        printf("Error %d generating Ed25519 key\n",
                ed25519GenerateKeyResultForIOT);
        return ed25519GenerateKeyResultForIOT;
    }
    printf(" \n");

    //Print Private Key
    printf("Private Key for IOT: \n");
    for (int i = 0; i < ED25519_KEY_SIZE; i++) {
        printf("%02x", keyPairED25519IOT.k[i]);
    }
    printf(" \n");
    printf(" \n");

    //Print Public Key
    printf("Public Key for IOT: \n");
    for (int i = 0; i < ED25519_PUB_KEY_SIZE; i++) {
        printf("%02x", keyPairED25519IOT.p[i]);
    }
    printf(" \n");
    printf(" \n");

    byte msg[16];
    byte signedD[64];
    byte signedData[ED25519_SIG_SIZE];

    //Create Dummy Data
    for (int i = 0; i < (int) sizeof(msg); i++) {
        msg[i] = (byte) i;
    }

    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 1);
    HAL_TIM_Base_Start(&htim6);
    ed25519SigningResult = wc_ed25519_sign_msg(&msg, sizeof(msg), signedData,
            sizeof(signedData), &keyPairED25519IOT);
    timer = TIM6->CNT;
    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 0);
    HAL_TIM_Base_Stop(&htim6);
    TIM6->CNT = 0;

    printf("wc_ed25519_sign_msg: \n");
    printf("%d", timer);
    printf(" \n");
    printf(" \n");

    wc_ed25519_free(&keyPairED25519IOT);
    wc_ed25519_free(&keyPairED25519Remote);

    printf(" \n");
    printf(" \n");


    printf("--------SECP256R1------ \n");
    wc_ecc_init(&keyPairSecp256r1IOT);
    wc_ecc_init(&keyPairSecp256r1REMOTE);

    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 1);
    HAL_TIM_Base_Start(&htim6);
    int sec26r1ReturnIOT = wc_ecc_make_key_ex(&rng, 32, &keyPairSecp256r1IOT,
            ECC_SECP256R1);
    timer = TIM6->CNT;
    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 0);
    HAL_TIM_Base_Stop(&htim6);
    TIM6->CNT = 0;

    printf("wc_ecc_make_key_ex for IOT: \n");
    printf("%d", timer);
    printf(" \n");
    printf(" \n");

    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 1);
    HAL_TIM_Base_Start(&htim6);
    int sec26r1ReturnREMOTE = wc_ecc_make_key_ex(&rng, 32, &keyPairSecp256r1REMOTE,
            ECC_SECP256R1);
    timer = TIM6->CNT;
    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 0);
    HAL_TIM_Base_Stop(&htim6);
    TIM6->CNT = 0;

    printf("wc_ecc_make_key_ex for Remote: \n");
    printf("%d", timer);
    printf(" \n");
    printf(" \n");

    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 1);
    HAL_TIM_Base_Start(&htim6);
    secredSharedGenerationResultForIOT = wc_ecc_shared_secret(&keyPairSecp256r1IOT,
            &keyPairSecp256r1REMOTE, sharedSecretSecp26r1,
            sizeof(sharedSecretSecp26r1));
    timer = TIM6->CNT;

    HAL_GPIO_WritePin(ld3_GPIO_Port, ld3_Pin, 0);
    HAL_TIM_Base_Stop(&htim6);
    TIM6->CNT = 0;

    printf("wc_ecc_shared_secret: \n");
    printf("%d", timer);
    printf(" \n");
    printf(" \n");

    wc_FreeRng(&rng);
    wc_ecc_free(&keyPairSecp256r1IOT);
    wc_ecc_free(&keyPairSecp256r1REMOTE);
    printf("Finishing \n");


  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
    while (1) {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 96;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  RCC_OscInitStruct.PLL.PLLR = 2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief RNG Initialization Function
  * @param None
  * @retval None
  */
static void MX_RNG_Init(void)
{

  /* USER CODE BEGIN RNG_Init 0 */

  /* USER CODE END RNG_Init 0 */

  /* USER CODE BEGIN RNG_Init 1 */

  /* USER CODE END RNG_Init 1 */
  hrng.Instance = RNG;
  if (HAL_RNG_Init(&hrng) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN RNG_Init 2 */

  /* USER CODE END RNG_Init 2 */

}

/**
  * @brief TIM6 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM6_Init(void)
{

  /* USER CODE BEGIN TIM6_Init 0 */

  /* USER CODE END TIM6_Init 0 */

  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM6_Init 1 */

  /* USER CODE END TIM6_Init 1 */
  htim6.Instance = TIM6;
  htim6.Init.Prescaler = 48000-1;
  htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim6.Init.Period = 1000-1;
  htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM6_Init 2 */

  /* USER CODE END TIM6_Init 2 */

}

/**
  * @brief USART2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */

  /* USER CODE END USART2_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, LD2_Pin|ld3_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : B1_Pin */
  GPIO_InitStruct.Pin = B1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : LD2_Pin ld3_Pin */
  GPIO_InitStruct.Pin = LD2_Pin|ld3_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */
int _write(int file, char *ptr, int len) {
    (void) file;
    int DataIdx;

    for (DataIdx = 0; DataIdx < len; DataIdx++) {
        ITM_SendChar(*ptr++);
    }
    return len;
}

void phex(uint8_t *str) {
    uint8_t i;
    for (i = 0; i < 16; ++i)
        printf("%.2x", str[i]);
    printf("\n");
}

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
    /* User can add his own implementation to report the HAL error return state */
    __disable_irq();
    while (1) {
    }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

The output 1 for Fast (stack) Math:

Starting...

--------Curve25519------
wc_curve25519_init for IOT:
0
wc_curve25519_init for Remote:
0
wc_curve25519_make_key for IOT:
4383
wc_curve25519_make_key for Remote:
4384

Key pairs are ready...


Private Key for IOT:
40251046acce5911cce8c94e708520073e8e464c672501af61a44ae12369f440

Public Key for IOT:
0cca06d83f09e75c3df59f28d087940b4c567a0f9d980d8d12a7fefaeaa63e05

Public Key from Private Key Of IOT :
0cca06d83f09e75c3df59f28d087940b4c567a0f9d980d8d12a7fefaeaa63e05

--------------
Private Key for Remote:
485c41acf2774e24a40d586d33d1c7260e0065ef1612d7538e778a625b187471

Public Key for Remote:
95433e41c55a0809ea23d95623d6349ebffede7dc07277e7a2ca2485c3aa3118

Public Key from Private Key Of Remote :
95433e41c55a0809ea23d95623d6349ebffede7dc07277e7a2ca2485c3aa3118

--------------
wc_curve25519_shared_secret for IOT:
4381

wc_curve25519_shared_secret for Remote:
4382

Secret Shared for IOT:
4903a28465471e5fe40b697287bf64e4ab30a111f52839d6513e47830d13e13b

Secret Shared for Remote:
4903a28465471e5fe40b697287bf64e4ab30a111f52839d6513e47830d13e13b



--------ED25519------
wc_edcurve25519_make_Key for IOT:
4418

Private Key for IOT:
9545acd88efa0c4d8d9ec0657702e8b7719504cad022613fc51024c50da7f0df

Public Key for IOT:
787060d9c395bf84519f84a2994e1e09974424ea7d0ce6e07a7c1edd51862eae

wc_ed25519_sign_msg:
4485



--------SECP256R1------
wc_ecc_make_key_ex for IOT:
4102

wc_ecc_make_key_ex for Remote:
4095

wc_ecc_shared_secret:
2

Finishing

---
The output 2 for Single Precision C Math :

Starting...

--------Curve25519------
wc_curve25519_init for IOT:
0
wc_curve25519_init for Remote:
0
wc_curve25519_make_key for IOT:
383
wc_curve25519_make_key for Remote:
384

Key pairs are ready...


Private Key for IOT:
387b5b3b3049f15af014803c5a032343f94ab069419aa1c39ab6268ae024207c

Public Key for IOT:
f73644eebe46b07e35e32405378e123f0169bcc4b359736587cb86e101d9ae03

Public Key from Private Key Of IOT :
f73644eebe46b07e35e32405378e123f0169bcc4b359736587cb86e101d9ae03

--------------
Private Key for Remote:
00bcb35c0dee068995c740332082217d95db6df383d007287680b2ae0d252865

Public Key for Remote:
d1a07f84bcfa708dca98d8967b642ef0e075a1f312910fc036fbed10835f9064

Public Key from Private Key Of Remote :
d1a07f84bcfa708dca98d8967b642ef0e075a1f312910fc036fbed10835f9064

--------------
wc_curve25519_shared_secret for IOT:
381

wc_curve25519_shared_secret for Remote:
382

Secret Shared for IOT:
4e1fe746a1a9fd3595f3c364d59d13a92a75588158661891ebff61b2432d8a0a

Secret Shared for Remote:
4e1fe746a1a9fd3595f3c364d59d13a92a75588158661891ebff61b2432d8a0a



--------ED25519------
wc_edcurve25519_make_Key for IOT:
418

Private Key for IOT:
f66b46cba84b0d1897cc8b85c9a0a87c0499c9906fc35596a0795eb12aa437f4

Public Key for IOT:
62447128d71d67c306ea056faab6d3bd39ef71e9137cfa3af604857bd13fd9fe

wc_ed25519_sign_msg:
485



--------SECP256R1------
wc_ecc_make_key_ex for IOT:
559

wc_ecc_make_key_ex for Remote:
559

wc_ecc_shared_secret:
0

Finishing

---
The output 3 for Single Precision ASM Cortex -M3+ Math:

Starting...

--------Curve25519------
wc_curve25519_init for IOT:
0
wc_curve25519_init for Remote:
0
wc_curve25519_make_key for IOT:
382
wc_curve25519_make_key for Remote:
382

Key pairs are ready...


Private Key for IOT:
5039c8a4af38f2cb189d92e298fbe81ff5e3b97cff3ba33ff42e402cd59f8764

Public Key for IOT:
7384fd67b5e8427c600db6033344548f432393a221eb58bac9051c457f46cc22

Public Key from Private Key Of IOT :
7384fd67b5e8427c600db6033344548f432393a221eb58bac9051c457f46cc22

--------------
Private Key for Remote:
b8ddf337da3111ad0e5c6a459572a86e6f5fd71a50d5f5044933ef30f0341a48

Public Key for Remote:
1d2d2046d722aeeb0a85831827c75dc01df7b2dec624fc5f2bc1bddc1146fe1b

Public Key from Private Key Of Remote :
1d2d2046d722aeeb0a85831827c75dc01df7b2dec624fc5f2bc1bddc1146fe1b

--------------
wc_curve25519_shared_secret for IOT:
381

wc_curve25519_shared_secret for Remote:
380

Secret Shared for IOT:
272c0bfc1ae59e127c32ba2d80a4595e063c1923dc5a4977afeb06541e318b9a

Secret Shared for Remote:
272c0bfc1ae59e127c32ba2d80a4595e063c1923dc5a4977afeb06541e318b9a



--------ED25519------
wc_edcurve25519_make_Key for IOT:
417

Private Key for IOT:
5295efc76dfb33634b90488e351a62c1a5e81d2514cd65102ffc88302dc2a14e

Public Key for IOT:
6a6c5bc2c8174758cc1eb50cdb8de147ab3492a3f09e9cbc7a1be2988aa42f4b

wc_ed25519_sign_msg:
483



--------SECP256R1------
wc_ecc_make_key_ex for IOT:
36

wc_ecc_make_key_ex for Remote:
36

wc_ecc_shared_secret:
0

Finishing
--

Share

Re: Curve25519, Secp256R1 time measurement on STM32F410

Hello solamnic

Welcome to the wolfSSL Forums. I've requested feedback from our engineers on your questions.

Thanks,
Eric - wolfSSL Support

Re: Curve25519, Secp256R1 time measurement on STM32F410

Hi Eric,

Thanks.

Share

Re: Curve25519, Secp256R1 time measurement on STM32F410

Hi solamnic,

I would also expect curve25519 to be faster than secp256r1. If your goal is to evaluate the performance of different elliptic curves with our different math libraries, have you considered running our built-in wolfCrypt benchmarks? You can find instructions on how to use them on the STM32 here: https://github.com/wolfSSL/wolfssl/tree … lec-output

4383 milliseconds for curve25519 keygen sounds like a lot to me. Do you have CURVE25519_SMALL defined? This macro helps with size optimization but slows things down considerably.

Thanks,

Lealem, wolfSSL Support

Share