Merge pull request #48 from jMyles/master

Frags to their own module; facility for default curve.
pull/49/head
Tux 2018-02-07 20:13:19 -07:00 committed by GitHub
commit ae9f4cea0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 143 additions and 102 deletions

View File

@ -1,5 +1,9 @@
import os
from cryptography.hazmat.backends.openssl import backend
from cryptography.hazmat.primitives.asymmetric import ec
from umbral.config import default_curve
class BigNum(object):
@ -14,11 +18,12 @@ class BigNum(object):
self.order = order
@classmethod
def gen_rand(cls, curve):
def gen_rand(cls, curve: ec.EllipticCurve = None):
"""
Returns a BigNum object with a cryptographically secure BigNum based
on the given curve.
"""
curve = curve if curve is not None else default_curve()
curve_nid = backend._elliptic_curve_to_nid(curve)
group = backend._lib.EC_GROUP_new_by_curve_name(curve_nid)

26
umbral/config.py Normal file
View File

@ -0,0 +1,26 @@
from cryptography.hazmat.primitives.asymmetric import ec
class _DEFAULT_CURVE:
__curve = None
@classmethod
def curve(cls):
if not cls.__curve:
raise RuntimeError("No default curve has been set.")
else:
return cls.__curve
@classmethod
def set_curve(cls, curve: ec.EllipticCurve=None):
if cls.__curve:
raise RuntimeError("You can only set the default curve once. Do it once and then leave it alone.")
else:
cls.__curve = curve
def set_default_curve(curve: ec.EllipticCurve=None):
_DEFAULT_CURVE.set_curve(curve)
def default_curve():
return _DEFAULT_CURVE.curve()

107
umbral/fragments.py Normal file
View File

@ -0,0 +1,107 @@
from cryptography.hazmat.primitives.asymmetric import ec
from umbral.bignum import BigNum
from umbral.config import default_curve
from umbral.point import Point
from umbral.utils import hash_to_bn
class KFrag(object):
def __init__(self, id_, key, x, u1, z1, z2):
self.bn_id = id_
self.bn_key = key
self.point_eph_ni = x
self.point_commitment = u1
self.bn_sig1 = z1
self.bn_sig2 = z2
@staticmethod
def from_bytes(data: bytes, curve: ec.EllipticCurve = None):
"""
Instantiate a KFrag object from the serialized data.
"""
curve = curve or default_curve
id = BigNum.from_bytes(data[0:32], curve)
key = BigNum.from_bytes(data[32:64], curve)
eph_ni = Point.from_bytes(data[64:97], curve)
commitment = Point.from_bytes(data[97:130], curve)
sig1 = BigNum.from_bytes(data[130:162], curve)
sig2 = BigNum.from_bytes(data[162:194], curve)
return KFrag(id, key, eph_ni, commitment, sig1, sig2)
def to_bytes(self):
"""
Serialize the KFrag into a bytestring.
"""
id = self.bn_id.to_bytes()
key = self.bn_key.to_bytes()
eph_ni = self.point_eph_ni.to_bytes()
commitment = self.point_commitment.to_bytes()
sig1 = self.bn_sig1.to_bytes()
sig2 = self.bn_sig2.to_bytes()
return id + key + eph_ni + commitment + sig1 + sig2
def verify(self, pub_a, pub_b, params: "UmbralParameters"):
u1 = self.point_commitment
z1 = self.bn_sig1
z2 = self.bn_sig2
x = self.point_eph_ni
g_y = (z2 * params.g) + (z1 * pub_a)
return z1 == hash_to_bn([g_y, self.bn_id, pub_a, pub_b, u1, x], params)
def is_consistent(self, vKeys, params: "UmbralParameters"):
if vKeys is None or len(vKeys) == 0:
raise ValueError('vKeys must not be empty')
h = params.h
lh_exp = self.bn_key * h
rh_exp = vKeys[0]
i_j = self.bn_id
for vKey in vKeys[1:]:
rh_exp = rh_exp + (i_j * vKey)
i_j = i_j * self.bn_id
return lh_exp == rh_exp
def __bytes__(self):
return self.to_bytes()
class CapsuleFrag(object):
def __init__(self, e1, v1, id_, x):
self.point_eph_e1 = e1
self.point_eph_v1 = v1
self.bn_kfrag_id = id_
self.point_eph_ni = x
@staticmethod
def from_bytes(data: bytes, curve: ec.EllipticCurve):
"""
Instantiates a CapsuleFrag object from the serialized data.
"""
e1 = Point.from_bytes(data[0:33], curve)
v1 = Point.from_bytes(data[33:66], curve)
kfrag_id = BigNum.from_bytes(data[66:98], curve)
eph_ni = Point.from_bytes(data[98:131], curve)
return CapsuleFrag(e1, v1, kfrag_id, eph_ni)
def to_bytes(self):
"""
Serialize the CapsuleFrag into a bytestring.
"""
e1 = self.point_eph_e1.to_bytes()
v1 = self.point_eph_v1.to_bytes()
kfrag_id = self.bn_kfrag_id.to_bytes()
eph_ni = self.point_eph_ni.to_bytes()
return e1 + v1 + kfrag_id + eph_ni
def __bytes__(self):
return self.to_bytes()

