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)
}

我尝试了以下方法:

  1. 使用a + (-1) * b;但结果似乎不正确
  2. 计算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)
}

你之前尝试的方法在理论上是正确的,问题可能出现在:

  1. 模运算没有正确处理
  2. 坐标系统转换问题(仿射坐标 vs 射影坐标)
  3. 曲线参数不匹配

确保在计算负点时正确执行模运算,并且所有点都在曲线上。可以通过IsOnCurve方法验证点的有效性。

回到顶部