Golang中如何对两个EcPoint进行减法运算
Golang中如何对两个EcPoint进行减法运算 我是密码学领域的初学者。最近尝试对椭圆曲线进行一些研究,但没有找到任何关于两个椭圆曲线点相减的代码。
例如:椭圆曲线点a - 椭圆曲线点b。
// reverse the transform than to operate in affine coordinates.
import (
"io"
"math/big"
"sync"
)
// A Curve represents a short-form Weierstrass curve with a=-3.
// See https://www.hyperelliptic.org/EFD/g1p/auto-shortw.html
type Curve interface {
// Params returns the parameters for the curve.
Params() *CurveParams
// IsOnCurve reports whether the given (x,y) lies on the curve.
IsOnCurve(x, y *big.Int) bool
// Add returns the sum of (x1,y1) and (x2,y2)
Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int)
// Double returns 2*(x,y)
Double(x1, y1 *big.Int) (x, y *big.Int)
// ScalarMult returns k*(Bx,By) where k is a number in big-endian form.
ScalarMult(x1, y1 *big.Int, k []byte) (x, y *big.Int)
}
我尝试了以下方法:
- 使用a + (-1) * b;但结果似乎不正确
- 计算b的负值公式(参考https://www.hyperelliptic.org/EFD/g1p/auto-shortw.html),然后计算a + b的负值。虽然b的负值加上b等于零,但b的负值不在曲线上,结果也不正确
有人对此有什么想法吗?我是不是做错了什么?
更多关于Golang中如何对两个EcPoint进行减法运算的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang中如何对两个EcPoint进行减法运算的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在椭圆曲线密码学中,点减法实际上是通过点加法实现的。具体来说,点A减去点B等于点A加上点B的负点(即B的逆元)。
对于椭圆曲线上的点P(x, y),其负点-P的坐标为(x, -y mod p),其中p是曲线定义的素数域。
以下是实现两个EcPoint减法的示例代码:
package main
import (
"math/big"
)
// 假设我们有一个实现了Curve接口的具体曲线类型
type ExampleCurve struct {
*CurveParams
}
// 点减法函数
func (curve *ExampleCurve) Subtract(x1, y1, x2, y2 *big.Int) (x, y *big.Int) {
// 计算点B的负点:-B = (x2, -y2 mod P)
p := curve.P
negY2 := new(big.Int).Neg(y2)
negY2.Mod(negY2, p)
// A - B = A + (-B)
return curve.Add(x1, y1, x2, negY2)
}
// 完整的示例使用
func main() {
// 假设我们有一个曲线实例
curve := &ExampleCurve{
CurveParams: &CurveParams{
P: big.NewInt(23), // 示例素数,实际使用中应该是曲线定义的大素数
// 其他曲线参数...
},
}
// 示例点坐标
x1 := big.NewInt(3)
y1 := big.NewInt(10)
x2 := big.NewInt(9)
y2 := big.NewInt(7)
// 计算点A - 点B
resultX, resultY := curve.Subtract(x1, y1, x2, y2)
// 验证结果:应该满足 (A - B) + B = A
verifyX, verifyY := curve.Add(resultX, resultY, x2, y2)
// 验证结果应该等于原始点A
if verifyX.Cmp(x1) == 0 && verifyY.Cmp(y1) == 0 {
// 验证通过
}
}
如果你在使用标准库的椭圆曲线(如crypto/elliptic包),可以直接这样实现:
import (
"crypto/elliptic"
"math/big"
)
func PointSubtract(curve elliptic.Curve, x1, y1, x2, y2 *big.Int) (x, y *big.Int) {
// 获取曲线参数
params := curve.Params()
// 计算点B的负点
negY2 := new(big.Int).Neg(y2)
negY2.Mod(negY2, params.P)
// A - B = A + (-B)
return curve.Add(x1, y1, x2, negY2)
}
你之前尝试的方法在理论上是正确的,问题可能出现在:
- 模运算没有正确处理
- 坐标系统转换问题(仿射坐标 vs 射影坐标)
- 曲线参数不匹配
确保在计算负点时正确执行模运算,并且所有点都在曲线上。可以通过IsOnCurve方法验证点的有效性。

