椭圆曲线的数学基础

一、引言

椭圆曲线密码学(Elliptic Curve Cryptography, ECC)是现代公钥密码学的核心工具之一。

相比传统的 RSA,ECC 可以用 更短的密钥长度 提供 同等甚至更高的安全性,因此被广泛应用于区块链、TLS、移动设备加密等场景。

要理解 ECC,必须先了解它背后的数学结构 ------ 椭圆曲线上的点运算。本文将从基础开始,逐步介绍椭圆曲线的数学原理。


二、椭圆曲线方程

一个椭圆曲线通常由如下方程表示:

y2=x3+ax+b y^2 = x^3 + ax + b y2=x3+ax+b

其中 a,ba, ba,b 是常数,要求曲线 无奇异点(即没有自相交和尖点),满足:

4a3+27b2≠0 4a^3 + 27b^2 \neq 0 4a3+27b2=0

在实数范围内,这条曲线看起来像一条光滑的对称曲线:

  • 关于 x 轴对称
  • 呈"S"形或"波浪"形

但在密码学中,我们不会在实数范围上研究,而是定义在 有限域 Fp\mathbb{F}_pFp (模素数 ppp)上的椭圆曲线。


三、有限域上的椭圆曲线

在有限域中,所有运算都取模 ppp:

y2≡x3+ax+b(modp) y^2 \equiv x^3 + ax + b \pmod p y2≡x3+ax+b(modp)

例如:

选择 p=17,a=2,b=2p = 17, a = 2, b = 2p=17,a=2,b=2,曲线为:

y2≡x3+2x+2(mod17) y^2 \equiv x^3 + 2x + 2 \pmod{17} y2≡x3+2x+2(mod17)

我们可以枚举 x∈[0,16]x \in [0,16]x∈[0,16],找到满足条件的点 (x,y)(x,y)(x,y),这就是曲线上的点集。


四、点运算(群结构)

ECC 的核心不是曲线方程本身,而是 曲线点上的运算规则

椭圆曲线上的点(包括一个"无穷远点" OOO)形成一个 ,支持以下运算:

  1. 点加法 P+QP+QP+Q

    • 几何直观:过两点作直线,直线与曲线相交于第三点 RRR,再取 RRR 关于 x 轴的对称点。
    • 特殊情况:P=QP=QP=Q 时,用切线定义加法。
  2. 点倍乘 kPkPkP

    • 相当于 P+P+...+PP+P+...+PP+P+...+P(共 kkk 次)。
    • 在 ECC 中,公钥计算就是 点倍乘

五、ECC 的安全性来源

  • 容易 :给定 PPP 和整数 kkk,计算 Q=kPQ = kPQ=kP 很快。
  • 困难 :给定 PPP 和 QQQ,求 kkk 很难(椭圆曲线离散对数问题,ECDLP)。

这种 单向性 是 ECC 的安全核心。


六、Go 语言小实验:有限域椭圆曲线点加法

下面我们用 Go 写一个小程序,在有限域 p=17p=17p=17 上实现椭圆曲线点加法。

go 复制代码
package main

import (
	"fmt"
	"math/big"
)

// 椭圆曲线参数: y^2 = x^3 + ax + b mod p
var p = big.NewInt(17)
var a = big.NewInt(2)
var b = big.NewInt(2)

// 点结构
type Point struct {
	x, y *big.Int
	inf  bool // 是否是无穷远点
}

// 取模
func mod(v *big.Int) *big.Int {
	r := new(big.Int).Mod(v, p)
	if r.Sign() < 0 {
		r.Add(r, p)
	}
	return r
}

// 逆元
func modInverse(v *big.Int) *big.Int {
	return new(big.Int).ModInverse(v, p)
}

// 点加法
func add(P, Q Point) Point {
	// 处理无穷远点
	if P.inf {
		return Q
	}
	if Q.inf {
		return P
	}

	var m *big.Int
	if P.x.Cmp(Q.x) == 0 && P.y.Cmp(Q.y) == 0 {
		// P == Q, 切线斜率
		num := new(big.Int).Mul(big.NewInt(3), new(big.Int).Mul(P.x, P.x))
		num.Add(num, a)
		den := new(big.Int).Mul(big.NewInt(2), P.y)
		m = new(big.Int).Mul(num, modInverse(den))
	} else {
		// P != Q, 直线斜率
		num := new(big.Int).Sub(Q.y, P.y)
		den := new(big.Int).Sub(Q.x, P.x)
		m = new(big.Int).Mul(num, modInverse(den))
	}

	m = mod(m)
	xr := mod(new(big.Int).Sub(new(big.Int).Sub(new(big.Int).Mul(m, m), P.x), Q.x))
	yr := mod(new(big.Int).Sub(new(big.Int).Mul(m, new(big.Int).Sub(P.x, xr)), P.y))
	return Point{xr, yr, false}
}

func main() {
	P := Point{big.NewInt(5), big.NewInt(1), false}
	Q := Point{big.NewInt(6), big.NewInt(3), false}
	R := add(P, Q)
	fmt.Printf("P=(%v,%v), Q=(%v,%v)\n", P.x, P.y, Q.x, Q.y)
	fmt.Printf("P+Q=(%v,%v)\n", R.x, R.y)
}

运行结果示例:

复制代码
P=(5,1), Q=(6,3)
P+Q=(10,6)

说明在有限域上,椭圆曲线点运算是完全可行的。


七、总结

本文介绍了椭圆曲线的数学基础,包括:

  • 椭圆曲线方程及有限域定义
  • 点加法和点倍乘运算
  • ECC 的安全来源 ------ 椭圆曲线离散对数问题
相关推荐
Tony Bai2 小时前
再见,丑陋的 container/heap!Go 泛型堆 heap/v2 提案解析
开发语言·后端·golang
念何架构之路5 小时前
Go进阶之panic
开发语言·后端·golang
先跑起来再说5 小时前
Git 入门到实战:一篇搞懂安装、命令、远程仓库与 IDEA 集成
ide·git·后端·elasticsearch·golang·intellij-idea
Tony Bai13 小时前
“Go 2,请不要发生!”:如果 Go 变成了“缝合怪”,你还会爱它吗?
开发语言·后端·golang
灰子学技术1 天前
go response.Body.close()导致连接异常处理
开发语言·后端·golang
源代码•宸1 天前
大厂技术岗面试之谈薪资
经验分享·后端·面试·职场和发展·golang·大厂·职级水平的薪资
ESBK20251 天前
第四届移动互联网、云计算与信息安全国际会议(MICCIS 2026)二轮征稿启动,诚邀全球学者共赴学术盛宴
大数据·网络·物联网·网络安全·云计算·密码学·信息与通信
有代理ip2 天前
Python 与 Golang 爬虫的隐藏优势
爬虫·python·golang
天远云服2 天前
天远车辆过户查询API微服务实战:用Go语言构建高性能车况溯源系统
大数据·微服务·架构·golang
女王大人万岁2 天前
Go标准库 sync 详解
服务器·开发语言·后端·golang