1.攻防世界初级区最后一题
已知椭圆曲线加密Ep(a,b)参数为
p = 15424654874903
a = 16546484
b = 4548674875
G(6478678675,5636379357093)
私钥为
k = 546768
求公钥K(x,y)
2.根据圆锥曲线的加密原理,写出解密脚本如下:
import collectionsimport randomEllipticCurve = collections.namedtuple('EllipticCurve', 'name p a b g n h')curve = EllipticCurve('secp256k1',# Field characteristic.p=int(input('p=')),# Curve coefficients.a=int(input('a=')),b=int(input('b=')),# Base point.g=(int(input('Gx=')),int(input('Gy='))),# Subgroup order.n=int(input('k=')),# Subgroup cofactor.h=1,)# Modular arithmetic ##########################################################def inverse_mod(k, p):"""Returns the inverse of k modulo p.This function returns the only integer x such that (x * k) % p == 1.k must be non-zero and p must be a prime."""if k == 0:raise ZeroDivisionError('division by zero')if k < 0:# k ** -1 = p - (-k) ** -1 (mod p)return p - inverse_mod(-k, p)# Extended Euclidean algorithm.s, old_s = 0, 1t, old_t = 1, 0r, old_r = p, kwhile r != 0:quotient = old_r // rold_r, r = r, old_r - quotient * rold_s, s = s, old_s - quotient * sold_t, t = t, old_t - quotient * tgcd, x, y = old_r, old_s, old_tassert gcd == 1assert (k * x) % p == 1return x % p# Functions that work on curve points #########################################def is_on_curve(point):"""Returns True if the given point lies on the elliptic curve."""if point is None:# None represents the point at infinity.return Truex, y = pointreturn (y * y - x * x * x - curve.a * x - curve.b) % curve.p == 0def point_neg(point):"""Returns -point."""assert is_on_curve(point)if point is None:# -0 = 0return Nonex, y = pointresult = (x, -y % curve.p)assert is_on_curve(result)return resultdef point_add(point1, point2):"""Returns the result of point1 + point2 according to the group law."""assert is_on_curve(point1)assert is_on_curve(point2)if point1 is None:# 0 + point2 = point2return point2if point2 is None:# point1 + 0 = point1return point1x1, y1 = point1x2, y2 = point2if x1 == x2 and y1 != y2:# point1 + (-point1) = 0return Noneif x1 == x2:# This is the case point1 == point2.m = (3 * x1 * x1 + curve.a) * inverse_mod(2 * y1, curve.p)else:# This is the case point1 != point2.m = (y1 - y2) * inverse_mod(x1 - x2, curve.p)x3 = m * m - x1 - x2y3 = y1 + m * (x3 - x1)result = (x3 % curve.p,-y3 % curve.p)assert is_on_curve(result)return resultdef scalar_mult(k, point):"""Returns k * point computed using the double and point_add algorithm."""assert is_on_curve(point)if k < 0:# k * point = -k * (-point)return scalar_mult(-k, point_neg(point))result = Noneaddend = pointwhile k:if k & 1:# Add.result = point_add(result, addend)# Double.addend = point_add(addend, addend)k >>= 1assert is_on_curve(result)return result# Keypair generation and ECDHE ################################################def make_keypair():"""Generates a random private-public key pair."""private_key = curve.npublic_key = scalar_mult(private_key, curve.g)return private_key, public_keyprivate_key, public_key = make_keypair()print("private key:", hex(private_key))print("public key: (0x{:x}, 0x{:x})".format(*public_key))
根据题目提示flag为公钥相加的值,提交的时候把末尾的**L**去掉
