• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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