secp256r1椭圆曲线算法研究

secp256r1 是 NIST 和 SECG 标准化的椭圆曲线,在蓝牙GFPS服务应用都会用到secp256r1椭圆曲线算法,下面列出secp256r1算法的详细信息和随机生成公私钥的python脚本

椭圆曲线函数表达式

曲线方程为 Weierstrass 标准形式
y 2 ≡ x 3 + a x + b    ( mod  p ) y^2 \equiv x^3 + ax + b \ \ (\text{mod} \ p) y2x3+ax+b  (mod p)
其中参数为:

  • 素数 ( p )(16进制):
    p = FFFFFFFF   00000001   00000000   00000000   00000000   FFFFFFFF   FFFFFFFF   FFFFFFFF   p=\texttt{FFFFFFFF 00000001 00000000 00000000 00000000 FFFFFFFF FFFFFFFF FFFFFFFF}\ p=FFFFFFFF 00000001 00000000 00000000 00000000 FFFFFFFF FFFFFFFF FFFFFFFF 
    对应十进制:
    p = 2 256 − 2 224 + 2 192 + 2 96 − 1 p = 2^{256} - 2^{224} + 2^{192} + 2^{96} - 1 p=22562224+2192+2961

  • 系数 ( a )
    a = FFFFFFFF   00000001   00000000   00000000   00000000   FFFFFFFF   FFFFFFFF   FFFFFFFC ( 即  a = − 3  mod  p ) a = \texttt{FFFFFFFF 00000001 00000000 00000000 00000000 FFFFFFFF FFFFFFFF FFFFFFFC} ({即} \ a = -3 \ \text{mod} \ p) a=FFFFFFFF 00000001 00000000 00000000 00000000 FFFFFFFF FFFFFFFF FFFFFFFC( a=3 mod p)

  • 系数 ( b )
    b = 5AC635D8   AA3A93E7   B3EBBD55   769886BC   651D06B0   CC53B0F6   3BCE3C3E   27D2604B b = \texttt{5AC635D8 AA3A93E7 B3EBBD55 769886BC 651D06B0 CC53B0F6 3BCE3C3E 27D2604B} b=5AC635D8 AA3A93E7 B3EBBD55 769886BC 651D06B0 CC53B0F6 3BCE3C3E 27D2604B

  • 基点 ( G )
    生成元的坐标为:
    ( ( x G , y G ) : ((x_G, y_G): ((xG,yG)

  • ( x_G )(16进制):
    x G = 6B17D1F2   E12C4247   F8BCE6E5   63A440F2   77037D81   2DEB33A0   F4A13945   D898C296 x_G = \texttt{6B17D1F2 E12C4247 F8BCE6E5 63A440F2 77037D81 2DEB33A0 F4A13945 D898C296} xG=6B17D1F2 E12C4247 F8BCE6E5 63A440F2 77037D81 2DEB33A0 F4A13945 D898C296

  • ( y_G )(16进制):
    y G = 4FE342E2   FE1A7F9B   8EE7EB4A   7C0F9E16   2BCE3357   6B315ECE   CBB64068   37BF51F5 y_G = \texttt{4FE342E2 FE1A7F9B 8EE7EB4A 7C0F9E16 2BCE3357 6B315ECE CBB64068 37BF51F5} yG=4FE342E2 FE1A7F9B 8EE7EB4A 7C0F9E16 2BCE3357 6B315ECE CBB64068 37BF51F5

  • 阶 ( n )(基点的周期,即私钥最大值):
    n = FFFFFFFF   00000000   FFFFFFFF   FFFFFFFF   BCE6FAAD   A7179E84   F3B9CAC2   FC632551 n = \texttt{FFFFFFFF 00000000 FFFFFFFF FFFFFFFF BCE6FAAD A7179E84 F3B9CAC2 FC632551} n=FFFFFFFF 00000000 FFFFFFFF FFFFFFFF BCE6FAAD A7179E84 F3B9CAC2 FC632551


  • 私钥( Private Key )

  • 定义:随机生成的整数 ( d ),满足 1 ≤ d < n 1 \leq d < n 1d<n

  • 表现形式:通常为 32字节(256位)的二进制或十六进制字符串,例如:
    0x6ee02380   78c0442d   11b2db2d   7c33bc76   884470bd   1823e7b2   3a4897d7   a3a253af \texttt{0x6ee02380 78c0442d 11b2db2d 7c33bc76 884470bd 1823e7b2 3a4897d7 a3a253af} 0x6ee02380 78c0442d 11b2db2d 7c33bc76 884470bd 1823e7b2 3a4897d7 a3a253af


  • 公钥( Public Key )
    公钥是椭圆曲线上的点 Q = d ⋅ G Q = d \cdot G Q=dG,有两种编码形式:
  1. 未压缩公钥
    • 格式:以 04 开头,后接完整的 ( x ) 和 ( y ) 坐标(共 65字节)。
    • 示例:
      04   854edf8a2549444b74328ff0639e49940229d4358de3410eb00ccd12f8b6c767   92e73d3fb6355644048ebf1d9905139d83c1502d8838539d4c91ed21bce01d6f \texttt{04 854edf8a2549444b74328ff0639e49940229d4358de3410eb00ccd12f8b6c767 92e73d3fb6355644048ebf1d9905139d83c1502d8838539d4c91ed21bce01d6f} 04 854edf8a2549444b74328ff0639e49940229d4358de3410eb00ccd12f8b6c767 92e73d3fb6355644048ebf1d9905139d83c1502d8838539d4c91ed21bce01d6f
  2. 压缩公钥
    • 格式:根据 ( y ) 的奇偶性选择前缀 02(偶)或 03(奇),后接 ( x ) 坐标(共 33字节)。
    • 原理:利用 y 2 = x 3 + a x + b y^2 = x^3 + ax + b y2=x3+ax+b从 ( x ) 计算 ( y )。
    • 示例:
      02   854edf8a2549444b74328ff0639e49940229d4358de3410eb00ccd12f8b6c767 ( 假设  y  为偶数 ) \texttt{02 854edf8a2549444b74328ff0639e49940229d4358de3410eb00ccd12f8b6c767} \quad (\text{假设} \ y \ \text{为偶数}) 02 854edf8a2549444b74328ff0639e49940229d4358de3410eb00ccd12f8b6c767(假设 y 为偶数)

基于ECDSA库的python脚本:

from ecdsa import SigningKey, NIST256p
from ecdsa.ellipticcurve import Point

# 获取secp256r1曲线参数
curve = NIST256p.curve
G = NIST256p.generator
n = NIST256p.order
p = curve.p()
a = curve.a()
b = curve.b()

# 打印曲线参数
print("椭圆曲线参数 secp256r1:")
print("--------------------------------------------------")
print(f"素数 p: {hex(p)}")
print(f"系数 a: {hex(a)}")
print(f"系数 b: {hex(b)}")
print(f"基点 G(x, y):")
print(f"  x = {hex(G.x())}")
print(f"  y = {hex(G.y())}")
print(f"阶 n: {hex(n)}")
print("--------------------------------------------------\n")

# 生成随机私钥
private_key = SigningKey.generate(curve=NIST256p)
private_key_int = private_key.privkey.secret_multiplier

# 计算公钥(点乘)
public_key_point = private_key.get_verifying_key().pubkey.point

# 打印密钥信息
print("生成的密钥对:")
print("--------------------------------------------------")
print(f"私钥 (d): {hex(private_key_int)}")
print("公钥坐标:")
print(f"  x = {hex(public_key_point.x())}")
print(f"  y = {hex(public_key_point.y())}")
print("--------------------------------------------------")

计算出来的结果如下:

在这里插入图片描述

基于tinyec库的python脚本:

from tinyec.ec import Curve, SubGroup
import secrets

# secp256r1 (NIST P-256) 曲线参数
p = 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF
a = 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC
b = 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B
Gx = 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296
Gy = 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5
n = 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551

# 创建子群和曲线
field = SubGroup(p, (Gx, Gy), n, 1)
curve = Curve(a, b, field, name='secp256r1')

# 打印曲线参数
print("G点坐标:")
print(f"Gx = {hex(curve.g.x)}")
print(f"Gy = {hex(curve.g.y)}\n")

print(f"曲线的阶 n = {hex(curve.field.n)}\n")
print(f"系数 a = {hex(curve.a)}")
print(f"系数 b = {hex(curve.b)}")
print(f"素数域 p = {hex(curve.field.p)}\n")

# 生成随机私钥(范围:1 到 n-1)
private_key = secrets.randbelow(curve.field.n)
while private_key == 0:
    private_key = secrets.randbelow(curve.field.n)

# 计算公钥
public_key = private_key * curve.g  # 椭圆曲线标量乘法

# 打印密钥信息
print("私钥 (d):")
print(hex(private_key))
print("\n公钥坐标:")
print(f"Qx = {hex(public_key.x)}")
print(f"Qy = {hex(public_key.y)}")

计算出结果:

G点坐标:
Gx = 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296
Gy = 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5

曲线的阶 n = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551

系数 a = 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc
系数 b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b
素数域 p = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff

私钥 (d):
0x6ee0238078c0442d11b2db2d7c33bc76884470bd1823e7b23a4897d7a3a253af

公钥坐标:
Qx = 0x854edf8a2549444b74328ff0639e49940229d4358de3410eb00ccd12f8b6c767
Qy = 0x92e73d3fb6355644048ebf1d9905139d83c1502d8838539d4c91ed21bce01d6f
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tim_Jiangzj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值