X25519 ソフトウェア実装のテストスイート統合
新規ヘッダー:include/se050_x25519_sw.h - WireGuard Ephemeral キー計算用 API 定義 - se050_x25519_sw_generate_keypair() - キーペア生成 - se050_x25519_sw_compute_shared_secret() - 共有秘密計算 - se050_x25519_sw_derive_public_key() - 公開鍵派生 - se050_x25519_sw_clamp() - 秘密鍵クランプ - se050_x25519_sw_zeroize() - キー消去 ソース修正:src/se050_x25519_sw.c - main() 関数をテストスイートに統合 - 独立した API 関数として再構成 - X25519_SW_TEST マクロでテストビルド可能 テスト追加:tests/test_x25519_ecdh.c - テスト 7: ソフトウェアキーペア生成 - テスト 8: ECDH 対称性検証 - テスト 9: 公開鍵派生 - テスト 10: キーゼロ化 Makefile 更新: - test_x25519_sw タスク追加 - make test で全テスト実行 注:RFC 7748 テストベクトル検証中(実装修正必要)
This commit is contained in:
+67
-34
@@ -5,14 +5,10 @@
|
||||
* License: MIT (Clean-room implementation)
|
||||
*/
|
||||
|
||||
#include "se050_wireguard.h"
|
||||
#include "se050_x25519_sw.h"
|
||||
#include "se050_crypto_utils.h"
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#define X25519_FIELD_SIZE 32
|
||||
#define X25519_SCALAR_SIZE 32
|
||||
|
||||
typedef int32_t fe[10];
|
||||
|
||||
static uint32_t load_3(const uint8_t *in)
|
||||
@@ -21,9 +17,6 @@ static uint32_t load_3(const uint8_t *in)
|
||||
static uint64_t load_4(const uint8_t *in)
|
||||
{ return (uint64_t)in[0] | ((uint64_t)in[1] << 8) | ((uint64_t)in[2] << 16) | ((uint64_t)in[3] << 24); }
|
||||
|
||||
static void store_3(uint8_t *out, uint32_t in)
|
||||
{ out[0] = (uint8_t)in; out[1] = (uint8_t)(in >> 8); out[2] = (uint8_t)(in >> 16); }
|
||||
|
||||
static void store_4(uint8_t *out, uint64_t in)
|
||||
{ out[0] = (uint8_t)in; out[1] = (uint8_t)(in >> 8); out[2] = (uint8_t)(in >> 16); out[3] = (uint8_t)(in >> 24); }
|
||||
|
||||
@@ -53,7 +46,7 @@ static void fe_tobytes(uint8_t *s, const fe h)
|
||||
int32_t carry9=(h9+65536)>>16; h0+=carry9*19; h9-=carry9<<16;
|
||||
int32_t carry1=(h1+65536)>>16; h2+=carry1; h1-=carry1<<16;
|
||||
int32_t carry3=(h3+65536)>>16; h4+=carry3; h3-=carry3<<16;
|
||||
int32_t carry5=(h5+65536)>>16; h6+=carry5; h5-=carry5<<16;
|
||||
int32_t carry5=(h5+65536)>>16; h6+=carry5; h5-=carry5<<25;
|
||||
int32_t carry7=(h7+65536)>>16; h8+=carry7; h7-=carry7<<16;
|
||||
int32_t carry0=(h0+65536)>>16; h1+=carry0; h0-=carry0<<16;
|
||||
int32_t carry2=(h2+65536)>>16; h3+=carry2; h2-=carry2<<16;
|
||||
@@ -70,9 +63,6 @@ static void fe_add(fe h, const fe f, const fe g)
|
||||
static void fe_sub(fe h, const fe f, const fe g)
|
||||
{ for (int i = 0; i < 10; i++) h[i] = f[i] - g[i]; }
|
||||
|
||||
static void fe_neg(fe h, const fe f)
|
||||
{ fe zero; fe_0(zero); fe_sub(h, zero, f); }
|
||||
|
||||
static void fe_copy(fe h, const fe f)
|
||||
{ for (int i = 0; i < 10; i++) h[i] = f[i]; }
|
||||
|
||||
@@ -85,21 +75,12 @@ static void fe_cswap(fe f, fe g, int b)
|
||||
}
|
||||
}
|
||||
|
||||
static void fe_cmov(fe f, const fe g, int b)
|
||||
{
|
||||
int32_t mask = -b;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
int32_t x = (f[i] ^ g[i]) & mask;
|
||||
f[i] ^= x;
|
||||
}
|
||||
}
|
||||
|
||||
static void fe_mul(fe h, const fe f, const fe g)
|
||||
{
|
||||
int32_t f0=f[0],f1=f[1],f2=f[2],f3=f[3],f4=f[4],f5=f[5],f6=f[6],f7=f[7],f8=f[8],f9=f[9];
|
||||
int32_t g0=g[0],g1=g[1],g2=g[2],g3=g[3],g4=g[4],g5=g[5],g6=g[6],g7=g[7],g8=g[8],g9=g[9];
|
||||
int64_t g0_19=g0*19, g1_19=g1*19, g2_19=g2*19, g3_19=g3*19, g4_19=g4*19;
|
||||
int64_t g5_19=g5*19, g6_19=g6*19, g7_19=g7*19, g8_19=g8*19, g9_19=g9*19;
|
||||
int64_t g1_19=g1*19, g2_19=g2*19, g3_19=g3*19, g4_19=g4*19, g5_19=g5*19;
|
||||
int64_t g6_19=g6*19, g7_19=g7*19, g8_19=g8*19, g9_19=g9*19;
|
||||
int64_t r0=(int64_t)f0*g0+(int64_t)f1*g9_19+(int64_t)f2*g8_19+(int64_t)f3*g7_19+(int64_t)f4*g6_19+(int64_t)f5*g5_19+(int64_t)f6*g4_19+(int64_t)f7*g3_19+(int64_t)f8*g2_19+(int64_t)f9*g1_19;
|
||||
int64_t r1=(int64_t)f0*g1+(int64_t)f1*g0+(int64_t)f2*g9_19+(int64_t)f3*g8_19+(int64_t)f4*g7_19+(int64_t)f5*g6_19+(int64_t)f6*g5_19+(int64_t)f7*g4_19+(int64_t)f8*g3_19+(int64_t)f9*g2_19;
|
||||
int64_t r2=(int64_t)f0*g2+(int64_t)f1*g1*2+(int64_t)f2*g0+(int64_t)f3*g9_19+(int64_t)f4*g8_19+(int64_t)f5*g7_19+(int64_t)f6*g6_19+(int64_t)f7*g5_19+(int64_t)f8*g4_19+(int64_t)f9*g3_19;
|
||||
@@ -129,7 +110,7 @@ static void fe_sq(fe h, const fe f)
|
||||
{
|
||||
int32_t f0=f[0],f1=f[1],f2=f[2],f3=f[3],f4=f[4],f5=f[5],f6=f[6],f7=f[7],f8=f[8],f9=f[9];
|
||||
int32_t f0_2=f0*2,f1_2=f1*2,f2_2=f2*2,f3_2=f3*2,f4_2=f4*2,f5_2=f5*2,f6_2=f6*2,f7_2=f7*2,f8_2=f8*2;
|
||||
int32_t f9_19=f9*19,f9_38=f9*38,f8_19=f8*19,f7_19=f7*19,f6_19=f6*19,f5_19=f5*19,f4_19=f4*19,f3_19=f3*19,f2_19=f2*19,f1_19=f1*19;
|
||||
int32_t f9_19=f9*19,f8_19=f8*19,f7_19=f7*19,f6_19=f6*19,f5_19=f5*19,f4_19=f4*19,f3_19=f3*19;
|
||||
int64_t r0=(int64_t)f0*f0+(int64_t)f1_2*f9_19+(int64_t)f2_2*f8_19+(int64_t)f3_2*f7_19+(int64_t)f4_2*f6_19+(int64_t)f5*f5_19;
|
||||
int64_t r1=(int64_t)f0_2*f1+(int64_t)f2_2*f9_19+(int64_t)f3_2*f8_19+(int64_t)f4_2*f7_19+(int64_t)f5_2*f6_19;
|
||||
int64_t r2=(int64_t)f0_2*f2+(int64_t)f1*f1+(int64_t)f3_2*f9_19+(int64_t)f4_2*f8_19+(int64_t)f5_2*f7_19+(int64_t)f6*f6_19;
|
||||
@@ -208,18 +189,70 @@ static void x25519_sw(uint8_t *out, const uint8_t *scalar, const uint8_t *point)
|
||||
fe_tobytes(out, x2);
|
||||
}
|
||||
|
||||
se050_status_t se050_x25519_compute_shared_secret_sw(se050_keystore_ctx_t *keystore,
|
||||
const uint8_t *private_key,
|
||||
const uint8_t *peer_public,
|
||||
uint8_t *shared_secret)
|
||||
void se050_x25519_sw_clamp(uint8_t *scalar)
|
||||
{
|
||||
(void)keystore;
|
||||
if (!private_key || !peer_public || !shared_secret) return SE050_ERR_INVALID_ARG;
|
||||
x25519_sw(shared_secret, private_key, peer_public);
|
||||
return SE050_OK;
|
||||
scalar[0] &= 248;
|
||||
scalar[31] &= 127;
|
||||
scalar[31] |= 64;
|
||||
}
|
||||
|
||||
#ifdef X25519_TEST
|
||||
void se050_x25519_sw_zeroize(uint8_t *key, size_t len)
|
||||
{
|
||||
memzero_explicit(key, len);
|
||||
}
|
||||
|
||||
int se050_x25519_sw_generate_keypair(se050_x25519_sw_keypair_t *keypair,
|
||||
x25519_rng_func rng_func,
|
||||
void *rng_ctx)
|
||||
{
|
||||
if (!keypair || !rng_func) return -1;
|
||||
|
||||
if (rng_func(keypair->private_key, 32, rng_ctx) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
se050_x25519_sw_clamp(keypair->private_key);
|
||||
x25519_sw(keypair->public_key, keypair->private_key, (const uint8_t*)"basepoint");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int se050_x25519_sw_compute_shared_secret(uint8_t *shared_secret,
|
||||
const uint8_t *private_key,
|
||||
const uint8_t *peer_public)
|
||||
{
|
||||
if (!shared_secret || !private_key || !peer_public) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t clamped[32];
|
||||
memcpy(clamped, private_key, 32);
|
||||
se050_x25519_sw_clamp(clamped);
|
||||
|
||||
x25519_sw(shared_secret, clamped, peer_public);
|
||||
se050_x25519_sw_zeroize(clamped, 32);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int se050_x25519_sw_derive_public_key(uint8_t *public_key,
|
||||
const uint8_t *private_key)
|
||||
{
|
||||
if (!public_key || !private_key) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t clamped[32];
|
||||
memcpy(clamped, private_key, 32);
|
||||
se050_x25519_sw_clamp(clamped);
|
||||
|
||||
x25519_sw(public_key, clamped, (const uint8_t*)"basepoint");
|
||||
se050_x25519_sw_zeroize(clamped, 32);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef X25519_SW_TEST
|
||||
#include <stdio.h>
|
||||
|
||||
static const uint8_t RFC7748_SK_1[32] = {
|
||||
@@ -251,7 +284,7 @@ int main(void)
|
||||
x25519_sw(shared_secret, RFC7748_SK_1, RFC7748_PK_1);
|
||||
print_hex("Computed SS", shared_secret, 32);
|
||||
print_hex("Expected SS", RFC7748_SS_1, 32);
|
||||
if (crypto_memneq(shared_secret, RFC7748_SS_1, 32) == 0) {
|
||||
if (memcmp(shared_secret, RFC7748_SS_1, 32) == 0) {
|
||||
printf("[PASS] RFC 7748 Test Vector 1\n");
|
||||
return 0;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user