|
| 1 | +# Copyright (C) 2017 The OpenTimestamps developers |
| 2 | +# |
| 3 | +# This file is part of python-opentimestamps. |
| 4 | +# |
| 5 | +# It is subject to the license terms in the LICENSE file found in the top-level |
| 6 | +# directory of this distribution. |
| 7 | +# |
| 8 | +# No part of python-opentimestamps including this file, may be copied, |
| 9 | +# modified, propagated, or distributed except according to the terms contained |
| 10 | +# in the LICENSE file. |
| 11 | + |
| 12 | +import binascii |
| 13 | +import unittest |
| 14 | + |
| 15 | +from opentimestamps.core.secp256k1 import * |
| 16 | + |
| 17 | +class Test_Secp256k1(unittest.TestCase): |
| 18 | + def test_point_rt(self): |
| 19 | + """Point encoding round trip""" |
| 20 | + gen = SECP256K1_GEN |
| 21 | + encode = gen.encode() |
| 22 | + self.assertEqual(encode, binascii.unhexlify("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798")) |
| 23 | + gen2 = Point().decode(encode) |
| 24 | + self.assertEqual(gen, gen2) |
| 25 | + |
| 26 | + def test_pinv(self): |
| 27 | + """Field inversion mod p""" |
| 28 | + self.assertEqual(pinv(1), 1) |
| 29 | + self.assertEqual(pinv(2), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffe18) |
| 30 | + self.assertEqual(pinv(3), 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9fffffd75) |
| 31 | + self.assertEqual(2, pinv(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffe18)) |
| 32 | + self.assertEqual(3, pinv(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9fffffd75)) |
| 33 | + |
| 34 | + def test_psqrt(self): |
| 35 | + """Field square root mod p""" |
| 36 | + self.assertEqual(psqrt(1), 1) |
| 37 | + self.assertEqual(psqrt(2), 0x210c790573632359b1edb4302c117d8a132654692c3feeb7de3a86ac3f3b53f7) |
| 38 | + self.assertEqual(psqrt(4), 2) |
| 39 | + # may return the sqrt or its negative |
| 40 | + self.assertEqual(psqrt(9), SECP256K1_P - 3) |
| 41 | + self.assertEqual(psqrt(49), SECP256K1_P - 7) |
| 42 | + |
| 43 | + def test_point_add(self): |
| 44 | + """Point adding and doubling""" |
| 45 | + |
| 46 | + inf = Point() |
| 47 | + # P random chosen by dice roll |
| 48 | + p1 = Point(0x394867ad93f5c9612e8d8b7600443334026e648e365337d799190e845d649e67, |
| 49 | + 0x0b84af9a00c1a55a7ac03917e59b21c68d1ffdf18720c3ad279077049cfaaf63) |
| 50 | + # 2P |
| 51 | + p2 = Point(0x8e6575f6c759aea04a8ec65f61f71eba237a0af54292d41e3a4bac2efa922dea, |
| 52 | + 0x2b3c07687787ff07ae312305f30481c451ae3b78d4f479a3b729615fedc040e4) |
| 53 | + # -2P |
| 54 | + np2 = Point(0x8e6575f6c759aea04a8ec65f61f71eba237a0af54292d41e3a4bac2efa922dea, |
| 55 | + 0xd4c3f897887800f851cedcfa0cfb7e3bae51c4872b0b865c48d69e9f123fbb4b) |
| 56 | + # 3P |
| 57 | + p3 = Point(0x53dd5e495c7404790f9347470cc9c38ee239809c758f02ec04ba641ab3d0e043, |
| 58 | + 0xd7a4f5e5bdf21000b1fe7216adbea92cb9917d8fea7b37628c1eddb409a5cd3f) |
| 59 | + |
| 60 | + self.assertEqual(inf.add(inf), inf) |
| 61 | + self.assertEqual(p1.add(inf), p1) |
| 62 | + self.assertEqual(inf.add(p1), p1) |
| 63 | + self.assertEqual(p1.add(p1), p2) |
| 64 | + self.assertEqual(p1.add(p2), p3) |
| 65 | + self.assertEqual(p2.add(p1), p3) |
| 66 | + self.assertEqual(p3.add(np2), p1) |
| 67 | + self.assertEqual(np2.add(p3), p1) |
| 68 | + self.assertEqual(p2.add(np2), inf) |
| 69 | + self.assertEqual(np2.add(p2), inf) |
| 70 | + |
| 71 | + def test_scalar_mul(self): |
| 72 | + inf = Point() |
| 73 | + # P random chosen by dice roll |
| 74 | + p1 = Point(0x394867ad93f5c9612e8d8b7600443334026e648e365337d799190e845d649e67, |
| 75 | + 0x0b84af9a00c1a55a7ac03917e59b21c68d1ffdf18720c3ad279077049cfaaf63) |
| 76 | + # 2P |
| 77 | + p2 = Point(0x8e6575f6c759aea04a8ec65f61f71eba237a0af54292d41e3a4bac2efa922dea, |
| 78 | + 0x2b3c07687787ff07ae312305f30481c451ae3b78d4f479a3b729615fedc040e4) |
| 79 | + # -2P |
| 80 | + np2 = Point(0x8e6575f6c759aea04a8ec65f61f71eba237a0af54292d41e3a4bac2efa922dea, |
| 81 | + 0xd4c3f897887800f851cedcfa0cfb7e3bae51c4872b0b865c48d69e9f123fbb4b) |
| 82 | + # 3P |
| 83 | + p3 = Point(0x53dd5e495c7404790f9347470cc9c38ee239809c758f02ec04ba641ab3d0e043, |
| 84 | + 0xd7a4f5e5bdf21000b1fe7216adbea92cb9917d8fea7b37628c1eddb409a5cd3f) |
| 85 | + |
| 86 | + # nP |
| 87 | + n = 0xa91ce154dcab9adabe08cc1ee84ec3cd0f426bbc08a54a1c41bd25f2587caedd |
| 88 | + pn = Point(0x9dc4b057a857ad2ef3535b4a207a7bfc9264e8fcacf718c895db7ead8d445b26, |
| 89 | + 0x5af110ecb68636e5c352b69fc6348173932b83ca64587a91fd88af1446e33979) |
| 90 | + |
| 91 | + self.assertEqual(inf.scalar_mul(0), inf) |
| 92 | + self.assertEqual(inf.scalar_mul(1000), inf) |
| 93 | + self.assertEqual(inf.scalar_mul(-1), inf) |
| 94 | + |
| 95 | + self.assertEqual(p1.scalar_mul(0), inf) |
| 96 | + self.assertEqual(p1.scalar_mul(1), p1) |
| 97 | + self.assertEqual(p1.scalar_mul(2), p2) |
| 98 | + self.assertEqual(p1.scalar_mul(-2), np2) |
| 99 | + self.assertEqual(p2.scalar_mul(-1), np2) |
| 100 | + self.assertEqual(p1.scalar_mul(3), p3) |
| 101 | + |
0 commit comments