Compare commits

...

4 Commits

Author SHA1 Message Date
ba45c2cd1d update compile config 2025-04-01 13:51:55 +08:00
dd1cc20be6 update benchmark 2025-04-01 13:51:29 +08:00
5ffc3f4c1e update dependencies version 2024-11-28 15:56:38 +08:00
ec5bab3697 add runtime 2024-11-28 13:42:00 +08:00
6 changed files with 289 additions and 46 deletions

116
Cargo.lock generated
View File

@@ -1,12 +1,12 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 4
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.3.0" version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
@@ -15,14 +15,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "ecc_rs" name = "crypto-bigint"
version = "0.1.1" version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96272c2ff28b807e09250b180ad1fb7889a3258f7455759b5c3c58b719467130"
dependencies = [ dependencies = [
"num-traits",
"rand_core",
"subtle",
]
[[package]]
name = "ecc_rs"
version = "0.1.2"
dependencies = [
"crypto-bigint",
"num-bigint", "num-bigint",
"num-traits", "num-traits",
"pyo3", "pyo3",
] ]
[[package]]
name = "getrandom"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.5.0" version = "0.5.0"
@@ -31,15 +54,15 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]] [[package]]
name = "indoc" name = "indoc"
version = "2.0.5" version = "2.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.158" version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
[[package]] [[package]]
name = "memoffset" name = "memoffset"
@@ -80,30 +103,30 @@ dependencies = [
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.19.0" version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]] [[package]]
name = "portable-atomic" name = "portable-atomic"
version = "1.7.0" version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.86" version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]] [[package]]
name = "pyo3" name = "pyo3"
version = "0.22.2" version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "831e8e819a138c36e212f3af3fd9eeffed6bf1510a805af35b0edee5ffa59433" checksum = "17da310086b068fbdcefbba30aeb3721d5bb9af8db4987d6735b2183ca567229"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"indoc", "indoc",
@@ -120,9 +143,9 @@ dependencies = [
[[package]] [[package]]
name = "pyo3-build-config" name = "pyo3-build-config"
version = "0.22.2" version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e8730e591b14492a8945cdff32f089250b05f5accecf74aeddf9e8272ce1fa8" checksum = "e27165889bd793000a098bb966adc4300c312497ea25cf7a690a9f0ac5aa5fc1"
dependencies = [ dependencies = [
"once_cell", "once_cell",
"target-lexicon", "target-lexicon",
@@ -130,9 +153,9 @@ dependencies = [
[[package]] [[package]]
name = "pyo3-ffi" name = "pyo3-ffi"
version = "0.22.2" version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e97e919d2df92eb88ca80a037969f44e5e70356559654962cbb3316d00300c6" checksum = "05280526e1dbf6b420062f3ef228b78c0c54ba94e157f5cb724a609d0f2faabc"
dependencies = [ dependencies = [
"libc", "libc",
"pyo3-build-config", "pyo3-build-config",
@@ -140,9 +163,9 @@ dependencies = [
[[package]] [[package]]
name = "pyo3-macros" name = "pyo3-macros"
version = "0.22.2" version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb57983022ad41f9e683a599f2fd13c3664d7063a3ac5714cae4b7bee7d3f206" checksum = "5c3ce5686aa4d3f63359a5100c62a127c9f15e8398e5fdeb5deef1fed5cd5f44"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"pyo3-macros-backend", "pyo3-macros-backend",
@@ -152,9 +175,9 @@ dependencies = [
[[package]] [[package]]
name = "pyo3-macros-backend" name = "pyo3-macros-backend"
version = "0.22.2" version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec480c0c51ddec81019531705acac51bcdbeae563557c982aa8263bb96880372" checksum = "f4cf6faa0cbfb0ed08e89beb8103ae9724eb4750e3a78084ba4017cbe94f3855"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
@@ -165,18 +188,33 @@ dependencies = [
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.37" version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]] [[package]]
name = "syn" name = "rand_core"
version = "2.0.77" version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "subtle"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
version = "2.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -185,18 +223,24 @@ dependencies = [
[[package]] [[package]]
name = "target-lexicon" name = "target-lexicon"
version = "0.12.16" version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.12" version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]] [[package]]
name = "unindent" name = "unindent"
version = "0.2.3" version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce" checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"

View File

@@ -1,7 +1,7 @@
[package] [package]
name = "ecc_rs" name = "ecc_rs"
version = "0.1.1" version = "0.1.2"
edition = "2021" edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib] [lib]
@@ -9,6 +9,11 @@ name = "ecc_rs"
crate-type = ["cdylib"] crate-type = ["cdylib"]
[dependencies] [dependencies]
num-bigint = "0.4.6" crypto-bigint = "0.6.1"
num-traits = "0.2.19" num-bigint = "0.*"
pyo3 = { version = "0.22.2", features = ["extension-module", "num-bigint"] } num-traits = "0.*"
pyo3 = { version = "0.*", features = [
"extension-module",
"num-bigint",
"abi3-py312",
] }

View File

@@ -1,5 +1,7 @@
import ecc_rs import ecc_rs
import time import time
import ecc_py
import random
point = tuple[int, int] point = tuple[int, int]
# Example point coordinates for P1 and P2 as tuples (x1, y1) and (x2, y2) # Example point coordinates for P1 and P2 as tuples (x1, y1) and (x2, y2)
@@ -58,16 +60,44 @@ def add(a: point, b: point) -> point:
return result return result
random_mul_times = random.randint(0, sm2p256v1.N)
start_time = time.time() # 获取开始时间 start_time = time.time() # 获取开始时间
for i in range(10): for i in range(10):
result = multiply(g, 10000) # 执行函数 result = multiply(g, random_mul_times) # 执行函数
end_time = time.time() # 获取结束时间 end_time = time.time() # 获取结束时间
elapsed_time = end_time - start_time # 计算执行时间 rs_mul_elapsed_time = end_time - start_time # 计算执行时间
print(f"rust multiply 执行时间: {elapsed_time:.6f}") print(f"rust multiply 执行时间: {rs_mul_elapsed_time:.6f}")
# rust multiply 执行时间: 0.000849 秒
start_time = time.time() # 获取开始时间
for i in range(10):
result = ecc_py.multiply(g, random_mul_times) # 执行函数
end_time = time.time() # 获取结束时间
py_mul_elapsed_time = end_time - start_time # 计算执行时间
print(f"ecc_py multiply 执行时间: {py_mul_elapsed_time:.6f}")
# ecc_py multiply 执行时间: 0.001374 秒
mul_improve = (py_mul_elapsed_time - rs_mul_elapsed_time) / py_mul_elapsed_time * 100
print(f"rust 实现 mul 提速 {mul_improve:.3f}%")
start_time = time.time() # 获取开始时间 start_time = time.time() # 获取开始时间
for i in range(10): for i in range(10):
result = add(g, g) # 执行函数 result = add(g, g) # 执行函数
end_time = time.time() # 获取结束时间 end_time = time.time() # 获取结束时间
elapsed_time = end_time - start_time # 计算执行时间 rs_add_elapsed_time = end_time - start_time # 计算执行时间
print(f"rust add 执行时间: {elapsed_time:.6f}") print(f"rust add 执行时间: {rs_add_elapsed_time:.6f}")
# rust add 执行时间: 0.000378 秒
start_time = time.time() # 获取开始时间
for i in range(10):
result = ecc_py.add(g, g) # 执行函数
end_time = time.time() # 获取结束时间
py_add_elapsed_time = end_time - start_time # 计算执行时间
print(f"ecc_py add 执行时间: {py_add_elapsed_time:.6f}")
# ecc_py add 执行时间: 0.000510 秒
add_improve = (py_add_elapsed_time - rs_add_elapsed_time) / py_add_elapsed_time * 100
print(f"rust 实现 add 提速 {add_improve:.3f}%")

132
ecc_py.py Normal file
View File

@@ -0,0 +1,132 @@
from typing import Tuple
point = Tuple[int, int]
# 生成密钥对模块
class CurveFp:
def __init__(self, A, B, P, N, Gx, Gy, name):
self.A = A
self.B = B
self.P = P
self.N = N
self.Gx = Gx
self.Gy = Gy
self.name = name
sm2p256v1 = CurveFp(
name="sm2p256v1",
A=0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC,
B=0x28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93,
P=0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF,
N=0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123,
Gx=0x32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7,
Gy=0xBC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0,
)
def multiply(a: point, n: int) -> point:
N = sm2p256v1.N
A = sm2p256v1.A
P = sm2p256v1.P
return fromJacobian(jacobianMultiply(toJacobian(a), n, N, A, P), P)
def add(
a: point,
b: point,
) -> point:
A = sm2p256v1.A
P = sm2p256v1.P
return fromJacobian(jacobianAdd(toJacobian(a), toJacobian(b), A, P), P)
def inv(a: int, n: int) -> int:
if a == 0:
return 0
lm, hm = 1, 0
low, high = a % n, n
while low > 1:
r = high // low
nm, new = hm - lm * r, high - low * r
lm, low, hm, high = nm, new, lm, low
return lm % n
def toJacobian(Xp_Yp: point) -> Tuple[int, int, int]:
Xp, Yp = Xp_Yp
return (Xp, Yp, 1)
def fromJacobian(Xp_Yp_Zp: Tuple[int, int, int], P: int) -> point:
Xp, Yp, Zp = Xp_Yp_Zp
z = inv(Zp, P)
return ((Xp * z**2) % P, (Yp * z**3) % P)
def jacobianDouble(
Xp_Yp_Zp: Tuple[int, int, int], A: int, P: int
) -> Tuple[int, int, int]:
Xp, Yp, Zp = Xp_Yp_Zp
if not Yp:
return (0, 0, 0)
ysq = (Yp**2) % P
S = (4 * Xp * ysq) % P
M = (3 * Xp**2 + A * Zp**4) % P
nx = (M**2 - 2 * S) % P
ny = (M * (S - nx) - 8 * ysq**2) % P
nz = (2 * Yp * Zp) % P
return (nx, ny, nz)
def jacobianAdd(
Xp_Yp_Zp: Tuple[int, int, int], Xq_Yq_Zq: Tuple[int, int, int], A: int, P: int
) -> Tuple[int, int, int]:
Xp, Yp, Zp = Xp_Yp_Zp
Xq, Yq, Zq = Xq_Yq_Zq
if not Yp:
return (Xq, Yq, Zq)
if not Yq:
return (Xp, Yp, Zp)
U1 = (Xp * Zq**2) % P
U2 = (Xq * Zp**2) % P
S1 = (Yp * Zq**3) % P
S2 = (Yq * Zp**3) % P
if U1 == U2:
if S1 != S2:
return (0, 0, 1)
return jacobianDouble((Xp, Yp, Zp), A, P)
H = U2 - U1
R = S2 - S1
H2 = (H * H) % P
H3 = (H * H2) % P
U1H2 = (U1 * H2) % P
nx = (R**2 - H3 - 2 * U1H2) % P
ny = (R * (U1H2 - nx) - S1 * H3) % P
nz = (H * Zp * Zq) % P
return (nx, ny, nz)
def jacobianMultiply(
Xp_Yp_Zp: Tuple[int, int, int], n: int, N: int, A: int, P: int
) -> Tuple[int, int, int]:
Xp, Yp, Zp = Xp_Yp_Zp
if Yp == 0 or n == 0:
return (0, 0, 1)
if n == 1:
return (Xp, Yp, Zp)
if n < 0 or n >= N:
return jacobianMultiply((Xp, Yp, Zp), n % N, N, A, P)
if (n % 2) == 0:
return jacobianDouble(jacobianMultiply((Xp, Yp, Zp), n // 2, N, A, P), A, P)
if (n % 2) == 1:
return jacobianAdd(
jacobianDouble(jacobianMultiply((Xp, Yp, Zp), n // 2, N, A, P), A, P),
(Xp, Yp, Zp),
A,
P,
)
raise ValueError("jacobian Multiply error")

View File

@@ -10,6 +10,12 @@ classifiers = [
"Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: CPython",
] ]
dynamic = ["version"] dynamic = ["version"]
authors = [{ name = "Liang Junyong", email = "2251250136@qq.com" }]
readme = "readme.md"
[project.urls]
Homepage = "https://git.mamahaha.work/sangge/ecc_rs"
[tool.maturin] [tool.maturin]
features = ["pyo3/extension-module"] features = ["pyo3/extension-module"]
bindings = "pyo3" bindings = "pyo3"

View File

@@ -2,3 +2,29 @@
a simple rust implementation of SM2 binding for python. a simple rust implementation of SM2 binding for python.
powered by pyo3. powered by pyo3.
useage
```python
import ecc_rs
point = tuple[int, int]
# Example point coordinates for P1 and P2 as tuples (x1, y1) and (x2, y2)
p1 = (
1234567890123456789012345678901234567890123456789012345678901234,
9876543210987654321098765432109876543210987654321098765432109876,
)
p2 = (
2234567890123456789012345678901234567890123456789012345678901234,
2876543210987654321098765432109876543210987654321098765432109876,
)
# Add the two points
result_x, result_y = ecc_rs.add(p1, p2)
print(f"Resulting Point: x = {result_x}, y = {result_y}")
result = ecc_rs.multiply(p1, 2)
print(f"Resulting Point: x = {result[0]}, y = {result[1]}")
```