现代密码学 | 椭圆曲线密码学—附py代码

news2025/6/12 19:44:49

Elliptic Curve Cryptography

椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。

椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签名算法(ECDSA)。这些签名对于确保数据的真实性和完整性至关重要。椭圆曲线迪菲-赫尔曼(ECDH)之类的协议能够在不安全的信道上实现安全的密钥交换,从而在没有预先共享密钥的情况下实现安全通信。

ECC 的吸引力在于其高效性以及使用较短密钥即可提供高级别的保护,这使其非常适合计算能力、存储和带宽有限的系统。

  • 椭圆曲线密码学能够以比RSA小得多的密钥尺寸提供相当的安全性。例如,256位的椭圆曲线密码学密钥所提供的安全性相当于3072位的RSA密钥。这使得计算速度更快,功耗更低。

  • 由于密钥尺寸较小使得椭圆曲线密码学特别适合计算能力和内存有限的设备,例如移动设备和物联网设备。也减少了加密操作期间传输的数据量,从而在带宽受限的环境中显著提升了性能。

ECC 建立在椭圆曲线理论的基础上,椭圆曲线由方程 y² = x³ + ax + b 定义,其中 a 和 b 是系数,满足 4a³ + 27b² ≠ 0 的条件以确保曲线是非奇异的。密码学中使用的椭圆曲线通常定义在有限域上(要么是素数域 Fp,要么是二进制域 F₂^m),从而曲线上的点数是有限的。

ECC 的核心原理在于椭圆曲线离散对数问题(ECDLP)的难度。简单来说,给定曲线上的两个点 A 和 B,找到满足 A = k × B 的整数 k 在计算上是不可行的。其中,× 表示椭圆曲线点乘法。正是这种难以解决性使得椭圆曲线密码学成为密码学中一种强大的工具。

py代码示例,包含密钥生成、ECDSA签名和验证功能(仅供参考)

import random
import hashlib
from typing import Tuple

# 定义椭圆曲线参数(使用secp256k1曲线 - 比特币使用的曲线)
class EllipticCurve:
    def __init__(self):
        # 曲线参数:y² = x³ + a*x + b mod p
        self.p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
        self.a = 0
        self.b = 7
        # 基点(生成元)
        self.G = (
            0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,
            0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
        )
        # 基点的阶(素数)
        self.n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
        self.h = 1  # 余因子

# 椭圆曲线点运算
class ECPoint:
    def __init__(self, curve: EllipticCurve, x: int = None, y: int = None):
        self.curve = curve
        self.x = x
        self.y = y
        
        # 检查点是否在曲线上(无穷远点除外)
        if x is not None and y is not None and not self.is_infinity():
            if (y * y) % curve.p != (x*x*x + curve.a*x + curve.b) % curve.p:
                raise ValueError(f"点 ({x}, {y}) 不在曲线上")
    
    def is_infinity(self) -> bool:
        """检查是否为无穷远点"""
        return self.x is None and self.y is None
    
    def __eq__(self, other) -> bool:
        """检查两点是否相等"""
        if not isinstance(other, ECPoint):
            return False
        return self.x == other.x and self.y == other.y
    
    def __add__(self, other):
        """点加法"""
        curve = self.curve
        
        # 处理无穷远点
        if self.is_infinity():
            return other
        if other.is_infinity():
            return self
        
        # 处理点与自身的加法(切线)
        if self == other:
            # 计算斜率:m = (3x₁² + a) / (2y₁) mod p
            if self.y == 0:  # 垂直线
                return ECPoint(curve)  # 返回无穷远点
            numerator = (3 * self.x * self.x + curve.a) % curve.p
            denominator = (2 * self.y) % curve.p
            m = (numerator * mod_inverse(denominator, curve.p)) % curve.p
        else:
            # 不同点的加法
            if self.x == other.x:  # 垂直线
                return ECPoint(curve)  # 返回无穷远点
            # 计算斜率:m = (y₂ - y₁) / (x₂ - x₁) mod p
            numerator = (other.y - self.y) % curve.p
            denominator = (other.x - self.x) % curve.p
            m = (numerator * mod_inverse(denominator, curve.p)) % curve.p
        
        # 计算新点坐标
        x3 = (m * m - self.x - other.x) % curve.p
        y3 = (m * (self.x - x3) - self.y) % curve.p
        
        return ECPoint(curve, x3, y3)
    
    def __rmul__(self, scalar: int):
        """标量乘法(快速幂算法)"""
        # 处理无穷远点
        if scalar == 0 or self.is_infinity():
            return ECPoint(self.curve)
        
        # 使用快速幂算法
        result = ECPoint(self.curve)  # 无穷远点
        addend = self
        
        while scalar:
            if scalar & 1:
                result += addend
            addend += addend
            scalar >>= 1
        
        return result
    
    def __repr__(self):
        return f"ECPoint({self.x}, {self.y})" if not self.is_infinity() else "ECPoint(Inf)"

