Merge pull request #41 from cygnusv/master

Deterministic generation of parameters h and u
pull/44/head
Tux 2018-01-31 11:35:08 -07:00 committed by GitHub
commit 78f259db97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 85 additions and 9 deletions

View File

@ -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

View File

@ -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

View File

@ -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):

View File

@ -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)