sm9/bn256: ppc64x gfp mul

This commit is contained in:
Sun Yimin 2024-10-05 16:33:01 +08:00 committed by GitHub
parent fca2c5e936
commit 9477b78fec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 543 additions and 6 deletions

View File

@ -31,3 +31,8 @@ func gfpTripleAsm(c, a *gfP)
// //
//go:noescape //go:noescape
func gfpSubAsm(c, a, b *gfP) func gfpSubAsm(c, a, b *gfP)
// Montgomery multiplication. Sets res = in1 * in2 * R⁻¹ mod p.
//
//go:noescape
func gfpMulAsm(c, a, b *gfP)

View File

@ -201,3 +201,536 @@ TEXT ·gfpTripleAsm(SB),0,$0-16
STXVD2X T0, (R0+R3) STXVD2X T0, (R0+R3)
STXVD2X T1, (R6+R3) STXVD2X T1, (R6+R3)
RET RET
#undef X1L
#undef X1H
#undef Y1L
#undef Y1H
#undef T1L
#undef T1H
#undef T0
#undef T1
#undef T2
#undef SEL1
#undef ZERO
#undef CAR1
#undef CAR2
#undef TT0
#undef TT1
#undef PL
#undef PH
// Vector multiply word
//
// VMLF x0, x1, out_low
// VMLHF x0, x1, out_hi
#define VMULT(x1, x2, out_low, out_hi) \
VMULEUW x1, x2, TMP1; \
VMULOUW x1, x2, TMP2; \
VMRGEW TMP1, TMP2, out_hi; \
VMRGOW TMP1, TMP2, out_low
//
// Vector multiply add word
//
// VMALF x0, x1, y, out_low
// VMALHF x0, x1, y, out_hi
#define VMULT_ADD(x1, x2, y, one, out_low, out_hi) \
VMULEUW y, one, TMP1; \
VMULOUW y, one, TMP2; \
VMULEUW x1, x2, out_hi; \
VMULOUW x1, x2, out_low; \
VADDUDM TMP1, out_hi, TMP1; \
VADDUDM TMP2, out_low, TMP2; \
VMRGEW TMP1, TMP2, out_hi; \
VMRGOW TMP1, TMP2, out_low
// ---------------------------------------
// gfpMulInternal
#define X0 V0
#define X1 V1
#define Y0 V2
#define Y1 V3
#define M1 V4
#define M0 V5
#define T0 V6
#define T1 V7
#define T2 V8
#define YDIG V9
#define ADD1 V16
#define ADD1H V17
#define ADD2 V18
#define ADD2H V19
#define RED1 V20
#define RED1H V21
#define RED2 V22
#define RED2H V23
#define CAR1 V24
#define CAR1M V25
#define MK0 V30
#define K0 V31
// TMP1, TMP2 used in
// VMULT macros
#define TMP1 V13
#define TMP2 V27
#define ONE V29 // 1s splatted by word
TEXT gfpMulInternal<>(SB), NOSPLIT, $0
// ---------------------------------------------------------------------------/
// VREPF $3, Y0, YDIG
VSPLTW $3, Y0, YDIG
VSPLTISW $1, ONE
// VMLF X0, YDIG, ADD1
// VMLF X1, YDIG, ADD2
// VMLHF X0, YDIG, ADD1H
// VMLHF X1, YDIG, ADD2H
VMULT(X0, YDIG, ADD1, ADD1H)
VMULT(X1, YDIG, ADD2, ADD2H)
// VMLF ADD1, K0, MK0
// VREPF $3, MK0, MK0
VMULUWM ADD1, K0, MK0
VSPLTW $3, MK0, MK0
// VMALF M0, MK0, ADD1, RED1
// VMALHF M0, MK0, ADD1, RED1H
// VMALF M1, MK0, ADD2, RED2
// VMALHF M1, MK0, ADD2, RED2H
VMULT_ADD(M0, MK0, ADD1, ONE, RED1, RED1H)
VMULT_ADD(M1, MK0, ADD2, ONE, RED2, RED2H)
VSPLTISB $0, T2 // VZERO T2
VSLDOI $12, RED2, RED1, RED1 // VSLDB
VSLDOI $12, T2, RED2, RED2 // VSLDB
VADDCUQ RED1, ADD1H, CAR1 // VACCQ
VADDUQM RED1, ADD1H, T0 // VAQ
VADDCUQ RED1H, T0, CAR1M // VACCQ
VADDUQM RED1H, T0, T0 // VAQ
// << ready for next MK0
VADDEUQM RED2, ADD2H, CAR1, T1 // VACQ
VADDECUQ RED2, ADD2H, CAR1, CAR1 // VACCCQ
VADDECUQ RED2H, T1, CAR1M, T2 // VACCCQ
VADDEUQM RED2H, T1, CAR1M, T1 // VACQ
VADDUQM CAR1, T2, T2 // VAQ
// ---------------------------------------------------
/* *
* ---+--------+--------+
* T2| T1 | T0 |
* ---+--------+--------+
* *(add)*
* +--------+--------+
* | X1 | X0 |
* +--------+--------+
* *(mul)*
* +--------+--------+
* | YDIG | YDIG |
* +--------+--------+
* *(add)*
* +--------+--------+
* | M1 | M0 |
* +--------+--------+
* *(mul)*
* +--------+--------+
* | MK0 | MK0 |
* +--------+--------+
*
* ---------------------
*
* +--------+--------+
* | ADD2 | ADD1 |
* +--------+--------+
* +--------+--------+
* | ADD2H | ADD1H |
* +--------+--------+
* +--------+--------+
* | RED2 | RED1 |
* +--------+--------+
* +--------+--------+
* | RED2H | RED1H |
* +--------+--------+
*/
// VREPF $2, Y0, YDIG
VSPLTW $2, Y0, YDIG
// VMALF X0, YDIG, T0, ADD1
// VMALF X1, YDIG, T1, ADD2
// VMALHF X0, YDIG, T0, ADD1H
// VMALHF X1, YDIG, T1, ADD2H
VMULT_ADD(X0, YDIG, T0, ONE, ADD1, ADD1H)
VMULT_ADD(X1, YDIG, T1, ONE, ADD2, ADD2H)
// VMLF ADD1, K0, MK0
// VREPF $3, MK0, MK0
VMULUWM ADD1, K0, MK0
VSPLTW $3, MK0, MK0
// VMALF M0, MK0, ADD1, RED1
// VMALHF M0, MK0, ADD1, RED1H
// VMALF M1, MK0, ADD2, RED2
// VMALHF M1, MK0, ADD2, RED2H
VMULT_ADD(M0, MK0, ADD1, ONE, RED1, RED1H)
VMULT_ADD(M1, MK0, ADD2, ONE, RED2, RED2H)
VSLDOI $12, RED2, RED1, RED1 // VSLDB
VSLDOI $12, T2, RED2, RED2 // VSLDB
VADDCUQ RED1, ADD1H, CAR1 // VACCQ
VADDUQM RED1, ADD1H, T0 // VAQ
VADDCUQ RED1H, T0, CAR1M // VACCQ
VADDUQM RED1H, T0, T0 // VAQ
// << ready for next MK0
VADDEUQM RED2, ADD2H, CAR1, T1 // VACQ
VADDECUQ RED2, ADD2H, CAR1, CAR1 // VACCCQ
VADDECUQ RED2H, T1, CAR1M, T2 // VACCCQ
VADDEUQM RED2H, T1, CAR1M, T1 // VACQ
VADDUQM CAR1, T2, T2 // VAQ
// ---------------------------------------------------
// VREPF $1, Y0, YDIG
VSPLTW $1, Y0, YDIG
// VMALF X0, YDIG, T0, ADD1
// VMALF X1, YDIG, T1, ADD2
// VMALHF X0, YDIG, T0, ADD1H
// VMALHF X1, YDIG, T1, ADD2H
VMULT_ADD(X0, YDIG, T0, ONE, ADD1, ADD1H)
VMULT_ADD(X1, YDIG, T1, ONE, ADD2, ADD2H)
// VMLF ADD1, K0, MK0
// VREPF $3, MK0, MK0
VMULUWM ADD1, K0, MK0
VSPLTW $3, MK0, MK0
// VMALF M0, MK0, ADD1, RED1
// VMALHF M0, MK0, ADD1, RED1H
// VMALF M1, MK0, ADD2, RED2
// VMALHF M1, MK0, ADD2, RED2H
VMULT_ADD(M0, MK0, ADD1, ONE, RED1, RED1H)
VMULT_ADD(M1, MK0, ADD2, ONE, RED2, RED2H)
VSLDOI $12, RED2, RED1, RED1 // VSLDB
VSLDOI $12, T2, RED2, RED2 // VSLDB
VADDCUQ RED1, ADD1H, CAR1 // VACCQ
VADDUQM RED1, ADD1H, T0 // VAQ
VADDCUQ RED1H, T0, CAR1M // VACCQ
VADDUQM RED1H, T0, T0 // VAQ
// << ready for next MK0
VADDEUQM RED2, ADD2H, CAR1, T1 // VACQ
VADDECUQ RED2, ADD2H, CAR1, CAR1 // VACCCQ
VADDECUQ RED2H, T1, CAR1M, T2 // VACCCQ
VADDEUQM RED2H, T1, CAR1M, T1 // VACQ
VADDUQM CAR1, T2, T2 // VAQ
// ---------------------------------------------------
// VREPF $0, Y0, YDIG
VSPLTW $0, Y0, YDIG
// VMALF X0, YDIG, T0, ADD1
// VMALF X1, YDIG, T1, ADD2
// VMALHF X0, YDIG, T0, ADD1H
// VMALHF X1, YDIG, T1, ADD2H
VMULT_ADD(X0, YDIG, T0, ONE, ADD1, ADD1H)
VMULT_ADD(X1, YDIG, T1, ONE, ADD2, ADD2H)
// VMLF ADD1, K0, MK0
// VREPF $3, MK0, MK0
VMULUWM ADD1, K0, MK0
VSPLTW $3, MK0, MK0
// VMALF M0, MK0, ADD1, RED1
// VMALHF M0, MK0, ADD1, RED1H
// VMALF M1, MK0, ADD2, RED2
// VMALHF M1, MK0, ADD2, RED2H
VMULT_ADD(M0, MK0, ADD1, ONE, RED1, RED1H)
VMULT_ADD(M1, MK0, ADD2, ONE, RED2, RED2H)
VSLDOI $12, RED2, RED1, RED1
VSLDOI $12, T2, RED2, RED2
VADDCUQ RED1, ADD1H, CAR1 // VACCQ
VADDUQM RED1, ADD1H, T0 // VAQ
VADDCUQ RED1H, T0, CAR1M // VACCQ
VADDUQM RED1H, T0, T0 // VAQ
// << ready for next MK0
VADDEUQM RED2, ADD2H, CAR1, T1 // VACQ
VADDECUQ RED2, ADD2H, CAR1, CAR1 // VACCCQ
VADDECUQ RED2H, T1, CAR1M, T2 // VACCCQ
VADDEUQM RED2H, T1, CAR1M, T1 // VACQ
VADDUQM CAR1, T2, T2 // VAQ
// ---------------------------------------------------
// VREPF $3, Y1, YDIG
VSPLTW $3, Y1, YDIG
// VMALF X0, YDIG, T0, ADD1
// VMALF X1, YDIG, T1, ADD2
// VMALHF X0, YDIG, T0, ADD1H
// VMALHF X1, YDIG, T1, ADD2H
VMULT_ADD(X0, YDIG, T0, ONE, ADD1, ADD1H)
VMULT_ADD(X1, YDIG, T1, ONE, ADD2, ADD2H)
// VMLF ADD1, K0, MK0
// VREPF $3, MK0, MK0
VMULUWM ADD1, K0, MK0
VSPLTW $3, MK0, MK0
// VMALF M0, MK0, ADD1, RED1
// VMALHF M0, MK0, ADD1, RED1H
// VMALF M1, MK0, ADD2, RED2
// VMALHF M1, MK0, ADD2, RED2H
VMULT_ADD(M0, MK0, ADD1, ONE, RED1, RED1H)
VMULT_ADD(M1, MK0, ADD2, ONE, RED2, RED2H)
VSLDOI $12, RED2, RED1, RED1
VSLDOI $12, T2, RED2, RED2
VADDCUQ RED1, ADD1H, CAR1 // VACCQ
VADDUQM RED1, ADD1H, T0 // VAQ
VADDCUQ RED1H, T0, CAR1M // VACCQ
VADDUQM RED1H, T0, T0 // VAQ
// << ready for next MK0
VADDEUQM RED2, ADD2H, CAR1, T1 // VACQ
VADDECUQ RED2, ADD2H, CAR1, CAR1 // VACCCQ
VADDECUQ RED2H, T1, CAR1M, T2 // VACCCQ
VADDEUQM RED2H, T1, CAR1M, T1 // VACQ
VADDUQM CAR1, T2, T2 // VAQ
// ---------------------------------------------------
// VREPF $2, Y1, YDIG
VSPLTW $2, Y1, YDIG
// VMALF X0, YDIG, T0, ADD1
// VMALF X1, YDIG, T1, ADD2
// VMALHF X0, YDIG, T0, ADD1H
// VMALHF X1, YDIG, T1, ADD2H
VMULT_ADD(X0, YDIG, T0, ONE, ADD1, ADD1H)
VMULT_ADD(X1, YDIG, T1, ONE, ADD2, ADD2H)
// VMLF ADD1, K0, MK0
// VREPF $3, MK0, MK0
VMULUWM ADD1, K0, MK0
VSPLTW $3, MK0, MK0
// VMALF M0, MK0, ADD1, RED1
// VMALHF M0, MK0, ADD1, RED1H
// VMALF M1, MK0, ADD2, RED2
// VMALHF M1, MK0, ADD2, RED2H
VMULT_ADD(M0, MK0, ADD1, ONE, RED1, RED1H)
VMULT_ADD(M1, MK0, ADD2, ONE, RED2, RED2H)
VSLDOI $12, RED2, RED1, RED1
VSLDOI $12, T2, RED2, RED2
VADDCUQ RED1, ADD1H, CAR1 // VACCQ
VADDUQM RED1, ADD1H, T0 // VAQ
VADDCUQ RED1H, T0, CAR1M // VACCQ
VADDUQM RED1H, T0, T0 // VAQ
// << ready for next MK0
VADDEUQM RED2, ADD2H, CAR1, T1 // VACQ
VADDECUQ RED2, ADD2H, CAR1, CAR1 // VACCCQ
VADDECUQ RED2H, T1, CAR1M, T2 // VACCCQ
VADDEUQM RED2H, T1, CAR1M, T1 // VACQ
VADDUQM CAR1, T2, T2 // VAQ
// ---------------------------------------------------
// VREPF $1, Y1, YDIG
VSPLTW $1, Y1, YDIG
// VMALF X0, YDIG, T0, ADD1
// VMALF X1, YDIG, T1, ADD2
// VMALHF X0, YDIG, T0, ADD1H
// VMALHF X1, YDIG, T1, ADD2H
VMULT_ADD(X0, YDIG, T0, ONE, ADD1, ADD1H)
VMULT_ADD(X1, YDIG, T1, ONE, ADD2, ADD2H)
// VMLF ADD1, K0, MK0
// VREPF $3, MK0, MK0
VMULUWM ADD1, K0, MK0
VSPLTW $3, MK0, MK0
// VMALF M0, MK0, ADD1, RED1
// VMALHF M0, MK0, ADD1, RED1H
// VMALF M1, MK0, ADD2, RED2
// VMALHF M1, MK0, ADD2, RED2H
VMULT_ADD(M0, MK0, ADD1, ONE, RED1, RED1H)
VMULT_ADD(M1, MK0, ADD2, ONE, RED2, RED2H)
VSLDOI $12, RED2, RED1, RED1
VSLDOI $12, T2, RED2, RED2
VADDCUQ RED1, ADD1H, CAR1 // VACCQ
VADDUQM RED1, ADD1H, T0 // VAQ
VADDCUQ RED1H, T0, CAR1M // VACCQ
VADDUQM RED1H, T0, T0 // VAQ
// << ready for next MK0
VADDEUQM RED2, ADD2H, CAR1, T1 // VACQ
VADDECUQ RED2, ADD2H, CAR1, CAR1 // VACCCQ
VADDECUQ RED2H, T1, CAR1M, T2 // VACCCQ
VADDEUQM RED2H, T1, CAR1M, T1 // VACQ
VADDUQM CAR1, T2, T2 // VAQ
// ---------------------------------------------------
// VREPF $0, Y1, YDIG
VSPLTW $0, Y1, YDIG
// VMALF X0, YDIG, T0, ADD1
// VMALF X1, YDIG, T1, ADD2
// VMALHF X0, YDIG, T0, ADD1H
// VMALHF X1, YDIG, T1, ADD2H
VMULT_ADD(X0, YDIG, T0, ONE, ADD1, ADD1H)
VMULT_ADD(X1, YDIG, T1, ONE, ADD2, ADD2H)
// VMLF ADD1, K0, MK0
// VREPF $3, MK0, MK0
VMULUWM ADD1, K0, MK0
VSPLTW $3, MK0, MK0
// VMALF M0, MK0, ADD1, RED1
// VMALHF M0, MK0, ADD1, RED1H
// VMALF M1, MK0, ADD2, RED2
// VMALHF M1, MK0, ADD2, RED2H
VMULT_ADD(M0, MK0, ADD1, ONE, RED1, RED1H)
VMULT_ADD(M1, MK0, ADD2, ONE, RED2, RED2H)
VSLDOI $12, RED2, RED1, RED1
VSLDOI $12, T2, RED2, RED2
VADDCUQ RED1, ADD1H, CAR1 // VACCQ
VADDUQM RED1, ADD1H, T0 // VAQ
VADDCUQ RED1H, T0, CAR1M // VACCQ
VADDUQM RED1H, T0, T0 // VAQ
// << ready for next MK0
VADDEUQM RED2, ADD2H, CAR1, T1 // VACQ
VADDECUQ RED2, ADD2H, CAR1, CAR1 // VACCCQ
VADDECUQ RED2H, T1, CAR1M, T2 // VACCCQ
VADDEUQM RED2H, T1, CAR1M, T1 // VACQ
VADDUQM CAR1, T2, T2 // VAQ
// ---------------------------------------------------
// VZERO RED1
// VSCBIQ M0, T0, CAR1
// VSQ M0, T0, ADD1
// VSBCBIQ T1, M1, CAR1, CAR1M
// VSBIQ T1, M1, CAR1, ADD2
// VSBIQ T2, RED1, CAR1M, T2
VSPLTISB $0, RED1 // VZERO RED1
VSUBCUQ T0, M0, CAR1 // VSCBIQ
VSUBUQM T0, M0, ADD1 // VSQ
VSUBECUQ T1, M1, CAR1, CAR1M // VSBCBIQ
VSUBEUQM T1, M1, CAR1, ADD2 // VSBIQ
VSUBEUQM T2, RED1, CAR1M, T2 // VSBIQ
// what output to use, ADD2||ADD1 or T1||T0?
VSEL ADD1, T0, T2, T0
VSEL ADD2, T1, T2, T1
RET
#undef X0
#undef X1
#undef Y0
#undef Y1
#undef M0
#undef M1
#undef T0
#undef T1
#undef T2
#undef YDIG
#undef ADD1
#undef ADD1H
#undef ADD2
#undef ADD2H
#undef RED1
#undef RED1H
#undef RED2
#undef RED2H
#undef CAR1
#undef CAR1M
#undef MK0
#undef K0
#undef TMP1
#undef TMP2
#undef ONE
// func gfpMul(c, a, b *gfP)
#define res_ptr R3
#define x_ptr R4
#define y_ptr R5
#define CPOOL R7
#define N R8
#define X0 V0
#define X1 V1
#define Y0 V2
#define Y1 V3
#define M0 V5
#define M1 V4
#define T0 V6
#define T1 V7
#define K0 V31
TEXT ·gfpMulAsm(SB),NOSPLIT,$0
MOVD c+0(FP), res_ptr
MOVD a+8(FP), x_ptr
MOVD b+16(FP), y_ptr
MOVD $16, R16
LXVD2X (R0)(x_ptr), X0
LXVD2X (R16)(x_ptr), X1
XXPERMDI X0, X0, $2, X0
XXPERMDI X1, X1, $2, X1
LXVD2X (R0)(y_ptr), Y0
LXVD2X (R16)(y_ptr), Y1
XXPERMDI Y0, Y0, $2, Y0
XXPERMDI Y1, Y1, $2, Y1
MOVD $·p2+0(SB), CPOOL
LXVD2X (CPOOL)(R0), M0
LXVD2X (CPOOL)(R16), M1
XXPERMDI M0, M0, $2, M0
XXPERMDI M1, M1, $2, M1
MOVD $·np+0(SB), CPOOL
LXVD2X (CPOOL)(R0), K0
VSPLTW $1, K0, K0
CALL gfpMulInternal<>(SB)
XXPERMDI T0, T0, $2, T0
XXPERMDI T1, T1, $2, T1
STXVD2X T0, (R0)(res_ptr)
STXVD2X T1, (R16)(res_ptr)
RET

