1# Copyright 2019 Google LLC. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15"""Test class for elliptic_curve module.""" 16 17import os 18import random 19import unittest 20from unittest import mock 21 22from private_join_and_compute.py.crypto_util import converters 23from private_join_and_compute.py.crypto_util import ssl_util 24from private_join_and_compute.py.crypto_util.elliptic_curve import ECKey 25from private_join_and_compute.py.crypto_util.elliptic_curve import ECPoint 26from private_join_and_compute.py.crypto_util.ssl_util import BigNum 27from private_join_and_compute.py.crypto_util.ssl_util import TempBNs 28from private_join_and_compute.py.crypto_util.supported_curves import SupportedCurve 29from private_join_and_compute.py.crypto_util.supported_hashes import HashType 30 31 32# Equivalent to C++ curve NID_X9_62_prime256v1 33TEST_CURVE = SupportedCurve.SECP256R1 34TEST_CURVE_ID = TEST_CURVE.id 35 36 37class EllipticCurveTest(unittest.TestCase): 38 39 def setUp(self): 40 super(EllipticCurveTest, self).setUp() 41 42 def testEcKey(self): 43 ec_key = ECKey(TEST_CURVE_ID) 44 ec_key_same = ECKey(TEST_CURVE_ID, ec_key.priv_key_bytes) 45 self.assertEqual( 46 ssl_util.BnToBytes(ec_key.priv_key_bn), 47 ssl_util.BnToBytes(ec_key_same.priv_key_bn), 48 ) 49 self.assertEqual(ec_key.curve_id, ec_key_same.curve_id) 50 self.assertEqual(ec_key.elliptic_curve, ec_key_same.elliptic_curve) 51 52 @mock.patch( 53 'private_join_and_compute.py.crypto_util.ssl_util.RandomOracle', 54 lambda x, bit_length, hash_type=None: 2 * x, 55 ) 56 def testHashToPoint(self): 57 t = random.getrandbits(160) 58 ec_key = ECKey(TEST_CURVE_ID) 59 x, y = ec_key.elliptic_curve.HashToCurve(t) 60 ECPoint.FromPoint(ec_key.elliptic_curve.group, x, y).CheckValidity() 61 62 def testEcPointsMultiplicationWithAddition(self): 63 ec_key = ECKey(TEST_CURVE_ID) 64 ec_point = ec_key.elliptic_curve.GetPointByHashingToCurve(10) 65 ec_point_sum = ec_point + ec_point + ec_point 66 with TempBNs(x=3) as bn: 67 ec_point_mul = ec_point * bn.x 68 self.assertEqual(ec_point_sum, ec_point_mul) 69 self.assertNotEqual(ec_point, ec_point_mul) 70 71 def testEcPointsInPlaceMult(self): 72 ec_key = ECKey(TEST_CURVE_ID) 73 ec_point = ec_key.elliptic_curve.GetPointByHashingToCurve(10) 74 with TempBNs(x=3) as bn: 75 ec_point *= bn.x 76 self.assertNotEqual( 77 ec_key.elliptic_curve.GetPointByHashingToCurve(10), ec_point 78 ) 79 80 def testEcPointsInPlaceAdd(self): 81 ec_key = ECKey(TEST_CURVE_ID) 82 ec_point = ec_key.elliptic_curve.GetPointByHashingToCurve(10) 83 ec_point += ec_key.elliptic_curve.GetPointByHashingToCurve(11) 84 self.assertNotEqual( 85 ec_key.elliptic_curve.GetPointByHashingToCurve(10), ec_point 86 ) 87 88 def testEcCurveOrder(self): 89 ec_key = ECKey(TEST_CURVE_ID) 90 ec_point = ec_key.elliptic_curve.GetPointByHashingToCurve(10) 91 ec_point1 = ec_point * BigNum.FromLongNumber(3) 92 ec_point2 = ec_point * BigNum.FromLongNumber( 93 3 + ec_key.elliptic_curve.order 94 ) 95 self.assertEqual(ec_point1, ec_point2) 96 97 def testDecryptKey(self): 98 ec_key = ECKey(TEST_CURVE_ID) 99 ec_point = ec_key.elliptic_curve.GetPointByHashingToCurve(10) 100 self.assertEqual( 101 ec_point, ec_point * ec_key.priv_key_bn * ec_key.decrypt_key_bignum 102 ) 103 104 @mock.patch( 105 'private_join_and_compute.py.crypto_util.ssl_util.BigNum' 106 '.GenerateRandWithStart' 107 ) 108 def testGetRandomGenerator(self, gen_rand): 109 gen_rand.return_value = BigNum.FromLongNumber(2) 110 ec_key = ECKey(TEST_CURVE_ID) 111 g1 = ec_key.elliptic_curve.GetRandomGenerator() 112 self.assertFalse(g1.IsAtInfinity()) 113 self.assertTrue(g1.IsOnCurve()) 114 gen_rand.return_value = BigNum.FromLongNumber(4) 115 g2 = ec_key.elliptic_curve.GetRandomGenerator() 116 self.assertFalse(g2.IsAtInfinity()) 117 self.assertTrue(g2.IsOnCurve()) 118 self.assertEqual(g2, g1 + g1) 119 120 121if __name__ == '__main__': 122 unittest.main() 123