├── .gitignore
├── README.md
├── build.gradle
├── configure.sh
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
└── main
└── java
├── core
├── AddressFormatException.java
├── Base58.java
├── ECKey.java
├── Sha256Hash.java
├── Utils.java
└── cryptohash
│ ├── Digest.java
│ ├── DigestEngine.java
│ ├── HashUtil.java
│ ├── Keccak256.java
│ └── KeccakCore.java
└── utils
└── UscConversionUtils.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # Gradle
2 | .gradle
3 | build
4 |
5 | # IDEA
6 | out
7 | .idea
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # usc-utils-api
2 |
3 | usc-utils-api is a java api for converting Ulord private key to Ulord-Sidechain private key and vice-versa.
4 |
5 | To use the api, download and copy the [usc-utils-api-1.0-SNAPSHOT-all.jar](https://github.com/UlordChain/usc-utils-api/releases) file into libs directory of the project,
6 | and add the following in build.gradle dependencies section:-
7 | ```
8 | compile fileTree(dir: 'libs', include: '*.jar')
9 | ```
10 |
11 | ### Import the UscConversionUtils class
12 | ```
13 | import utils.UscConversionUtils;
14 | ```
15 |
16 | ### Call static functions
17 | ```
18 | //To convert Ulord private key to USC private key
19 | String uscPrivKey = UscConversionUtils.privKeyToUscFormat("UlordPrivateKey");
20 |
21 | //To get the USC address
22 | String address = UscConversionUtils.getUscAddress("uscPrivKey").toLowerCase();
23 |
24 | //To get USC Public key
25 | String uscPubKey = UscConversionUtils.getUscPubKey("uscPrivKey").toLowerCase();
26 |
27 | //To convert USC private key to Ulord private key
28 | //First Parameter can be either ("main", "test")
29 | //@main to generate private key for mainnet.
30 | //@test to generate Private key for testnet.
31 | String ulordPrivateKey = UscConversionUtils.getUldPrivateKey("test","UscPrivateKey")
32 | ```
33 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | version '1.0-SNAPSHOT'
2 |
3 | apply plugin: 'java'
4 |
5 | sourceCompatibility = 1.8
6 |
7 | repositories {
8 | mavenCentral()
9 | }
10 |
11 | dependencies {
12 | compile 'com.madgag.spongycastle:core:1.58.0.0'
13 | implementation 'com.google.guava:guava:24.0-android'
14 | testCompile group: 'junit', name: 'junit', version: '4.12'
15 | }
16 |
17 | task fatJar(type: Jar) {
18 | classifier = 'all'
19 | from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
20 | with jar
21 | }
--------------------------------------------------------------------------------
/configure.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | unamestr=`uname`
4 |
5 |
6 | function downloadJar(){
7 | platform
8 | if [ ! -d ./libs ]; then
9 | mkdir ./libs
10 | fi
11 |
12 |
13 | curl -o ./libs/ulordj-thin-0.0.1-usc-1-bundled.jar -L https://github.com/UlordChain/ulordj-thin/releases/download/ulordj-thin-0.0.1/ulordj-thin-0.0.1-usc-1-bundled.jar;
14 |
15 | }
16 |
17 | function platform() {
18 | if [[ "$unamestr" == 'Linux' ]]; then
19 | PLATFORM='linux'
20 | elif [[ "$unamestr" == 'Darwin' ]]; then
21 | PLATFORM='mac'
22 | elif [[ "$unamestr" =~ 'MINGW' ]]; then
23 | PLATFORM='windows'
24 | else
25 | echo -e "\e[1m\e[31m[ ERROR ]\e[0m UNRECOGNIZED PLATFORM"
26 | exit 2
27 | fi
28 | }
29 |
30 | downloadJar
31 |
32 | exit 0
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/UlordChain/usc-utils-api/671606cf0830244ce2f79812ba84120b277ec0ab/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip
6 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'usc-utils-api'
2 |
3 |
--------------------------------------------------------------------------------
/src/main/java/core/AddressFormatException.java:
--------------------------------------------------------------------------------
1 | package core;
2 |
3 | @SuppressWarnings("serial")
4 | public class AddressFormatException extends IllegalArgumentException {
5 | public AddressFormatException() {
6 | super();
7 | }
8 |
9 | public AddressFormatException(String message) {
10 | super(message);
11 | }
12 | }
--------------------------------------------------------------------------------
/src/main/java/core/Base58.java:
--------------------------------------------------------------------------------
1 | package core;
2 |
3 | import java.util.Arrays;
4 |
5 | public class Base58 {
6 | public static final char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray();
7 | private static final char ENCODED_ZERO = ALPHABET[0];
8 | private static final int[] INDEXES = new int[128];
9 |
10 | static {
11 | Arrays.fill(INDEXES, -1);
12 | for (int i = 0; i < ALPHABET.length; i++) {
13 | INDEXES[ALPHABET[i]] = i;
14 | }
15 | }
16 |
17 | public static String encode(byte[] input) {
18 | if (input.length == 0) {
19 | return "";
20 | }
21 | // Count leading zeros.
22 | int zeros = 0;
23 | while (zeros < input.length && input[zeros] == 0) {
24 | ++zeros;
25 | }
26 | // Convert base-256 digits to base-58 digits (plus conversion to ASCII characters)
27 | input = Arrays.copyOf(input, input.length); // since we modify it in-place
28 | char[] encoded = new char[input.length * 2]; // upper bound
29 | int outputStart = encoded.length;
30 | for (int inputStart = zeros; inputStart < input.length; ) {
31 | encoded[--outputStart] = ALPHABET[divmod(input, inputStart, 256, 58)];
32 | if (input[inputStart] == 0) {
33 | ++inputStart; // optimization - skip leading zeros
34 | }
35 | }
36 | // Preserve exactly as many leading encoded zeros in output as there were leading zeros in input.
37 | while (outputStart < encoded.length && encoded[outputStart] == ENCODED_ZERO) {
38 | ++outputStart;
39 | }
40 | while (--zeros >= 0) {
41 | encoded[--outputStart] = ENCODED_ZERO;
42 | }
43 | // Return encoded string (including encoded leading zeros).
44 | return new String(encoded, outputStart, encoded.length - outputStart);
45 | }
46 |
47 | public static byte[] decode(String input) throws AddressFormatException {
48 | if (input.length() == 0) {
49 | return new byte[0];
50 | }
51 | // Convert the base58-encoded ASCII chars to a base58 byte sequence (base58 digits).
52 | byte[] input58 = new byte[input.length()];
53 | for (int i = 0; i < input.length(); ++i) {
54 | char c = input.charAt(i);
55 | int digit = c < 128 ? INDEXES[c] : -1;
56 | if (digit < 0) {
57 | throw new AddressFormatException("Illegal character " + c + " at position " + i);
58 | }
59 | input58[i] = (byte) digit;
60 | }
61 | // Count leading zeros.
62 | int zeros = 0;
63 | while (zeros < input58.length && input58[zeros] == 0) {
64 | ++zeros;
65 | }
66 | // Convert base-58 digits to base-256 digits.
67 | byte[] decoded = new byte[input.length()];
68 | int outputStart = decoded.length;
69 | for (int inputStart = zeros; inputStart < input58.length; ) {
70 | decoded[--outputStart] = divmod(input58, inputStart, 58, 256);
71 | if (input58[inputStart] == 0) {
72 | ++inputStart; // optimization - skip leading zeros
73 | }
74 | }
75 | // Ignore extra leading zeroes that were added during the calculation.
76 | while (outputStart < decoded.length && decoded[outputStart] == 0) {
77 | ++outputStart;
78 | }
79 | // Return decoded data (including original number of leading zeros).
80 | return Arrays.copyOfRange(decoded, outputStart - zeros, decoded.length);
81 | }
82 |
83 | private static byte divmod(byte[] number, int firstDigit, int base, int divisor) {
84 | // this is just long division which accounts for the base of the input digits
85 | int remainder = 0;
86 | for (int i = firstDigit; i < number.length; i++) {
87 | int digit = (int) number[i] & 0xFF;
88 | int temp = remainder * base + digit;
89 | number[i] = (byte) (temp / divisor);
90 | remainder = temp % divisor;
91 | }
92 | return (byte) remainder;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/main/java/core/ECKey.java:
--------------------------------------------------------------------------------
1 | package core;
2 |
3 | import core.cryptohash.HashUtil;
4 | import org.spongycastle.asn1.sec.SECNamedCurves;
5 | import org.spongycastle.asn1.x9.X9ECParameters;
6 | import org.spongycastle.crypto.AsymmetricCipherKeyPair;
7 | import org.spongycastle.crypto.generators.ECKeyPairGenerator;
8 | import org.spongycastle.crypto.params.*;
9 | import org.spongycastle.math.ec.ECPoint;
10 | import javax.annotation.Nullable;
11 | import java.io.Serializable;
12 | import java.math.BigInteger;
13 | import java.security.SecureRandom;
14 | import java.util.Arrays;
15 |
16 |
17 | public class ECKey implements Serializable {
18 |
19 | /**
20 | * The parameters of the secp256k1 curve that Ethereum uses.
21 | */
22 | public static final ECDomainParameters CURVE;
23 |
24 | /**
25 | * Equal to CURVE.getN().shiftRight(1), used for canonicalising the S value of a signature. If you aren't
26 | * sure what this is about, you can ignore it.
27 | */
28 | public static final BigInteger HALF_CURVE_ORDER;
29 |
30 | private static final SecureRandom secureRandom;
31 | private static final long serialVersionUID = -728224901792295832L;
32 |
33 | static {
34 | // All clients must agree on the curve to use by agreement. Ethereum uses secp256k1.
35 | X9ECParameters params = SECNamedCurves.getByName("secp256k1");
36 | CURVE = new ECDomainParameters(params.getCurve(), params.getG(), params.getN(), params.getH());
37 | HALF_CURVE_ORDER = params.getN().shiftRight(1);
38 | secureRandom = new SecureRandom();
39 | }
40 |
41 | // The two parts of the key. If "priv" is set, "pub" can always be calculated. If "pub" is set but not "priv", we
42 | // can only verify signatures not make them.
43 | // TODO: Redesign this class to use consistent internals and more efficient serialization.
44 | private BigInteger priv;
45 | protected final ECPoint pub;
46 |
47 | // Transient because it's calculated on demand.
48 | private transient byte[] pubKeyHash;
49 | private transient byte[] nodeId;
50 |
51 | /**
52 | * Generates an entirely new keypair. Point compression is used so the resulting public key will be 33 bytes
53 | * (32 for the co-ordinate and 1 byte to represent the y bit).
54 | */
55 | public ECKey() {
56 | this(secureRandom);
57 | }
58 |
59 | /**
60 | * Generates an entirely new keypair with the given {@link SecureRandom} object. Point compression is used so the
61 | * resulting public key will be 33 bytes (32 for the co-ordinate and 1 byte to represent the y bit).
62 | *
63 | * @param secureRandom -
64 | */
65 | public ECKey(SecureRandom secureRandom) {
66 | ECKeyPairGenerator generator = new ECKeyPairGenerator();
67 | ECKeyGenerationParameters keygenParams = new ECKeyGenerationParameters(CURVE, secureRandom);
68 | generator.init(keygenParams);
69 | AsymmetricCipherKeyPair keypair = generator.generateKeyPair();
70 | ECPrivateKeyParameters privParams = (ECPrivateKeyParameters) keypair.getPrivate();
71 | ECPublicKeyParameters pubParams = (ECPublicKeyParameters) keypair.getPublic();
72 | priv = privParams.getD();
73 | pub = CURVE.getCurve().decodePoint(pubParams.getQ().getEncoded(true));
74 | }
75 |
76 | public ECKey(@Nullable BigInteger priv, ECPoint pub) {
77 | this.priv = priv;
78 | if (pub == null) {
79 | throw new IllegalArgumentException("Public key may not be null");
80 | }
81 | this.pub = pub;
82 | }
83 |
84 | /**
85 | * Utility for compressing an elliptic curve point. Returns the same point if it's already compressed.
86 | * See the ECKey class docs for a discussion of point compression.
87 | *
88 | * @param uncompressed -
89 | *
90 | * @return -
91 | */
92 | public static ECPoint compressPoint(ECPoint uncompressed) {
93 | return CURVE.getCurve().decodePoint(uncompressed.getEncoded(true));
94 | }
95 |
96 | /**
97 | * Utility for decompressing an elliptic curve point. Returns the same point if it's already compressed.
98 | * See the ECKey class docs for a discussion of point compression.
99 | *
100 | * @param compressed -
101 | *
102 | * @return -
103 | */
104 | public static ECPoint decompressPoint(ECPoint compressed) {
105 | return CURVE.getCurve().decodePoint(compressed.getEncoded(false));
106 | }
107 |
108 | /**
109 | * Creates an ECKey given the private key only. The public key is calculated from it (this is slow). Note that
110 | * the resulting public key is compressed.
111 | *
112 | * @param privKey -
113 | *
114 | *
115 | * @return -
116 | */
117 | public static ECKey fromPrivate(BigInteger privKey) {
118 | return new ECKey(privKey, compressPoint(CURVE.getG().multiply(privKey)));
119 | }
120 |
121 | /**
122 | * Creates an ECKey given the private key only. The public key is calculated from it (this is slow). The resulting
123 | * public key is compressed.
124 | *
125 | * @param privKeyBytes -
126 | *
127 | * @return -
128 | */
129 | public static ECKey fromPrivate(byte[] privKeyBytes) {
130 | return fromPrivate(new BigInteger(1, privKeyBytes));
131 | }
132 |
133 | /**
134 | * Gets the hash160 form of the public key (as seen in addresses).
135 | *
136 | * @return -
137 | */
138 | public byte[] getAddress() {
139 | if (pubKeyHash == null) {
140 | byte[] pubBytes = this.pub.getEncoded(false);
141 | pubKeyHash = HashUtil.sha3omit12(Arrays.copyOfRange(pubBytes, 1, pubBytes.length));
142 | }
143 | return pubKeyHash;
144 | }
145 |
146 | /**
147 | * Gets the raw public key value. This appears in transaction scriptSigs. Note that this is not the same
148 | * as the pubKeyHash/address.
149 | *
150 | * @return -
151 | */
152 | public byte[] getPubKey() {
153 | return pub.getEncoded(false);
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/src/main/java/core/Sha256Hash.java:
--------------------------------------------------------------------------------
1 | package core;
2 |
3 | import java.io.Serializable;
4 | import java.security.MessageDigest;
5 | import java.security.NoSuchAlgorithmException;
6 |
7 | import static com.google.common.base.Preconditions.checkArgument;
8 |
9 | public class Sha256Hash implements Serializable, Comparable {
10 | public static final int LENGTH = 32; // bytes
11 |
12 | private final byte[] bytes;
13 |
14 | private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
15 |
16 | public static String bytesToHex(byte[] bytes) {
17 | char[] hexChars = new char[bytes.length * 2];
18 | for ( int j = 0; j < bytes.length; j++ ) {
19 | int v = bytes[j] & 0xFF;
20 | hexChars[j * 2] = hexArray[v >>> 4];
21 | hexChars[j * 2 + 1] = hexArray[v & 0x0F];
22 | }
23 | return new String(hexChars);
24 | }
25 |
26 | public static byte[] hexStringToByteArray(String s) {
27 | int len = s.length();
28 | byte[] data = new byte[len / 2];
29 | for (int i = 0; i < len; i += 2) {
30 | data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
31 | + Character.digit(s.charAt(i+1), 16));
32 | }
33 | return data;
34 | }
35 |
36 | @Deprecated
37 | public Sha256Hash(byte[] rawHashBytes) {
38 | checkArgument(rawHashBytes.length == LENGTH);
39 | this.bytes = rawHashBytes;
40 | }
41 |
42 | @Deprecated
43 | public Sha256Hash(String hexString) {
44 | checkArgument(hexString.length() == LENGTH * 2);
45 | this.bytes = Utils.HEX.decode(hexString);
46 | }
47 |
48 | public static MessageDigest newDigest() {
49 | try {
50 | return MessageDigest.getInstance("SHA-256");
51 | } catch (NoSuchAlgorithmException e) {
52 | throw new RuntimeException(e); // Can't happen.
53 | }
54 | }
55 |
56 | public static byte[] hashTwice(byte[] input) {
57 | return hashTwice(input, 0, input.length);
58 | }
59 |
60 | public static byte[] hashTwice(byte[] input, int offset, int length) {
61 | MessageDigest digest = newDigest();
62 | digest.update(input, offset, length);
63 | return digest.digest(digest.digest());
64 | }
65 |
66 | public static byte[] hashTwice(byte[] input1, int offset1, int length1,
67 | byte[] input2, int offset2, int length2) {
68 | MessageDigest digest = newDigest();
69 | digest.update(input1, offset1, length1);
70 | digest.update(input2, offset2, length2);
71 | return digest.digest(digest.digest());
72 | }
73 |
74 | @Override
75 | public int compareTo(final Sha256Hash other) {
76 | for (int i = LENGTH - 1; i >= 0; i--) {
77 | final int thisByte = this.bytes[i] & 0xff;
78 | final int otherByte = other.bytes[i] & 0xff;
79 | if (thisByte > otherByte)
80 | return 1;
81 | if (thisByte < otherByte)
82 | return -1;
83 | }
84 | return 0;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/core/Utils.java:
--------------------------------------------------------------------------------
1 | package core;
2 |
3 | import com.google.common.io.BaseEncoding;
4 |
5 | public class Utils {
6 |
7 | public static final BaseEncoding HEX = BaseEncoding.base16().lowerCase();
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/core/cryptohash/Digest.java:
--------------------------------------------------------------------------------
1 | package core.cryptohash;
2 |
3 | public interface Digest {
4 |
5 | public void update(byte[] inbuf);
6 |
7 | public int getDigestLength();
8 |
9 | public int getBlockLength();
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/core/cryptohash/DigestEngine.java:
--------------------------------------------------------------------------------
1 | package core.cryptohash;
2 |
3 | public abstract class DigestEngine implements Digest {
4 |
5 | protected abstract void engineReset();
6 |
7 | protected abstract void doInit();
8 |
9 | protected abstract void processBlock(byte[] data);
10 |
11 | protected abstract void doPadding(byte[] buf, int off);
12 |
13 | private int digestLen;
14 | private int blockLen;
15 | private int inputLen;
16 | private byte[] inputBuf;
17 | byte[] outputBuf;
18 | private long blockCount;
19 |
20 | public DigestEngine()
21 | {
22 | doInit();
23 | digestLen = getDigestLength();
24 | blockLen = getInternalBlockLength();
25 | inputBuf = new byte[blockLen];
26 | outputBuf = new byte[digestLen];
27 | inputLen = 0;
28 | blockCount = 0;
29 | }
30 |
31 | private void adjustDigestLen()
32 | {
33 | if (digestLen == 0) {
34 | digestLen = getDigestLength();
35 | outputBuf = new byte[digestLen];
36 | }
37 | }
38 |
39 | public byte[] digest()
40 | {
41 | adjustDigestLen();
42 | byte[] result = new byte[digestLen];
43 | digest(result, 0, digestLen);
44 | return result;
45 | }
46 |
47 | public int digest(byte[] buf, int offset, int len)
48 | {
49 | adjustDigestLen();
50 | if (len >= digestLen) {
51 | doPadding(buf, offset);
52 | reset();
53 | return digestLen;
54 | } else {
55 | doPadding(outputBuf, 0);
56 | System.arraycopy(outputBuf, 0, buf, offset, len);
57 | reset();
58 | return len;
59 | }
60 | }
61 |
62 | public void reset()
63 | {
64 | engineReset();
65 | inputLen = 0;
66 | blockCount = 0;
67 | }
68 |
69 | public void update(byte[] input)
70 | {
71 | update(input, 0, input.length);
72 | }
73 |
74 | public void update(byte[] input, int offset, int len)
75 | {
76 | while (len > 0) {
77 | int copyLen = blockLen - inputLen;
78 | if (copyLen > len) {
79 | copyLen = len;
80 | }
81 | System.arraycopy(input, offset, inputBuf, inputLen,
82 | copyLen);
83 | offset += copyLen;
84 | inputLen += copyLen;
85 | len -= copyLen;
86 | if (inputLen == blockLen) {
87 | processBlock(inputBuf);
88 | blockCount ++;
89 | inputLen = 0;
90 | }
91 | }
92 | }
93 |
94 | protected int getInternalBlockLength()
95 | {
96 | return getBlockLength();
97 | }
98 |
99 | protected final int flush()
100 | {
101 | return inputLen;
102 | }
103 |
104 | protected final byte[] getBlockBuffer()
105 | {
106 | return inputBuf;
107 | }
108 |
109 | protected Digest copyState(DigestEngine dest)
110 | {
111 | dest.inputLen = inputLen;
112 | dest.blockCount = blockCount;
113 | System.arraycopy(inputBuf, 0, dest.inputBuf, 0,
114 | inputBuf.length);
115 | adjustDigestLen();
116 | dest.adjustDigestLen();
117 | System.arraycopy(outputBuf, 0, dest.outputBuf, 0,
118 | outputBuf.length);
119 | return dest;
120 | }
121 | }
122 |
123 |
--------------------------------------------------------------------------------
/src/main/java/core/cryptohash/HashUtil.java:
--------------------------------------------------------------------------------
1 | package core.cryptohash;
2 |
3 | import core.cryptohash.Keccak256;
4 |
5 | import static java.util.Arrays.copyOfRange;
6 |
7 | public class HashUtil {
8 | /**
9 | * Calculates RIGTMOST160(SHA3(input)). This is used in address calculations.
10 | * *
11 | * @param input - data
12 | * @return - 20 right bytes of the hash sha3 of the data
13 | */
14 | public static byte[] sha3omit12(byte[] input) {
15 | byte[] hash = keccak256(input);
16 | return copyOfRange(hash, 12, hash.length);
17 | }
18 |
19 | public static byte[] keccak256(byte[] input) {
20 | Keccak256 digest = new Keccak256();
21 | digest.update(input);
22 | return digest.digest();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/core/cryptohash/Keccak256.java:
--------------------------------------------------------------------------------
1 | package core.cryptohash;
2 |
3 | public class Keccak256 extends KeccakCore {
4 |
5 | /**
6 | * Create the engine.
7 | */
8 | public Keccak256()
9 | {
10 | }
11 |
12 | public Digest copy()
13 | {
14 | return copyState(new Keccak256());
15 | }
16 |
17 | public int getDigestLength()
18 | {
19 | return 32;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/core/cryptohash/KeccakCore.java:
--------------------------------------------------------------------------------
1 | package core.cryptohash;
2 |
3 | abstract class KeccakCore extends DigestEngine{
4 |
5 | KeccakCore()
6 | {
7 | }
8 |
9 | private long[] a;
10 | private byte[] tmpOut;
11 |
12 | private static final long[] RC = {
13 | 0x0000000000000001L, 0x0000000000008082L,
14 | 0x800000000000808AL, 0x8000000080008000L,
15 | 0x000000000000808BL, 0x0000000080000001L,
16 | 0x8000000080008081L, 0x8000000000008009L,
17 | 0x000000000000008AL, 0x0000000000000088L,
18 | 0x0000000080008009L, 0x000000008000000AL,
19 | 0x000000008000808BL, 0x800000000000008BL,
20 | 0x8000000000008089L, 0x8000000000008003L,
21 | 0x8000000000008002L, 0x8000000000000080L,
22 | 0x000000000000800AL, 0x800000008000000AL,
23 | 0x8000000080008081L, 0x8000000000008080L,
24 | 0x0000000080000001L, 0x8000000080008008L
25 | };
26 |
27 | private static final void encodeLELong(long val, byte[] buf, int off)
28 | {
29 | buf[off + 0] = (byte)val;
30 | buf[off + 1] = (byte)(val >>> 8);
31 | buf[off + 2] = (byte)(val >>> 16);
32 | buf[off + 3] = (byte)(val >>> 24);
33 | buf[off + 4] = (byte)(val >>> 32);
34 | buf[off + 5] = (byte)(val >>> 40);
35 | buf[off + 6] = (byte)(val >>> 48);
36 | buf[off + 7] = (byte)(val >>> 56);
37 | }
38 |
39 | private static final long decodeLELong(byte[] buf, int off)
40 | {
41 | return (buf[off + 0] & 0xFFL)
42 | | ((buf[off + 1] & 0xFFL) << 8)
43 | | ((buf[off + 2] & 0xFFL) << 16)
44 | | ((buf[off + 3] & 0xFFL) << 24)
45 | | ((buf[off + 4] & 0xFFL) << 32)
46 | | ((buf[off + 5] & 0xFFL) << 40)
47 | | ((buf[off + 6] & 0xFFL) << 48)
48 | | ((buf[off + 7] & 0xFFL) << 56);
49 | }
50 |
51 | protected Digest copyState(KeccakCore dst)
52 | {
53 | System.arraycopy(a, 0, dst.a, 0, 25);
54 | return super.copyState(dst);
55 | }
56 |
57 | public int getBlockLength()
58 | {
59 | return 200 - 2 * getDigestLength();
60 | }
61 |
62 | protected void doPadding(byte[] out, int off)
63 | {
64 | int ptr = flush();
65 | byte[] buf = getBlockBuffer();
66 | if ((ptr + 1) == buf.length) {
67 | buf[ptr] = (byte)0x81;
68 | } else {
69 | buf[ptr] = (byte)0x01;
70 | for (int i = ptr + 1; i < (buf.length - 1); i ++) {
71 | buf[i] = 0;
72 | }
73 | buf[buf.length - 1] = (byte)0x80;
74 | }
75 | processBlock(buf);
76 | a[ 1] = ~a[ 1];
77 | a[ 2] = ~a[ 2];
78 | a[ 8] = ~a[ 8];
79 | a[12] = ~a[12];
80 | a[17] = ~a[17];
81 | a[20] = ~a[20];
82 | int dlen = getDigestLength();
83 | for (int i = 0; i < dlen; i += 8) {
84 | encodeLELong(a[i >>> 3], tmpOut, i);
85 | }
86 | System.arraycopy(tmpOut, 0, out, off, dlen);
87 | }
88 |
89 | protected void doInit()
90 | {
91 | a = new long[25];
92 | tmpOut = new byte[(getDigestLength() + 7) & ~7];
93 | doReset();
94 | }
95 |
96 | private final void doReset()
97 | {
98 | for (int i = 0; i < 25; i ++) {
99 | a[i] = 0;
100 | }
101 | a[ 1] = 0xFFFFFFFFFFFFFFFFL;
102 | a[ 2] = 0xFFFFFFFFFFFFFFFFL;
103 | a[ 8] = 0xFFFFFFFFFFFFFFFFL;
104 | a[12] = 0xFFFFFFFFFFFFFFFFL;
105 | a[17] = 0xFFFFFFFFFFFFFFFFL;
106 | a[20] = 0xFFFFFFFFFFFFFFFFL;
107 | }
108 |
109 | protected void engineReset()
110 | {
111 | doReset();
112 | }
113 |
114 | protected void processBlock(byte[] data)
115 | {
116 | /* Input block */
117 | for (int i = 0; i < data.length; i += 8) {
118 | a[i >>> 3] ^= decodeLELong(data, i);
119 | }
120 |
121 | long t0;
122 | long t1;
123 | long t2;
124 | long t3;
125 | long t4;
126 | long tt0;
127 | long tt1;
128 | long tt2;
129 | long tt3;
130 | long tt4;
131 | long t;
132 | long kt;
133 | long c0;
134 | long c1;
135 | long c2;
136 | long c3;
137 | long c4;
138 | long bnn;
139 |
140 | /*
141 | * Unrolling four rounds kills performance big time
142 | * on Intel x86 Core2, in both 32-bit and 64-bit modes
143 | * (less than 1 MB/s instead of 55 MB/s on x86-64).
144 | * Unrolling two rounds appears to be fine.
145 | */
146 | for (int j = 0; j < 24; j += 2) {
147 |
148 | tt0 = a[ 1] ^ a[ 6];
149 | tt1 = a[11] ^ a[16];
150 | tt0 ^= a[21] ^ tt1;
151 | tt0 = (tt0 << 1) | (tt0 >>> 63);
152 | tt2 = a[ 4] ^ a[ 9];
153 | tt3 = a[14] ^ a[19];
154 | tt0 ^= a[24];
155 | tt2 ^= tt3;
156 | t0 = tt0 ^ tt2;
157 |
158 | tt0 = a[ 2] ^ a[ 7];
159 | tt1 = a[12] ^ a[17];
160 | tt0 ^= a[22] ^ tt1;
161 | tt0 = (tt0 << 1) | (tt0 >>> 63);
162 | tt2 = a[ 0] ^ a[ 5];
163 | tt3 = a[10] ^ a[15];
164 | tt0 ^= a[20];
165 | tt2 ^= tt3;
166 | t1 = tt0 ^ tt2;
167 |
168 | tt0 = a[ 3] ^ a[ 8];
169 | tt1 = a[13] ^ a[18];
170 | tt0 ^= a[23] ^ tt1;
171 | tt0 = (tt0 << 1) | (tt0 >>> 63);
172 | tt2 = a[ 1] ^ a[ 6];
173 | tt3 = a[11] ^ a[16];
174 | tt0 ^= a[21];
175 | tt2 ^= tt3;
176 | t2 = tt0 ^ tt2;
177 |
178 | tt0 = a[ 4] ^ a[ 9];
179 | tt1 = a[14] ^ a[19];
180 | tt0 ^= a[24] ^ tt1;
181 | tt0 = (tt0 << 1) | (tt0 >>> 63);
182 | tt2 = a[ 2] ^ a[ 7];
183 | tt3 = a[12] ^ a[17];
184 | tt0 ^= a[22];
185 | tt2 ^= tt3;
186 | t3 = tt0 ^ tt2;
187 |
188 | tt0 = a[ 0] ^ a[ 5];
189 | tt1 = a[10] ^ a[15];
190 | tt0 ^= a[20] ^ tt1;
191 | tt0 = (tt0 << 1) | (tt0 >>> 63);
192 | tt2 = a[ 3] ^ a[ 8];
193 | tt3 = a[13] ^ a[18];
194 | tt0 ^= a[23];
195 | tt2 ^= tt3;
196 | t4 = tt0 ^ tt2;
197 |
198 | a[ 0] = a[ 0] ^ t0;
199 | a[ 5] = a[ 5] ^ t0;
200 | a[10] = a[10] ^ t0;
201 | a[15] = a[15] ^ t0;
202 | a[20] = a[20] ^ t0;
203 | a[ 1] = a[ 1] ^ t1;
204 | a[ 6] = a[ 6] ^ t1;
205 | a[11] = a[11] ^ t1;
206 | a[16] = a[16] ^ t1;
207 | a[21] = a[21] ^ t1;
208 | a[ 2] = a[ 2] ^ t2;
209 | a[ 7] = a[ 7] ^ t2;
210 | a[12] = a[12] ^ t2;
211 | a[17] = a[17] ^ t2;
212 | a[22] = a[22] ^ t2;
213 | a[ 3] = a[ 3] ^ t3;
214 | a[ 8] = a[ 8] ^ t3;
215 | a[13] = a[13] ^ t3;
216 | a[18] = a[18] ^ t3;
217 | a[23] = a[23] ^ t3;
218 | a[ 4] = a[ 4] ^ t4;
219 | a[ 9] = a[ 9] ^ t4;
220 | a[14] = a[14] ^ t4;
221 | a[19] = a[19] ^ t4;
222 | a[24] = a[24] ^ t4;
223 | a[ 5] = (a[ 5] << 36) | (a[ 5] >>> (64 - 36));
224 | a[10] = (a[10] << 3) | (a[10] >>> (64 - 3));
225 | a[15] = (a[15] << 41) | (a[15] >>> (64 - 41));
226 | a[20] = (a[20] << 18) | (a[20] >>> (64 - 18));
227 | a[ 1] = (a[ 1] << 1) | (a[ 1] >>> (64 - 1));
228 | a[ 6] = (a[ 6] << 44) | (a[ 6] >>> (64 - 44));
229 | a[11] = (a[11] << 10) | (a[11] >>> (64 - 10));
230 | a[16] = (a[16] << 45) | (a[16] >>> (64 - 45));
231 | a[21] = (a[21] << 2) | (a[21] >>> (64 - 2));
232 | a[ 2] = (a[ 2] << 62) | (a[ 2] >>> (64 - 62));
233 | a[ 7] = (a[ 7] << 6) | (a[ 7] >>> (64 - 6));
234 | a[12] = (a[12] << 43) | (a[12] >>> (64 - 43));
235 | a[17] = (a[17] << 15) | (a[17] >>> (64 - 15));
236 | a[22] = (a[22] << 61) | (a[22] >>> (64 - 61));
237 | a[ 3] = (a[ 3] << 28) | (a[ 3] >>> (64 - 28));
238 | a[ 8] = (a[ 8] << 55) | (a[ 8] >>> (64 - 55));
239 | a[13] = (a[13] << 25) | (a[13] >>> (64 - 25));
240 | a[18] = (a[18] << 21) | (a[18] >>> (64 - 21));
241 | a[23] = (a[23] << 56) | (a[23] >>> (64 - 56));
242 | a[ 4] = (a[ 4] << 27) | (a[ 4] >>> (64 - 27));
243 | a[ 9] = (a[ 9] << 20) | (a[ 9] >>> (64 - 20));
244 | a[14] = (a[14] << 39) | (a[14] >>> (64 - 39));
245 | a[19] = (a[19] << 8) | (a[19] >>> (64 - 8));
246 | a[24] = (a[24] << 14) | (a[24] >>> (64 - 14));
247 | bnn = ~a[12];
248 | kt = a[ 6] | a[12];
249 | c0 = a[ 0] ^ kt;
250 | kt = bnn | a[18];
251 | c1 = a[ 6] ^ kt;
252 | kt = a[18] & a[24];
253 | c2 = a[12] ^ kt;
254 | kt = a[24] | a[ 0];
255 | c3 = a[18] ^ kt;
256 | kt = a[ 0] & a[ 6];
257 | c4 = a[24] ^ kt;
258 | a[ 0] = c0;
259 | a[ 6] = c1;
260 | a[12] = c2;
261 | a[18] = c3;
262 | a[24] = c4;
263 | bnn = ~a[22];
264 | kt = a[ 9] | a[10];
265 | c0 = a[ 3] ^ kt;
266 | kt = a[10] & a[16];
267 | c1 = a[ 9] ^ kt;
268 | kt = a[16] | bnn;
269 | c2 = a[10] ^ kt;
270 | kt = a[22] | a[ 3];
271 | c3 = a[16] ^ kt;
272 | kt = a[ 3] & a[ 9];
273 | c4 = a[22] ^ kt;
274 | a[ 3] = c0;
275 | a[ 9] = c1;
276 | a[10] = c2;
277 | a[16] = c3;
278 | a[22] = c4;
279 | bnn = ~a[19];
280 | kt = a[ 7] | a[13];
281 | c0 = a[ 1] ^ kt;
282 | kt = a[13] & a[19];
283 | c1 = a[ 7] ^ kt;
284 | kt = bnn & a[20];
285 | c2 = a[13] ^ kt;
286 | kt = a[20] | a[ 1];
287 | c3 = bnn ^ kt;
288 | kt = a[ 1] & a[ 7];
289 | c4 = a[20] ^ kt;
290 | a[ 1] = c0;
291 | a[ 7] = c1;
292 | a[13] = c2;
293 | a[19] = c3;
294 | a[20] = c4;
295 | bnn = ~a[17];
296 | kt = a[ 5] & a[11];
297 | c0 = a[ 4] ^ kt;
298 | kt = a[11] | a[17];
299 | c1 = a[ 5] ^ kt;
300 | kt = bnn | a[23];
301 | c2 = a[11] ^ kt;
302 | kt = a[23] & a[ 4];
303 | c3 = bnn ^ kt;
304 | kt = a[ 4] | a[ 5];
305 | c4 = a[23] ^ kt;
306 | a[ 4] = c0;
307 | a[ 5] = c1;
308 | a[11] = c2;
309 | a[17] = c3;
310 | a[23] = c4;
311 | bnn = ~a[ 8];
312 | kt = bnn & a[14];
313 | c0 = a[ 2] ^ kt;
314 | kt = a[14] | a[15];
315 | c1 = bnn ^ kt;
316 | kt = a[15] & a[21];
317 | c2 = a[14] ^ kt;
318 | kt = a[21] | a[ 2];
319 | c3 = a[15] ^ kt;
320 | kt = a[ 2] & a[ 8];
321 | c4 = a[21] ^ kt;
322 | a[ 2] = c0;
323 | a[ 8] = c1;
324 | a[14] = c2;
325 | a[15] = c3;
326 | a[21] = c4;
327 | a[ 0] = a[ 0] ^ RC[j + 0];
328 |
329 | tt0 = a[ 6] ^ a[ 9];
330 | tt1 = a[ 7] ^ a[ 5];
331 | tt0 ^= a[ 8] ^ tt1;
332 | tt0 = (tt0 << 1) | (tt0 >>> 63);
333 | tt2 = a[24] ^ a[22];
334 | tt3 = a[20] ^ a[23];
335 | tt0 ^= a[21];
336 | tt2 ^= tt3;
337 | t0 = tt0 ^ tt2;
338 |
339 | tt0 = a[12] ^ a[10];
340 | tt1 = a[13] ^ a[11];
341 | tt0 ^= a[14] ^ tt1;
342 | tt0 = (tt0 << 1) | (tt0 >>> 63);
343 | tt2 = a[ 0] ^ a[ 3];
344 | tt3 = a[ 1] ^ a[ 4];
345 | tt0 ^= a[ 2];
346 | tt2 ^= tt3;
347 | t1 = tt0 ^ tt2;
348 |
349 | tt0 = a[18] ^ a[16];
350 | tt1 = a[19] ^ a[17];
351 | tt0 ^= a[15] ^ tt1;
352 | tt0 = (tt0 << 1) | (tt0 >>> 63);
353 | tt2 = a[ 6] ^ a[ 9];
354 | tt3 = a[ 7] ^ a[ 5];
355 | tt0 ^= a[ 8];
356 | tt2 ^= tt3;
357 | t2 = tt0 ^ tt2;
358 |
359 | tt0 = a[24] ^ a[22];
360 | tt1 = a[20] ^ a[23];
361 | tt0 ^= a[21] ^ tt1;
362 | tt0 = (tt0 << 1) | (tt0 >>> 63);
363 | tt2 = a[12] ^ a[10];
364 | tt3 = a[13] ^ a[11];
365 | tt0 ^= a[14];
366 | tt2 ^= tt3;
367 | t3 = tt0 ^ tt2;
368 |
369 | tt0 = a[ 0] ^ a[ 3];
370 | tt1 = a[ 1] ^ a[ 4];
371 | tt0 ^= a[ 2] ^ tt1;
372 | tt0 = (tt0 << 1) | (tt0 >>> 63);
373 | tt2 = a[18] ^ a[16];
374 | tt3 = a[19] ^ a[17];
375 | tt0 ^= a[15];
376 | tt2 ^= tt3;
377 | t4 = tt0 ^ tt2;
378 |
379 | a[ 0] = a[ 0] ^ t0;
380 | a[ 3] = a[ 3] ^ t0;
381 | a[ 1] = a[ 1] ^ t0;
382 | a[ 4] = a[ 4] ^ t0;
383 | a[ 2] = a[ 2] ^ t0;
384 | a[ 6] = a[ 6] ^ t1;
385 | a[ 9] = a[ 9] ^ t1;
386 | a[ 7] = a[ 7] ^ t1;
387 | a[ 5] = a[ 5] ^ t1;
388 | a[ 8] = a[ 8] ^ t1;
389 | a[12] = a[12] ^ t2;
390 | a[10] = a[10] ^ t2;
391 | a[13] = a[13] ^ t2;
392 | a[11] = a[11] ^ t2;
393 | a[14] = a[14] ^ t2;
394 | a[18] = a[18] ^ t3;
395 | a[16] = a[16] ^ t3;
396 | a[19] = a[19] ^ t3;
397 | a[17] = a[17] ^ t3;
398 | a[15] = a[15] ^ t3;
399 | a[24] = a[24] ^ t4;
400 | a[22] = a[22] ^ t4;
401 | a[20] = a[20] ^ t4;
402 | a[23] = a[23] ^ t4;
403 | a[21] = a[21] ^ t4;
404 | a[ 3] = (a[ 3] << 36) | (a[ 3] >>> (64 - 36));
405 | a[ 1] = (a[ 1] << 3) | (a[ 1] >>> (64 - 3));
406 | a[ 4] = (a[ 4] << 41) | (a[ 4] >>> (64 - 41));
407 | a[ 2] = (a[ 2] << 18) | (a[ 2] >>> (64 - 18));
408 | a[ 6] = (a[ 6] << 1) | (a[ 6] >>> (64 - 1));
409 | a[ 9] = (a[ 9] << 44) | (a[ 9] >>> (64 - 44));
410 | a[ 7] = (a[ 7] << 10) | (a[ 7] >>> (64 - 10));
411 | a[ 5] = (a[ 5] << 45) | (a[ 5] >>> (64 - 45));
412 | a[ 8] = (a[ 8] << 2) | (a[ 8] >>> (64 - 2));
413 | a[12] = (a[12] << 62) | (a[12] >>> (64 - 62));
414 | a[10] = (a[10] << 6) | (a[10] >>> (64 - 6));
415 | a[13] = (a[13] << 43) | (a[13] >>> (64 - 43));
416 | a[11] = (a[11] << 15) | (a[11] >>> (64 - 15));
417 | a[14] = (a[14] << 61) | (a[14] >>> (64 - 61));
418 | a[18] = (a[18] << 28) | (a[18] >>> (64 - 28));
419 | a[16] = (a[16] << 55) | (a[16] >>> (64 - 55));
420 | a[19] = (a[19] << 25) | (a[19] >>> (64 - 25));
421 | a[17] = (a[17] << 21) | (a[17] >>> (64 - 21));
422 | a[15] = (a[15] << 56) | (a[15] >>> (64 - 56));
423 | a[24] = (a[24] << 27) | (a[24] >>> (64 - 27));
424 | a[22] = (a[22] << 20) | (a[22] >>> (64 - 20));
425 | a[20] = (a[20] << 39) | (a[20] >>> (64 - 39));
426 | a[23] = (a[23] << 8) | (a[23] >>> (64 - 8));
427 | a[21] = (a[21] << 14) | (a[21] >>> (64 - 14));
428 | bnn = ~a[13];
429 | kt = a[ 9] | a[13];
430 | c0 = a[ 0] ^ kt;
431 | kt = bnn | a[17];
432 | c1 = a[ 9] ^ kt;
433 | kt = a[17] & a[21];
434 | c2 = a[13] ^ kt;
435 | kt = a[21] | a[ 0];
436 | c3 = a[17] ^ kt;
437 | kt = a[ 0] & a[ 9];
438 | c4 = a[21] ^ kt;
439 | a[ 0] = c0;
440 | a[ 9] = c1;
441 | a[13] = c2;
442 | a[17] = c3;
443 | a[21] = c4;
444 | bnn = ~a[14];
445 | kt = a[22] | a[ 1];
446 | c0 = a[18] ^ kt;
447 | kt = a[ 1] & a[ 5];
448 | c1 = a[22] ^ kt;
449 | kt = a[ 5] | bnn;
450 | c2 = a[ 1] ^ kt;
451 | kt = a[14] | a[18];
452 | c3 = a[ 5] ^ kt;
453 | kt = a[18] & a[22];
454 | c4 = a[14] ^ kt;
455 | a[18] = c0;
456 | a[22] = c1;
457 | a[ 1] = c2;
458 | a[ 5] = c3;
459 | a[14] = c4;
460 | bnn = ~a[23];
461 | kt = a[10] | a[19];
462 | c0 = a[ 6] ^ kt;
463 | kt = a[19] & a[23];
464 | c1 = a[10] ^ kt;
465 | kt = bnn & a[ 2];
466 | c2 = a[19] ^ kt;
467 | kt = a[ 2] | a[ 6];
468 | c3 = bnn ^ kt;
469 | kt = a[ 6] & a[10];
470 | c4 = a[ 2] ^ kt;
471 | a[ 6] = c0;
472 | a[10] = c1;
473 | a[19] = c2;
474 | a[23] = c3;
475 | a[ 2] = c4;
476 | bnn = ~a[11];
477 | kt = a[ 3] & a[ 7];
478 | c0 = a[24] ^ kt;
479 | kt = a[ 7] | a[11];
480 | c1 = a[ 3] ^ kt;
481 | kt = bnn | a[15];
482 | c2 = a[ 7] ^ kt;
483 | kt = a[15] & a[24];
484 | c3 = bnn ^ kt;
485 | kt = a[24] | a[ 3];
486 | c4 = a[15] ^ kt;
487 | a[24] = c0;
488 | a[ 3] = c1;
489 | a[ 7] = c2;
490 | a[11] = c3;
491 | a[15] = c4;
492 | bnn = ~a[16];
493 | kt = bnn & a[20];
494 | c0 = a[12] ^ kt;
495 | kt = a[20] | a[ 4];
496 | c1 = bnn ^ kt;
497 | kt = a[ 4] & a[ 8];
498 | c2 = a[20] ^ kt;
499 | kt = a[ 8] | a[12];
500 | c3 = a[ 4] ^ kt;
501 | kt = a[12] & a[16];
502 | c4 = a[ 8] ^ kt;
503 | a[12] = c0;
504 | a[16] = c1;
505 | a[20] = c2;
506 | a[ 4] = c3;
507 | a[ 8] = c4;
508 | a[ 0] = a[ 0] ^ RC[j + 1];
509 | t = a[ 5];
510 | a[ 5] = a[18];
511 | a[18] = a[11];
512 | a[11] = a[10];
513 | a[10] = a[ 6];
514 | a[ 6] = a[22];
515 | a[22] = a[20];
516 | a[20] = a[12];
517 | a[12] = a[19];
518 | a[19] = a[15];
519 | a[15] = a[24];
520 | a[24] = a[ 8];
521 | a[ 8] = t;
522 | t = a[ 1];
523 | a[ 1] = a[ 9];
524 | a[ 9] = a[14];
525 | a[14] = a[ 2];
526 | a[ 2] = a[13];
527 | a[13] = a[23];
528 | a[23] = a[ 4];
529 | a[ 4] = a[21];
530 | a[21] = a[16];
531 | a[16] = a[ 3];
532 | a[ 3] = a[17];
533 | a[17] = a[ 7];
534 | a[ 7] = t;
535 | }
536 | }
537 | }
538 |
--------------------------------------------------------------------------------
/src/main/java/utils/UscConversionUtils.java:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 |
4 | import core.Base58;
5 | import core.ECKey;
6 | import core.Sha256Hash;
7 |
8 |
9 | import java.util.Arrays;
10 |
11 | public class UscConversionUtils {
12 |
13 | private static byte[] keyUldToUscInBytes(String privKeyAsExportedByUlordDumpprivkey){
14 | byte[] decodedKey = Base58.decode(privKeyAsExportedByUlordDumpprivkey);
15 | byte[] privKeyBytes = Arrays.copyOfRange(decodedKey,1,decodedKey.length - 5);
16 | return privKeyBytes;
17 | }
18 |
19 | public static String privKeyToUscFormat(String uldPrivateKey){
20 | byte []privKeyBytes = keyUldToUscInBytes(uldPrivateKey);
21 | String privKeyInUscFormat = Sha256Hash.bytesToHex(privKeyBytes);
22 | return privKeyInUscFormat;
23 | }
24 |
25 | public static String getUscAddress(String uscPrivateKey){
26 | ECKey ecKey = ECKey.fromPrivate(Sha256Hash.hexStringToByteArray(uscPrivateKey));
27 | byte[] addressInUscFormat = ecKey.getAddress();
28 | return Sha256Hash.bytesToHex(addressInUscFormat);
29 | }
30 |
31 | public static String getUscPubKey(String uscPrivateKey){
32 | ECKey ecKey = ECKey.fromPrivate(Sha256Hash.hexStringToByteArray(uscPrivateKey));
33 | byte []pubKey = ecKey.getPubKey();
34 | return Sha256Hash.bytesToHex(pubKey);
35 | }
36 |
37 | public static String getUldPrivateKey(String uldNet, String uscPrivateKey){
38 | byte[] uscPrivateKeyArray = Sha256Hash.hexStringToByteArray(uscPrivateKey);
39 | byte[] partialResult = new byte[uscPrivateKeyArray.length+2];
40 | byte[] result = null;
41 | if(uldNet.equals("main")) {
42 | partialResult[0] = (byte)0x80;
43 | } else {
44 | partialResult[0] = (byte)0xEF;
45 | }
46 |
47 | for (int i = 1; i <= uscPrivateKeyArray.length; i++) {
48 | partialResult[i] = (uscPrivateKeyArray[i-1]);
49 | }
50 | partialResult[uscPrivateKeyArray.length+1] = (byte)0x01;
51 |
52 | result = new byte[partialResult.length+4];
53 |
54 | byte[] check = Sha256Hash.hashTwice(partialResult);
55 |
56 | for (int i = 0; i < partialResult.length; i++) {
57 | result[i] = partialResult[i];
58 | }
59 |
60 | for (int i = 0; i < 4; i++) {
61 | result[partialResult.length+i] = check[i];
62 | }
63 |
64 | return Base58.encode(result);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------