From 3296b3ce1567e11cc8b7fc06755a7bc25855d135 Mon Sep 17 00:00:00 2001 From: Sun Yimin Date: Thu, 9 Oct 2025 14:34:22 +0800 Subject: [PATCH] internal/sm2ec: test loong64 --- internal/sm2ec/p256_asm_loong64.s | 53 ++++++++++++++++++++++ internal/sm2ec/sm2p256_asm_loong64.go | 11 +++++ internal/sm2ec/sm2p256_asm_loong64_test.go | 35 ++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 internal/sm2ec/p256_asm_loong64.s create mode 100644 internal/sm2ec/sm2p256_asm_loong64.go create mode 100644 internal/sm2ec/sm2p256_asm_loong64_test.go diff --git a/internal/sm2ec/p256_asm_loong64.s b/internal/sm2ec/p256_asm_loong64.s new file mode 100644 index 0000000..91c9cf6 --- /dev/null +++ b/internal/sm2ec/p256_asm_loong64.s @@ -0,0 +1,53 @@ +// Copyright 2025 Sun Yimin. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +//go:build !purego + +#include "textflag.h" + +#define res_ptr R29 +#define x_ptr R30 +#define y_ptr R31 + +#define acc0 R8 +#define acc1 R9 +#define acc2 R10 +#define acc3 R11 +#define acc4 R12 +#define acc5 R13 + +/* ---------------------------------------*/ +// func p256OrdLittleToBig(res *[32]byte, in *p256OrdElement) +TEXT ·p256OrdLittleToBig(SB),NOSPLIT,$0 + JMP ·p256BigToLittle(SB) +/* ---------------------------------------*/ +// func p256OrdBigToLittle(res *p256OrdElement, in *[32]byte) +TEXT ·p256OrdBigToLittle(SB),NOSPLIT,$0 + JMP ·p256BigToLittle(SB) +/* ---------------------------------------*/ +// func p256LittleToBig(res *[32]byte, in *p256Element) +TEXT ·p256LittleToBig(SB),NOSPLIT,$0 + JMP ·p256BigToLittle(SB) +/* ---------------------------------------*/ +// func p256BigToLittle(res *p256Element, in *[32]byte) +TEXT ·p256BigToLittle(SB),NOSPLIT,$0 + MOVV res+0(FP), res_ptr + MOVV in+8(FP), x_ptr + + MOVV (8*0)(x_ptr), acc0 + MOVV (8*1)(x_ptr), acc1 + MOVV (8*2)(x_ptr), acc2 + MOVV (8*3)(x_ptr), acc3 + + REVBV acc0 + REVBV acc1 + REVBV acc2 + REVBV acc3 + + MOVV acc3, (8*0)(res_ptr) + MOVV acc2, (8*1)(res_ptr) + MOVV acc1, (8*2)(res_ptr) + MOVV acc0, (8*3)(res_ptr) + + RET diff --git a/internal/sm2ec/sm2p256_asm_loong64.go b/internal/sm2ec/sm2p256_asm_loong64.go new file mode 100644 index 0000000..b45e167 --- /dev/null +++ b/internal/sm2ec/sm2p256_asm_loong64.go @@ -0,0 +1,11 @@ +package sm2ec + +// p256Element is a P-256 base field element in [0, P-1] in the Montgomery +// domain (with R 2²⁵⁶) as four limbs in little-endian order value. +type p256Element [4]uint64 + +//go:noescape +func p256BigToLittle(res *p256Element, in *[32]byte) + +//go:noescape +func p256LittleToBig(res *[32]byte, in *p256Element) diff --git a/internal/sm2ec/sm2p256_asm_loong64_test.go b/internal/sm2ec/sm2p256_asm_loong64_test.go new file mode 100644 index 0000000..2d29783 --- /dev/null +++ b/internal/sm2ec/sm2p256_asm_loong64_test.go @@ -0,0 +1,35 @@ +//go:build loong64 && !purego + +package sm2ec + +import ( + "bytes" + "encoding/binary" + "testing" +) + +func TestP256BigToLittle(t *testing.T) { + // 构造一个已知的 32 字节大端输入 + var in [32]byte + for i := 0; i < 32; i++ { + in[i] = byte(i + 1) + } + var out p256Element + + p256BigToLittle(&out, &in) + + // 检查每个 limb 是否为小端解包 + for i := 0; i < 4; i++ { + expected := binary.BigEndian.Uint64(in[i*8 : (i+1)*8]) + if out[i] != expected { + t.Errorf("limb %d: got 0x%x, want 0x%x", i, out[i], expected) + } + } + + // 逆操作测试 + var back [32]byte + p256LittleToBig(&back, &out) + if !bytes.Equal(in[:], back[:]) { + t.Errorf("p256LittleToBig(p256BigToLittle(...)) mismatch\nin: %x\nback: %x", in, back) + } +}