View File

@ -31,7 +31,7 @@ func TestGfpAsmBasicOperations(t *testing.T) {
expectedDouble := fromBigInt(bigFromHex("551de7a0ee24723edcf314ff72f478fac1c7c4e7044238acc3913cfbcdaf7d05")) expectedDouble := fromBigInt(bigFromHex("551de7a0ee24723edcf314ff72f478fac1c7c4e7044238acc3913cfbcdaf7d05"))
expectedSub := fromBigInt(bigFromHex("67b381821c52a5624f3304a8149be8461e3bc07adcb872c38aa65051ba53ba97")) expectedSub := fromBigInt(bigFromHex("67b381821c52a5624f3304a8149be8461e3bc07adcb872c38aa65051ba53ba97"))
expectedNeg := fromBigInt(bigFromHex("7f1d8aad70909be90358f1d02240062433cc3a0248ded72febb879ec33ce6f22")) expectedNeg := fromBigInt(bigFromHex("7f1d8aad70909be90358f1d02240062433cc3a0248ded72febb879ec33ce6f22"))
//expectedMul := fromBigInt(bigFromHex("3d08bbad376584e4f74bd31f78f716372b96ba8c3f939c12b8d54e79b6489e76")) expectedMul := fromBigInt(bigFromHex("3d08bbad376584e4f74bd31f78f716372b96ba8c3f939c12b8d54e79b6489e76"))
//expectedMul2 := fromBigInt(bigFromHex("1df94a9e05a559ff38e0ab50cece734dc058d33738ceacaa15986a67cbff1ef6")) //expectedMul2 := fromBigInt(bigFromHex("1df94a9e05a559ff38e0ab50cece734dc058d33738ceacaa15986a67cbff1ef6"))
t.Parallel() t.Parallel()
@ -103,20 +103,20 @@ func TestGfpAsmBasicOperations(t *testing.T) {
t.Errorf("neg not same when neg self") t.Errorf("neg not same when neg self")
} }
}) })
/*
t.Run("mul", func(t *testing.T) { t.Run("mul", func(t *testing.T) {
ret := &gfP{} ret := &gfP{}
gfpMul(ret, x, y) gfpMulAsm(ret, x, y)
if *expectedMul != *ret { if *expectedMul != *ret {
t.Errorf("mul not same") t.Errorf("mul not same")
} }
ret.Set(x) ret.Set(x)
gfpMul(ret, ret, y) gfpMulAsm(ret, ret, y)
if *expectedMul != *ret { if *expectedMul != *ret {
t.Errorf("mul not same when mul self") t.Errorf("mul not same when mul self")
} }
}) })
/*
t.Run("square", func(t *testing.T) { t.Run("square", func(t *testing.T) {
ret, ret1, ret2 := &gfP{}, &gfP{}, &gfP{} ret, ret1, ret2 := &gfP{}, &gfP{}, &gfP{}
gfpMul(ret, x, y) gfpMul(ret, x, y)
@ -137,4 +137,3 @@ func TestGfpAsmBasicOperations(t *testing.T) {
}) })
*/ */
} }