View File

@ -1,6 +1,8 @@
from umbral.bignum import BigNum
from cryptography.hazmat.backends.openssl import backend
from umbral.config import default_curve
class Point(object):
"""
@ -18,6 +20,7 @@ class Point(object):
Returns a Point object with a cryptographically secure EC_POINT based
on the provided curve.
"""
curve = curve if curve is not None else default_curve()
curve_nid = backend._elliptic_curve_to_nid(curve)
group = backend._lib.EC_GROUP_new_by_curve_name(curve_nid)

View File

@ -3,113 +3,13 @@ from nacl.secret import SecretBox
from umbral.bignum import BigNum
from umbral.dem import UmbralDEM
from umbral.fragments import KFrag, CapsuleFrag
from umbral.keys import UmbralPrivateKey, UmbralPublicKey
from umbral.params import UmbralParameters
from umbral.point import Point
from umbral.utils import poly_eval, lambda_coeff, hash_to_bn, kdf
class KFrag(object):
def __init__(self, id_, key, x, u1, z1, z2):
self.bn_id = id_
self.bn_key = key
self.point_eph_ni = x
self.point_commitment = u1
self.bn_sig1 = z1
self.bn_sig2 = z2
@staticmethod
def from_bytes(data: bytes, curve: ec.EllipticCurve):
"""
Instantiate a KFrag object from the serialized data.
"""
id = BigNum.from_bytes(data[0:32], curve)
key = BigNum.from_bytes(data[32:64], curve)
eph_ni = Point.from_bytes(data[64:97], curve)
commitment = Point.from_bytes(data[97:130], curve)
sig1 = BigNum.from_bytes(data[130:162], curve)
sig2 = BigNum.from_bytes(data[162:194], curve)
return KFrag(id, key, eph_ni, commitment, sig1, sig2)
def to_bytes(self):
"""
Serialize the KFrag into a bytestring.
"""
id = self.bn_id.to_bytes()
key = self.bn_key.to_bytes()
eph_ni = self.point_eph_ni.to_bytes()
commitment = self.point_commitment.to_bytes()
sig1 = self.bn_sig1.to_bytes()
sig2 = self.bn_sig2.to_bytes()
return id + key + eph_ni + commitment + sig1 + sig2
def verify(self, pub_a, pub_b, params: UmbralParameters):
u1 = self.point_commitment
z1 = self.bn_sig1
z2 = self.bn_sig2
x = self.point_eph_ni
g_y = (z2 * params.g) + (z1 * pub_a)
return z1 == hash_to_bn([g_y, self.bn_id, pub_a, pub_b, u1, x], params)
def is_consistent(self, vKeys, params: UmbralParameters):
if vKeys is None or len(vKeys) == 0:
raise ValueError('vKeys must not be empty')
# TODO: change this!
h = params.h
lh_exp = self.bn_key * h
rh_exp = vKeys[0]
i_j = self.bn_id
for vKey in vKeys[1:]:
rh_exp = rh_exp + (i_j * vKey)
i_j = i_j * self.bn_id
return lh_exp == rh_exp
def __bytes__(self):
return self.to_bytes()
class CapsuleFrag(object):
def __init__(self, e1, v1, id_, x):
self.point_eph_e1 = e1
self.point_eph_v1 = v1
self.bn_kfrag_id = id_
self.point_eph_ni = x
@staticmethod
def from_bytes(data: bytes, curve: ec.EllipticCurve):
"""
Instantiates a CapsuleFrag object from the serialized data.
"""
e1 = Point.from_bytes(data[0:33], curve)
v1 = Point.from_bytes(data[33:66], curve)
kfrag_id = BigNum.from_bytes(data[66:98], curve)
eph_ni = Point.from_bytes(data[98:131], curve)
return CapsuleFrag(e1, v1, kfrag_id, eph_ni)
def to_bytes(self):
"""
Serialize the CapsuleFrag into a bytestring.
"""
e1 = self.point_eph_e1.to_bytes()
v1 = self.point_eph_v1.to_bytes()
kfrag_id = self.bn_kfrag_id.to_bytes()
eph_ni = self.point_eph_ni.to_bytes()
return e1 + v1 + kfrag_id + eph_ni
def __bytes__(self):
return self.to_bytes()
class Capsule(object):
def __init__(self,
point_eph_e=None,