如何使用 Kinets LTC ECC HW 加速 Curve25519。 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
Curve22519 是一条蒙哥马利椭圆曲线。例如Apple HomeKit,大多数网络和物联网软件都使用它 在 Diffie-Hellman 算法中用于密钥交换。 在 Security Kinets MCU 芯片上,如果我们只使用软件算法(基于 mbedTLS),Curve25519 将花费 共享安全性计算需要 180ms。 由于共享安全性,它比其他 256 位椭圆曲线软件算法更快 使用软件算法时,使用 Weierstrass 的 BP256R1 曲线计算将花费 1200ms 以上。 通过LTC ECC硬件加速,在256位椭圆曲线上计算共享安全性仅需16ms。 无论做什么,硬件加速的速度总是比软件算法快。 现在我们也应该想利用LTC来加速Curve22519。然而,LTC 仅 支持魏尔斯特拉斯形式曲线,但 Curve22519 是蒙哥马利曲线…… 虽然我们不能直接在 Curve22519 中使用 LTC,但我们可以通过将其映射到 Weierstrass 形式来使用它 使用它。下面给出了这些曲线的参数、变换公式、示例代码和测试结果 展示如何以及为何这么做。 1. Curve parameter: 蒙哥马利形式的 Cuvre22519: Y^2 = X^3 + A*X^2 + X Fp = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed A=486662 Gx = 9 Gy = 0x20ae19a1b8a086b4e01edd2c7748d14c923d4d7e6d7c61b229e9c5a27eced3d9 G点的顺序 = 0x1000000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed Cuvre22519 的 Weierstrass 形式: Y^2 = X^3 + a*X + b Fp = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed a = 0x2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa984914a144L b = 0x7b425ed097b425ed097b425ed097b425ed097b425ed097b4260b5e9c7710c864L Gx = 0x2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaad245a Gy = 0x20ae19a1b8a086b4e01edd2c7748d14c923d4d7e6d7c61b229e9c5a27eced3d9 G点的顺序 = 0x1000000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed 2.计算公式: x_w – Weierstrass 形式的 x 坐标值 y_w – Weierstrass 形式的 y 坐标值 x_m - x 坐标 蒙哥马利形式的值 y_m - 我们不关心 Weierstrass 模式下的 y 坐标值 a_m – 系数 蒙哥马利方程(Y^2 = X^3 + a_m * X^2 + X) a_w – 系数 魏尔斯特拉斯方程( Y^2 = X^3 + a*X + b ) b_w – 系数 魏尔斯特拉斯方程( Y^2 = X^3 + a*X + b ) a)x_w =(x_m + a_m/3)%p b) y_w ^2 = x_w ^ 3 + a_w*x_w + b_w c)x_m =(x_w-a_m/3)%p 您可以参考以下文档: https://en.wikipedia.org/wiki/Curve25519 https://en.wikipedia.org/wiki/Montgomery_curve 3.示例代码: // public and private at Montgomery end
#define M255_d "0x7178DAC11D42AA5F39B10A62A8584DB0C8864564ADC9DF84EC0B13D9AEC220F8"
#define M255_Qx "0x3BA5048381744348D84E754B9944ABE080B37F7D4158DCE60CD79F66B98AB89E"
// public and private at Weierstrass end
#define WTS255_d "0x09CC5CCF43C656C1309EE5A3491D5A8361607CEEB0C9B2B31A575E0FEF2B8835"
#define WTS255_Qx "0x3F4BDE110EE7AF71EF428D1018D188E35BAFB019F34F84E6465C5194B363DC2D"
#define WTS255_Qy "0x7540577CE6F920354E2A9D38CE88847D7447E66FA4D188AC75CB63C17210B718"
#define WTS255_Qx_TO_M255_Qx "0x14A13366643D04C74497E2656E26DE38B105056F48A4DA3B9BB1A6EA08B6B7DC"
#define AM_INV3 "0x2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaad2451"
int ecdh_wts_curve_end( )
{
unsigned int ticks;
int ret = 0;
size_t blen = 0, blen_peer = 0;
ecdh_context ecdh;
ecdh_context ecdh_peer; // to_wts255
ecdh_context ecdh_peer_m255;
mpi R;
mpi_init(&R);
ecdh_init( &ecdh);
ecdh_init( &ecdh_peer);
ecdh_init( &ecdh_peer_m255);
MPI_CHK(ecp_use_known_dp( &ecdh.grp, ECP_DP_WTS25519 ));
MPI_CHK(ecp_use_known_dp( &ecdh_peer.grp, ECP_DP_WTS25519 ));
MPI_CHK(ecp_use_known_dp( &ecdh_peer_m255.grp, ECP_DP_M255 ));
blen = set_hash_buff(/*TEST_ECP_GRP_ID*/ECP_DP_WTS25519, &secret_buf, ecp_name);
if(blen == 0) {
ret = -1;
goto cleanup;
}
mpi_read_string(&ecdh.d, 16, WTS255_d);
mpi_read_string(&ecdh.Q.X, 16, WTS255_Qx);
mpi_read_string(&ecdh.Q.Y, 16, WTS255_Qy);
mpi_lset(&ecdh.Q.Z, 1);
mpi_read_string(&ecdh_peer_m255.d, 16, M255_d);
mpi_read_string(&ecdh_peer_m255.Q.X, 16, M255_Qx);
mpi_init(&ecdh_peer_m255.Q.Y);
mpi_lset(&ecdh_peer_m255.Q.Z, 1);
// map M255 point to WTS255 point
my_timer_start();
mpi_read_string(&R, 16, AM_INV3);
mpi_add_mpi(&ecdh_peer.Q.X, &ecdh_peer_m255.Q.X, &R);
mpi_mod_mpi(&ecdh_peer.Q.X, &ecdh_peer.Q.X, &ecdh_peer_m255.grp.P);
mpi_lset(&R, 3);
mpi_exp_mod (&ecdh_peer_m255.Q.Y , &ecdh_peer.Q.X, &R, &ecdh_peer_m255.grp.P, NULL);
mpi_mul_mpi(&R, &ecdh_peer.grp.A, &ecdh_peer.Q.X);
mpi_mod_mpi(&R, &R, &ecdh_peer.grp.P);
mpi_add_mpi(&ecdh_peer_m255.Q.Y, &ecdh_peer_m255.Q.Y, &R);
mpi_add_mpi(&ecdh_peer_m255.Q.Y, &ecdh_peer_m255.Q.Y, &ecdh_peer.grp.B);
mpi_mod_mpi(&ecdh_peer_m255.Q.Y, &ecdh_peer_m255.Q.Y, &ecdh_peer.grp.P);
mpi_mod_sqrt(&ecdh_peer.Q.Y, &ecdh_peer_m255.Q.Y, &ecdh_peer_m255.grp.P);
// z = 1
mpi_lset(&ecdh_peer.Q.Z, 1);
MPI_CHK(ecp_copy(&ecdh.Qp, &ecdh_peer.Q));
MPI_CHK(ecdh_calc_secret_wts2mont( &ecdh, &blen, secret_buf, blen, myrand, NULL));
mpi_read_string(&R, 16, AM_INV3);
mpi_sub_mpi(&ecdh_peer_m255.Q.X, &ecdh.Q.X, &R);
mpi_mod_mpi(&ecdh_peer_m255.Q.X, &ecdh_peer_m255.Q.X, &ecdh_peer_m255.grp.P);
ticks = my_timer_stop();
// print out message
polarssl_printf("Weierstrass curve shared secutiy:\n");
mpi_printf_string( &ecdh.z, 16);
polarssl_printf("%s ecdh peer to peer: %lu ticks, %d ms (%d) \n", ecp_name , ticks, ticks / (CLOCK_SYS_GetPitFreq(0) / 1000),CLOCK_SYS_GetPitFreq(0) );
cleanup:
if( ret !=0 )
polarssl_printf( "%s test Unexpected error, return code = %08X\n", ecp_name, ret );
mpi_free(&R);
ecdh_free( &ecdh);
ecdh_free( &ecdh_peer);
ecdh_free( &ecdh_peer_m255);
return( 0 );
}
int ecdh_mont_curve_end( )
{
int verbose = 1;
unsigned int ticks;
int ret = 0;
size_t blen = 0, blen_peer = 0;
ecdh_context ecdh;
ecp_point Q_peer; // peer public point
ecdh_init( &ecdh);
ecp_point_init( &Q_peer);
MPI_CHK(ecp_use_known_dp( &ecdh.grp, ECP_DP_M255 ));
blen_peer = set_hash_buff(ECP_DP_M255, &secret_buf_peer, ecp_name);
if(blen_peer == 0) {
ret = -1;
goto cleanup;
}
mpi_read_string(&ecdh.d, 16, M255_d);
mpi_read_string(&ecdh.Q.X, 16, M255_Qx);
mpi_init(&ecdh.Q.Y); // don't care Y, only init it
mpi_lset(&ecdh.Q.Z, 1);
mpi_read_string(&Q_peer.X, 16, WTS255_Qx_TO_M255_Qx);
mpi_init(&Q_peer.Y);
mpi_lset(&Q_peer.Z, 1);
MPI_CHK(ecp_copy(&ecdh.Qp, &Q_peer));
my_timer_start();
MPI_CHK(ecdh_calc_secret( &ecdh, &blen_peer, secret_buf_peer, blen_peer, myrand, NULL));
ticks = my_timer_stop();
polarssl_printf("%s ecdh peer to peer: %lu ticks, %d ms (%d) \n", ecp_name , ticks, ticks / (CLOCK_SYS_GetPitFreq(0) / 1000),CLOCK_SYS_GetPitFreq(0) );
polarssl_printf("Montogemory curve shared secutiy:\n");
mpi_printf_string( &ecdh.z, 16);
polarssl_printf( "passed\n" );
cleanup:
if( ret !=0 && verbose != 0 )
polarssl_printf( "%s test Unexpected error, return code = %08X\n", ecp_name, ret );
ecdh_free( &ecdh);
ecp_point_free( &Q_peer);
if( verbose != 0 )
polarssl_printf( "\n" );
return( 0 );
}
4.测试结果: 使用 LTC 对 Weierstrass 形式的 curv25519 进行测试的结果: 2.用软件算法对Montgomery形式的curve25519进行测试结果: 我们可以看到,Weierstrass形式与LTC以及Montgomery形式共享的安全性均为“0x1454BDCD6A94D6336AA5A76F3CB40BBE12B65A2CDC9DA6B478948906638896D1”。 但LTC的计算速度比其他方法快十倍。 Kinetis K系列MCU
View full article