mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-27 04:36:19 +08:00
sm9/bn256: gfp ppc64x add/sub
This commit is contained in:
parent
94372eac9d
commit
0ef82b1be5
6
.github/workflows/test_ppc64.yaml
vendored
6
.github/workflows/test_ppc64.yaml
vendored
@ -36,6 +36,12 @@ jobs:
|
|||||||
GOARCH: ${{ matrix.arch }}
|
GOARCH: ${{ matrix.arch }}
|
||||||
GOPPC64: ${{ matrix.ppc64 }}
|
GOPPC64: ${{ matrix.ppc64 }}
|
||||||
|
|
||||||
|
- name: Test bn256
|
||||||
|
run: go test -v ./sm9/bn256/...
|
||||||
|
env:
|
||||||
|
GOARCH: ${{ matrix.arch }}
|
||||||
|
GOPPC64: ${{ matrix.ppc64 }}
|
||||||
|
|
||||||
- name: Test ZUC
|
- name: Test ZUC
|
||||||
run: go test -v ./zuc/...
|
run: go test -v ./zuc/...
|
||||||
env:
|
env:
|
||||||
|
33
sm9/bn256/gfp_ppc64x.go
Normal file
33
sm9/bn256/gfp_ppc64x.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2024 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 (ppc64 || ppc64le) && !purego
|
||||||
|
|
||||||
|
package bn256
|
||||||
|
|
||||||
|
// Set c = p - a, if c == p, then c = 0
|
||||||
|
// It seems this function's performance is worse than gfpSub with zero.
|
||||||
|
//
|
||||||
|
//go:noescape
|
||||||
|
func gfpNegAsm(c, a *gfP)
|
||||||
|
|
||||||
|
// Set c = a + b, if c >= p, then c = c - p
|
||||||
|
//
|
||||||
|
//go:noescape
|
||||||
|
func gfpAddAsm(c, a, b *gfP)
|
||||||
|
|
||||||
|
// Set c = a + a
|
||||||
|
//
|
||||||
|
//go:noescape
|
||||||
|
func gfpDoubleAsm(c, a *gfP)
|
||||||
|
|
||||||
|
// Set c = a + a + a
|
||||||
|
//
|
||||||
|
//go:noescape
|
||||||
|
func gfpTripleAsm(c, a *gfP)
|
||||||
|
|
||||||
|
// Set c = a - b, if c is negative, then c = c + p
|
||||||
|
//
|
||||||
|
//go:noescape
|
||||||
|
func gfpSubAsm(c, a, b *gfP)
|
221
sm9/bn256/gfp_ppc64x.s
Normal file
221
sm9/bn256/gfp_ppc64x.s
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
// Copyright 2024 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 (ppc64 || ppc64le) && !purego
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
#define X1L V0
|
||||||
|
#define X1H V1
|
||||||
|
#define Y1L V2
|
||||||
|
#define Y1H V3
|
||||||
|
#define T1L V4
|
||||||
|
#define T1H V5
|
||||||
|
#define SEL V6
|
||||||
|
#define ZERO V7
|
||||||
|
#define CAR1 V8
|
||||||
|
#define CAR2 V9
|
||||||
|
#define TT0 V10
|
||||||
|
#define TT1 V11
|
||||||
|
|
||||||
|
#define PL V30
|
||||||
|
#define PH V31
|
||||||
|
|
||||||
|
TEXT ·gfpNegAsm(SB),0,$0-16
|
||||||
|
MOVD c+0(FP), R3
|
||||||
|
MOVD a+8(FP), R4
|
||||||
|
|
||||||
|
MOVD $16, R5
|
||||||
|
LXVD2X (R4)(R0), Y1L
|
||||||
|
LXVD2X (R4)(R5), Y1H
|
||||||
|
|
||||||
|
XXPERMDI Y1H, Y1H, $2, Y1H
|
||||||
|
XXPERMDI Y1L, Y1L, $2, Y1L
|
||||||
|
|
||||||
|
MOVD $·p2+0(SB), R6
|
||||||
|
LXVD2X (R6)(R0), PL
|
||||||
|
LXVD2X (R6)(R5), PH
|
||||||
|
|
||||||
|
XXPERMDI PH, PH, $2, PH
|
||||||
|
XXPERMDI PL, PL, $2, PL
|
||||||
|
|
||||||
|
VSUBCUQ PL, Y1L, CAR1 // subtract part2 giving carry
|
||||||
|
VSUBUQM PL, Y1L, T1L // subtract part2 giving result
|
||||||
|
VSUBEUQM PH, Y1H, CAR1, T1H // subtract part1 using carry from part2
|
||||||
|
|
||||||
|
VSUBCUQ Y1L, PL, CAR1
|
||||||
|
VSUBUQM Y1L, PL, Y1L
|
||||||
|
VSUBECUQ Y1H, PH, CAR1, SEL
|
||||||
|
VSUBEUQM Y1H, PH, CAR1, Y1H
|
||||||
|
|
||||||
|
VSEL T1H, Y1H, SEL, Y1H
|
||||||
|
VSEL T1L, Y1L, SEL, Y1L
|
||||||
|
|
||||||
|
XXPERMDI Y1H, Y1H, $2, Y1H
|
||||||
|
XXPERMDI Y1L, Y1L, $2, Y1L
|
||||||
|
|
||||||
|
STXVD2X Y1L, (R0+R3)
|
||||||
|
STXVD2X Y1H, (R5+R3)
|
||||||
|
RET
|
||||||
|
|
||||||
|
|
||||||
|
#define gfpSubInternal(T1, T0, X1, X0, Y1, Y0) \
|
||||||
|
VSPLTISB $0, ZERO \ // VZERO
|
||||||
|
VSUBCUQ X0, Y0, CAR1 \
|
||||||
|
VSUBUQM X0, Y0, T0 \
|
||||||
|
VSUBECUQ X1, Y1, CAR1, SEL1 \
|
||||||
|
VSUBEUQM X1, Y1, CAR1, T1 \
|
||||||
|
VSUBUQM ZERO, SEL1, SEL1 \ // VSQ
|
||||||
|
\
|
||||||
|
VADDCUQ T0, PL, CAR1 \ // VACCQ
|
||||||
|
VADDUQM T0, PL, TT0 \ // VAQ
|
||||||
|
VADDEUQM T1, PH, CAR1, TT1 \ // VACQ
|
||||||
|
\
|
||||||
|
VSEL TT0, T0, SEL1, T0 \
|
||||||
|
VSEL TT1, T1, SEL1, T1 \
|
||||||
|
|
||||||
|
TEXT ·gfpSubAsm(SB),0,$0-24
|
||||||
|
MOVD c+0(FP), R3
|
||||||
|
MOVD a+8(FP), R4
|
||||||
|
MOVD b+16(FP), R5
|
||||||
|
|
||||||
|
MOVD $16, R6
|
||||||
|
LXVD2X (R4)(R0), X1L
|
||||||
|
LXVD2X (R4)(R6), X1H
|
||||||
|
XXPERMDI X1H, X1H, $2, X1H
|
||||||
|
XXPERMDI X1L, X1L, $2, X1L
|
||||||
|
|
||||||
|
LXVD2X (R5)(R0), Y1L
|
||||||
|
LXVD2X (R5)(R6), X1H
|
||||||
|
XXPERMDI Y1H, Y1H, $2, Y1H
|
||||||
|
XXPERMDI Y1L, Y1L, $2, Y1L
|
||||||
|
|
||||||
|
MOVD $·p2+0(SB), R7
|
||||||
|
LXVD2X (R7)(R0), PL
|
||||||
|
LXVD2X (R7)(R5), PH
|
||||||
|
XXPERMDI PH, PH, $2, PH
|
||||||
|
XXPERMDI PL, PL, $2, PL
|
||||||
|
|
||||||
|
gfpSubInternal(T1, T0, X1H, X1L, Y1H, Y1L)
|
||||||
|
|
||||||
|
XXPERMDI T1, T1, $2, T1
|
||||||
|
XXPERMDI T0, T0, $2, T0
|
||||||
|
|
||||||
|
STXVD2X T0, (R0+R3)
|
||||||
|
STXVD2X T1, (R6+R3)
|
||||||
|
RET
|
||||||
|
|
||||||
|
#define gfpAddInternal(T1, T0, X1, X0, Y1, Y0) \
|
||||||
|
VADDCUQ X0, Y0, CAR1 \
|
||||||
|
VADDUQM X0, Y0, T0 \
|
||||||
|
VADDECUQ X1, Y1, CAR1, T2 \ // VACCCQ
|
||||||
|
VADDEUQM X1, Y1, CAR1, T1 \
|
||||||
|
\
|
||||||
|
VSUBCUQ T0, PL, CAR1 \ // VSCBIQ
|
||||||
|
VSUBUQM T0, PL, TT0 \
|
||||||
|
VSUBECUQ T1, PH, CAR1, CAR2 \ // VSBCBIQ
|
||||||
|
VSUBEUQM T1, PH, CAR1, TT1 \ // VSBIQ
|
||||||
|
VSUBEUQM T2, ZERO, CAR2, SEL1 \
|
||||||
|
\
|
||||||
|
VSEL TT0, T0, SEL1, T0 \
|
||||||
|
VSEL TT1, T1, SEL1, T1
|
||||||
|
|
||||||
|
TEXT ·gfpAddAsm(SB),0,$0-24
|
||||||
|
MOVD c+0(FP), R3
|
||||||
|
MOVD a+8(FP), R4
|
||||||
|
MOVD b+16(FP), R5
|
||||||
|
|
||||||
|
MOVD $16, R6
|
||||||
|
LXVD2X (R4)(R0), X1L
|
||||||
|
LXVD2X (R4)(R6), X1H
|
||||||
|
XXPERMDI X1H, X1H, $2, X1H
|
||||||
|
XXPERMDI X1L, X1L, $2, X1L
|
||||||
|
|
||||||
|
LXVD2X (R5)(R0), Y1L
|
||||||
|
LXVD2X (R5)(R6), X1H
|
||||||
|
XXPERMDI Y1H, Y1H, $2, Y1H
|
||||||
|
XXPERMDI Y1L, Y1L, $2, Y1L
|
||||||
|
|
||||||
|
MOVD $·p2+0(SB), R7
|
||||||
|
LXVD2X (R7)(R0), PL
|
||||||
|
LXVD2X (R7)(R5), PH
|
||||||
|
XXPERMDI PH, PH, $2, PH
|
||||||
|
XXPERMDI PL, PL, $2, PL
|
||||||
|
|
||||||
|
VSPLTISB $0, ZERO
|
||||||
|
|
||||||
|
gfpAddInternal(T1, T0, X1H, X1L, Y1H, Y1L)
|
||||||
|
|
||||||
|
XXPERMDI T1, T1, $2, T1
|
||||||
|
XXPERMDI T0, T0, $2, T0
|
||||||
|
|
||||||
|
STXVD2X T0, (R0+R3)
|
||||||
|
STXVD2X T1, (R6+R3)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·gfpDoubleAsm(SB),0,$0-16
|
||||||
|
MOVD c+0(FP), R3
|
||||||
|
MOVD a+8(FP), R4
|
||||||
|
|
||||||
|
MOVD $16, R6
|
||||||
|
LXVD2X (R4)(R0), X1L
|
||||||
|
LXVD2X (R4)(R6), X1H
|
||||||
|
XXPERMDI X1H, X1H, $2, X1H
|
||||||
|
XXPERMDI X1L, X1L, $2, X1L
|
||||||
|
|
||||||
|
MOVD $·p2+0(SB), R7
|
||||||
|
LXVD2X (R7)(R0), PL
|
||||||
|
LXVD2X (R7)(R5), PH
|
||||||
|
XXPERMDI PH, PH, $2, PH
|
||||||
|
XXPERMDI PL, PL, $2, PL
|
||||||
|
|
||||||
|
VSPLTISB $0, ZERO
|
||||||
|
|
||||||
|
gfpAddInternal(T1, T0, X1H, X1L, X1H, X1L)
|
||||||
|
|
||||||
|
VOR T1, T1, X1H
|
||||||
|
VOR T0, T0, X1L
|
||||||
|
gfpAddInternal(T1, T0, X1H, X1L, X1H, X1L)
|
||||||
|
|
||||||
|
XXPERMDI T1, T1, $2, T1
|
||||||
|
XXPERMDI T0, T0, $2, T0
|
||||||
|
|
||||||
|
STXVD2X T0, (R0+R3)
|
||||||
|
STXVD2X T1, (R6+R3)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·gfpTripleAsm(SB),0,$0-16
|
||||||
|
MOVD c+0(FP), R3
|
||||||
|
MOVD a+8(FP), R4
|
||||||
|
|
||||||
|
MOVD $16, R6
|
||||||
|
LXVD2X (R4)(R0), X1L
|
||||||
|
LXVD2X (R4)(R6), X1H
|
||||||
|
XXPERMDI X1H, X1H, $2, X1H
|
||||||
|
XXPERMDI X1L, X1L, $2, X1L
|
||||||
|
|
||||||
|
MOVD $·p2+0(SB), R7
|
||||||
|
LXVD2X (R7)(R0), PL
|
||||||
|
LXVD2X (R7)(R5), PH
|
||||||
|
XXPERMDI PH, PH, $2, PH
|
||||||
|
XXPERMDI PL, PL, $2, PL
|
||||||
|
|
||||||
|
VSPLTISB $0, ZERO
|
||||||
|
|
||||||
|
gfpAddInternal(T1, T0, X1H, X1L, X1H, X1L)
|
||||||
|
|
||||||
|
VOR T1, T1, X1H
|
||||||
|
VOR T0, T0, X1L
|
||||||
|
gfpAddInternal(T1, T0, X1H, X1L, X1H, X1L)
|
||||||
|
|
||||||
|
VOR T1, T1, X1H
|
||||||
|
VOR T0, T0, X1L
|
||||||
|
gfpAddInternal(T1, T0, X1H, X1L, X1H, X1L)
|
||||||
|
|
||||||
|
XXPERMDI T1, T1, $2, T1
|
||||||
|
XXPERMDI T0, T0, $2, T0
|
||||||
|
|
||||||
|
STXVD2X T0, (R0+R3)
|
||||||
|
STXVD2X T1, (R6+R3)
|
||||||
|
RET
|
136
sm9/bn256/gfp_ppc64x_test.go
Normal file
136
sm9/bn256/gfp_ppc64x_test.go
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
// Copyright 2024 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 (ppc64 || ppc64le) && !purego
|
||||||
|
|
||||||
|
package bn256
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestGfpNeg(t *testing.T) {
|
||||||
|
x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596"))
|
||||||
|
got := &gfP{}
|
||||||
|
gfpSubAsm(got, zero, x)
|
||||||
|
expected := &gfP{}
|
||||||
|
gfpNegAsm(expected, x)
|
||||||
|
if *expected != *got {
|
||||||
|
t.Errorf("got %v, expected %v", got, expected)
|
||||||
|
}
|
||||||
|
gfpSubAsm(got, zero, zero)
|
||||||
|
gfpNegAsm(expected, zero)
|
||||||
|
if *expected != *got {
|
||||||
|
t.Errorf("got %v, expected %v", got, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGfpBasicOperations(t *testing.T) {
|
||||||
|
x := fromBigInt(bigFromHex("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141"))
|
||||||
|
y := fromBigInt(bigFromHex("3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B"))
|
||||||
|
expectedAdd := fromBigInt(bigFromHex("0691692307d370af56226e57920199fbbe10f216c67fbc9468c7f225a4b1f21f"))
|
||||||
|
expectedDouble := fromBigInt(bigFromHex("551de7a0ee24723edcf314ff72f478fac1c7c4e7044238acc3913cfbcdaf7d05"))
|
||||||
|
expectedSub := fromBigInt(bigFromHex("67b381821c52a5624f3304a8149be8461e3bc07adcb872c38aa65051ba53ba97"))
|
||||||
|
expectedNeg := fromBigInt(bigFromHex("7f1d8aad70909be90358f1d02240062433cc3a0248ded72febb879ec33ce6f22"))
|
||||||
|
expectedMul := fromBigInt(bigFromHex("3d08bbad376584e4f74bd31f78f716372b96ba8c3f939c12b8d54e79b6489e76"))
|
||||||
|
expectedMul2 := fromBigInt(bigFromHex("1df94a9e05a559ff38e0ab50cece734dc058d33738ceacaa15986a67cbff1ef6"))
|
||||||
|
|
||||||
|
t.Parallel()
|
||||||
|
t.Run("add", func(t *testing.T) {
|
||||||
|
ret := &gfP{}
|
||||||
|
gfpAddAsm(ret, x, y)
|
||||||
|
if *expectedAdd != *ret {
|
||||||
|
t.Errorf("add not same")
|
||||||
|
}
|
||||||
|
x1 := &gfP{}
|
||||||
|
x1.Set(x)
|
||||||
|
gfpAddAsm(x1, x1, y)
|
||||||
|
if *expectedAdd != *x1 {
|
||||||
|
t.Errorf("add not same when add self")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("double", func(t *testing.T) {
|
||||||
|
ret := &gfP{}
|
||||||
|
gfpDoubleAsm(ret, x)
|
||||||
|
if ret.Equal(expectedDouble) != 1 {
|
||||||
|
t.Errorf("double not same, got %v, expected %v", ret, expectedDouble)
|
||||||
|
}
|
||||||
|
ret.Set(x)
|
||||||
|
gfpDoubleAsm(ret, ret)
|
||||||
|
if ret.Equal(expectedDouble) != 1 {
|
||||||
|
t.Errorf("double not same, got %v, expected %v", ret, expectedDouble)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("triple", func(t *testing.T) {
|
||||||
|
expected := &gfP{}
|
||||||
|
gfpAddAsm(expected, x, expectedDouble)
|
||||||
|
ret := &gfP{}
|
||||||
|
ret.Set(x)
|
||||||
|
gfpTripleAsm(ret, ret)
|
||||||
|
if ret.Equal(expected) != 1 {
|
||||||
|
t.Errorf("expected %v, got %v", expected, ret)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("sub", func(t *testing.T) {
|
||||||
|
ret := &gfP{}
|
||||||
|
gfpSubAsm(ret, y, x)
|
||||||
|
if *expectedSub != *ret {
|
||||||
|
t.Errorf("sub not same")
|
||||||
|
}
|
||||||
|
x1 := &gfP{}
|
||||||
|
x1.Set(x)
|
||||||
|
gfpSubAsm(x1, y, x1)
|
||||||
|
if *expectedSub != *x1 {
|
||||||
|
t.Errorf("sub not same when sub self")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("neg", func(t *testing.T) {
|
||||||
|
ret := &gfP{}
|
||||||
|
gfpNegAsm(ret, y)
|
||||||
|
if *expectedNeg != *ret {
|
||||||
|
t.Errorf("neg not same")
|
||||||
|
}
|
||||||
|
ret.Set(y)
|
||||||
|
gfpNegAsm(ret, ret)
|
||||||
|
if *expectedNeg != *ret {
|
||||||
|
t.Errorf("neg not same when neg self")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
/*
|
||||||
|
t.Run("mul", func(t *testing.T) {
|
||||||
|
ret := &gfP{}
|
||||||
|
gfpMul(ret, x, y)
|
||||||
|
if *expectedMul != *ret {
|
||||||
|
t.Errorf("mul not same")
|
||||||
|
}
|
||||||
|
ret.Set(x)
|
||||||
|
gfpMul(ret, ret, y)
|
||||||
|
if *expectedMul != *ret {
|
||||||
|
t.Errorf("mul not same when mul self")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("square", func(t *testing.T) {
|
||||||
|
ret, ret1, ret2 := &gfP{}, &gfP{}, &gfP{}
|
||||||
|
gfpMul(ret, x, y)
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
ret2.Set(ret)
|
||||||
|
gfpSqr(ret2, ret2, 2)
|
||||||
|
if *ret1 != *ret2 {
|
||||||
|
t.Errorf("mul/sqr not same when square self")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user