mirror of
https://github.com/aljazceru/nutshell.git
synced 2025-12-21 11:04:19 +01:00
works
This commit is contained in:
@@ -1,40 +1,32 @@
|
||||
# Don't trust me with cryptography.
|
||||
|
||||
"""
|
||||
Implementation of https://gist.github.com/RubenSomsen/be7a4760dd4596d06963d67baf140406
|
||||
|
||||
Alice:
|
||||
A = a*G
|
||||
return A
|
||||
|
||||
Bob:
|
||||
Y = hash_to_curve(secret_message)
|
||||
r = random blinding factor
|
||||
B'= Y + r*G
|
||||
return B'
|
||||
|
||||
Alice:
|
||||
C' = a*B'
|
||||
(= a*Y + a*r*G)
|
||||
return C'
|
||||
|
||||
Bob:
|
||||
C = C' - r*A
|
||||
(= C' - a*r*G)
|
||||
(= a*Y)
|
||||
return C, secret_message
|
||||
|
||||
Alice:
|
||||
Y = hash_to_curve(secret_message)
|
||||
C == a*Y
|
||||
|
||||
If true, C must have originated from Alice
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
|
||||
from ecc.curve import Point, secp256k1
|
||||
from ecc.key import gen_keypair
|
||||
|
||||
G = secp256k1.G
|
||||
from secp256k1 import PrivateKey, PublicKey
|
||||
|
||||
|
||||
def hash_to_curve(secret_msg):
|
||||
@@ -43,13 +35,15 @@ def hash_to_curve(secret_msg):
|
||||
point = None
|
||||
msg = secret_msg
|
||||
while point is None:
|
||||
x_coord = int(hashlib.sha256(msg).hexdigest().encode("utf-8"), 16)
|
||||
y_coord = secp256k1.compute_y(x_coord)
|
||||
_hash = hashlib.sha256(msg).hexdigest().encode("utf-8")
|
||||
try:
|
||||
# Fails if the point is not on the curve
|
||||
point = Point(x_coord, y_coord, secp256k1)
|
||||
# We construct compressed pub which has x coordinate encoded with even y
|
||||
_hash = list(_hash[:33]) # take the 33 bytes and get a list of bytes
|
||||
_hash[0] = 0x02 # set first byte to represent even y coord
|
||||
_hash = bytes(_hash)
|
||||
point = PublicKey(_hash, raw=True)
|
||||
except:
|
||||
msg = str(x_coord).encode("utf-8")
|
||||
msg = _hash
|
||||
|
||||
return point
|
||||
|
||||
@@ -57,35 +51,42 @@ def hash_to_curve(secret_msg):
|
||||
def step1_bob(secret_msg):
|
||||
secret_msg = secret_msg.encode("utf-8")
|
||||
Y = hash_to_curve(secret_msg)
|
||||
r, _ = gen_keypair(secp256k1)
|
||||
B_ = Y + r * G
|
||||
r = PrivateKey()
|
||||
B_ = Y + r.pubkey
|
||||
return B_, r
|
||||
|
||||
|
||||
def step2_alice(B_, a):
|
||||
C_ = a * B_
|
||||
C_ = B_.mult(a)
|
||||
return C_
|
||||
|
||||
|
||||
def step3_bob(C_, r, A):
|
||||
C = C_ - r * A
|
||||
C = C_ - A.mult(r)
|
||||
return C
|
||||
|
||||
|
||||
def verify(a, C, secret_msg):
|
||||
Y = hash_to_curve(secret_msg.encode("utf-8"))
|
||||
return C == a * Y
|
||||
return C == Y.mult(a)
|
||||
|
||||
|
||||
### Below is a test of a simple positive and negative case
|
||||
|
||||
# # Alice private key
|
||||
# a, A = gen_keypair(secp256k1)
|
||||
# # Alice's keys
|
||||
# a = PrivateKey()
|
||||
# A = a.pubkey
|
||||
# secret_msg = "test"
|
||||
# B_, r = step1_bob(secret_msg)
|
||||
# C_ = step2_alice(B_, a)
|
||||
# C = step3_bob(C_, r, A)
|
||||
# print("C:{}, secret_msg:{}".format(C, secret_msg))
|
||||
|
||||
# assert verify(a, C, secret_msg)
|
||||
# assert verify(a, C + 1*G, secret_msg) == False # adding 1*G shouldn't pass
|
||||
# assert verify(a, C + C, secret_msg) == False # adding C twice shouldn't pass
|
||||
# assert verify(a, A, secret_msg) == False # A shouldn't pass
|
||||
|
||||
# # Test operations
|
||||
# b = PrivateKey()
|
||||
# B = b.pubkey
|
||||
# assert -A -A + A == -A # neg
|
||||
# assert B.mult(a) == A.mult(b) # a*B = A*b
|
||||
|
||||
Reference in New Issue
Block a user