From 9b4a77482a90d493311c25a03bbb285a15fdd984 Mon Sep 17 00:00:00 2001 From: emmansun Date: Sat, 24 Jun 2023 09:38:45 +0800 Subject: [PATCH] sm9/bn256: add test cases and refactoring --- sm9/bn256/gfp.go | 2 +- sm9/bn256/gfp2.go | 4 +- sm9/bn256/gfp_amd64.s | 136 ++++++++++-------------------------------- sm9/bn256/gfp_test.go | 40 ++++++++++++- 4 files changed, 73 insertions(+), 109 deletions(-) diff --git a/sm9/bn256/gfp.go b/sm9/bn256/gfp.go index 10291de..2a56759 100644 --- a/sm9/bn256/gfp.go +++ b/sm9/bn256/gfp.go @@ -78,7 +78,7 @@ func (e *gfP) exp(f *gfP, bits [4]uint64) { if (bits[word]>>bit)&1 == 1 { gfpMul(sum, sum, power) } - gfpMul(power, power, power) + gfpSqr(power, power, 1) } } diff --git a/sm9/bn256/gfp2.go b/sm9/bn256/gfp2.go index 606ba2b..40034b4 100644 --- a/sm9/bn256/gfp2.go +++ b/sm9/bn256/gfp2.go @@ -218,9 +218,9 @@ func (e *gfP2) Invert(a *gfP2) *gfP2 { // See "Implementing cryptographic pairings", M. Scott, section 3.2. // ftp://136.206.11.249/pub/crypto/pairings.pdf t1, t2, t3 := &gfP{}, &gfP{}, &gfP{} - gfpMul(t1, &a.x, &a.x) + gfpSqr(t1, &a.x, 1) gfpAdd(t3, t1, t1) - gfpMul(t2, &a.y, &a.y) + gfpSqr(t2, &a.y, 1) gfpAdd(t3, t3, t2) inv := &gfP{} diff --git a/sm9/bn256/gfp_amd64.s b/sm9/bn256/gfp_amd64.s index 0031a24..2dabf75 100644 --- a/sm9/bn256/gfp_amd64.s +++ b/sm9/bn256/gfp_amd64.s @@ -28,13 +28,12 @@ MOVQ 16+r, a2 \ MOVQ 24+r, a3 -#define gfpCarry(a0,a1,a2,a3,a4, b0,b1,b2,b3,b4) \ +#define gfpCarry(a0,a1,a2,a3, b0,b1,b2,b3,b4) \ \ // b = a-p MOVQ a0, b0 \ MOVQ a1, b1 \ MOVQ a2, b2 \ MOVQ a3, b3 \ - MOVQ a4, b4 \ \ SUBQ ·p2+0(SB), b0 \ SBBQ ·p2+8(SB), b1 \ @@ -49,6 +48,25 @@ CMOVQCC b2, a2 \ CMOVQCC b3, a3 +#define gfpCarryWithoutCarry(a0,a1,a2,a3, b0,b1,b2,b3) \ + \ // b = a-p + MOVQ a0, b0 \ + MOVQ a1, b1 \ + MOVQ a2, b2 \ + MOVQ a3, b3 \ + \ + SUBQ ·p2+0(SB), b0 \ + SBBQ ·p2+8(SB), b1 \ + SBBQ ·p2+16(SB), b2 \ + SBBQ ·p2+24(SB), b3 \ + \ + \ // if b is negative then return a + \ // else return b + CMOVQCC b0, a0 \ + CMOVQCC b1, a1 \ + CMOVQCC b2, a2 \ + CMOVQCC b3, a3 + TEXT ·gfpNeg(SB),0,$0-16 MOVQ ·p2+0(SB), R8 MOVQ ·p2+8(SB), R9 @@ -61,8 +79,7 @@ TEXT ·gfpNeg(SB),0,$0-16 SBBQ 16(DI), R10 SBBQ 24(DI), R11 - MOVQ $0, AX - gfpCarry(R8,R9,R10,R11,AX, R12,R13,R14,CX,BX) + gfpCarryWithoutCarry(R8,R9,R10,R11, R12,R13,R14,CX) MOVQ c+0(FP), DI storeBlock(R8,R9,R10,R11, 0(DI)) @@ -81,7 +98,7 @@ TEXT ·gfpAdd(SB),0,$0-24 ADCQ 24(SI), R11 ADCQ $0, R12 - gfpCarry(R8,R9,R10,R11,R12, R13,R14,CX,AX,BX) + gfpCarry(R8,R9,R10,R11, R13,R14,CX,AX,R12) MOVQ c+0(FP), DI storeBlock(R8,R9,R10,R11, 0(DI)) @@ -306,26 +323,8 @@ TEXT ·gfpMul(SB),0,$0-24 ADCQ t1, acc1 ADCQ $0, acc2 // Copy result [255:0] - MOVQ acc4, x_ptr - MOVQ acc5, acc3 - MOVQ acc0, t0 - MOVQ acc1, t1 - // Subtract p2 - SUBQ ·p2+0x00(SB), acc4 - SBBQ ·p2+0x08(SB) ,acc5 - SBBQ ·p2+0x10(SB), acc0 - SBBQ ·p2+0x18(SB), acc1 - SBBQ $0, acc2 - - CMOVQCS x_ptr, acc4 - CMOVQCS acc3, acc5 - CMOVQCS t0, acc0 - CMOVQCS t1, acc1 - - MOVQ acc4, (8*0)(res_ptr) - MOVQ acc5, (8*1)(res_ptr) - MOVQ acc0, (8*2)(res_ptr) - MOVQ acc1, (8*3)(res_ptr) + gfpCarry(acc4,acc5,acc0,acc1, x_ptr,acc3,t0,t1,acc2) + storeBlock(acc4,acc5,acc0,acc1, 0(res_ptr)) RET nobmi2Mul: @@ -588,26 +587,8 @@ nobmi2Mul: ADCQ DX, acc1 ADCQ $0, acc2 // Copy result [255:0] - MOVQ acc4, x_ptr - MOVQ acc5, acc3 - MOVQ acc0, t0 - MOVQ acc1, t1 - // Subtract p2 - SUBQ ·p2+0x00(SB), acc4 - SBBQ ·p2+0x08(SB) ,acc5 - SBBQ ·p2+0x10(SB), acc0 - SBBQ ·p2+0x18(SB), acc1 - SBBQ $0, acc2 - - CMOVQCS x_ptr, acc4 - CMOVQCS acc3, acc5 - CMOVQCS t0, acc0 - CMOVQCS t1, acc1 - - MOVQ acc4, (8*0)(res_ptr) - MOVQ acc5, (8*1)(res_ptr) - MOVQ acc0, (8*2)(res_ptr) - MOVQ acc1, (8*3)(res_ptr) + gfpCarry(acc4,acc5,acc0,acc1, x_ptr,acc3,t0,t1,acc2) + storeBlock(acc4,acc5,acc0,acc1, 0(res_ptr)) RET @@ -780,26 +761,9 @@ gfpSqrLoopBMI2: ADCQ x_ptr, acc3 ADCQ $0, t0 - MOVQ acc0, acc4 - MOVQ acc1, acc5 - MOVQ acc2, y_ptr - MOVQ acc3, t1 - // Subtract p2 - SUBQ ·p2+0x00(SB), acc0 - SBBQ ·p2+0x08(SB) ,acc1 - SBBQ ·p2+0x10(SB), acc2 - SBBQ ·p2+0x18(SB), acc3 - SBBQ $0, t0 + gfpCarry(acc0,acc1,acc2,acc3, acc4,acc5,y_ptr,t1,t0) + storeBlock(acc0,acc1,acc2,acc3, 0(res_ptr)) - CMOVQCS acc4, acc0 - CMOVQCS acc5, acc1 - CMOVQCS y_ptr, acc2 - CMOVQCS t1, acc3 - - MOVQ acc0, (8*0)(res_ptr) - MOVQ acc1, (8*1)(res_ptr) - MOVQ acc2, (8*2)(res_ptr) - MOVQ acc3, (8*3)(res_ptr) MOVQ res_ptr, x_ptr DECQ BX JNE gfpSqrLoopBMI2 @@ -1039,26 +1003,8 @@ gfpSqrLoop: ADCQ x_ptr, acc3 ADCQ $0, t0 - MOVQ acc0, acc4 - MOVQ acc1, acc5 - MOVQ acc2, y_ptr - MOVQ acc3, t1 - // Subtract p2 - SUBQ ·p2+0x00(SB), acc0 - SBBQ ·p2+0x08(SB) ,acc1 - SBBQ ·p2+0x10(SB), acc2 - SBBQ ·p2+0x18(SB), acc3 - SBBQ $0, t0 - - CMOVQCS acc4, acc0 - CMOVQCS acc5, acc1 - CMOVQCS y_ptr, acc2 - CMOVQCS t1, acc3 - - MOVQ acc0, (8*0)(res_ptr) - MOVQ acc1, (8*1)(res_ptr) - MOVQ acc2, (8*2)(res_ptr) - MOVQ acc3, (8*3)(res_ptr) + gfpCarry(acc0,acc1,acc2,acc3, acc4,acc5,y_ptr,t1,t0) + storeBlock(acc0,acc1,acc2,acc3, 0(res_ptr)) MOVQ res_ptr, x_ptr DECQ BX JNE gfpSqrLoop @@ -1222,24 +1168,6 @@ TEXT ·gfpFromMont(SB),NOSPLIT,$0 ADDQ AX, acc0 ADCQ DX, acc1 - MOVQ acc4, x_ptr - MOVQ acc5, acc3 - MOVQ acc0, t0 - MOVQ acc1, t1 - - SUBQ ·p2+0x00(SB), acc4 - SBBQ ·p2+0x08(SB) ,acc5 - SBBQ ·p2+0x10(SB), acc0 - SBBQ ·p2+0x18(SB), acc1 - - CMOVQCS x_ptr, acc4 - CMOVQCS acc3, acc5 - CMOVQCS t0, acc0 - CMOVQCS t1, acc1 - - MOVQ acc4, (8*0)(res_ptr) - MOVQ acc5, (8*1)(res_ptr) - MOVQ acc0, (8*2)(res_ptr) - MOVQ acc1, (8*3)(res_ptr) - + gfpCarryWithoutCarry(acc4, acc5, acc0, acc1, x_ptr, acc3, t0, t1) + storeBlock(acc4,acc5,acc0,acc1, 0(res_ptr)) RET diff --git a/sm9/bn256/gfp_test.go b/sm9/bn256/gfp_test.go index 963c9aa..da3dbef 100644 --- a/sm9/bn256/gfp_test.go +++ b/sm9/bn256/gfp_test.go @@ -36,10 +36,26 @@ func Test_gfpBasicOperations(t *testing.T) { t.Errorf("mul not same") } - gfpMul(ret, ret, ret) - if *expectedMul2 != *ret { + ret1, ret2 := &gfP{}, &gfP{} + gfpMul(ret1, ret, ret) + if *ret1 != *expectedMul2 { t.Errorf("mul not same") } + gfpMul(ret1, ret1, ret1) + gfpSqr(ret2, ret, 2) + if *ret1 != *ret2 { + t.Errorf("mul/sqr not same") + } +} + +func TestFromMont(t *testing.T) { + x := fromBigInt(bigFromHex("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141")) + ret1, ret2 := &gfP{}, &gfP{} + gfpFromMont(ret1, x) + gfpMul(ret2, x, &gfP{1}) + if *ret1 != *ret2 { + t.Errorf("mul/fromMont not same") + } } func TestGfpExp(t *testing.T) { @@ -140,3 +156,23 @@ func TestInvert(t *testing.T) { t.Errorf("got %v, expected %v", y, one) } } + +func BenchmarkGfPMul(b *testing.B) { + x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596")) + b.ReportAllocs() + b.ResetTimer() + ret := &gfP{} + for i := 0; i < b.N; i++ { + gfpMul(ret, x, x) + } +} + +func BenchmarkGfPSqr(b *testing.B) { + x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596")) + b.ReportAllocs() + b.ResetTimer() + ret := &gfP{} + for i := 0; i < b.N; i++ { + gfpSqr(ret, x, 1) + } +}