def mod_inverse(a: int, p: int) -> int:
    """使用扩展欧几里得算法计算模逆元"""
    # 处理特殊情况
    if a == 0:
        raise ValueError("0没有逆元")
    if a < 0:
        a = a % p
    
    # 扩展欧几里得算法
    t0, t1 = 0, 1
    r0, r1 = p, a
    while r1 != 0:
        q = r0 // r1
        t0, t1 = t1, t0 - q * t1
        r0, r1 = r1, r0 - q * r1
    
    if r0 != 1:
        raise ValueError(f"{a} 在模 {p} 下没有逆元")
    return t0 % p

# ECC密钥生成
def generate_ecc_keypair(curve: EllipticCurve) -> Tuple[int, ECPoint]:
    """生成ECC密钥对"""
    # 随机生成私钥 (1 <= d < n)
    private_key = random.randint(1, curve.n - 1)
    
    # 计算公钥:公钥 = 私钥 * 基点G
    G = ECPoint(curve, curve.G[0], curve.G[1])
    public_key = private_key * G
    
    return private_key, public_key

# ECDSA签名
def ecdsa_sign(curve: EllipticCurve, private_key: int, message: bytes) -> Tuple[int, int]:
    """ECDSA签名算法"""
    # 计算消息哈希
    h = int.from_bytes(hashlib.sha256(message).digest(), 'big')
    h = h % curve.n  # 确保在[0, n-1]范围内
    if h == 0:
        h = 1
    
    # 生成临时密钥对
    k = random.randint(1, curve.n - 1)
    G = ECPoint(curve, curve.G[0], curve.G[1])
    R = k * G
    
    # 计算签名
    r = R.x % curve.n
    if r == 0:
        return ecdsa_sign(curve, private_key, message)  # 重新选择k
    
    s = (mod_inverse(k, curve.n) * (h + private_key * r)) % curve.n
    if s == 0:
        return ecdsa_sign(curve, private_key, message)  # 重新选择k
    
    return r, s

# ECDSA验证
def ecdsa_verify(curve: EllipticCurve, public_key: ECPoint, message: bytes, signature: Tuple[int, int]) -> bool:
    """ECDSA验证算法"""
    r, s = signature
    
    # 验证签名值范围
    if r < 1 or r >= curve.n or s < 1 or s >= curve.n:
        return False
    
    # 计算消息哈希
    h = int.from_bytes(hashlib.sha256(message).digest(), 'big')
    h = h % curve.n
    if h == 0:
        h = 1
    
    # 计算中间值
    w = mod_inverse(s, curve.n)
    u1 = (h * w) % curve.n
    u2 = (r * w) % curve.n
    
    # 计算点
    G = ECPoint(curve, curve.G[0], curve.G[1])
    P = u1 * G + u2 * public_key
    
    # 验证签名
    if P.is_infinity():
        return False
    
    return r == (P.x % curve.n)

# 示例测试
if __name__ == "__main__":
    # 创建椭圆曲线
    curve = EllipticCurve()
    
    # 生成密钥对
    private_key, public_key = generate_ecc_keypair(curve)
    print(f"私钥: {private_key}")
    print(f"公钥: {public_key}")
    
    # 签名消息
    message = b"Hello, Elliptic Curve Cryptography!"
    signature = ecdsa_sign(curve, private_key, message)
    print(f"\n消息: '{message.decode()}'")
    print(f"签名: (r={signature[0]}, s={signature[1]})")
    
    # 验证签名
    is_valid = ecdsa_verify(curve, public_key, message, signature)
    print(f"\n签名验证结果: {'有效' if is_valid else '无效'}")
    
    # 尝试篡改消息
    tampered_message = b"Hello, Hacker!"
    is_valid_tampered = ecdsa_verify(curve, public_key, tampered_message, signature)
    print(f"篡改消息后验证结果: {'有效' if is_valid_tampered else '无效'} (应为无效)")
    
    # 尝试篡改签名
    tampered_signature = (signature[0], signature[1] + 1)
    is_valid_tampered_sig = ecdsa_verify(curve, public_key, message, tampered_signature)
    print(f"篡改签名后验证结果: {'有效' if is_valid_tampered_sig else '无效'} (应为无效)")

运行结果:

在这里插入图片描述
代码步骤:

  1. 创建椭圆曲线(secp256k1)
  2. 生成ECC密钥对
  3. 对消息"Hello, Elliptic Curve Cryptography!"进行签名
  4. 验证签名有效性
  5. 测试篡改消息和签名后的验证结果

核心功能:

  • generate_ecc_keypair:生成ECC密钥对

  • ecdsa_sign:使用私钥对消息签名

  • ecdsa_verify:使用公钥验证签名

辅助函数:

  • mod_inverse:计算模逆元(用于签名/验证)

  • 使用SHA-256作为哈希函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2407614.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章&#xff1f;AI自动生成&#xff0c;效率提升10倍&#xff01; 支持多语言、自动配图、定时发布&#xff0c;让内容创作更轻松&#xff01; AI内容生成 → 不想每天写文章&#xff1f;AI一键生成高质量内容&#xff01;多语言支持 → 跨境电商必备&am…

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…