1 package org.bitcoin;
2 
3 import com.google.common.io.BaseEncoding;
4 import java.util.Arrays;
5 import java.math.BigInteger;
6 import javax.xml.bind.DatatypeConverter;
7 import static org.bitcoin.NativeSecp256k1Util.*;
8 
9 /**
10  * This class holds test cases defined for testing this library.
11  */
12 public class NativeSecp256k1Test {
13 
14     //TODO improve comments/add more tests
15     /**
16       * This tests verify() for a valid signature
17       */
18     public static void testVerifyPos() throws AssertFailException{
19         boolean result = false;
20         byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()); //sha256hash of "testing"
21         byte[] sig = BaseEncoding.base16().lowerCase().decode("3044022079BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817980220294F14E883B3F525B5367756C2A11EF6CF84B730B36C17CB0C56F0AAB2C98589".toLowerCase());
22         byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase());
23 
24         result = NativeSecp256k1.verify( data, sig, pub);
25         assertEquals( result, true , "testVerifyPos");
26     }
27 
28     /**
29       * This tests verify() for a non-valid signature
30       */
31     public static void testVerifyNeg() throws AssertFailException{
32         boolean result = false;
33         byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A91".toLowerCase()); //sha256hash of "testing"
34         byte[] sig = BaseEncoding.base16().lowerCase().decode("3044022079BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817980220294F14E883B3F525B5367756C2A11EF6CF84B730B36C17CB0C56F0AAB2C98589".toLowerCase());
35         byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase());
36 
37         result = NativeSecp256k1.verify( data, sig, pub);
38         //System.out.println(" TEST " + new BigInteger(1, resultbytes).toString(16));
39         assertEquals( result, false , "testVerifyNeg");
40     }
41 
42     /**
43       * This tests secret key verify() for a valid secretkey
44       */
45     public static void testSecKeyVerifyPos() throws AssertFailException{
46         boolean result = false;
47         byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase());
48 
49         result = NativeSecp256k1.secKeyVerify( sec );
50         //System.out.println(" TEST " + new BigInteger(1, resultbytes).toString(16));
51         assertEquals( result, true , "testSecKeyVerifyPos");
52     }
53 
54     /**
55       * This tests secret key verify() for a invalid secretkey
56       */
57     public static void testSecKeyVerifyNeg() throws AssertFailException{
58         boolean result = false;
59         byte[] sec = BaseEncoding.base16().lowerCase().decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase());
60 
61         result = NativeSecp256k1.secKeyVerify( sec );
useful_pmodref_access_node62         //System.out.println(" TEST " + new BigInteger(1, resultbytes).toString(16));
63         assertEquals( result, false , "testSecKeyVerifyNeg");
64     }
65 
66     /**
range_info_useful_pmodref_access_node67       * This tests public key create() for a valid secretkey
68       */
69     public static void testPubKeyCreatePos() throws AssertFailException{
70         byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase());
71 
72         byte[] resultArr = NativeSecp256k1.computePubkey( sec);
73         String pubkeyString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr);
74         assertEquals( pubkeyString , "04C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2D2103ED494718C697AC9AEBCFD19612E224DB46661011863ED2FC54E71861E2A6" , "testPubKeyCreatePos");
75     }
76 
77     /**
78       * This tests public key create() for a invalid secretkey
79       */
80     public static void testPubKeyCreateNeg() throws AssertFailException{
81        byte[] sec = BaseEncoding.base16().lowerCase().decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase());
82 
83        byte[] resultArr = NativeSecp256k1.computePubkey( sec);
84        String pubkeyString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr);
85        assertEquals( pubkeyString, "" , "testPubKeyCreateNeg");
86     }
87 
88     /**
89       * This tests sign() for a valid secretkey
90       */
91     public static void testSignPos() throws AssertFailException{
92 
93         byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()); //sha256hash of "testing"
94         byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase());
95 
96         byte[] resultArr = NativeSecp256k1.sign(data, sec);
97         String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr);
98         assertEquals( sigString, "30440220182A108E1448DC8F1FB467D06A0F3BB8EA0533584CB954EF8DA112F1D60E39A202201C66F36DA211C087F3AF88B50EDF4F9BDAA6CF5FD6817E74DCA34DB12390C6E9" , "testSignPos");
99     }
100 
101     /**
102       * This tests sign() for a invalid secretkey
103       */
modref_ref_nodemodref_ref_node104     public static void testSignNeg() throws AssertFailException{
105         byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()); //sha256hash of "testing"
106         byte[] sec = BaseEncoding.base16().lowerCase().decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase());
107 
108         byte[] resultArr = NativeSecp256k1.sign(data, sec);
109         String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr);
110         assertEquals( sigString, "" , "testSignNeg");
111     }
112 
113     /**
114       * This tests private key tweak-add
115       */
116     public static void testPrivKeyTweakAdd_1() throws AssertFailException {
117         byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase());
118         byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak"
119 
120         byte[] resultArr = NativeSecp256k1.privKeyTweakAdd( sec , data );
121         String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr);
collapsemodref_ref_node122         assertEquals( sigString , "A168571E189E6F9A7E2D657A4B53AE99B909F7E712D1C23CED28093CD57C88F3" , "testPrivKeyAdd_1");
123     }
124 
125     /**
126       * This tests private key tweak-mul
127       */
128     public static void testPrivKeyTweakMul_1() throws AssertFailException {
129         byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase());
130         byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak"
131 
insert_accessmodref_ref_node132         byte[] resultArr = NativeSecp256k1.privKeyTweakMul( sec , data );
133         String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr);
134         assertEquals( sigString , "97F8184235F101550F3C71C927507651BD3F1CDB4A5A33B8986ACF0DEE20FFFC" , "testPrivKeyMul_1");
135     }
136 
137     /**
138       * This tests private key tweak-add uncompressed
139       */
140     public static void testPrivKeyTweakAdd_2() throws AssertFailException {
141         byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase());
142         byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak"
143 
144         byte[] resultArr = NativeSecp256k1.pubKeyTweakAdd( pub , data );
145         String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr);
146         assertEquals( sigString , "0411C6790F4B663CCE607BAAE08C43557EDC1A4D11D88DFCB3D841D0C6A941AF525A268E2A863C148555C48FB5FBA368E88718A46E205FABC3DBA2CCFFAB0796EF" , "testPrivKeyAdd_2");
147     }
148 
149     /**
150       * This tests private key tweak-mul uncompressed
151       */
152     public static void testPrivKeyTweakMul_2() throws AssertFailException {
153         byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase());
154         byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak"
155 
156         byte[] resultArr = NativeSecp256k1.pubKeyTweakMul( pub , data );
157         String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr);
158         assertEquals( sigString , "04E0FE6FE55EBCA626B98A807F6CAF654139E14E5E3698F01A9A658E21DC1D2791EC060D4F412A794D5370F672BC94B722640B5F76914151CFCA6E712CA48CC589" , "testPrivKeyMul_2");
159     }
160 
161     /**
162       * This tests seed randomization
163       */
164     public static void testRandomize() throws AssertFailException {
165         byte[] seed = BaseEncoding.base16().lowerCase().decode("A441B15FE9A3CF56661190A0B93B9DEC7D04127288CC87250967CF3B52894D11".toLowerCase()); //sha256hash of "random"
166         boolean result = NativeSecp256k1.randomize(seed);
modref_base_nodemodref_base_node167         assertEquals( result, true, "testRandomize");
168     }
169 
170     public static void testCreateECDHSecret() throws AssertFailException{
171 
172         byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase());
searchmodref_base_node173         byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase());
174 
175         byte[] resultArr = NativeSecp256k1.createECDHSecret(sec, pub);
176         String ecdhString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr);
177         assertEquals( ecdhString, "2A2A67007A926E6594AF3EB564FC74005B37A9C8AEF2033C4552051B5C87F043" , "testCreateECDHSecret");
178     }
179 
180     public static void main(String[] args) throws AssertFailException{
181 
182 
183         System.out.println("\n libsecp256k1 enabled: " + Secp256k1Context.isEnabled() + "\n");
184 
185         assertEquals( Secp256k1Context.isEnabled(), true, "isEnabled" );
186 
187         //Test verify() success/fail
188         testVerifyPos();
189         testVerifyNeg();
190 
191         //Test secKeyVerify() success/fail
192         testSecKeyVerifyPos();
193         testSecKeyVerifyNeg();
194 
195         //Test computePubkey() success/fail
196         testPubKeyCreatePos();
197         testPubKeyCreateNeg();
198 
199         //Test sign() success/fail
200         testSignPos();
201         testSignNeg();
202 
203         //Test privKeyTweakAdd() 1
204         testPrivKeyTweakAdd_1();
205 
206         //Test privKeyTweakMul() 2
207         testPrivKeyTweakMul_1();
208 
209         //Test privKeyTweakAdd() 3
210         testPrivKeyTweakAdd_2();
211 
212         //Test privKeyTweakMul() 4
213         testPrivKeyTweakMul_2();
214 
215         //Test randomize()
216         testRandomize();
217 
collapsemodref_base_node218         //Test ECDH
219         testCreateECDHSecret();
220 
221         NativeSecp256k1.cleanup();
222 
223         System.out.println(" All tests passed." );
224 
225     }
226 }
227