mirror of https://github.com/nucypher/pyUmbral.git
Merge pull request #41 from cygnusv/master
Deterministic generation of parameters h and upull/44/head
commit
78f259db97
|
@ -6,10 +6,7 @@ def test_from_to_int():
|
|||
x = BigNum.gen_rand(curve)
|
||||
|
||||
xint = x.__int__()
|
||||
print()
|
||||
print("xint: ", xint)
|
||||
|
||||
y = BigNum.from_int(xint, curve)
|
||||
print("yint: ", y.__int__())
|
||||
|
||||
assert x == y
|
|
@ -1,6 +1,7 @@
|
|||
from umbral.point import Point
|
||||
from umbral.bignum import BigNum
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.exceptions import InternalError
|
||||
|
||||
def test_from_to_bytes():
|
||||
curve = ec.SECP256K1()
|
||||
|
@ -27,7 +28,35 @@ def test_invalid_points():
|
|||
|
||||
try:
|
||||
q = Point.from_bytes(pbytes, curve)
|
||||
assert False
|
||||
except:
|
||||
pass
|
||||
except InternalError as e:
|
||||
# We want to catch specific InternalExceptions:
|
||||
# - Point not in the curve (code 107)
|
||||
# - Invalid compressed point (code 110)
|
||||
# https://github.com/openssl/openssl/blob/master/include/openssl/ecerr.h#L228
|
||||
if e.err_code[0].reason in (107, 110):
|
||||
pass
|
||||
else:
|
||||
assert False
|
||||
else:
|
||||
assert False
|
||||
|
||||
def test_generator():
|
||||
curve = ec.SECP256K1()
|
||||
g1 = Point.get_generator_from_curve(curve)
|
||||
|
||||
# http://www.secg.org/SEC2-Ver-1.0.pdf
|
||||
# Section 2.7.1
|
||||
g_compressed = 0x0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
|
||||
g_compressed = g_compressed.to_bytes(32+1, byteorder='big')
|
||||
|
||||
g_uncompressed = 0x0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
|
||||
g_uncompressed = g_uncompressed.to_bytes(64+1, byteorder='big')
|
||||
|
||||
g2 = Point.from_bytes(g_compressed, curve)
|
||||
assert g1 == g2
|
||||
|
||||
g3 = Point.from_bytes(g_uncompressed, curve)
|
||||
assert g1 == g3
|
||||
|
||||
|
||||
assert g2 == g3
|
|
@ -5,7 +5,7 @@ from umbral.bignum import BigNum
|
|||
from umbral.dem import UmbralDEM
|
||||
from umbral.keys import UmbralPrivateKey, UmbralPublicKey
|
||||
from umbral.point import Point
|
||||
from umbral.utils import poly_eval, lambda_coeff, hash_to_bn, kdf
|
||||
from umbral.utils import poly_eval, lambda_coeff, hash_to_bn, kdf, unsafe_hash_to_point
|
||||
|
||||
|
||||
class UmbralParameters(object):
|
||||
|
@ -13,9 +13,13 @@ class UmbralParameters(object):
|
|||
self.curve = ec.SECP256K1()
|
||||
self.g = Point.get_generator_from_curve(self.curve)
|
||||
self.order = Point.get_order_from_curve(self.curve)
|
||||
self.h = self.g
|
||||
self.u = self.g
|
||||
|
||||
g_bytes = self.g.to_bytes(is_compressed=True)
|
||||
|
||||
domain_seed = b'NuCypherKMS/UmbralParameters/'
|
||||
|
||||
self.h = unsafe_hash_to_point(self.curve, g_bytes, domain_seed + b'h')
|
||||
self.u = unsafe_hash_to_point(self.curve, g_bytes, domain_seed + b'u')
|
||||
|
||||
class KFrag(object):
|
||||
def __init__(self, id_, key, x, u1, z1, z2):
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
|
||||
from cryptography.exceptions import InternalError
|
||||
|
||||
from umbral.bignum import BigNum
|
||||
from umbral.point import Point
|
||||
|
@ -55,6 +56,51 @@ def hash_to_bn(list, params):
|
|||
|
||||
return res
|
||||
|
||||
def unsafe_hash_to_point(curve, data, label=None):
|
||||
"""
|
||||
Hashes arbitrary data into a valid EC point of the specified curve,
|
||||
using the try-and-increment method.
|
||||
It admits an optional label as an additional input to the hash function.
|
||||
It uses SHA256 as the internal hash function.
|
||||
|
||||
WARNING: Do not use when the input data is secret, as this implementation is not
|
||||
in label time, and hence, it is not safe with respect to timing attacks.
|
||||
|
||||
TODO: Check how to uniformly generate ycoords. Currently, it only outputs points
|
||||
where ycoord is even (i.e., starting with 0x02 in compressed notation)
|
||||
"""
|
||||
if label is None:
|
||||
label = []
|
||||
|
||||
# We use a 32-bit counter as additional input
|
||||
i = 1
|
||||
while i < 2**32:
|
||||
ibytes = i.to_bytes(4, byteorder='big')
|
||||
digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
|
||||
digest.update(label + ibytes + data)
|
||||
hash = digest.finalize()
|
||||
|
||||
compressed02 = b"\x02"+hash
|
||||
|
||||
try:
|
||||
h = Point.from_bytes(compressed02, curve)
|
||||
return h
|
||||
except InternalError as e:
|
||||
# We want to catch specific InternalExceptions:
|
||||
# - Point not in the curve (code 107)
|
||||
# - Invalid compressed point (code 110)
|
||||
# https://github.com/openssl/openssl/blob/master/include/openssl/ecerr.h#L228
|
||||
if e.err_code[0].reason in (107, 110):
|
||||
pass
|
||||
else:
|
||||
# Any other exception, we raise it
|
||||
raise e
|
||||
|
||||
i += 1
|
||||
|
||||
# Only happens with probability 2^(-32)
|
||||
raise ValueError('Could not hash input into the curve')
|
||||
|
||||
def kdf(ecpoint, key_length):
|
||||
data = ecpoint.to_bytes(is_compressed=True)
|
||||
|
||||
|
|
Loading…
Reference in New Issue