Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_point_operations():
vector_file = os.path.join('vectors', 'vectors_point_operations.json')
try:
with open(vector_file) as f:
vector_suite = json.load(f)
except OSError:
raise
point1 = Point.from_bytes(bytes.fromhex(vector_suite['first Point operand']))
point2 = Point.from_bytes(bytes.fromhex(vector_suite['second Point operand']))
bn1 = CurveBN.from_bytes(bytes.fromhex(vector_suite['CurveBN operand']))
expected = dict()
for op_result in vector_suite['vectors']:
expected[op_result['operation']] = bytes.fromhex(op_result['result'])
test = [('Addition', point1 + point2),
('Subtraction', point1 - point2),
('Multiplication', bn1 * point1),
('Inversion', -point1),
]
for (operation, result) in test:
assert result == Point.from_bytes(expected[operation]), 'Error in {}'.format(operation)
test = [('To_affine.X', point1.to_affine()[0]),
def test_point_curve_multiplication_regression():
k256_point_bytes = b'\x03\xe0{\x1bQ\xbf@\x1f\x95\x8d\xe1\x17\xa7\xbe\x9e-G`T\xbf\xd7\x9e\xa7\x10\xc8uA\xc0z$\xc0\x92\x8a'
k256_bn_bytes = b'4u\xd70-\xa0h\xdeG\xf0\x143\x06!\x91\x05{\xe4jC\n\xf1h\xed7a\xf8\x9d\xec^\x19\x8c'
k256_point = Point.from_bytes(k256_point_bytes)
k256_bn = CurveBN.from_bytes(k256_bn_bytes)
product_with_star_operator = k256_point * k256_bn
# Make sure we have instantiated a new, unequal point in the same curve and group
assert isinstance(product_with_star_operator, Point), "Point.__mul__ did not return a point instance"
assert k256_point != product_with_star_operator
assert k256_point.curve == product_with_star_operator.curve
product_bytes = b'\x03\xc9\xda\xa2\x88\xe2\xa0+\xb1N\xb6\xe6\x1c\xa5(\xe6\xe0p\xf6\xf4\xa9\xfc\xb1\xfaUV\xd3\xb3\x0e4\x94\xbe\x12'
product_point = Point.from_bytes(product_bytes)
assert product_with_star_operator.to_bytes() == product_bytes
assert product_point == product_with_star_operator
# Repeating the operation, should return the same result.
product_with_star_operator_again = k256_point * k256_bn
assert product_with_star_operator == product_with_star_operator_again
def test_bytes_serializers(point_bytes, nid, curve):
point_with_curve = Point.from_bytes(point_bytes, curve=curve) # from curve
assert isinstance(point_with_curve, Point)
the_same_point_bytes = point_with_curve.to_bytes()
assert point_bytes == the_same_point_bytes
representations = (point_bytes, # Compressed representation
point_with_curve.to_bytes(is_compressed=False)) # Uncompressed
for point_representation in representations:
malformed_point_bytes = point_representation + b'0x'
with pytest.raises(InternalError):
_ = Point.from_bytes(malformed_point_bytes)
malformed_point_bytes = point_representation[1:]
with pytest.raises(InternalError):
_ = Point.from_bytes(malformed_point_bytes)
malformed_point_bytes = point_representation[:-1]
with pytest.raises(InternalError):
_ = Point.from_bytes(malformed_point_bytes)
def test_generator_point():
"""http://www.secg.org/SEC2-Ver-1.0.pdf Section 2.7.1"""
g1 = Point.get_generator_from_curve()
g_compressed = 0x0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
g_uncompressed = 0x0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
g_compressed = g_compressed.to_bytes(32+1, byteorder='big')
g_uncompressed = g_uncompressed.to_bytes(64+1, byteorder='big')
g2 = Point.from_bytes(g_compressed)
assert g1 == g2
g3 = Point.from_bytes(g_uncompressed)
assert g1 == g3
assert g2 == g3
def test_point_not_on_curve():
"""
We want to be unable to create a Point that's not on the curve.
When we try, we get cryptography.exceptions.InternalError - is that specifically because it isn't
on the curve? It seems to be reliably raised in the event of the Point being off the curve.
The OpenSSL docs don't explicitly say that they raise an error for this reason:
https://www.openssl.org/docs/man1.1.0/crypto/EC_GFp_simple_method.html
"""
point_on_koblitz256_but_not_P256 = Point.from_bytes(b'\x03%\x98Dk\x88\xe2\x97\xab?\xabZ\xef\xd4' \
b'\x9e\xaa\xc6\xb3\xa4\xa3\x89\xb2\xd7b.\x8f\x16Ci_&\xe0\x7f', curve=SECP256K1)
from cryptography.exceptions import InternalError
with pytest.raises(InternalError):
Point.from_bytes(point_on_koblitz256_but_not_P256.to_bytes(), curve=SECP256R1)
def test_point_curve_multiplication_regression():
k256_point_bytes = b'\x03\xe0{\x1bQ\xbf@\x1f\x95\x8d\xe1\x17\xa7\xbe\x9e-G`T\xbf\xd7\x9e\xa7\x10\xc8uA\xc0z$\xc0\x92\x8a'
k256_bn_bytes = b'4u\xd70-\xa0h\xdeG\xf0\x143\x06!\x91\x05{\xe4jC\n\xf1h\xed7a\xf8\x9d\xec^\x19\x8c'
k256_point = Point.from_bytes(k256_point_bytes)
k256_bn = CurveBN.from_bytes(k256_bn_bytes)
product_with_star_operator = k256_point * k256_bn
# Make sure we have instantiated a new, unequal point in the same curve and group
assert isinstance(product_with_star_operator, Point), "Point.__mul__ did not return a point instance"
assert k256_point != product_with_star_operator
assert k256_point.curve == product_with_star_operator.curve
product_bytes = b'\x03\xc9\xda\xa2\x88\xe2\xa0+\xb1N\xb6\xe6\x1c\xa5(\xe6\xe0p\xf6\xf4\xa9\xfc\xb1\xfaUV\xd3\xb3\x0e4\x94\xbe\x12'
product_point = Point.from_bytes(product_bytes)
assert product_with_star_operator.to_bytes() == product_bytes
assert product_point == product_with_star_operator
# Repeating the operation, should return the same result.
product_with_star_operator_again = k256_point * k256_bn
def test_invalid_points(random_ec_point2):
point_bytes = bytearray(random_ec_point2.to_bytes(is_compressed=False))
point_bytes[-1] = point_bytes[-1] ^ 0x01 # Flips last bit
point_bytes = bytes(point_bytes)
with pytest.raises(InternalError) as e:
_point = Point.from_bytes(point_bytes)
# 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
assert e.value.err_code[0].reason in (107, 110)
def from_bytes(cls,
key_bytes: bytes,
params: Optional[UmbralParameters] = None,
decoder: Optional[Callable] = None) -> 'UmbralPublicKey':
"""
Loads an Umbral public key from bytes.
Optionally, if an decoder function is provided it will be used to decode
the data before returning it as an Umbral key.
"""
if params is None:
params = default_params()
if decoder:
key_bytes = decoder(key_bytes)
point_key = Point.from_bytes(key_bytes, params.curve)
return cls(point_key, params)