11package org .arkecosystem .crypto ;
22
3- import org .bitcoinj .core .Sha256Hash ;
4-
53import java .math .BigInteger ;
4+ import org .bitcoinj .core .Sha256Hash ;
65
7- /**
8- * Heavily inspired in https://github.com/miketwk/bip-schnorr-java/blob/master/Schnorr.java
9- */
6+ /** Heavily inspired in https://github.com/miketwk/bip-schnorr-java/blob/master/Schnorr.java */
107public class Schnorr {
11- public static final BigInteger p = new BigInteger ("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F" , 16 );
12- public static final BigInteger n = new BigInteger ("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141" , 16 );
8+ public static final BigInteger p =
9+ new BigInteger ("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F" , 16 );
10+ public static final BigInteger n =
11+ new BigInteger ("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141" , 16 );
1312 public static final BigInteger [] G = {
1413 new BigInteger ("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798" , 16 ),
1514 new BigInteger ("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8" , 16 )
@@ -18,27 +17,32 @@ public class Schnorr {
1817 public static final BigInteger TWO = BigInteger .valueOf (2 );
1918 public static final BigInteger THREE = BigInteger .valueOf (3 );
2019
21- private final static char [] hexArray = "0123456789ABCDEF" .toCharArray ();
20+ private static final char [] hexArray = "0123456789ABCDEF" .toCharArray ();
2221
2322 public static BigInteger [] addPoint (BigInteger [] p1 , BigInteger [] p2 ) {
24- if (p1 == null || p1 .length != 2 )
25- return p2 ;
23+ if (p1 == null || p1 .length != 2 ) return p2 ;
2624
27- if (p2 == null || p2 .length != 2 )
28- return p1 ;
25+ if (p2 == null || p2 .length != 2 ) return p1 ;
2926
30- if (p1 [0 ].compareTo (p2 [0 ]) == 0 && p1 [1 ].compareTo (p2 [1 ]) != 0 )
31- return null ;
27+ if (p1 [0 ].compareTo (p2 [0 ]) == 0 && p1 [1 ].compareTo (p2 [1 ]) != 0 ) return null ;
3228
3329 BigInteger lam ;
3430 if (p1 [0 ].compareTo (p2 [0 ]) == 0 && p1 [1 ].compareTo (p2 [1 ]) == 0 )
35- lam = (THREE .multiply (p1 [0 ]).multiply (p1 [0 ]).multiply (TWO .multiply (p1 [1 ]).modPow (p .subtract (TWO ), p ))).mod (p );
31+ lam =
32+ (THREE .multiply (p1 [0 ])
33+ .multiply (p1 [0 ])
34+ .multiply (TWO .multiply (p1 [1 ]).modPow (p .subtract (TWO ), p )))
35+ .mod (p );
3636 else
37- lam = (p2 [1 ].subtract (p1 [1 ]).multiply (p2 [0 ].subtract (p1 [0 ]).modPow (p .subtract (TWO ), p ))).mod (p );
37+ lam =
38+ (p2 [1 ]
39+ .subtract (p1 [1 ])
40+ .multiply (p2 [0 ].subtract (p1 [0 ]).modPow (p .subtract (TWO ), p )))
41+ .mod (p );
3842
3943 BigInteger x3 = (lam .multiply (lam ).subtract (p1 [0 ]).subtract (p2 [0 ])).mod (p );
4044
41- return new BigInteger []{x3 , lam .multiply (p1 [0 ].subtract (x3 )).subtract (p1 [1 ]).mod (p )};
45+ return new BigInteger [] {x3 , lam .multiply (p1 [0 ].subtract (x3 )).subtract (p1 [1 ]).mod (p )};
4246 }
4347
4448 public static BigInteger [] multiplyPoint (BigInteger [] P , BigInteger n ) {
@@ -56,27 +60,24 @@ public static BigInteger jacobi(BigInteger x) {
5660 }
5761
5862 public static BigInteger [] bytesToPoint (byte [] b ) {
59- if (b [0 ] != 2 && b [0 ] != 3 )
60- return null ;
63+ if (b [0 ] != 2 && b [0 ] != 3 ) return null ;
6164
6265 BigInteger odd = b [0 ] == 3 ? BigInteger .ONE : BigInteger .ZERO ;
6366 BigInteger x = toBigInteger (b , 1 , 32 );
6467 BigInteger y_sq = x .modPow (THREE , p ).add (BigInteger .valueOf (7 )).mod (p );
6568 BigInteger y0 = y_sq .modPow (p .add (BigInteger .ONE ).divide (BigInteger .valueOf (4 )), p );
66- if (y_sq .compareTo (y0 .modPow (TWO , p )) != 0 )
67- return null ;
69+ if (y_sq .compareTo (y0 .modPow (TWO , p )) != 0 ) return null ;
6870
6971 BigInteger y = y0 .and (BigInteger .ONE ).compareTo (odd ) != 0 ? p .subtract (y0 ) : y0 ;
7072
71- return new BigInteger []{x , y };
73+ return new BigInteger [] {x , y };
7274 }
7375
7476 public static byte [] to32BytesData (BigInteger num ) {
7577 String hexNum = num .toString (16 );
7678 if (hexNum .length () < 64 ) {
7779 StringBuilder sb = new StringBuilder ();
78- for (int i = 0 ; i < 64 - hexNum .length (); i ++)
79- sb .append ("0" );
80+ for (int i = 0 ; i < 64 - hexNum .length (); i ++) sb .append ("0" );
8081
8182 hexNum = sb .append (hexNum ).toString ();
8283 }
@@ -93,16 +94,19 @@ public static BigInteger toBigInteger(byte[] data) {
9394
9495 public static byte [] pointToBytes (BigInteger [] point ) {
9596 byte [] res = new byte [33 ];
96- res [0 ] = BigInteger .ONE .compareTo (point [1 ].and (BigInteger .ONE )) == 0 ? (byte ) 0x03 : (byte ) 0x02 ;
97+ res [0 ] =
98+ BigInteger .ONE .compareTo (point [1 ].and (BigInteger .ONE )) == 0
99+ ? (byte ) 0x03
100+ : (byte ) 0x02 ;
97101 System .arraycopy (to32BytesData (point [0 ]), 0 , res , 1 , 32 );
98102 return res ;
99103 }
100104
101105 public static byte [] schnorrSign (byte [] msg , BigInteger seckey ) {
102- if (msg .length != 32 )
103- throw new RuntimeException ("The message must be a 32-byte array." );
106+ if (msg .length != 32 ) throw new RuntimeException ("The message must be a 32-byte array." );
104107
105- if (BigInteger .ZERO .compareTo (seckey ) > 0 || seckey .compareTo (n .subtract (BigInteger .ONE )) > 0 )
108+ if (BigInteger .ZERO .compareTo (seckey ) > 0
109+ || seckey .compareTo (n .subtract (BigInteger .ONE )) > 0 )
106110 throw new RuntimeException ("The secret key must be an integer in the range 1..n-1." );
107111
108112 byte [] resultData = new byte [32 + msg .length ];
@@ -132,24 +136,20 @@ public static byte[] schnorrSign(byte[] msg, BigInteger seckey) {
132136 }
133137
134138 public static boolean schnorrVerify (byte [] msg , byte [] pubkey , byte [] sig ) {
135- if (msg .length != 32 )
136- throw new RuntimeException ("The message must be a 32-byte array." );
139+ if (msg .length != 32 ) throw new RuntimeException ("The message must be a 32-byte array." );
137140
138141 if (pubkey .length != 33 )
139142 throw new RuntimeException ("The public key must be a 33-byte array." );
140143
141- if (sig .length != 64 )
142- throw new RuntimeException ("The signature must be a 64-byte array." );
144+ if (sig .length != 64 ) throw new RuntimeException ("The signature must be a 64-byte array." );
143145
144146 BigInteger [] P = bytesToPoint (pubkey );
145- if (P == null )
146- return false ;
147+ if (P == null ) return false ;
147148
148149 BigInteger r = toBigInteger (sig , 0 , 32 );
149150 BigInteger s = toBigInteger (sig , 32 , 32 );
150151
151- if (r .compareTo (p ) >= 0 || s .compareTo (n ) >= 0 )
152- return false ;
152+ if (r .compareTo (p ) >= 0 || s .compareTo (n ) >= 0 ) return false ;
153153
154154 byte [] eData = new byte [32 + 33 + 32 ];
155155 System .arraycopy (sig , 0 , eData , 0 , 32 );
@@ -167,8 +167,10 @@ public static byte[] hexStringToByteArray(String s) {
167167 int len = s .length ();
168168 byte [] data = new byte [len / 2 ];
169169 for (int i = 0 ; i < len ; i += 2 ) {
170- data [i / 2 ] = (byte ) ((Character .digit (s .charAt (i ), 16 ) << 4 )
171- + Character .digit (s .charAt (i + 1 ), 16 ));
170+ data [i / 2 ] =
171+ (byte )
172+ ((Character .digit (s .charAt (i ), 16 ) << 4 )
173+ + Character .digit (s .charAt (i + 1 ), 16 ));
172174 }
173175 return data ;
174176 }
0 commit comments