diff --git a/.codeclimate.yml b/.codeclimate.yml
index 72109288061..164135dd2de 100644
--- a/.codeclimate.yml
+++ b/.codeclimate.yml
@@ -1,6 +1,6 @@
-version: "2"
-plugins:
- sonar-java:
- enabled: true
- config:
+version: "2"
+plugins:
+ sonar-java:
+ enabled: true
+ config:
sonar.java.source: 8
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 653abf1be53..0b036c33f9f 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -1,13 +1,13 @@
-Please answer these questions before submitting your issue. Thanks!
-
-1. What did you do?
-If possible, provide a recipe for reproducing the error.
-
-
-2. What did you expect to see?
-
-
-
-3. What did you see instead?
-
-
+Please answer these questions before submitting your issue. Thanks!
+
+1. What did you do?
+If possible, provide a recipe for reproducing the error.
+
+
+2. What did you expect to see?
+
+
+
+3. What did you see instead?
+
+
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 8eabd5369c9..7166b0949a5 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,12 +1,12 @@
-**What does this PR do?**
-
-**Why are these changes required?**
-
-**This PR has been tested by:**
-- Unit Tests
-- Manual Testing
-
-**Follow up**
-
-**Extra details**
-
+**What does this PR do?**
+
+**Why are these changes required?**
+
+**This PR has been tested by:**
+- Unit Tests
+- Manual Testing
+
+**Follow up**
+
+**Extra details**
+
diff --git a/README.md b/README.md
index 547c0ab3af1..15d2adbaaed 100644
--- a/README.md
+++ b/README.md
@@ -19,101 +19,15 @@ TRON is a block chain-based decentralized smart protocol and an application deve
TRON is a product of Web 4.0 and the decentralized internet of next generation.
-# Quick Start
-
-> Note: This repository is a IDEA project which you can simply download and import.
-
-**Download and build**
-
-```shell
-> git clone https://github.com/tronprotocol/java-tron.git
-> cd java-tron
-> gradle build
-```
-
-**Import project to IDEA**
-
-- [File] -> [New] -> [Project from Existing Sources...]
-- Select java-tron/build.gradle
-- Dialog [Import Project from Gradle], confirm [Use auto-import] and [Use gradle wrapper task configuration] have been
- selected,then select Gradle JVM(JDK 1.8)and click [OK]
-
-# Testing
-
-**Install Kafka and create two topics (block and transaction)**
+
-**Update the configuration**
-
-
-**Starting program**
-
-IDEA:
-- [Edit Configurations...] -> [Add New Configuration] -> [Application]
-- [Edit Configurations...] -> [Main Class]: `org.tron.example.Tron`
-- [Edit Configurations...] -> [Use classpath of module]: `java-tron_main`
-- [Edit Configurations...] -> [Program arguments]: `--type server`
-- Run
-
-![run](https://github.com/tronprotocol/wiki/blob/master/images/commands/default-set.gif)
-
-or simply from terminal:
-- ./gradlew run -Pserver=true
-
-**Complete process**
+# Quick Start
-![help](https://github.com/tronprotocol/wiki/blob/master/images/commands/process.gif)
+Read the [Quick Srart](http://wiki.tron.network/en/latest/quick_start.html).
-**Other nodes to join need to modify the connection ip**
-![help](https://github.com/tronprotocol/wiki/blob/master/images/commands/node-ip.gif)
# Commands
-**help**
-
-| Description | Example |
-| --- | --- |
-| Help tips | `help` |
-
-![help](https://github.com/tronprotocol/wiki/blob/master/images/commands/help.gif)
-
-**account**
-
-| Description | Example |
-| --- | --- |
-| Get address | `account` |
-
-![help](https://github.com/tronprotocol/wiki/blob/master/images/commands/account.gif)
-
-**getbalance**
-
-| Description | Example |
-| --- | --- |
-| Get balance | `getbalance` |
-
-![help](https://github.com/tronprotocol/wiki/blob/master/images/commands/getbalance.gif)
-
-**send [to] [balance]**
-
-| Description | Example |
-| --- | --- |
-| Send balance to address | `send 2cddf5707aefefb199cb16430fb0f6220d460dfe 2` |
-
-![help](https://github.com/tronprotocol/wiki/blob/master/images/commands/send1.gif)
-
-**printblockchain**
-
-| Description | Example |
-| --- | --- |
-| Print blockchain | `printblockchain`|
-
-![help](https://github.com/tronprotocol/wiki/blob/master/images/commands/printblockchain.gif)
-
-**exit**
-
-| Description | Example |
-| --- | --- |
-| Exit | `exit` |
-
-![help](https://github.com/tronprotocol/wiki/blob/master/images/commands/exit.gif)
+Read the [Commands](http://wiki.tron.network/en/latest/quick_start.html#commands).
# Contact
diff --git a/build.gradle b/build.gradle
index 519dbc2702d..c7045bbb356 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,7 +7,7 @@ apply plugin: 'application'
apply plugin: 'checkstyle'
sourceCompatibility = 1.8
-mainClassName = 'org.tron.program.example.Tron'
+mainClassName = 'org.tron.program.FullNode'
repositories {
mavenCentral()
@@ -112,8 +112,9 @@ dependencies {
compile group: 'io.grpc', name: 'grpc-stub', version: '1.9.0'
// end google grpc
-
-
+ compile group: 'io.scalecube', name: 'scalecube-services', version: '1.0.7'
+ compile group: 'io.scalecube', name: 'scalecube-cluster', version: '1.0.7'
+ compile group: 'io.scalecube', name: 'scalecube-transport', version: '1.0.7'
}
task lint(type: Checkstyle) {
@@ -148,9 +149,9 @@ sourceSets {
proto {
- srcDir 'src/proto'
- }
+ srcDir 'src/proto'
}
+ }
}
@@ -171,7 +172,7 @@ protobuf {
generateProtoTasks {
all().each { task ->
task.builtins {
- java {outputSubDir = "gen"}
+ java { outputSubDir = "gen" }
}
}
all()*.plugins {
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 824c8a8745c..a069a3351f4 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -2,7 +2,7 @@ FROM tronprotocol/centos7-jdk8
MAINTAINER tronprotocol
# Install dependencies && Download java-tron
-RUN yum update && \
+RUN yum update -y && \
yum install -y git && \
git clone https://github.com/tronprotocol/java-tron.git /home/java-tron
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 4c637cca379..92165eede80 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.3-bin.zip
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.3-bin.zip
diff --git a/gradlew b/gradlew
old mode 100755
new mode 100644
diff --git a/src/main/java/org/tron/common/application/Application.java b/src/main/java/org/tron/common/application/Application.java
index 8eaaadb07d2..1d8dbf5920f 100644
--- a/src/main/java/org/tron/common/application/Application.java
+++ b/src/main/java/org/tron/common/application/Application.java
@@ -12,59 +12,32 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see
- * See https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki - * #Low_S_values_in_signatures - */ - public static final BigInteger HALF_CURVE_ORDER; - private static final Logger logger = LoggerFactory.getLogger(ECKey.class); - private static final BigInteger SECP256K1N = new BigInteger - ("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16); - private static final SecureRandom secureRandom; - private static final long serialVersionUID = -728224901792295832L; - - static { - // All clients must agree on the curve to use by agreement. - X9ECParameters params = SECNamedCurves.getByName("secp256k1"); - CURVE = new ECDomainParameters(params.getCurve(), params.getG(), - params.getN(), params.getH()); - CURVE_SPEC = new ECParameterSpec(params.getCurve(), params.getG(), - params.getN(), params.getH()); - HALF_CURVE_ORDER = params.getN().shiftRight(1); - secureRandom = new SecureRandom(); - } - protected final ECPoint pub; - // The two parts of the key. If "priv" is set, "pub" can always be - // calculated. If "pub" is set but not "priv", we - // can only verify signatures not make them. - // TODO: Redesign this class to use consistent internals and more - // efficient serialization. - private final PrivateKey privKey; - // the Java Cryptographic Architecture provider to use for Signature - // this is set along with the PrivateKey privKey and must be compatible - // this provider will be used when selecting a Signature instance - // https://docs.oracle.com/javase/8/docs/technotes/guides/security - // /SunProviders.html - private final Provider provider; - - // Transient because it's calculated on demand. - transient private byte[] pubKeyHash; - transient private byte[] nodeId; - - /** - * Generates an entirely new keypair. - *
- * BouncyCastle will be used as the Java Security Provider - */ - public ECKey() { - this(secureRandom); + /** + * The parameters of the secp256k1 curve. + */ + public static final ECDomainParameters CURVE; + public static final ECParameterSpec CURVE_SPEC; + /** + * Equal to CURVE.getN().shiftRight(1), used for canonicalising the S value of a signature. ECDSA + * signatures are mutable in the sense that for a given (R, S) pair, then both (R, S) and (R, N - + * S mod N) are valid signatures. Canonical signatures are those where 1 <= S <= N/2
See + * https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki #Low_S_values_in_signatures + */ + public static final BigInteger HALF_CURVE_ORDER; + private static final Logger logger = LoggerFactory.getLogger(ECKey.class); + private static final BigInteger SECP256K1N = new BigInteger + ("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16); + private static final SecureRandom secureRandom; + private static final long serialVersionUID = -728224901792295832L; + + static { + // All clients must agree on the curve to use by agreement. + X9ECParameters params = SECNamedCurves.getByName("secp256k1"); + CURVE = new ECDomainParameters(params.getCurve(), params.getG(), + params.getN(), params.getH()); + CURVE_SPEC = new ECParameterSpec(params.getCurve(), params.getG(), + params.getN(), params.getH()); + HALF_CURVE_ORDER = params.getN().shiftRight(1); + secureRandom = new SecureRandom(); + } + + protected final ECPoint pub; + // The two parts of the key. If "priv" is set, "pub" can always be + // calculated. If "pub" is set but not "priv", we + // can only verify signatures not make them. + // TODO: Redesign this class to use consistent internals and more + // efficient serialization. + private final PrivateKey privKey; + // the Java Cryptographic Architecture provider to use for Signature + // this is set along with the PrivateKey privKey and must be compatible + // this provider will be used when selecting a Signature instance + // https://docs.oracle.com/javase/8/docs/technotes/guides/security + // /SunProviders.html + private final Provider provider; + + // Transient because it's calculated on demand. + transient private byte[] pubKeyHash; + transient private byte[] nodeId; + + /** + * Generates an entirely new keypair.
BouncyCastle will be used as the Java Security Provider + */ + public ECKey() { + this(secureRandom); + } + + /** + * Generate a new keypair using the given Java Security Provider.
All private key operations + * will use the provider. + */ + public ECKey(Provider provider, SecureRandom secureRandom) { + this.provider = provider; + + final KeyPairGenerator keyPairGen = ECKeyPairGenerator.getInstance + (provider, secureRandom); + final KeyPair keyPair = keyPairGen.generateKeyPair(); + + this.privKey = keyPair.getPrivate(); + + final PublicKey pubKey = keyPair.getPublic(); + if (pubKey instanceof BCECPublicKey) { + pub = ((BCECPublicKey) pubKey).getQ(); + } else if (pubKey instanceof ECPublicKey) { + pub = extractPublicKey((ECPublicKey) pubKey); + } else { + throw new AssertionError( + "Expected Provider " + provider.getName() + + " to produce a subtype of ECPublicKey, found " + + pubKey.getClass()); } - - /** - * Generate a new keypair using the given Java Security Provider. - *
- * All private key operations will use the provider. - */ - public ECKey(Provider provider, SecureRandom secureRandom) { - this.provider = provider; - - final KeyPairGenerator keyPairGen = ECKeyPairGenerator.getInstance - (provider, secureRandom); - final KeyPair keyPair = keyPairGen.generateKeyPair(); - - this.privKey = keyPair.getPrivate(); - - final PublicKey pubKey = keyPair.getPublic(); - if (pubKey instanceof BCECPublicKey) { - pub = ((BCECPublicKey) pubKey).getQ(); - } else if (pubKey instanceof ECPublicKey) { - pub = extractPublicKey((ECPublicKey) pubKey); - } else { - throw new AssertionError( - "Expected Provider " + provider.getName() + - " to produce a subtype of ECPublicKey, found " + - pubKey.getClass()); - } + } + + /** + * Generates an entirely new keypair with the given {@link SecureRandom} object.
BouncyCastle + * will be used as the Java Security Provider + * + * @param secureRandom - + */ + public ECKey(SecureRandom secureRandom) { + this(TronCastleProvider.getInstance(), secureRandom); + } + + /** + * Pair a private key with a public EC point.
All private key operations will use the + * provider. + */ + public ECKey(Provider provider, @Nullable PrivateKey privKey, ECPoint pub) { + this.provider = provider; + + if (privKey == null || isECPrivateKey(privKey)) { + this.privKey = privKey; + } else { + throw new IllegalArgumentException( + "Expected EC private key, given a private key object with" + + " class " + + privKey.getClass().toString() + + " and algorithm " + privKey.getAlgorithm()); } - /** - * Generates an entirely new keypair with the given {@link SecureRandom} - * object. - *
- * BouncyCastle will be used as the Java Security Provider - * - * @param secureRandom - - */ - public ECKey(SecureRandom secureRandom) { - this(TronCastleProvider.getInstance(), secureRandom); + if (pub == null) { + throw new IllegalArgumentException("Public key may not be null"); + } else { + this.pub = pub; } - - /** - * Pair a private key with a public EC point. - *
- * All private key operations will use the provider. - */ - public ECKey(Provider provider, @Nullable PrivateKey privKey, ECPoint pub) { - this.provider = provider; - - if (privKey == null || isECPrivateKey(privKey)) { - this.privKey = privKey; - } else { - throw new IllegalArgumentException( - "Expected EC private key, given a private key object with" + - " class " + - privKey.getClass().toString() + - " and algorithm " + privKey.getAlgorithm()); - } - - if (pub == null) { - throw new IllegalArgumentException("Public key may not be null"); - } else { - this.pub = pub; - } + } + + /** + * Pair a private key integer with a public EC point
BouncyCastle will be used as the Java + * Security Provider + */ + public ECKey(@Nullable BigInteger priv, ECPoint pub) { + this( + TronCastleProvider.getInstance(), + privateKeyFromBigInteger(priv), + pub + ); + } + + /* Convert a Java JCE ECPublicKey into a BouncyCastle ECPoint + */ + private static ECPoint extractPublicKey(final ECPublicKey ecPublicKey) { + final java.security.spec.ECPoint publicPointW = ecPublicKey.getW(); + final BigInteger xCoord = publicPointW.getAffineX(); + final BigInteger yCoord = publicPointW.getAffineY(); + + return CURVE.getCurve().createPoint(xCoord, yCoord); + } + + /* Test if a generic private key is an EC private key + * + * it is not sufficient to check that privKey is a subtype of ECPrivateKey + * as the SunPKCS11 Provider will return a generic PrivateKey instance + * a fallback that covers this case is to check the key algorithm + */ + private static boolean isECPrivateKey(PrivateKey privKey) { + return privKey instanceof ECPrivateKey || privKey.getAlgorithm() + .equals("EC"); + } + + /* Convert a BigInteger into a PrivateKey object + */ + private static PrivateKey privateKeyFromBigInteger(BigInteger priv) { + if (priv == null) { + return null; + } else { + try { + return ECKeyFactory + .getInstance(TronCastleProvider.getInstance()) + .generatePrivate(new ECPrivateKeySpec(priv, + CURVE_SPEC)); + } catch (InvalidKeySpecException ex) { + throw new AssertionError("Assumed correct key spec statically"); + } } - - /** - * Pair a private key integer with a public EC point - *
- * BouncyCastle will be used as the Java Security Provider - */ - public ECKey(@Nullable BigInteger priv, ECPoint pub) { - this( - TronCastleProvider.getInstance(), - privateKeyFromBigInteger(priv), - pub - ); + } + + /** + * Utility for compressing an elliptic curve point. Returns the same point if it's already + * compressed. See the ECKey class docs for a discussion of point compression. + * + * @param uncompressed - + * @return - + * @deprecated per-point compression property will be removed in Bouncy Castle + */ + public static ECPoint compressPoint(ECPoint uncompressed) { + return CURVE.getCurve().decodePoint(uncompressed.getEncoded(true)); + } + + /** + * Utility for decompressing an elliptic curve point. Returns the same point if it's already + * compressed. See the ECKey class docs for a discussion of point compression. + * + * @param compressed - + * @return - + * @deprecated per-point compression property will be removed in Bouncy Castle + */ + public static ECPoint decompressPoint(ECPoint compressed) { + return CURVE.getCurve().decodePoint(compressed.getEncoded(false)); + } + + /** + * Creates an ECKey given the private key only. + * + * @param privKey - + * @return - + */ + public static ECKey fromPrivate(BigInteger privKey) { + return new ECKey(privKey, CURVE.getG().multiply(privKey)); + } + + /** + * Creates an ECKey given the private key only. + * + * @param privKeyBytes - + * @return - + */ + public static ECKey fromPrivate(byte[] privKeyBytes) { + return fromPrivate(new BigInteger(1, privKeyBytes)); + } + + /** + * Creates an ECKey that simply trusts the caller to ensure that point is really the result of + * multiplying the generator point by the private key. This is used to speed things up when you + * know you have the right values already. The compression state of pub will be preserved. + * + * @param priv - + * @param pub - + * @return - + */ + public static ECKey fromPrivateAndPrecalculatedPublic(BigInteger priv, + ECPoint pub) { + return new ECKey(priv, pub); + } + + /** + * Creates an ECKey that simply trusts the caller to ensure that point is really the result of + * multiplying the generator point by the private key. This is used to speed things up when you + * know you have the right values already. The compression state of the point will be preserved. + * + * @param priv - + * @param pub - + * @return - + */ + public static ECKey fromPrivateAndPrecalculatedPublic(byte[] priv, byte[] + pub) { + check(priv != null, "Private key must not be null"); + check(pub != null, "Public key must not be null"); + return new ECKey(new BigInteger(1, priv), CURVE.getCurve() + .decodePoint(pub)); + } + + /** + * Creates an ECKey that cannot be used for signing, only verifying signatures, from the given + * point. The compression state of pub will be preserved. + * + * @param pub - + * @return - + */ + public static ECKey fromPublicOnly(ECPoint pub) { + return new ECKey(null, pub); + } + + /** + * Creates an ECKey that cannot be used for signing, only verifying signatures, from the given + * encoded point. The compression state of pub will be preserved. + * + * @param pub - + * @return - + */ + public static ECKey fromPublicOnly(byte[] pub) { + return new ECKey(null, CURVE.getCurve().decodePoint(pub)); + } + + /** + * Returns public key bytes from the given private key. To convert a byte array into a BigInteger, + * use new BigInteger(1, bytes); + * + * @param privKey - + * @param compressed - + * @return - + */ + public static byte[] publicKeyFromPrivate(BigInteger privKey, boolean + compressed) { + ECPoint point = CURVE.getG().multiply(privKey); + return point.getEncoded(compressed); + } + + /** + * Compute an address from an encoded public key. + * + * @param pubBytes an encoded (uncompressed) public key + * @return 20-byte address + */ + public static byte[] computeAddress(byte[] pubBytes) { + return Hash.sha3omit12( + Arrays.copyOfRange(pubBytes, 1, pubBytes.length)); + } + + /** + * Compute an address from a public point. + * + * @param pubPoint a public point + * @return 20-byte address + */ + public static byte[] computeAddress(ECPoint pubPoint) { + return computeAddress(pubPoint.getEncoded(/* uncompressed */ false)); + } + + /** + * Compute the encoded X, Y coordinates of a public point.
This is the encoded public key + * without the leading byte. + * + * @param pubPoint a public point + * @return 64-byte X,Y point pair + */ + public static byte[] pubBytesWithoutFormat(ECPoint pubPoint) { + final byte[] pubBytes = pubPoint.getEncoded(/* uncompressed */ false); + return Arrays.copyOfRange(pubBytes, 1, pubBytes.length); + } + + /** + * Recover the public key from an encoded node id. + * + * @param nodeId a 64-byte X,Y point pair + */ + public static ECKey fromNodeId(byte[] nodeId) { + check(nodeId.length == 64, "Expected a 64 byte node id"); + byte[] pubBytes = new byte[65]; + System.arraycopy(nodeId, 0, pubBytes, 1, nodeId.length); + pubBytes[0] = 0x04; // uncompressed + return ECKey.fromPublicOnly(pubBytes); + } + + public static byte[] signatureToKeyBytes(byte[] messageHash, String + signatureBase64) throws SignatureException { + byte[] signatureEncoded; + try { + signatureEncoded = Base64.decode(signatureBase64); + } catch (RuntimeException e) { + // This is what you getData back from Bouncy Castle if base64 doesn't + // decode :( + throw new SignatureException("Could not decode base64", e); } - - /* Convert a Java JCE ECPublicKey into a BouncyCastle ECPoint - */ - private static ECPoint extractPublicKey(final ECPublicKey ecPublicKey) { - final java.security.spec.ECPoint publicPointW = ecPublicKey.getW(); - final BigInteger xCoord = publicPointW.getAffineX(); - final BigInteger yCoord = publicPointW.getAffineY(); - - return CURVE.getCurve().createPoint(xCoord, yCoord); + // Parse the signature bytes into r/s and the selector value. + if (signatureEncoded.length < 65) { + throw new SignatureException("Signature truncated, expected 65 " + + "bytes and got " + signatureEncoded.length); } - /* Test if a generic private key is an EC private key - * - * it is not sufficient to check that privKey is a subtype of ECPrivateKey - * as the SunPKCS11 Provider will return a generic PrivateKey instance - * a fallback that covers this case is to check the key algorithm - */ - private static boolean isECPrivateKey(PrivateKey privKey) { - return privKey instanceof ECPrivateKey || privKey.getAlgorithm() - .equals("EC"); + return signatureToKeyBytes( + messageHash, + ECDSASignature.fromComponents( + Arrays.copyOfRange(signatureEncoded, 1, 33), + Arrays.copyOfRange(signatureEncoded, 33, 65), + (byte) (signatureEncoded[0] & 0xFF))); + } + + public static byte[] signatureToKeyBytes(byte[] messageHash, + ECDSASignature sig) throws + SignatureException { + check(messageHash.length == 32, "messageHash argument has length " + + messageHash.length); + int header = sig.v; + // The header byte: 0x1B = first key with even y, 0x1C = first key + // with odd y, + // 0x1D = second key with even y, 0x1E = second key + // with odd y + if (header < 27 || header > 34) { + throw new SignatureException("Header byte out of range: " + header); } - - /* Convert a BigInteger into a PrivateKey object - */ - private static PrivateKey privateKeyFromBigInteger(BigInteger priv) { - if (priv == null) { - return null; - } else { - try { - return ECKeyFactory - .getInstance(TronCastleProvider.getInstance()) - .generatePrivate(new ECPrivateKeySpec(priv, - CURVE_SPEC)); - } catch (InvalidKeySpecException ex) { - throw new AssertionError("Assumed correct key spec statically"); - } - } + if (header >= 31) { + header -= 4; } - - /** - * Utility for compressing an elliptic curve point. Returns the same - * point if it's already compressed. - * See the ECKey class docs for a discussion of point compression. - * - * @param uncompressed - - * @return - - * @deprecated per-point compression property will be removed in Bouncy - * Castle - */ - public static ECPoint compressPoint(ECPoint uncompressed) { - return CURVE.getCurve().decodePoint(uncompressed.getEncoded(true)); + int recId = header - 27; + byte[] key = ECKey.recoverPubBytesFromSignature(recId, sig, + messageHash); + if (key == null) { + throw new SignatureException("Could not recover public key from " + + "signature"); } - - /** - * Utility for decompressing an elliptic curve point. Returns the same - * point if it's already compressed. - * See the ECKey class docs for a discussion of point compression. - * - * @param compressed - - * @return - - * @deprecated per-point compression property will be removed in Bouncy - * Castle - */ - public static ECPoint decompressPoint(ECPoint compressed) { - return CURVE.getCurve().decodePoint(compressed.getEncoded(false)); + return key; + } + + /** + * Compute the address of the key that signed the given signature. + * + * @param messageHash 32-byte hash of message + * @param signatureBase64 Base-64 encoded signature + * @return 20-byte address + */ + public static byte[] signatureToAddress(byte[] messageHash, String + signatureBase64) throws SignatureException { + return computeAddress(signatureToKeyBytes(messageHash, + signatureBase64)); + } + + /** + * Compute the address of the key that signed the given signature. + * + * @param messageHash 32-byte hash of message + * @param sig - + * @return 20-byte address + */ + public static byte[] signatureToAddress(byte[] messageHash, + ECDSASignature sig) throws + SignatureException { + return computeAddress(signatureToKeyBytes(messageHash, sig)); + } + + /** + * Compute the key that signed the given signature. + * + * @param messageHash 32-byte hash of message + * @param signatureBase64 Base-64 encoded signature + * @return ECKey + */ + public static ECKey signatureToKey(byte[] messageHash, String + signatureBase64) throws SignatureException { + final byte[] keyBytes = signatureToKeyBytes(messageHash, + signatureBase64); + return ECKey.fromPublicOnly(keyBytes); + } + + /** + * Compute the key that signed the given signature. + * + * @param messageHash 32-byte hash of message + * @param sig - + * @return ECKey + */ + public static ECKey signatureToKey(byte[] messageHash, ECDSASignature + sig) throws SignatureException { + final byte[] keyBytes = signatureToKeyBytes(messageHash, sig); + return ECKey.fromPublicOnly(keyBytes); + } + + /** + *
Verifies the given ECDSA signature against the message bytes using the public key bytes.
+ *
When using native ECDSA verification, data must be 32 bytes, and no element may be + * larger than 520 bytes.
+ * + * @param data Hash of the data to verify. + * @param signature signature. + * @param pub The public key bytes to use. + * @return - + */ + public static boolean verify(byte[] data, ECDSASignature signature, + byte[] pub) { + ECDSASigner signer = new ECDSASigner(); + ECPublicKeyParameters params = new ECPublicKeyParameters(CURVE + .getCurve().decodePoint(pub), CURVE); + signer.init(false, params); + try { + return signer.verifySignature(data, signature.r, signature.s); + } catch (NullPointerException npe) { + // Bouncy Castle contains a bug that can cause NPEs given + // specially crafted signatures. + // Those signatures are inherently invalid/attack sigs so we just + // fail them here rather than crash the thread. + logger.error("Caught NPE inside bouncy castle", npe); + return false; } - - /** - * Creates an ECKey given the private key only. - * - * @param privKey - - * @return - - */ - public static ECKey fromPrivate(BigInteger privKey) { - return new ECKey(privKey, CURVE.getG().multiply(privKey)); + } + + /** + * Verifies the given ASN.1 encoded ECDSA signature against a hash using the public key. + * + * @param data Hash of the data to verify. + * @param signature signature. + * @param pub The public key bytes to use. + * @return - + */ + public static boolean verify(byte[] data, byte[] signature, byte[] pub) { + return verify(data, ECDSASignature.decodeFromDER(signature), pub); + } + + /** + * Returns true if the given pubkey is canonical, i.e. the correct length taking into account + * compression. + * + * @param pubkey - + * @return - + */ + public static boolean isPubKeyCanonical(byte[] pubkey) { + if (pubkey[0] == 0x04) { + // Uncompressed pubkey + return pubkey.length == 65; + } else if (pubkey[0] == 0x02 || pubkey[0] == 0x03) { + // Compressed pubkey + return pubkey.length == 33; + } else { + return false; } - - /** - * Creates an ECKey given the private key only. - * - * @param privKeyBytes - - * @return - - */ - public static ECKey fromPrivate(byte[] privKeyBytes) { - return fromPrivate(new BigInteger(1, privKeyBytes)); + } + + /** + *Given the components of a signature and a selector value, recover and return the public key + * that generated the signature according to the algorithm in SEC1v2 section 4.1.6.
The + * recId is an index from 0 to 3 which indicates which of the 4 possible allKeys is the correct + * one. Because the key recovery operation yields multiple potential allKeys, the correct key must + * either be stored alongside the signature, or you must be willing to try each recId in turn + * until you find one that outputs the key you are expecting.
If this method returns + * null it means recovery was not possible and recId should be iterated.
Given the + * above two points, a correct usage of this method is inside a for loop from 0 to 3, and if the + * output is null OR a key that is not the one you expect, you try again with the next recId.
+ * + * @param recId Which possible key to recover. + * @param sig the R and S components of the signature, wrapped. + * @param messageHash Hash of the data that was signed. + * @return 65-byte encoded public key + */ + @Nullable + public static byte[] recoverPubBytesFromSignature(int recId, + ECDSASignature sig, + byte[] messageHash) { + check(recId >= 0, "recId must be positive"); + check(sig.r.signum() >= 0, "r must be positive"); + check(sig.s.signum() >= 0, "s must be positive"); + check(messageHash != null, "messageHash must not be null"); + // 1.0 For j from 0 to h (h == recId here and the loop is outside + // this function) + // 1.1 Let x = r + jn + BigInteger n = CURVE.getN(); // Curve order. + BigInteger i = BigInteger.valueOf((long) recId / 2); + BigInteger x = sig.r.add(i.multiply(n)); + // 1.2. Convert the integer x to an octet string X of length mlen + // using the conversion routine + // specified in Section 2.3.7, where mlen = ⌈(log2 p)/8⌉ or + // mlen = ⌈m/8⌉. + // 1.3. Convert the octet string (16 set binary digits)||X to an + // elliptic curve point R using the + // conversion routine specified in Section 2.3.4. If this + // conversion routine outputs “invalid”, then + // do another iteration of Step 1. + // + // More concisely, what these points mean is to use X as a compressed + // public key. + ECCurve.Fp curve = (ECCurve.Fp) CURVE.getCurve(); + BigInteger prime = curve.getQ(); // Bouncy Castle is not consistent + // about the letter it uses for the prime. + if (x.compareTo(prime) >= 0) { + // Cannot have point co-ordinates larger than this as everything + // takes place modulo Q. + return null; } - - /** - * Creates an ECKey that simply trusts the caller to ensure that point is - * really the result of multiplying the - * generator point by the private key. This is used to speed things up - * when you know you have the right values - * already. The compression state of pub will be preserved. - * - * @param priv - - * @param pub - - * @return - - */ - public static ECKey fromPrivateAndPrecalculatedPublic(BigInteger priv, - ECPoint pub) { - return new ECKey(priv, pub); + // Compressed allKeys require you to know an extra bit of data about the + // y-coord as there are two possibilities. + // So it's encoded in the recId. + ECPoint R = decompressKey(x, (recId & 1) == 1); + // 1.4. If nR != point at infinity, then do another iteration of + // Step 1 (callers responsibility). + if (!R.multiply(n).isInfinity()) { + return null; } - - /** - * Creates an ECKey that simply trusts the caller to ensure that point is - * really the result of multiplying the - * generator point by the private key. This is used to speed things up - * when you know you have the right values - * already. The compression state of the point will be preserved. - * - * @param priv - - * @param pub - - * @return - - */ - public static ECKey fromPrivateAndPrecalculatedPublic(byte[] priv, byte[] - pub) { - check(priv != null, "Private key must not be null"); - check(pub != null, "Public key must not be null"); - return new ECKey(new BigInteger(1, priv), CURVE.getCurve() - .decodePoint(pub)); + // 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature + // verification. + BigInteger e = new BigInteger(1, messageHash); + // 1.6. For k from 1 to 2 do the following. (loop is outside this + // function via iterating recId) + // 1.6.1. Compute a candidate public key as: + // Q = mi(r) * (sR - eG) + // + // Where mi(x) is the modular multiplicative inverse. We transform + // this into the following: + // Q = (mi(r) * s ** R) + (mi(r) * -e ** G) + // Where -e is the modular additive inverse of e, that is z such that + // z + e = 0 (mod n). In the above equation + // ** is point multiplication and + is point addition (the EC group + // operator). + // + // We can find the additive inverse by subtracting e from zero then + // taking the mod. For example the additive + // inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and -3 mod + // 11 = 8. + BigInteger eInv = BigInteger.ZERO.subtract(e).mod(n); + BigInteger rInv = sig.r.modInverse(n); + BigInteger srInv = rInv.multiply(sig.s).mod(n); + BigInteger eInvrInv = rInv.multiply(eInv).mod(n); + ECPoint.Fp q = (ECPoint.Fp) ECAlgorithms.sumOfTwoMultiplies(CURVE + .getG(), eInvrInv, R, srInv); + return q.getEncoded(/* compressed */ false); + } + + /** + * @param recId Which possible key to recover. + * @param sig the R and S components of the signature, wrapped. + * @param messageHash Hash of the data that was signed. + * @return 20-byte address + */ + @Nullable + public static byte[] recoverAddressFromSignature(int recId, + ECDSASignature sig, + byte[] messageHash) { + final byte[] pubBytes = recoverPubBytesFromSignature(recId, sig, + messageHash); + if (pubBytes == null) { + return null; + } else { + return computeAddress(pubBytes); } - - /** - * Creates an ECKey that cannot be used for signing, only verifying - * signatures, from the given point. The - * compression state of pub will be preserved. - * - * @param pub - - * @return - - */ - public static ECKey fromPublicOnly(ECPoint pub) { - return new ECKey(null, pub); + } + + /** + * @param recId Which possible key to recover. + * @param sig the R and S components of the signature, wrapped. + * @param messageHash Hash of the data that was signed. + * @return ECKey + */ + @Nullable + public static ECKey recoverFromSignature(int recId, ECDSASignature sig, + byte[] messageHash) { + final byte[] pubBytes = recoverPubBytesFromSignature(recId, sig, + messageHash); + if (pubBytes == null) { + return null; + } else { + return ECKey.fromPublicOnly(pubBytes); } - - /** - * Creates an ECKey that cannot be used for signing, only verifying - * signatures, from the given encoded point. - * The compression state of pub will be preserved. - * - * @param pub - - * @return - - */ - public static ECKey fromPublicOnly(byte[] pub) { - return new ECKey(null, CURVE.getCurve().decodePoint(pub)); + } + + /** + * Decompress a compressed public key (x co-ord and low-bit of y-coord). + * + * @param xBN - + * @param yBit - + * @return - + */ + private static ECPoint decompressKey(BigInteger xBN, boolean yBit) { + X9IntegerConverter x9 = new X9IntegerConverter(); + byte[] compEnc = x9.integerToBytes(xBN, 1 + x9.getByteLength(CURVE + .getCurve())); + compEnc[0] = (byte) (yBit ? 0x03 : 0x02); + return CURVE.getCurve().decodePoint(compEnc); + } + + private static void check(boolean test, String message) { + if (!test) { + throw new IllegalArgumentException(message); } - - /** - * Returns public key bytes from the given private key. To convert a byte - * array into a BigInteger, use - * new BigInteger(1, bytes); - * - * @param privKey - - * @param compressed - - * @return - - */ - public static byte[] publicKeyFromPrivate(BigInteger privKey, boolean - compressed) { - ECPoint point = CURVE.getG().multiply(privKey); - return point.getEncoded(compressed); + } + + /** + * Returns a copy of this key, but with the public point represented in uncompressed form. + * Normally you would never need this: it's for specialised scenarios or when backwards + * compatibility in encoded form is necessary. + * + * @return - + * @deprecated per-point compression property will be removed in Bouncy Castle + */ + public ECKey decompress() { + if (!pub.isCompressed()) { + return this; + } else { + return new ECKey(this.provider, this.privKey, decompressPoint(pub)); } - - /** - * Compute an address from an encoded public key. - * - * @param pubBytes an encoded (uncompressed) public key - * @return 20-byte address - */ - public static byte[] computeAddress(byte[] pubBytes) { - return Hash.sha3omit12( - Arrays.copyOfRange(pubBytes, 1, pubBytes.length)); + } + + /** + * @deprecated per-point compression property will be removed in Bouncy Castle + */ + public ECKey compress() { + if (pub.isCompressed()) { + return this; + } else { + return new ECKey(this.provider, this.privKey, compressPoint(pub)); } - - /** - * Compute an address from a public point. - * - * @param pubPoint a public point - * @return 20-byte address - */ - public static byte[] computeAddress(ECPoint pubPoint) { - return computeAddress(pubPoint.getEncoded(/* uncompressed */ false)); + } + + /** + * Returns true if this key doesn't have access to private key bytes. This may be because it was + * never given any private key bytes to begin with (a watching key). + * + * @return - + */ + public boolean isPubKeyOnly() { + return privKey == null; + } + + /** + * Returns true if this key has access to private key bytes. Does the opposite of {@link + * #isPubKeyOnly()}. + * + * @return - + */ + public boolean hasPrivKey() { + return privKey != null; + } + + /** + * Gets the address form of the public key. + * + * @return 20-byte address + */ + public byte[] getAddress() { + if (pubKeyHash == null) { + pubKeyHash = computeAddress(this.pub); } - - /** - * Compute the encoded X, Y coordinates of a public point. - *- * This is the encoded public key without the leading byte. - * - * @param pubPoint a public point - * @return 64-byte X,Y point pair - */ - public static byte[] pubBytesWithoutFormat(ECPoint pubPoint) { - final byte[] pubBytes = pubPoint.getEncoded(/* uncompressed */ false); - return Arrays.copyOfRange(pubBytes, 1, pubBytes.length); + return pubKeyHash; + } + + /** + * Generates the NodeID based on this key, that is the public key without first format byte + */ + public byte[] getNodeId() { + if (nodeId == null) { + nodeId = pubBytesWithoutFormat(this.pub); } - - /** - * Recover the public key from an encoded node id. - * - * @param nodeId a 64-byte X,Y point pair - */ - public static ECKey fromNodeId(byte[] nodeId) { - check(nodeId.length == 64, "Expected a 64 byte node id"); - byte[] pubBytes = new byte[65]; - System.arraycopy(nodeId, 0, pubBytes, 1, nodeId.length); - pubBytes[0] = 0x04; // uncompressed - return ECKey.fromPublicOnly(pubBytes); + return nodeId; + } + + /** + * Gets the encoded public key value. + * + * @return 65-byte encoded public key + */ + public byte[] getPubKey() { + return pub.getEncoded(/* compressed */ false); + } + + /** + * Gets the public key in the form of an elliptic curve point object from Bouncy Castle. + * + * @return - + */ + public ECPoint getPubKeyPoint() { + return pub; + } + + /** + * Gets the private key in the form of an integer field element. The public key is derived by + * performing EC point addition this number of times (i.e. point multiplying). + * + * @return - + * @throws IllegalStateException if the private key bytes are not available. + */ + public BigInteger getPrivKey() { + if (privKey == null) { + throw new MissingPrivateKeyException(); + } else if (privKey instanceof BCECPrivateKey) { + return ((BCECPrivateKey) privKey).getD(); + } else { + throw new MissingPrivateKeyException(); } - - public static byte[] signatureToKeyBytes(byte[] messageHash, String - signatureBase64) throws SignatureException { - byte[] signatureEncoded; - try { - signatureEncoded = Base64.decode(signatureBase64); - } catch (RuntimeException e) { - // This is what you getData back from Bouncy Castle if base64 doesn't - // decode :( - throw new SignatureException("Could not decode base64", e); - } - // Parse the signature bytes into r/s and the selector value. - if (signatureEncoded.length < 65) { - throw new SignatureException("Signature truncated, expected 65 " + - "bytes and got " + signatureEncoded.length); - } - - return signatureToKeyBytes( - messageHash, - ECDSASignature.fromComponents( - Arrays.copyOfRange(signatureEncoded, 1, 33), - Arrays.copyOfRange(signatureEncoded, 33, 65), - (byte) (signatureEncoded[0] & 0xFF))); + } + + /** + * Returns whether this key is using the compressed form or not. Compressed pubkeys are only 33 + * bytes, not 64. + * + * @return - + */ + public boolean isCompressed() { + return pub.isCompressed(); + } + + public String toString() { + StringBuilder b = new StringBuilder(); + b.append("pub:").append(Hex.toHexString(pub.getEncoded(false))); + return b.toString(); + } + + /** + * Produce a string rendering of the ECKey INCLUDING the private key. Unless you absolutely need + * the private key it is better for security reasons to just use toString(). + * + * @return - + */ + public String toStringWithPrivate() { + StringBuilder b = new StringBuilder(); + b.append(toString()); + if (privKey != null && privKey instanceof BCECPrivateKey) { + b.append(" priv:").append(Hex.toHexString(((BCECPrivateKey) + privKey).getD().toByteArray())); } - - public static byte[] signatureToKeyBytes(byte[] messageHash, - ECDSASignature sig) throws - SignatureException { - check(messageHash.length == 32, "messageHash argument has length " + - messageHash.length); - int header = sig.v; - // The header byte: 0x1B = first key with even y, 0x1C = first key - // with odd y, - // 0x1D = second key with even y, 0x1E = second key - // with odd y - if (header < 27 || header > 34) { - throw new SignatureException("Header byte out of range: " + header); - } - if (header >= 31) { - header -= 4; - } - int recId = header - 27; - byte[] key = ECKey.recoverPubBytesFromSignature(recId, sig, - messageHash); - if (key == null) { - throw new SignatureException("Could not recover public key from " + - "signature"); - } - return key; + return b.toString(); + } + + /** + * Signs the given hash and returns the R and S components as BigIntegers and putData them in + * ECDSASignature + * + * @param input to sign + * @return ECDSASignature signature that contains the R and S components + */ + public ECDSASignature doSign(byte[] input) { + if (input.length != 32) { + throw new IllegalArgumentException("Expected 32 byte input to " + + "ECDSA signature, not " + input.length); } - - /** - * Compute the address of the key that signed the given signature. - * - * @param messageHash 32-byte hash of message - * @param signatureBase64 Base-64 encoded signature - * @return 20-byte address - */ - public static byte[] signatureToAddress(byte[] messageHash, String - signatureBase64) throws SignatureException { - return computeAddress(signatureToKeyBytes(messageHash, - signatureBase64)); + // No decryption of private key required. + if (privKey == null) { + throw new MissingPrivateKeyException(); } - - /** - * Compute the address of the key that signed the given signature. - * - * @param messageHash 32-byte hash of message - * @param sig - - * @return 20-byte address - */ - public static byte[] signatureToAddress(byte[] messageHash, - ECDSASignature sig) throws - SignatureException { - return computeAddress(signatureToKeyBytes(messageHash, sig)); + if (privKey instanceof BCECPrivateKey) { + ECDSASigner signer = new ECDSASigner(new HMacDSAKCalculator(new + SHA256Digest())); + ECPrivateKeyParameters privKeyParams = new ECPrivateKeyParameters + (((BCECPrivateKey) privKey).getD(), CURVE); + signer.init(true, privKeyParams); + BigInteger[] components = signer.generateSignature(input); + return new ECDSASignature(components[0], components[1]) + .toCanonicalised(); + } else { + try { + final Signature ecSig = ECSignatureFactory.getRawInstance + (provider); + ecSig.initSign(privKey); + ecSig.update(input); + final byte[] derSignature = ecSig.sign(); + return ECDSASignature.decodeFromDER(derSignature) + .toCanonicalised(); + } catch (SignatureException | InvalidKeyException ex) { + throw new RuntimeException("ECKey signing error", ex); + } } - - /** - * Compute the key that signed the given signature. - * - * @param messageHash 32-byte hash of message - * @param signatureBase64 Base-64 encoded signature - * @return ECKey - */ - public static ECKey signatureToKey(byte[] messageHash, String - signatureBase64) throws SignatureException { - final byte[] keyBytes = signatureToKeyBytes(messageHash, - signatureBase64); - return ECKey.fromPublicOnly(keyBytes); + } + + /** + * Takes the keccak hash (32 bytes) of data and returns the ECDSA signature + * + * @param messageHash - + * @return - + * @throws IllegalStateException if this ECKey does not have the private part. + */ + public ECDSASignature sign(byte[] messageHash) { + ECDSASignature sig = doSign(messageHash); + // Now we have to work backwards to figure out the recId needed to + // recover the signature. + int recId = -1; + byte[] thisKey = this.pub.getEncoded(/* compressed */ false); + for (int i = 0; i < 4; i++) { + byte[] k = ECKey.recoverPubBytesFromSignature(i, sig, messageHash); + if (k != null && Arrays.equals(k, thisKey)) { + recId = i; + break; + } } - - /** - * Compute the key that signed the given signature. - * - * @param messageHash 32-byte hash of message - * @param sig - - * @return ECKey - */ - public static ECKey signatureToKey(byte[] messageHash, ECDSASignature - sig) throws SignatureException { - final byte[] keyBytes = signatureToKeyBytes(messageHash, sig); - return ECKey.fromPublicOnly(keyBytes); + if (recId == -1) { + throw new RuntimeException("Could not construct a recoverable key" + + ". This should never happen."); } - - /** - *
Verifies the given ECDSA signature against the message bytes using - * the public key bytes.
- *- *
When using native ECDSA verification, data must be 32 bytes, and no - * element may be - * larger than 520 bytes.
- * - * @param data Hash of the data to verify. - * @param signature signature. - * @param pub The public key bytes to use. - * @return - - */ - public static boolean verify(byte[] data, ECDSASignature signature, - byte[] pub) { - ECDSASigner signer = new ECDSASigner(); - ECPublicKeyParameters params = new ECPublicKeyParameters(CURVE - .getCurve().decodePoint(pub), CURVE); - signer.init(false, params); - try { - return signer.verifySignature(data, signature.r, signature.s); - } catch (NullPointerException npe) { - // Bouncy Castle contains a bug that can cause NPEs given - // specially crafted signatures. - // Those signatures are inherently invalid/attack sigs so we just - // fail them here rather than crash the thread. - logger.error("Caught NPE inside bouncy castle", npe); - return false; - } + sig.v = (byte) (recId + 27); + return sig; + } + + public BigInteger keyAgreement(ECPoint otherParty) { + if (privKey == null) { + throw new MissingPrivateKeyException(); + } else if (privKey instanceof BCECPrivateKey) { + final ECDHBasicAgreement agreement = new ECDHBasicAgreement(); + agreement.init(new ECPrivateKeyParameters(((BCECPrivateKey) + privKey).getD(), CURVE)); + return agreement.calculateAgreement(new ECPublicKeyParameters + (otherParty, CURVE)); + } else { + try { + final KeyAgreement agreement = ECKeyAgreement.getInstance + (this.provider); + agreement.init(this.privKey); + agreement.doPhase( + ECKeyFactory.getInstance(this.provider) + .generatePublic(new ECPublicKeySpec + (otherParty, CURVE_SPEC)), + /* lastPhase */ true); + return new BigInteger(1, agreement.generateSecret()); + } catch (IllegalStateException | InvalidKeyException | + InvalidKeySpecException ex) { + throw new RuntimeException("ECDH key agreement failure", ex); + } } - - /** - * Verifies the given ASN.1 encoded ECDSA signature against a hash using - * the public key. - * - * @param data Hash of the data to verify. - * @param signature signature. - * @param pub The public key bytes to use. - * @return - - */ - public static boolean verify(byte[] data, byte[] signature, byte[] pub) { - return verify(data, ECDSASignature.decodeFromDER(signature), pub); + } + + /** + * Decrypt cipher by AES in SIC(also know as CTR) mode + * + * @param cipher -proper cipher + * @return decrypted cipher, equal length to the cipher. + * @deprecated should not use EC private scalar value as an AES key + */ + public byte[] decryptAES(byte[] cipher) { + + if (privKey == null) { + throw new MissingPrivateKeyException(); } - - /** - * Returns true if the given pubkey is canonical, i.e. the correct length - * taking into account compression. - * - * @param pubkey - - * @return - - */ - public static boolean isPubKeyCanonical(byte[] pubkey) { - if (pubkey[0] == 0x04) { - // Uncompressed pubkey - return pubkey.length == 65; - } else if (pubkey[0] == 0x02 || pubkey[0] == 0x03) { - // Compressed pubkey - return pubkey.length == 33; - } else { - return false; - } + if (!(privKey instanceof BCECPrivateKey)) { + throw new UnsupportedOperationException("Cannot use the private " + + "key as an AES key"); } - /** - *Given the components of a signature and a selector value, recover - * and return the public key - * that generated the signature according to the algorithm in SEC1v2 - * section 4.1.6.
- *- *
The recId is an index from 0 to 3 which indicates which of the 4 - * possible allKeys is the correct one. Because - * the key recovery operation yields multiple potential allKeys, the correct - * key must either be stored alongside the - * signature, or you must be willing to try each recId in turn until you - * find one that outputs the key you are - * expecting.
- *- *
If this method returns null it means recovery was not possible and - * recId should be iterated.
- *- *
Given the above two points, a correct usage of this method is - * inside a for loop from 0 to 3, and if the - * output is null OR a key that is not the one you expect, you try again - * with the next recId.
- * - * @param recId Which possible key to recover. - * @param sig the R and S components of the signature, wrapped. - * @param messageHash Hash of the data that was signed. - * @return 65-byte encoded public key - */ - @Nullable - public static byte[] recoverPubBytesFromSignature(int recId, - ECDSASignature sig, - byte[] messageHash) { - check(recId >= 0, "recId must be positive"); - check(sig.r.signum() >= 0, "r must be positive"); - check(sig.s.signum() >= 0, "s must be positive"); - check(messageHash != null, "messageHash must not be null"); - // 1.0 For j from 0 to h (h == recId here and the loop is outside - // this function) - // 1.1 Let x = r + jn - BigInteger n = CURVE.getN(); // Curve order. - BigInteger i = BigInteger.valueOf((long) recId / 2); - BigInteger x = sig.r.add(i.multiply(n)); - // 1.2. Convert the integer x to an octet string X of length mlen - // using the conversion routine - // specified in Section 2.3.7, where mlen = ⌈(log2 p)/8⌉ or - // mlen = ⌈m/8⌉. - // 1.3. Convert the octet string (16 set binary digits)||X to an - // elliptic curve point R using the - // conversion routine specified in Section 2.3.4. If this - // conversion routine outputs “invalid”, then - // do another iteration of Step 1. - // - // More concisely, what these points mean is to use X as a compressed - // public key. - ECCurve.Fp curve = (ECCurve.Fp) CURVE.getCurve(); - BigInteger prime = curve.getQ(); // Bouncy Castle is not consistent - // about the letter it uses for the prime. - if (x.compareTo(prime) >= 0) { - // Cannot have point co-ordinates larger than this as everything - // takes place modulo Q. - return null; - } - // Compressed allKeys require you to know an extra bit of data about the - // y-coord as there are two possibilities. - // So it's encoded in the recId. - ECPoint R = decompressKey(x, (recId & 1) == 1); - // 1.4. If nR != point at infinity, then do another iteration of - // Step 1 (callers responsibility). - if (!R.multiply(n).isInfinity()) { - return null; - } - // 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature - // verification. - BigInteger e = new BigInteger(1, messageHash); - // 1.6. For k from 1 to 2 do the following. (loop is outside this - // function via iterating recId) - // 1.6.1. Compute a candidate public key as: - // Q = mi(r) * (sR - eG) - // - // Where mi(x) is the modular multiplicative inverse. We transform - // this into the following: - // Q = (mi(r) * s ** R) + (mi(r) * -e ** G) - // Where -e is the modular additive inverse of e, that is z such that - // z + e = 0 (mod n). In the above equation - // ** is point multiplication and + is point addition (the EC group - // operator). - // - // We can find the additive inverse by subtracting e from zero then - // taking the mod. For example the additive - // inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and -3 mod - // 11 = 8. - BigInteger eInv = BigInteger.ZERO.subtract(e).mod(n); - BigInteger rInv = sig.r.modInverse(n); - BigInteger srInv = rInv.multiply(sig.s).mod(n); - BigInteger eInvrInv = rInv.multiply(eInv).mod(n); - ECPoint.Fp q = (ECPoint.Fp) ECAlgorithms.sumOfTwoMultiplies(CURVE - .getG(), eInvrInv, R, srInv); - return q.getEncoded(/* compressed */ false); - } + AESFastEngine engine = new AESFastEngine(); + SICBlockCipher ctrEngine = new SICBlockCipher(engine); - /** - * @param recId Which possible key to recover. - * @param sig the R and S components of the signature, wrapped. - * @param messageHash Hash of the data that was signed. - * @return 20-byte address - */ - @Nullable - public static byte[] recoverAddressFromSignature(int recId, - ECDSASignature sig, - byte[] messageHash) { - final byte[] pubBytes = recoverPubBytesFromSignature(recId, sig, - messageHash); - if (pubBytes == null) { - return null; - } else { - return computeAddress(pubBytes); - } - } + KeyParameter key = new KeyParameter(BigIntegers.asUnsignedByteArray(( + (BCECPrivateKey) privKey).getD())); + ParametersWithIV params = new ParametersWithIV(key, new byte[16]); - /** - * @param recId Which possible key to recover. - * @param sig the R and S components of the signature, wrapped. - * @param messageHash Hash of the data that was signed. - * @return ECKey - */ - @Nullable - public static ECKey recoverFromSignature(int recId, ECDSASignature sig, - byte[] messageHash) { - final byte[] pubBytes = recoverPubBytesFromSignature(recId, sig, - messageHash); - if (pubBytes == null) { - return null; - } else { - return ECKey.fromPublicOnly(pubBytes); - } - } + ctrEngine.init(false, params); - /** - * Decompress a compressed public key (x co-ord and low-bit of y-coord). - * - * @param xBN - - * @param yBit - - * @return - - */ - private static ECPoint decompressKey(BigInteger xBN, boolean yBit) { - X9IntegerConverter x9 = new X9IntegerConverter(); - byte[] compEnc = x9.integerToBytes(xBN, 1 + x9.getByteLength(CURVE - .getCurve())); - compEnc[0] = (byte) (yBit ? 0x03 : 0x02); - return CURVE.getCurve().decodePoint(compEnc); + int i = 0; + byte[] out = new byte[cipher.length]; + while (i < cipher.length) { + ctrEngine.processBlock(cipher, i, out, i); + i += engine.getBlockSize(); + if (cipher.length - i < engine.getBlockSize()) { + break; + } } - private static void check(boolean test, String message) { - if (!test) { - throw new IllegalArgumentException(message); - } + // process left bytes + if (cipher.length - i > 0) { + byte[] tmpBlock = new byte[16]; + System.arraycopy(cipher, i, tmpBlock, 0, cipher.length - i); + ctrEngine.processBlock(tmpBlock, 0, tmpBlock, 0); + System.arraycopy(tmpBlock, 0, out, i, cipher.length - i); } - /** - * Returns a copy of this key, but with the public point represented in - * uncompressed form. Normally you would - * never need this: it's for specialised scenarios or when backwards - * compatibility in encoded form is necessary. - * - * @return - - * @deprecated per-point compression property will be removed in Bouncy - * Castle - */ - public ECKey decompress() { - if (!pub.isCompressed()) { - return this; - } else { - return new ECKey(this.provider, this.privKey, decompressPoint(pub)); - } + return out; + } + + /** + * Verifies the given ASN.1 encoded ECDSA signature against a hash using the public key. + * + * @param data Hash of the data to verify. + * @param signature signature. + * @return - + */ + public boolean verify(byte[] data, byte[] signature) { + return ECKey.verify(data, signature, getPubKey()); + } + + /** + * Verifies the given R/S pair (signature) against a hash using the public key. + * + * @param sigHash - + * @param signature - + * @return - + */ + public boolean verify(byte[] sigHash, ECDSASignature signature) { + return ECKey.verify(sigHash, signature, getPubKey()); + } + + /** + * Returns true if this pubkey is canonical, i.e. the correct length taking into account + * compression. + * + * @return - + */ + public boolean isPubKeyCanonical() { + return isPubKeyCanonical(pub.getEncoded(/* uncompressed */ false)); + } + + /** + * Returns a 32 byte array containing the private key, or null if the key is encrypted or public + * only + * + * @return - + */ + @Nullable + public byte[] getPrivKeyBytes() { + if (privKey == null) { + return null; + } else if (privKey instanceof BCECPrivateKey) { + return bigIntegerToBytes(((BCECPrivateKey) privKey).getD(), 32); + } else { + return null; } + } - /** - * @deprecated per-point compression property will be removed in Bouncy - * Castle - */ - public ECKey compress() { - if (pub.isCompressed()) { - return this; - } else { - return new ECKey(this.provider, this.privKey, compressPoint(pub)); - } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - /** - * Returns true if this key doesn't have access to private key bytes. - * This may be because it was never - * given any private key bytes to begin with (a watching key). - * - * @return - - */ - public boolean isPubKeyOnly() { - return privKey == null; + if (o == null || !(o instanceof ECKey)) { + return false; } - /** - * Returns true if this key has access to private key bytes. Does the - * opposite of - * {@link #isPubKeyOnly()}. - * - * @return - - */ - public boolean hasPrivKey() { - return privKey != null; - } + ECKey ecKey = (ECKey) o; - /** - * Gets the address form of the public key. - * - * @return 20-byte address - */ - public byte[] getAddress() { - if (pubKeyHash == null) { - pubKeyHash = computeAddress(this.pub); - } - return pubKeyHash; + if (privKey != null && !privKey.equals(ecKey.privKey)) { + return false; } + return pub == null || pub.equals(ecKey.pub); + } - /** - * Generates the NodeID based on this key, that is the public key without - * first format byte - */ - public byte[] getNodeId() { - if (nodeId == null) { - nodeId = pubBytesWithoutFormat(this.pub); - } - return nodeId; - } + @Override + public int hashCode() { + return Arrays.hashCode(getPubKey()); + } - /** - * Gets the encoded public key value. - * - * @return 65-byte encoded public key - */ - public byte[] getPubKey() { - return pub.getEncoded(/* compressed */ false); - } + public static class ECDSASignature { /** - * Gets the public key in the form of an elliptic curve point object from - * Bouncy Castle. - * - * @return - + * The two components of the signature. */ - public ECPoint getPubKeyPoint() { - return pub; - } + public final BigInteger r, s; + public byte v; /** - * Gets the private key in the form of an integer field element. The - * public key is derived by performing EC - * point addition this number of times (i.e. point multiplying). + * Constructs a signature with the given components. Does NOT automatically canonicalise the + * signature. * - * @return - - * @throws IllegalStateException if the private key bytes are not available. + * @param r - + * @param s - */ - public BigInteger getPrivKey() { - if (privKey == null) { - throw new MissingPrivateKeyException(); - } else if (privKey instanceof BCECPrivateKey) { - return ((BCECPrivateKey) privKey).getD(); - } else { - throw new MissingPrivateKeyException(); - } + public ECDSASignature(BigInteger r, BigInteger s) { + this.r = r; + this.s = s; } /** - * Returns whether this key is using the compressed form or not. - * Compressed pubkeys are only 33 bytes, not 64. + * t * * @return - */ - public boolean isCompressed() { - return pub.isCompressed(); - } - - public String toString() { - StringBuilder b = new StringBuilder(); - b.append("pub:").append(Hex.toHexString(pub.getEncoded(false))); - return b.toString(); + private static ECDSASignature fromComponents(byte[] r, byte[] s) { + return new ECDSASignature(new BigInteger(1, r), new BigInteger(1, + s)); } /** - * Produce a string rendering of the ECKey INCLUDING the private key. - * Unless you absolutely need the private key it is better for security - * reasons to just use toString(). - * + * @param r - + * @param s - + * @param v - * @return - */ - public String toStringWithPrivate() { - StringBuilder b = new StringBuilder(); - b.append(toString()); - if (privKey != null && privKey instanceof BCECPrivateKey) { - b.append(" priv:").append(Hex.toHexString(((BCECPrivateKey) - privKey).getD().toByteArray())); - } - return b.toString(); + public static ECDSASignature fromComponents(byte[] r, byte[] s, byte + v) { + ECDSASignature signature = fromComponents(r, s); + signature.v = v; + return signature; } - /** - * Signs the given hash and returns the R and S components as BigIntegers - * and putData them in ECDSASignature - * - * @param input to sign - * @return ECDSASignature signature that contains the R and S components - */ - public ECDSASignature doSign(byte[] input) { - if (input.length != 32) { - throw new IllegalArgumentException("Expected 32 byte input to " + - "ECDSA signature, not " + input.length); - } - // No decryption of private key required. - if (privKey == null) { - throw new MissingPrivateKeyException(); - } - if (privKey instanceof BCECPrivateKey) { - ECDSASigner signer = new ECDSASigner(new HMacDSAKCalculator(new - SHA256Digest())); - ECPrivateKeyParameters privKeyParams = new ECPrivateKeyParameters - (((BCECPrivateKey) privKey).getD(), CURVE); - signer.init(true, privKeyParams); - BigInteger[] components = signer.generateSignature(input); - return new ECDSASignature(components[0], components[1]) - .toCanonicalised(); - } else { - try { - final Signature ecSig = ECSignatureFactory.getRawInstance - (provider); - ecSig.initSign(privKey); - ecSig.update(input); - final byte[] derSignature = ecSig.sign(); - return ECDSASignature.decodeFromDER(derSignature) - .toCanonicalised(); - } catch (SignatureException | InvalidKeyException ex) { - throw new RuntimeException("ECKey signing error", ex); - } - } - } + public static boolean validateComponents(BigInteger r, BigInteger s, + byte v) { - /** - * Takes the keccak hash (32 bytes) of data and returns the ECDSA signature - * - * @param messageHash - - * @return - - * @throws IllegalStateException if this ECKey does not have the private - * part. - */ - public ECDSASignature sign(byte[] messageHash) { - ECDSASignature sig = doSign(messageHash); - // Now we have to work backwards to figure out the recId needed to - // recover the signature. - int recId = -1; - byte[] thisKey = this.pub.getEncoded(/* compressed */ false); - for (int i = 0; i < 4; i++) { - byte[] k = ECKey.recoverPubBytesFromSignature(i, sig, messageHash); - if (k != null && Arrays.equals(k, thisKey)) { - recId = i; - break; - } - } - if (recId == -1) { - throw new RuntimeException("Could not construct a recoverable key" + - ". This should never happen."); - } - sig.v = (byte) (recId + 27); - return sig; - } + if (v != 27 && v != 28) { + return false; + } - public BigInteger keyAgreement(ECPoint otherParty) { - if (privKey == null) { - throw new MissingPrivateKeyException(); - } else if (privKey instanceof BCECPrivateKey) { - final ECDHBasicAgreement agreement = new ECDHBasicAgreement(); - agreement.init(new ECPrivateKeyParameters(((BCECPrivateKey) - privKey).getD(), CURVE)); - return agreement.calculateAgreement(new ECPublicKeyParameters - (otherParty, CURVE)); - } else { - try { - final KeyAgreement agreement = ECKeyAgreement.getInstance - (this.provider); - agreement.init(this.privKey); - agreement.doPhase( - ECKeyFactory.getInstance(this.provider) - .generatePublic(new ECPublicKeySpec - (otherParty, CURVE_SPEC)), - /* lastPhase */ true); - return new BigInteger(1, agreement.generateSecret()); - } catch (IllegalStateException | InvalidKeyException | - InvalidKeySpecException ex) { - throw new RuntimeException("ECDH key agreement failure", ex); - } - } - } + if (isLessThan(r, BigInteger.ONE)) { + return false; + } + if (isLessThan(s, BigInteger.ONE)) { + return false; + } - /** - * Decrypt cipher by AES in SIC(also know as CTR) mode - * - * @param cipher -proper cipher - * @return decrypted cipher, equal length to the cipher. - * @deprecated should not use EC private scalar value as an AES key - */ - public byte[] decryptAES(byte[] cipher) { + if (!isLessThan(r, SECP256K1N)) { + return false; + } + return isLessThan(s, SECP256K1N); + } - if (privKey == null) { - throw new MissingPrivateKeyException(); - } - if (!(privKey instanceof BCECPrivateKey)) { - throw new UnsupportedOperationException("Cannot use the private " + - "key as an AES key"); + public static ECDSASignature decodeFromDER(byte[] bytes) { + ASN1InputStream decoder = null; + try { + decoder = new ASN1InputStream(bytes); + DLSequence seq = (DLSequence) decoder.readObject(); + if (seq == null) { + throw new RuntimeException("Reached past end of ASN.1 " + + "stream."); } - - - AESFastEngine engine = new AESFastEngine(); - SICBlockCipher ctrEngine = new SICBlockCipher(engine); - - KeyParameter key = new KeyParameter(BigIntegers.asUnsignedByteArray(( - (BCECPrivateKey) privKey).getD())); - ParametersWithIV params = new ParametersWithIV(key, new byte[16]); - - ctrEngine.init(false, params); - - int i = 0; - byte[] out = new byte[cipher.length]; - while (i < cipher.length) { - ctrEngine.processBlock(cipher, i, out, i); - i += engine.getBlockSize(); - if (cipher.length - i < engine.getBlockSize()) { - break; - } + ASN1Integer r, s; + try { + r = (ASN1Integer) seq.getObjectAt(0); + s = (ASN1Integer) seq.getObjectAt(1); + } catch (ClassCastException e) { + throw new IllegalArgumentException(e); } - - // process left bytes - if (cipher.length - i > 0) { - byte[] tmpBlock = new byte[16]; - System.arraycopy(cipher, i, tmpBlock, 0, cipher.length - i); - ctrEngine.processBlock(tmpBlock, 0, tmpBlock, 0); - System.arraycopy(tmpBlock, 0, out, i, cipher.length - i); + // OpenSSL deviates from the DER spec by interpreting these + // values as unsigned, though they should not be + // Thus, we always use the positive versions. See: + // http://r6.ca/blog/20111119T211504Z.html + return new ECDSASignature(r.getPositiveValue(), s + .getPositiveValue()); + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + if (decoder != null) { + try { + decoder.close(); + } catch (IOException x) { + } } + } + } - return out; + public boolean validateComponents() { + return validateComponents(r, s, v); } - /** - * Verifies the given ASN.1 encoded ECDSA signature against a hash using - * the public key. - * - * @param data Hash of the data to verify. - * @param signature signature. - * @return - - */ - public boolean verify(byte[] data, byte[] signature) { - return ECKey.verify(data, signature, getPubKey()); + public ECDSASignature toCanonicalised() { + if (s.compareTo(HALF_CURVE_ORDER) > 0) { + // The order of the curve is the number of valid points that + // exist on that curve. If S is in the upper + // half of the number of valid points, then bring it back to + // the lower half. Otherwise, imagine that + // N = 10 + // s = 8, so (-8 % 10 == 2) thus both (r, 8) and (r, 2) + // are valid solutions. + // 10 - 8 == 2, giving us always the latter solution, + // which is canonical. + return new ECDSASignature(r, CURVE.getN().subtract(s)); + } else { + return this; + } } /** - * Verifies the given R/S pair (signature) against a hash using the - * public key. - * - * @param sigHash - - * @param signature - * @return - */ - public boolean verify(byte[] sigHash, ECDSASignature signature) { - return ECKey.verify(sigHash, signature, getPubKey()); + public String toBase64() { + byte[] sigData = new byte[65]; // 1 header + 32 bytes for R + 32 + // bytes for S + sigData[0] = v; + System.arraycopy(bigIntegerToBytes(this.r, 32), 0, sigData, 1, 32); + System.arraycopy(bigIntegerToBytes(this.s, 32), 0, sigData, 33, 32); + return new String(Base64.encode(sigData), Charset.forName("UTF-8")); } - /** - * Returns true if this pubkey is canonical, i.e. the correct length - * taking into account compression. - * - * @return - - */ - public boolean isPubKeyCanonical() { - return isPubKeyCanonical(pub.getEncoded(/* uncompressed */ false)); + public byte[] toByteArray() { + final byte fixedV = this.v >= 27 + ? (byte) (this.v - 27) + : this.v; + + return ByteUtil.merge( + ByteUtil.bigIntegerToBytes(this.r), + ByteUtil.bigIntegerToBytes(this.s), + new byte[]{fixedV}); } - /** - * Returns a 32 byte array containing the private key, or null if the key - * is encrypted or public only - * - * @return - - */ - @Nullable - public byte[] getPrivKeyBytes() { - if (privKey == null) { - return null; - } else if (privKey instanceof BCECPrivateKey) { - return bigIntegerToBytes(((BCECPrivateKey) privKey).getD(), 32); - } else { - return null; - } + public String toHex() { + return Hex.toHexString(toByteArray()); } @Override public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || !(o instanceof ECKey)) { - return false; - } - - ECKey ecKey = (ECKey) o; - - if (privKey != null && !privKey.equals(ecKey.privKey)) { - return false; - } - return pub == null || pub.equals(ecKey.pub); + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + ECDSASignature signature = (ECDSASignature) o; + + if (!r.equals(signature.r)) { + return false; + } + return s.equals(signature.s); } @Override public int hashCode() { - return Arrays.hashCode(getPubKey()); + int result = r.hashCode(); + result = 31 * result + s.hashCode(); + return result; } + } - public static class ECDSASignature { - /** - * The two components of the signature. - */ - public final BigInteger r, s; - public byte v; - - /** - * Constructs a signature with the given components. Does NOT - * automatically canonicalise the signature. - * - * @param r - - * @param s - - */ - public ECDSASignature(BigInteger r, BigInteger s) { - this.r = r; - this.s = s; - } + @SuppressWarnings("serial") + public static class MissingPrivateKeyException extends RuntimeException { - /** - * t - * - * @param r - * @param s - * @return - - */ - private static ECDSASignature fromComponents(byte[] r, byte[] s) { - return new ECDSASignature(new BigInteger(1, r), new BigInteger(1, - s)); - } - - /** - * @param r - - * @param s - - * @param v - - * @return - - */ - public static ECDSASignature fromComponents(byte[] r, byte[] s, byte - v) { - ECDSASignature signature = fromComponents(r, s); - signature.v = v; - return signature; - } - - public static boolean validateComponents(BigInteger r, BigInteger s, - byte v) { - - if (v != 27 && v != 28) { - return false; - } - - if (isLessThan(r, BigInteger.ONE)) { - return false; - } - if (isLessThan(s, BigInteger.ONE)) { - return false; - } - - if (!isLessThan(r, SECP256K1N)) { - return false; - } - return isLessThan(s, SECP256K1N); - } - - public static ECDSASignature decodeFromDER(byte[] bytes) { - ASN1InputStream decoder = null; - try { - decoder = new ASN1InputStream(bytes); - DLSequence seq = (DLSequence) decoder.readObject(); - if (seq == null) { - throw new RuntimeException("Reached past end of ASN.1 " + - "stream."); - } - ASN1Integer r, s; - try { - r = (ASN1Integer) seq.getObjectAt(0); - s = (ASN1Integer) seq.getObjectAt(1); - } catch (ClassCastException e) { - throw new IllegalArgumentException(e); - } - // OpenSSL deviates from the DER spec by interpreting these - // values as unsigned, though they should not be - // Thus, we always use the positive versions. See: - // http://r6.ca/blog/20111119T211504Z.html - return new ECDSASignature(r.getPositiveValue(), s - .getPositiveValue()); - } catch (IOException e) { - throw new RuntimeException(e); - } finally { - if (decoder != null) { - try { - decoder.close(); - } catch (IOException x) { - } - } - } - } - - public boolean validateComponents() { - return validateComponents(r, s, v); - } - - public ECDSASignature toCanonicalised() { - if (s.compareTo(HALF_CURVE_ORDER) > 0) { - // The order of the curve is the number of valid points that - // exist on that curve. If S is in the upper - // half of the number of valid points, then bring it back to - // the lower half. Otherwise, imagine that - // N = 10 - // s = 8, so (-8 % 10 == 2) thus both (r, 8) and (r, 2) - // are valid solutions. - // 10 - 8 == 2, giving us always the latter solution, - // which is canonical. - return new ECDSASignature(r, CURVE.getN().subtract(s)); - } else { - return this; - } - } - - /** - * @return - - */ - public String toBase64() { - byte[] sigData = new byte[65]; // 1 header + 32 bytes for R + 32 - // bytes for S - sigData[0] = v; - System.arraycopy(bigIntegerToBytes(this.r, 32), 0, sigData, 1, 32); - System.arraycopy(bigIntegerToBytes(this.s, 32), 0, sigData, 33, 32); - return new String(Base64.encode(sigData), Charset.forName("UTF-8")); - } - - public byte[] toByteArray() { - final byte fixedV = this.v >= 27 - ? (byte) (this.v - 27) - : this.v; - - return ByteUtil.merge( - ByteUtil.bigIntegerToBytes(this.r), - ByteUtil.bigIntegerToBytes(this.s), - new byte[]{fixedV}); - } - - public String toHex() { - return Hex.toHexString(toByteArray()); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - ECDSASignature signature = (ECDSASignature) o; - - if (!r.equals(signature.r)) { - return false; - } - return s.equals(signature.s); - } - - @Override - public int hashCode() { - int result = r.hashCode(); - result = 31 * result + s.hashCode(); - return result; - } - } - - @SuppressWarnings("serial") - public static class MissingPrivateKeyException extends RuntimeException { - } + } } diff --git a/src/main/java/org/tron/common/crypto/Hash.java b/src/main/java/org/tron/common/crypto/Hash.java index fbe5f6457a7..5c173065f73 100644 --- a/src/main/java/org/tron/common/crypto/Hash.java +++ b/src/main/java/org/tron/common/crypto/Hash.java @@ -18,120 +18,118 @@ package org.tron.common.crypto; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.tron.common.crypto.jce.TronCastleProvider; +import static java.util.Arrays.copyOfRange; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.security.Security; - -import static java.util.Arrays.copyOfRange; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.tron.common.crypto.jce.TronCastleProvider; public class Hash { - private static final Logger LOG = LoggerFactory.getLogger(Hash.class); - private static final Provider CRYPTO_PROVIDER; + private static final Logger LOG = LoggerFactory.getLogger(Hash.class); + private static final Provider CRYPTO_PROVIDER; - private static final String HASH_256_ALGORITHM_NAME; - private static final String HASH_512_ALGORITHM_NAME; + private static final String HASH_256_ALGORITHM_NAME; + private static final String HASH_512_ALGORITHM_NAME; - private static final MessageDigest sha256digest; - - static { - Security.addProvider(TronCastleProvider.getInstance()); - CRYPTO_PROVIDER = Security.getProvider("SC"); - HASH_256_ALGORITHM_NAME = "TRON-KECCAK-256"; - HASH_512_ALGORITHM_NAME = "TRON-KECCAK-512"; - try { - sha256digest = MessageDigest.getInstance("SHA-256"); - } catch (NoSuchAlgorithmException e) { - LOG.error("Can't initialize HashUtils", e); - throw new RuntimeException(e); // Can't happen. - } - - } - - /** - * @param input - data for hashing - * @return - sha256 hash of the data - */ - public static byte[] sha256(byte[] input) { - return sha256digest.digest(input); - } - - public static byte[] sha3(byte[] input) { - MessageDigest digest; - try { - digest = MessageDigest.getInstance(HASH_256_ALGORITHM_NAME, - CRYPTO_PROVIDER); - digest.update(input); - return digest.digest(); - } catch (NoSuchAlgorithmException e) { - LOG.error("Can't find such algorithm", e); - throw new RuntimeException(e); - } + private static final MessageDigest sha256digest; + static { + Security.addProvider(TronCastleProvider.getInstance()); + CRYPTO_PROVIDER = Security.getProvider("SC"); + HASH_256_ALGORITHM_NAME = "TRON-KECCAK-256"; + HASH_512_ALGORITHM_NAME = "TRON-KECCAK-512"; + try { + sha256digest = MessageDigest.getInstance("SHA-256"); + } catch (NoSuchAlgorithmException e) { + LOG.error("Can't initialize HashUtils", e); + throw new RuntimeException(e); // Can't happen. } - public static byte[] sha3(byte[] input1, byte[] input2) { - MessageDigest digest; - try { - digest = MessageDigest.getInstance(HASH_256_ALGORITHM_NAME, - CRYPTO_PROVIDER); - digest.update(input1, 0, input1.length); - digest.update(input2, 0, input2.length); - return digest.digest(); - } catch (NoSuchAlgorithmException e) { - LOG.error("Can't find such algorithm", e); - throw new RuntimeException(e); - } + } + + /** + * @param input - data for hashing + * @return - sha256 hash of the data + */ + public static byte[] sha256(byte[] input) { + return sha256digest.digest(input); + } + + public static byte[] sha3(byte[] input) { + MessageDigest digest; + try { + digest = MessageDigest.getInstance(HASH_256_ALGORITHM_NAME, + CRYPTO_PROVIDER); + digest.update(input); + return digest.digest(); + } catch (NoSuchAlgorithmException e) { + LOG.error("Can't find such algorithm", e); + throw new RuntimeException(e); } - /** - * hashing chunk of the data - * - * @param input - data for hash - * @param start - start of hashing chunk - * @param length - length of hashing chunk - * @return - keccak hash of the chunk - */ - public static byte[] sha3(byte[] input, int start, int length) { - MessageDigest digest; - try { - digest = MessageDigest.getInstance(HASH_256_ALGORITHM_NAME, - CRYPTO_PROVIDER); - digest.update(input, start, length); - return digest.digest(); - } catch (NoSuchAlgorithmException e) { - LOG.error("Can't find such algorithm", e); - throw new RuntimeException(e); - } + } + + public static byte[] sha3(byte[] input1, byte[] input2) { + MessageDigest digest; + try { + digest = MessageDigest.getInstance(HASH_256_ALGORITHM_NAME, + CRYPTO_PROVIDER); + digest.update(input1, 0, input1.length); + digest.update(input2, 0, input2.length); + return digest.digest(); + } catch (NoSuchAlgorithmException e) { + LOG.error("Can't find such algorithm", e); + throw new RuntimeException(e); } - - public static byte[] sha512(byte[] input) { - MessageDigest digest; - try { - digest = MessageDigest.getInstance(HASH_512_ALGORITHM_NAME, - CRYPTO_PROVIDER); - digest.update(input); - return digest.digest(); - } catch (NoSuchAlgorithmException e) { - LOG.error("Can't find such algorithm", e); - throw new RuntimeException(e); - } + } + + /** + * hashing chunk of the data + * + * @param input - data for hash + * @param start - start of hashing chunk + * @param length - length of hashing chunk + * @return - keccak hash of the chunk + */ + public static byte[] sha3(byte[] input, int start, int length) { + MessageDigest digest; + try { + digest = MessageDigest.getInstance(HASH_256_ALGORITHM_NAME, + CRYPTO_PROVIDER); + digest.update(input, start, length); + return digest.digest(); + } catch (NoSuchAlgorithmException e) { + LOG.error("Can't find such algorithm", e); + throw new RuntimeException(e); } - - /** - * Calculates RIGTMOST160(SHA3(input)). This is used in address - * calculations. * - * - * @param input - data - * @return - 20 right bytes of the hash keccak of the data - */ - public static byte[] sha3omit12(byte[] input) { - byte[] hash = sha3(input); - return copyOfRange(hash, 12, hash.length); + } + + public static byte[] sha512(byte[] input) { + MessageDigest digest; + try { + digest = MessageDigest.getInstance(HASH_512_ALGORITHM_NAME, + CRYPTO_PROVIDER); + digest.update(input); + return digest.digest(); + } catch (NoSuchAlgorithmException e) { + LOG.error("Can't find such algorithm", e); + throw new RuntimeException(e); } + } + + /** + * Calculates RIGTMOST160(SHA3(input)). This is used in address calculations. * + * + * @param input - data + * @return - 20 right bytes of the hash keccak of the data + */ + public static byte[] sha3omit12(byte[] input) { + byte[] hash = sha3(input); + return copyOfRange(hash, 12, hash.length); + } } diff --git a/src/main/java/org/tron/common/crypto/cryptohash/Digest.java b/src/main/java/org/tron/common/crypto/cryptohash/Digest.java index c46c4586018..bc62556e220 100644 --- a/src/main/java/org/tron/common/crypto/cryptohash/Digest.java +++ b/src/main/java/org/tron/common/crypto/cryptohash/Digest.java @@ -21,132 +21,118 @@ /** * Copyright (c) 2007-2010 Projet RNRT SAPHIR * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ public interface Digest { - /** - * Insert one more input data byte. - * - * @param in the input byte - */ - void update(byte in); + /** + * Insert one more input data byte. + * + * @param in the input byte + */ + void update(byte in); - /** - * Insert some more bytes. - * - * @param inbuf the data bytes - */ - void update(byte[] inbuf); + /** + * Insert some more bytes. + * + * @param inbuf the data bytes + */ + void update(byte[] inbuf); - /** - * Insert some more bytes. - * - * @param inbuf the data buffer - * @param off the data offset in {@code inbuf} - * @param len the data length (in bytes) - */ - void update(byte[] inbuf, int off, int len); + /** + * Insert some more bytes. + * + * @param inbuf the data buffer + * @param off the data offset in {@code inbuf} + * @param len the data length (in bytes) + */ + void update(byte[] inbuf, int off, int len); - /** - * Finalize the current hash computation and return the hash value - * in a newly-allocated array. The object is resetted. - * - * @return the hash output - */ - byte[] digest(); + /** + * Finalize the current hash computation and return the hash value in a newly-allocated array. The + * object is resetted. + * + * @return the hash output + */ + byte[] digest(); - /** - * Input some bytes, then finalize the current hash computation - * and return the hash value in a newly-allocated array. The object - * is resetted. - * - * @param inbuf the input data - * @return the hash output - */ - byte[] digest(byte[] inbuf); + /** + * Input some bytes, then finalize the current hash computation and return the hash value in a + * newly-allocated array. The object is resetted. + * + * @param inbuf the input data + * @return the hash output + */ + byte[] digest(byte[] inbuf); - /** - * Finalize the current hash computation and store the hash value - * in the provided output buffer. The {@code len} parameter - * contains the maximum number of bytes that should be written; - * no more bytes than the natural hash function output length will - * be produced. If {@code len} is smaller than the natural - * hash output length, the hash output is truncated to its first - * {@code len} bytes. The object is resetted. - * - * @param outbuf the output buffer - * @param off the output offset within {@code outbuf} - * @param len the requested hash output length (in bytes) - * @return the number of bytes actually written in {@code outbuf} - */ - int digest(byte[] outbuf, int off, int len); + /** + * Finalize the current hash computation and store the hash value in the provided output buffer. + * The {@code len} parameter contains the maximum number of bytes that should be written; no more + * bytes than the natural hash function output length will be produced. If {@code len} is smaller + * than the natural hash output length, the hash output is truncated to its first {@code len} + * bytes. The object is resetted. + * + * @param outbuf the output buffer + * @param off the output offset within {@code outbuf} + * @param len the requested hash output length (in bytes) + * @return the number of bytes actually written in {@code outbuf} + */ + int digest(byte[] outbuf, int off, int len); - /** - * Get the natural hash function output length (in bytes). - * - * @return the digest output length (in bytes) - */ - int getDigestLength(); + /** + * Get the natural hash function output length (in bytes). + * + * @return the digest output length (in bytes) + */ + int getDigestLength(); - /** - * Reset the object: this makes it suitable for a new hash - * computation. The current computation, if any, is discarded. - */ - void reset(); + /** + * Reset the object: this makes it suitable for a new hash computation. The current computation, + * if any, is discarded. + */ + void reset(); - /** - * Clone the current state. The returned object evolves independantly - * of this object. - * - * @return the clone - */ - Digest copy(); + /** + * Clone the current state. The returned object evolves independantly of this object. + * + * @return the clone + */ + Digest copy(); - /** - *Return the "block length" for the hash function. This - * value is naturally defined for iterated hash functions - * (Merkle-Damgard). It is used in HMAC (that's what the - * HMAC specification - * names the "{@code B}" parameter).
- *- *
If the function is "block-less" then this function may - * return {@code -n} where {@code n} is an integer such that the - * block length for HMAC ("{@code B}") will be inferred from the - * key length, by selecting the smallest multiple of {@code n} - * which is no smaller than the key length. For instance, for - * the Fugue-xxx hash functions, this function returns -4: the - * virtual block length B is the HMAC key length, rounded up to - * the next multiple of 4.
- * - * @return the internal block length (in bytes), or {@code -n} - */ - int getBlockLength(); + /** + *Return the "block length" for the hash function. This value is naturally defined for + * iterated hash functions (Merkle-Damgard). It is used in HMAC (that's what the HMAC specification names the "{@code B}" + * parameter).
If the function is "block-less" then this function may return {@code -n} + * where {@code n} is an integer such that the block length for HMAC ("{@code B}") will be + * inferred from the key length, by selecting the smallest multiple of {@code n} which is no + * smaller than the key length. For instance, for the Fugue-xxx hash functions, this function + * returns -4: the virtual block length B is the HMAC key length, rounded up to the next multiple + * of 4.
+ * + * @return the internal block length (in bytes), or {@code -n} + */ + int getBlockLength(); - /** - *Get the display name for this function (e.g. {@code "SHA-1"} - * for SHA-1).
- * - * @see Object - */ - String toString(); + /** + *Get the display name for this function (e.g. {@code "SHA-1"} for SHA-1).
+ * + * @see Object + */ + String toString(); } diff --git a/src/main/java/org/tron/common/crypto/cryptohash/DigestEngine.java b/src/main/java/org/tron/common/crypto/cryptohash/DigestEngine.java index e1939646b05..baf6735b75d 100644 --- a/src/main/java/org/tron/common/crypto/cryptohash/DigestEngine.java +++ b/src/main/java/org/tron/common/crypto/cryptohash/DigestEngine.java @@ -22,220 +22,208 @@ public abstract class DigestEngine extends MessageDigest implements Digest { - private int digestLen, blockLen, inputLen; - private byte[] inputBuf, outputBuf; - private long blockCount; - - /** - * Instantiate the engine. - */ - public DigestEngine(String alg) { - super(alg); - doInit(); - digestLen = engineGetDigestLength(); - blockLen = getInternalBlockLength(); - inputBuf = new byte[blockLen]; - outputBuf = new byte[digestLen]; - inputLen = 0; - blockCount = 0; - } - - /** - * Reset the hash algorithm state. - */ - protected abstract void engineReset(); - - /** - * Process one block of data. - * - * @param data the data block - */ - protected abstract void processBlock(byte[] data); - - /** - * Perform the final padding and store the result in the - * provided buffer. This method shall call {@link #flush} - * and then {@link #update} with the appropriate padding - * data in order to getData the full input data. - * - * @param buf the output buffer - * @param off the output offset - */ - protected abstract void doPadding(byte[] buf, int off); - - /** - * This function is called at object creation time; the - * implementation should use it to perform initialization tasks. - * After this method is called, the implementation should be ready - * to process data or meaningfully honour calls such as - * {@link #engineGetDigestLength} - */ - protected abstract void doInit(); - - private void adjustDigestLen() { - if (digestLen == 0) { - digestLen = engineGetDigestLength(); - outputBuf = new byte[digestLen]; - } + private int digestLen, blockLen, inputLen; + private byte[] inputBuf, outputBuf; + private long blockCount; + + /** + * Instantiate the engine. + */ + public DigestEngine(String alg) { + super(alg); + doInit(); + digestLen = engineGetDigestLength(); + blockLen = getInternalBlockLength(); + inputBuf = new byte[blockLen]; + outputBuf = new byte[digestLen]; + inputLen = 0; + blockCount = 0; + } + + /** + * Reset the hash algorithm state. + */ + protected abstract void engineReset(); + + /** + * Process one block of data. + * + * @param data the data block + */ + protected abstract void processBlock(byte[] data); + + /** + * Perform the final padding and store the result in the provided buffer. This method shall call + * {@link #flush} and then {@link #update} with the appropriate padding data in order to getData + * the full input data. + * + * @param buf the output buffer + * @param off the output offset + */ + protected abstract void doPadding(byte[] buf, int off); + + /** + * This function is called at object creation time; the implementation should use it to perform + * initialization tasks. After this method is called, the implementation should be ready to + * process data or meaningfully honour calls such as {@link #engineGetDigestLength} + */ + protected abstract void doInit(); + + private void adjustDigestLen() { + if (digestLen == 0) { + digestLen = engineGetDigestLength(); + outputBuf = new byte[digestLen]; } - - /** - * @see Digest - */ - public byte[] digest() { - adjustDigestLen(); - byte[] result = new byte[digestLen]; - digest(result, 0, digestLen); - return result; - } - - /** - * @see Digest - */ - public byte[] digest(byte[] input) { - update(input, 0, input.length); - return digest(); + } + + /** + * @see Digest + */ + public byte[] digest() { + adjustDigestLen(); + byte[] result = new byte[digestLen]; + digest(result, 0, digestLen); + return result; + } + + /** + * @see Digest + */ + public byte[] digest(byte[] input) { + update(input, 0, input.length); + return digest(); + } + + /** + * @see Digest + */ + public int digest(byte[] buf, int offset, int len) { + adjustDigestLen(); + if (len >= digestLen) { + doPadding(buf, offset); + reset(); + return digestLen; + } else { + doPadding(outputBuf, 0); + System.arraycopy(outputBuf, 0, buf, offset, len); + reset(); + return len; } - - /** - * @see Digest - */ - public int digest(byte[] buf, int offset, int len) { - adjustDigestLen(); - if (len >= digestLen) { - doPadding(buf, offset); - reset(); - return digestLen; - } else { - doPadding(outputBuf, 0); - System.arraycopy(outputBuf, 0, buf, offset, len); - reset(); - return len; - } + } + + /** + * @see Digest + */ + public void reset() { + engineReset(); + inputLen = 0; + blockCount = 0; + } + + /** + * @see Digest + */ + public void update(byte input) { + inputBuf[inputLen++] = input; + if (inputLen == blockLen) { + processBlock(inputBuf); + blockCount++; + inputLen = 0; } - - /** - * @see Digest - */ - public void reset() { - engineReset(); + } + + /** + * @see Digest + */ + public void update(byte[] input) { + update(input, 0, input.length); + } + + /** + * @see Digest + */ + public void update(byte[] input, int offset, int len) { + while (len > 0) { + int copyLen = blockLen - inputLen; + if (copyLen > len) { + copyLen = len; + } + System.arraycopy(input, offset, inputBuf, inputLen, + copyLen); + offset += copyLen; + inputLen += copyLen; + len -= copyLen; + if (inputLen == blockLen) { + processBlock(inputBuf); + blockCount++; inputLen = 0; - blockCount = 0; - } - - /** - * @see Digest - */ - public void update(byte input) { - inputBuf[inputLen++] = input; - if (inputLen == blockLen) { - processBlock(inputBuf); - blockCount++; - inputLen = 0; - } - } - - /** - * @see Digest - */ - public void update(byte[] input) { - update(input, 0, input.length); - } - - /** - * @see Digest - */ - public void update(byte[] input, int offset, int len) { - while (len > 0) { - int copyLen = blockLen - inputLen; - if (copyLen > len) { - copyLen = len; - } - System.arraycopy(input, offset, inputBuf, inputLen, - copyLen); - offset += copyLen; - inputLen += copyLen; - len -= copyLen; - if (inputLen == blockLen) { - processBlock(inputBuf); - blockCount++; - inputLen = 0; - } - } - } - - /** - * Get the internal block length. This is the length (in - * bytes) of the array which will be passed as parameter to - * {@link #processBlock}. The default implementation of this - * method calls {@link #getBlockLength} and returns the same - * value. Overriding this method is useful when the advertised - * block length (which is used, for instance, by HMAC) is - * suboptimal with regards to internal buffering needs. - * - * @return the internal block length (in bytes) - */ - protected int getInternalBlockLength() { - return getBlockLength(); - } - - /** - * Flush internal buffers, so that less than a block of data - * may at most be upheld. - * - * @return the number of bytes still unprocessed after the flush - */ - protected final int flush() { - return inputLen; - } - - /** - * Get a reference to an internal buffer with the same size - * than a block. The contents of that buffer are defined only - * immediately after a call to {@link #flush()}: if - * {@link #flush()} return the value {@code n}, then the - * first {@code n} bytes of the array returned by this method - * are the {@code n} bytes of input data which are still - * unprocessed. The values of the remaining bytes are - * undefined and may be altered at will. - * - * @return a block-sized internal buffer - */ - protected final byte[] getBlockBuffer() { - return inputBuf; - } - - /** - * Get the "block count": this is the number of times the - * {@link #processBlock} method has been invoked for the - * current hash operation. That counter is incremented - * after the call to {@link #processBlock}. - * - * @return the block count - */ - protected long getBlockCount() { - return blockCount; - } - - /** - * This function copies the internal buffering state to some - * other instance of a class extending {@code DigestEngine}. - * It returns a reference to the copy. This method is intended - * to be called by the implementation of the {@link #copy} - * method. - * - * @param dest the copy - * @return the value {@code dest} - */ - protected Digest copyState(DigestEngine dest) { - dest.inputLen = inputLen; - dest.blockCount = blockCount; - System.arraycopy(inputBuf, 0, dest.inputBuf, 0, - inputBuf.length); - adjustDigestLen(); - dest.adjustDigestLen(); - System.arraycopy(outputBuf, 0, dest.outputBuf, 0, - outputBuf.length); - return dest; + } } + } + + /** + * Get the internal block length. This is the length (in bytes) of the array which will be passed + * as parameter to {@link #processBlock}. The default implementation of this method calls {@link + * #getBlockLength} and returns the same value. Overriding this method is useful when the + * advertised block length (which is used, for instance, by HMAC) is suboptimal with regards to + * internal buffering needs. + * + * @return the internal block length (in bytes) + */ + protected int getInternalBlockLength() { + return getBlockLength(); + } + + /** + * Flush internal buffers, so that less than a block of data may at most be upheld. + * + * @return the number of bytes still unprocessed after the flush + */ + protected final int flush() { + return inputLen; + } + + /** + * Get a reference to an internal buffer with the same size than a block. The contents of that + * buffer are defined only immediately after a call to {@link #flush()}: if {@link #flush()} + * return the value {@code n}, then the first {@code n} bytes of the array returned by this method + * are the {@code n} bytes of input data which are still unprocessed. The values of the remaining + * bytes are undefined and may be altered at will. + * + * @return a block-sized internal buffer + */ + protected final byte[] getBlockBuffer() { + return inputBuf; + } + + /** + * Get the "block count": this is the number of times the {@link #processBlock} method has been + * invoked for the current hash operation. That counter is incremented after the call to + * {@link #processBlock}. + * + * @return the block count + */ + protected long getBlockCount() { + return blockCount; + } + + /** + * This function copies the internal buffering state to some other instance of a class extending + * {@code DigestEngine}. It returns a reference to the copy. This method is intended to be called + * by the implementation of the {@link #copy} method. + * + * @param dest the copy + * @return the value {@code dest} + */ + protected Digest copyState(DigestEngine dest) { + dest.inputLen = inputLen; + dest.blockCount = blockCount; + System.arraycopy(inputBuf, 0, dest.inputBuf, 0, + inputBuf.length); + adjustDigestLen(); + dest.adjustDigestLen(); + System.arraycopy(outputBuf, 0, dest.outputBuf, 0, + outputBuf.length); + return dest; + } } diff --git a/src/main/java/org/tron/common/crypto/cryptohash/Keccak256.java b/src/main/java/org/tron/common/crypto/cryptohash/Keccak256.java index 7d069da98fa..ea11f4a13a4 100644 --- a/src/main/java/org/tron/common/crypto/cryptohash/Keccak256.java +++ b/src/main/java/org/tron/common/crypto/cryptohash/Keccak256.java @@ -20,31 +20,31 @@ public class Keccak256 extends KeccakCore { - /** - * Create the engine. - */ - public Keccak256() { - super("tron-keccak-256"); - } - - public Digest copy() { - return copyState(new Keccak256()); - } - - public int engineGetDigestLength() { - return 32; - } - - @Override - protected byte[] engineDigest() { - return null; - } - - @Override - protected void engineUpdate(byte arg0) { - } - - @Override - protected void engineUpdate(byte[] arg0, int arg1, int arg2) { - } + /** + * Create the engine. + */ + public Keccak256() { + super("tron-keccak-256"); + } + + public Digest copy() { + return copyState(new Keccak256()); + } + + public int engineGetDigestLength() { + return 32; + } + + @Override + protected byte[] engineDigest() { + return null; + } + + @Override + protected void engineUpdate(byte arg0) { + } + + @Override + protected void engineUpdate(byte[] arg0, int arg1, int arg2) { + } } diff --git a/src/main/java/org/tron/common/crypto/cryptohash/Keccak512.java b/src/main/java/org/tron/common/crypto/cryptohash/Keccak512.java index 6d8eef58a03..824e3b2afde 100644 --- a/src/main/java/org/tron/common/crypto/cryptohash/Keccak512.java +++ b/src/main/java/org/tron/common/crypto/cryptohash/Keccak512.java @@ -20,31 +20,31 @@ public class Keccak512 extends KeccakCore { - /** - * Create the engine. - */ - public Keccak512() { - super("tron-keccak-512"); - } - - public Digest copy() { - return copyState(new Keccak512()); - } - - public int engineGetDigestLength() { - return 64; - } - - @Override - protected byte[] engineDigest() { - return null; - } - - @Override - protected void engineUpdate(byte input) { - } - - @Override - protected void engineUpdate(byte[] input, int offset, int len) { - } + /** + * Create the engine. + */ + public Keccak512() { + super("tron-keccak-512"); + } + + public Digest copy() { + return copyState(new Keccak512()); + } + + public int engineGetDigestLength() { + return 64; + } + + @Override + protected byte[] engineDigest() { + return null; + } + + @Override + protected void engineUpdate(byte input) { + } + + @Override + protected void engineUpdate(byte[] input, int offset, int len) { + } } diff --git a/src/main/java/org/tron/common/crypto/cryptohash/KeccakCore.java b/src/main/java/org/tron/common/crypto/cryptohash/KeccakCore.java index 770238c4ed6..3fa7e660d5a 100644 --- a/src/main/java/org/tron/common/crypto/cryptohash/KeccakCore.java +++ b/src/main/java/org/tron/common/crypto/cryptohash/KeccakCore.java @@ -20,533 +20,531 @@ abstract class KeccakCore extends DigestEngine { - private static final long[] RC = { - 0x0000000000000001L, 0x0000000000008082L, - 0x800000000000808AL, 0x8000000080008000L, - 0x000000000000808BL, 0x0000000080000001L, - 0x8000000080008081L, 0x8000000000008009L, - 0x000000000000008AL, 0x0000000000000088L, - 0x0000000080008009L, 0x000000008000000AL, - 0x000000008000808BL, 0x800000000000008BL, - 0x8000000000008089L, 0x8000000000008003L, - 0x8000000000008002L, 0x8000000000000080L, - 0x000000000000800AL, 0x800000008000000AL, - 0x8000000080008081L, 0x8000000000008080L, - 0x0000000080000001L, 0x8000000080008008L - }; - private long[] A; - private byte[] tmpOut; + private static final long[] RC = { + 0x0000000000000001L, 0x0000000000008082L, + 0x800000000000808AL, 0x8000000080008000L, + 0x000000000000808BL, 0x0000000080000001L, + 0x8000000080008081L, 0x8000000000008009L, + 0x000000000000008AL, 0x0000000000000088L, + 0x0000000080008009L, 0x000000008000000AL, + 0x000000008000808BL, 0x800000000000008BL, + 0x8000000000008089L, 0x8000000000008003L, + 0x8000000000008002L, 0x8000000000000080L, + 0x000000000000800AL, 0x800000008000000AL, + 0x8000000080008081L, 0x8000000000008080L, + 0x0000000080000001L, 0x8000000080008008L + }; + private long[] A; + private byte[] tmpOut; - KeccakCore(String alg) { - super(alg); - } + KeccakCore(String alg) { + super(alg); + } - /** - * Encode the 64-bit word {@code val} into the array - * {@code buf} at offset {@code off}, in little-endian - * convention (least significant byte first). - * - * @param val the value to encode - * @param buf the destination buffer - * @param off the destination offset - */ - private static void encodeLELong(long val, byte[] buf, int off) { - buf[off + 0] = (byte) val; - buf[off + 1] = (byte) (val >>> 8); - buf[off + 2] = (byte) (val >>> 16); - buf[off + 3] = (byte) (val >>> 24); - buf[off + 4] = (byte) (val >>> 32); - buf[off + 5] = (byte) (val >>> 40); - buf[off + 6] = (byte) (val >>> 48); - buf[off + 7] = (byte) (val >>> 56); - } + /** + * Encode the 64-bit word {@code val} into the array {@code buf} at offset {@code off}, in + * little-endian convention (least significant byte first). + * + * @param val the value to encode + * @param buf the destination buffer + * @param off the destination offset + */ + private static void encodeLELong(long val, byte[] buf, int off) { + buf[off + 0] = (byte) val; + buf[off + 1] = (byte) (val >>> 8); + buf[off + 2] = (byte) (val >>> 16); + buf[off + 3] = (byte) (val >>> 24); + buf[off + 4] = (byte) (val >>> 32); + buf[off + 5] = (byte) (val >>> 40); + buf[off + 6] = (byte) (val >>> 48); + buf[off + 7] = (byte) (val >>> 56); + } - /** - * Decode a 64-bit little-endian word from the array {@code buf} - * at offset {@code off}. - * - * @param buf the source buffer - * @param off the source offset - * @return the decoded value - */ - private static long decodeLELong(byte[] buf, int off) { - return (buf[off + 0] & 0xFFL) - | ((buf[off + 1] & 0xFFL) << 8) - | ((buf[off + 2] & 0xFFL) << 16) - | ((buf[off + 3] & 0xFFL) << 24) - | ((buf[off + 4] & 0xFFL) << 32) - | ((buf[off + 5] & 0xFFL) << 40) - | ((buf[off + 6] & 0xFFL) << 48) - | ((buf[off + 7] & 0xFFL) << 56); - } + /** + * Decode a 64-bit little-endian word from the array {@code buf} at offset {@code off}. + * + * @param buf the source buffer + * @param off the source offset + * @return the decoded value + */ + private static long decodeLELong(byte[] buf, int off) { + return (buf[off + 0] & 0xFFL) + | ((buf[off + 1] & 0xFFL) << 8) + | ((buf[off + 2] & 0xFFL) << 16) + | ((buf[off + 3] & 0xFFL) << 24) + | ((buf[off + 4] & 0xFFL) << 32) + | ((buf[off + 5] & 0xFFL) << 40) + | ((buf[off + 6] & 0xFFL) << 48) + | ((buf[off + 7] & 0xFFL) << 56); + } - protected void engineReset() { - doReset(); - } + protected void engineReset() { + doReset(); + } - protected void processBlock(byte[] data) { - /* Input block */ - for (int i = 0; i < data.length; i += 8) { - A[i >>> 3] ^= decodeLELong(data, i); - } + protected void processBlock(byte[] data) { + /* Input block */ + for (int i = 0; i < data.length; i += 8) { + A[i >>> 3] ^= decodeLELong(data, i); + } - long t0, t1, t2, t3, t4; - long tt0, tt1, tt2, tt3, tt4; - long t, kt; - long c0, c1, c2, c3, c4, bnn; + long t0, t1, t2, t3, t4; + long tt0, tt1, tt2, tt3, tt4; + long t, kt; + long c0, c1, c2, c3, c4, bnn; - /* - * Unrolling four rounds kills performance big time - * on Intel x86 Core2, in both 32-bit and 64-bit modes - * (less than 1 MB/s instead of 55 MB/s on x86-64). - * Unrolling two rounds appears to be fine. - */ - for (int j = 0; j < 24; j += 2) { + /* + * Unrolling four rounds kills performance big time + * on Intel x86 Core2, in both 32-bit and 64-bit modes + * (less than 1 MB/s instead of 55 MB/s on x86-64). + * Unrolling two rounds appears to be fine. + */ + for (int j = 0; j < 24; j += 2) { - tt0 = A[1] ^ A[6]; - tt1 = A[11] ^ A[16]; - tt0 ^= A[21] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[4] ^ A[9]; - tt3 = A[14] ^ A[19]; - tt0 ^= A[24]; - tt2 ^= tt3; - t0 = tt0 ^ tt2; + tt0 = A[1] ^ A[6]; + tt1 = A[11] ^ A[16]; + tt0 ^= A[21] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[4] ^ A[9]; + tt3 = A[14] ^ A[19]; + tt0 ^= A[24]; + tt2 ^= tt3; + t0 = tt0 ^ tt2; - tt0 = A[2] ^ A[7]; - tt1 = A[12] ^ A[17]; - tt0 ^= A[22] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[0] ^ A[5]; - tt3 = A[10] ^ A[15]; - tt0 ^= A[20]; - tt2 ^= tt3; - t1 = tt0 ^ tt2; + tt0 = A[2] ^ A[7]; + tt1 = A[12] ^ A[17]; + tt0 ^= A[22] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[0] ^ A[5]; + tt3 = A[10] ^ A[15]; + tt0 ^= A[20]; + tt2 ^= tt3; + t1 = tt0 ^ tt2; - tt0 = A[3] ^ A[8]; - tt1 = A[13] ^ A[18]; - tt0 ^= A[23] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[1] ^ A[6]; - tt3 = A[11] ^ A[16]; - tt0 ^= A[21]; - tt2 ^= tt3; - t2 = tt0 ^ tt2; + tt0 = A[3] ^ A[8]; + tt1 = A[13] ^ A[18]; + tt0 ^= A[23] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[1] ^ A[6]; + tt3 = A[11] ^ A[16]; + tt0 ^= A[21]; + tt2 ^= tt3; + t2 = tt0 ^ tt2; - tt0 = A[4] ^ A[9]; - tt1 = A[14] ^ A[19]; - tt0 ^= A[24] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[2] ^ A[7]; - tt3 = A[12] ^ A[17]; - tt0 ^= A[22]; - tt2 ^= tt3; - t3 = tt0 ^ tt2; + tt0 = A[4] ^ A[9]; + tt1 = A[14] ^ A[19]; + tt0 ^= A[24] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[2] ^ A[7]; + tt3 = A[12] ^ A[17]; + tt0 ^= A[22]; + tt2 ^= tt3; + t3 = tt0 ^ tt2; - tt0 = A[0] ^ A[5]; - tt1 = A[10] ^ A[15]; - tt0 ^= A[20] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[3] ^ A[8]; - tt3 = A[13] ^ A[18]; - tt0 ^= A[23]; - tt2 ^= tt3; - t4 = tt0 ^ tt2; + tt0 = A[0] ^ A[5]; + tt1 = A[10] ^ A[15]; + tt0 ^= A[20] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[3] ^ A[8]; + tt3 = A[13] ^ A[18]; + tt0 ^= A[23]; + tt2 ^= tt3; + t4 = tt0 ^ tt2; - A[0] = A[0] ^ t0; - A[5] = A[5] ^ t0; - A[10] = A[10] ^ t0; - A[15] = A[15] ^ t0; - A[20] = A[20] ^ t0; - A[1] = A[1] ^ t1; - A[6] = A[6] ^ t1; - A[11] = A[11] ^ t1; - A[16] = A[16] ^ t1; - A[21] = A[21] ^ t1; - A[2] = A[2] ^ t2; - A[7] = A[7] ^ t2; - A[12] = A[12] ^ t2; - A[17] = A[17] ^ t2; - A[22] = A[22] ^ t2; - A[3] = A[3] ^ t3; - A[8] = A[8] ^ t3; - A[13] = A[13] ^ t3; - A[18] = A[18] ^ t3; - A[23] = A[23] ^ t3; - A[4] = A[4] ^ t4; - A[9] = A[9] ^ t4; - A[14] = A[14] ^ t4; - A[19] = A[19] ^ t4; - A[24] = A[24] ^ t4; - A[5] = (A[5] << 36) | (A[5] >>> (64 - 36)); - A[10] = (A[10] << 3) | (A[10] >>> (64 - 3)); - A[15] = (A[15] << 41) | (A[15] >>> (64 - 41)); - A[20] = (A[20] << 18) | (A[20] >>> (64 - 18)); - A[1] = (A[1] << 1) | (A[1] >>> (64 - 1)); - A[6] = (A[6] << 44) | (A[6] >>> (64 - 44)); - A[11] = (A[11] << 10) | (A[11] >>> (64 - 10)); - A[16] = (A[16] << 45) | (A[16] >>> (64 - 45)); - A[21] = (A[21] << 2) | (A[21] >>> (64 - 2)); - A[2] = (A[2] << 62) | (A[2] >>> (64 - 62)); - A[7] = (A[7] << 6) | (A[7] >>> (64 - 6)); - A[12] = (A[12] << 43) | (A[12] >>> (64 - 43)); - A[17] = (A[17] << 15) | (A[17] >>> (64 - 15)); - A[22] = (A[22] << 61) | (A[22] >>> (64 - 61)); - A[3] = (A[3] << 28) | (A[3] >>> (64 - 28)); - A[8] = (A[8] << 55) | (A[8] >>> (64 - 55)); - A[13] = (A[13] << 25) | (A[13] >>> (64 - 25)); - A[18] = (A[18] << 21) | (A[18] >>> (64 - 21)); - A[23] = (A[23] << 56) | (A[23] >>> (64 - 56)); - A[4] = (A[4] << 27) | (A[4] >>> (64 - 27)); - A[9] = (A[9] << 20) | (A[9] >>> (64 - 20)); - A[14] = (A[14] << 39) | (A[14] >>> (64 - 39)); - A[19] = (A[19] << 8) | (A[19] >>> (64 - 8)); - A[24] = (A[24] << 14) | (A[24] >>> (64 - 14)); - bnn = ~A[12]; - kt = A[6] | A[12]; - c0 = A[0] ^ kt; - kt = bnn | A[18]; - c1 = A[6] ^ kt; - kt = A[18] & A[24]; - c2 = A[12] ^ kt; - kt = A[24] | A[0]; - c3 = A[18] ^ kt; - kt = A[0] & A[6]; - c4 = A[24] ^ kt; - A[0] = c0; - A[6] = c1; - A[12] = c2; - A[18] = c3; - A[24] = c4; - bnn = ~A[22]; - kt = A[9] | A[10]; - c0 = A[3] ^ kt; - kt = A[10] & A[16]; - c1 = A[9] ^ kt; - kt = A[16] | bnn; - c2 = A[10] ^ kt; - kt = A[22] | A[3]; - c3 = A[16] ^ kt; - kt = A[3] & A[9]; - c4 = A[22] ^ kt; - A[3] = c0; - A[9] = c1; - A[10] = c2; - A[16] = c3; - A[22] = c4; - bnn = ~A[19]; - kt = A[7] | A[13]; - c0 = A[1] ^ kt; - kt = A[13] & A[19]; - c1 = A[7] ^ kt; - kt = bnn & A[20]; - c2 = A[13] ^ kt; - kt = A[20] | A[1]; - c3 = bnn ^ kt; - kt = A[1] & A[7]; - c4 = A[20] ^ kt; - A[1] = c0; - A[7] = c1; - A[13] = c2; - A[19] = c3; - A[20] = c4; - bnn = ~A[17]; - kt = A[5] & A[11]; - c0 = A[4] ^ kt; - kt = A[11] | A[17]; - c1 = A[5] ^ kt; - kt = bnn | A[23]; - c2 = A[11] ^ kt; - kt = A[23] & A[4]; - c3 = bnn ^ kt; - kt = A[4] | A[5]; - c4 = A[23] ^ kt; - A[4] = c0; - A[5] = c1; - A[11] = c2; - A[17] = c3; - A[23] = c4; - bnn = ~A[8]; - kt = bnn & A[14]; - c0 = A[2] ^ kt; - kt = A[14] | A[15]; - c1 = bnn ^ kt; - kt = A[15] & A[21]; - c2 = A[14] ^ kt; - kt = A[21] | A[2]; - c3 = A[15] ^ kt; - kt = A[2] & A[8]; - c4 = A[21] ^ kt; - A[2] = c0; - A[8] = c1; - A[14] = c2; - A[15] = c3; - A[21] = c4; - A[0] = A[0] ^ RC[j + 0]; + A[0] = A[0] ^ t0; + A[5] = A[5] ^ t0; + A[10] = A[10] ^ t0; + A[15] = A[15] ^ t0; + A[20] = A[20] ^ t0; + A[1] = A[1] ^ t1; + A[6] = A[6] ^ t1; + A[11] = A[11] ^ t1; + A[16] = A[16] ^ t1; + A[21] = A[21] ^ t1; + A[2] = A[2] ^ t2; + A[7] = A[7] ^ t2; + A[12] = A[12] ^ t2; + A[17] = A[17] ^ t2; + A[22] = A[22] ^ t2; + A[3] = A[3] ^ t3; + A[8] = A[8] ^ t3; + A[13] = A[13] ^ t3; + A[18] = A[18] ^ t3; + A[23] = A[23] ^ t3; + A[4] = A[4] ^ t4; + A[9] = A[9] ^ t4; + A[14] = A[14] ^ t4; + A[19] = A[19] ^ t4; + A[24] = A[24] ^ t4; + A[5] = (A[5] << 36) | (A[5] >>> (64 - 36)); + A[10] = (A[10] << 3) | (A[10] >>> (64 - 3)); + A[15] = (A[15] << 41) | (A[15] >>> (64 - 41)); + A[20] = (A[20] << 18) | (A[20] >>> (64 - 18)); + A[1] = (A[1] << 1) | (A[1] >>> (64 - 1)); + A[6] = (A[6] << 44) | (A[6] >>> (64 - 44)); + A[11] = (A[11] << 10) | (A[11] >>> (64 - 10)); + A[16] = (A[16] << 45) | (A[16] >>> (64 - 45)); + A[21] = (A[21] << 2) | (A[21] >>> (64 - 2)); + A[2] = (A[2] << 62) | (A[2] >>> (64 - 62)); + A[7] = (A[7] << 6) | (A[7] >>> (64 - 6)); + A[12] = (A[12] << 43) | (A[12] >>> (64 - 43)); + A[17] = (A[17] << 15) | (A[17] >>> (64 - 15)); + A[22] = (A[22] << 61) | (A[22] >>> (64 - 61)); + A[3] = (A[3] << 28) | (A[3] >>> (64 - 28)); + A[8] = (A[8] << 55) | (A[8] >>> (64 - 55)); + A[13] = (A[13] << 25) | (A[13] >>> (64 - 25)); + A[18] = (A[18] << 21) | (A[18] >>> (64 - 21)); + A[23] = (A[23] << 56) | (A[23] >>> (64 - 56)); + A[4] = (A[4] << 27) | (A[4] >>> (64 - 27)); + A[9] = (A[9] << 20) | (A[9] >>> (64 - 20)); + A[14] = (A[14] << 39) | (A[14] >>> (64 - 39)); + A[19] = (A[19] << 8) | (A[19] >>> (64 - 8)); + A[24] = (A[24] << 14) | (A[24] >>> (64 - 14)); + bnn = ~A[12]; + kt = A[6] | A[12]; + c0 = A[0] ^ kt; + kt = bnn | A[18]; + c1 = A[6] ^ kt; + kt = A[18] & A[24]; + c2 = A[12] ^ kt; + kt = A[24] | A[0]; + c3 = A[18] ^ kt; + kt = A[0] & A[6]; + c4 = A[24] ^ kt; + A[0] = c0; + A[6] = c1; + A[12] = c2; + A[18] = c3; + A[24] = c4; + bnn = ~A[22]; + kt = A[9] | A[10]; + c0 = A[3] ^ kt; + kt = A[10] & A[16]; + c1 = A[9] ^ kt; + kt = A[16] | bnn; + c2 = A[10] ^ kt; + kt = A[22] | A[3]; + c3 = A[16] ^ kt; + kt = A[3] & A[9]; + c4 = A[22] ^ kt; + A[3] = c0; + A[9] = c1; + A[10] = c2; + A[16] = c3; + A[22] = c4; + bnn = ~A[19]; + kt = A[7] | A[13]; + c0 = A[1] ^ kt; + kt = A[13] & A[19]; + c1 = A[7] ^ kt; + kt = bnn & A[20]; + c2 = A[13] ^ kt; + kt = A[20] | A[1]; + c3 = bnn ^ kt; + kt = A[1] & A[7]; + c4 = A[20] ^ kt; + A[1] = c0; + A[7] = c1; + A[13] = c2; + A[19] = c3; + A[20] = c4; + bnn = ~A[17]; + kt = A[5] & A[11]; + c0 = A[4] ^ kt; + kt = A[11] | A[17]; + c1 = A[5] ^ kt; + kt = bnn | A[23]; + c2 = A[11] ^ kt; + kt = A[23] & A[4]; + c3 = bnn ^ kt; + kt = A[4] | A[5]; + c4 = A[23] ^ kt; + A[4] = c0; + A[5] = c1; + A[11] = c2; + A[17] = c3; + A[23] = c4; + bnn = ~A[8]; + kt = bnn & A[14]; + c0 = A[2] ^ kt; + kt = A[14] | A[15]; + c1 = bnn ^ kt; + kt = A[15] & A[21]; + c2 = A[14] ^ kt; + kt = A[21] | A[2]; + c3 = A[15] ^ kt; + kt = A[2] & A[8]; + c4 = A[21] ^ kt; + A[2] = c0; + A[8] = c1; + A[14] = c2; + A[15] = c3; + A[21] = c4; + A[0] = A[0] ^ RC[j + 0]; - tt0 = A[6] ^ A[9]; - tt1 = A[7] ^ A[5]; - tt0 ^= A[8] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[24] ^ A[22]; - tt3 = A[20] ^ A[23]; - tt0 ^= A[21]; - tt2 ^= tt3; - t0 = tt0 ^ tt2; + tt0 = A[6] ^ A[9]; + tt1 = A[7] ^ A[5]; + tt0 ^= A[8] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[24] ^ A[22]; + tt3 = A[20] ^ A[23]; + tt0 ^= A[21]; + tt2 ^= tt3; + t0 = tt0 ^ tt2; - tt0 = A[12] ^ A[10]; - tt1 = A[13] ^ A[11]; - tt0 ^= A[14] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[0] ^ A[3]; - tt3 = A[1] ^ A[4]; - tt0 ^= A[2]; - tt2 ^= tt3; - t1 = tt0 ^ tt2; + tt0 = A[12] ^ A[10]; + tt1 = A[13] ^ A[11]; + tt0 ^= A[14] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[0] ^ A[3]; + tt3 = A[1] ^ A[4]; + tt0 ^= A[2]; + tt2 ^= tt3; + t1 = tt0 ^ tt2; - tt0 = A[18] ^ A[16]; - tt1 = A[19] ^ A[17]; - tt0 ^= A[15] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[6] ^ A[9]; - tt3 = A[7] ^ A[5]; - tt0 ^= A[8]; - tt2 ^= tt3; - t2 = tt0 ^ tt2; + tt0 = A[18] ^ A[16]; + tt1 = A[19] ^ A[17]; + tt0 ^= A[15] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[6] ^ A[9]; + tt3 = A[7] ^ A[5]; + tt0 ^= A[8]; + tt2 ^= tt3; + t2 = tt0 ^ tt2; - tt0 = A[24] ^ A[22]; - tt1 = A[20] ^ A[23]; - tt0 ^= A[21] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[12] ^ A[10]; - tt3 = A[13] ^ A[11]; - tt0 ^= A[14]; - tt2 ^= tt3; - t3 = tt0 ^ tt2; + tt0 = A[24] ^ A[22]; + tt1 = A[20] ^ A[23]; + tt0 ^= A[21] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[12] ^ A[10]; + tt3 = A[13] ^ A[11]; + tt0 ^= A[14]; + tt2 ^= tt3; + t3 = tt0 ^ tt2; - tt0 = A[0] ^ A[3]; - tt1 = A[1] ^ A[4]; - tt0 ^= A[2] ^ tt1; - tt0 = (tt0 << 1) | (tt0 >>> 63); - tt2 = A[18] ^ A[16]; - tt3 = A[19] ^ A[17]; - tt0 ^= A[15]; - tt2 ^= tt3; - t4 = tt0 ^ tt2; + tt0 = A[0] ^ A[3]; + tt1 = A[1] ^ A[4]; + tt0 ^= A[2] ^ tt1; + tt0 = (tt0 << 1) | (tt0 >>> 63); + tt2 = A[18] ^ A[16]; + tt3 = A[19] ^ A[17]; + tt0 ^= A[15]; + tt2 ^= tt3; + t4 = tt0 ^ tt2; - A[0] = A[0] ^ t0; - A[3] = A[3] ^ t0; - A[1] = A[1] ^ t0; - A[4] = A[4] ^ t0; - A[2] = A[2] ^ t0; - A[6] = A[6] ^ t1; - A[9] = A[9] ^ t1; - A[7] = A[7] ^ t1; - A[5] = A[5] ^ t1; - A[8] = A[8] ^ t1; - A[12] = A[12] ^ t2; - A[10] = A[10] ^ t2; - A[13] = A[13] ^ t2; - A[11] = A[11] ^ t2; - A[14] = A[14] ^ t2; - A[18] = A[18] ^ t3; - A[16] = A[16] ^ t3; - A[19] = A[19] ^ t3; - A[17] = A[17] ^ t3; - A[15] = A[15] ^ t3; - A[24] = A[24] ^ t4; - A[22] = A[22] ^ t4; - A[20] = A[20] ^ t4; - A[23] = A[23] ^ t4; - A[21] = A[21] ^ t4; - A[3] = (A[3] << 36) | (A[3] >>> (64 - 36)); - A[1] = (A[1] << 3) | (A[1] >>> (64 - 3)); - A[4] = (A[4] << 41) | (A[4] >>> (64 - 41)); - A[2] = (A[2] << 18) | (A[2] >>> (64 - 18)); - A[6] = (A[6] << 1) | (A[6] >>> (64 - 1)); - A[9] = (A[9] << 44) | (A[9] >>> (64 - 44)); - A[7] = (A[7] << 10) | (A[7] >>> (64 - 10)); - A[5] = (A[5] << 45) | (A[5] >>> (64 - 45)); - A[8] = (A[8] << 2) | (A[8] >>> (64 - 2)); - A[12] = (A[12] << 62) | (A[12] >>> (64 - 62)); - A[10] = (A[10] << 6) | (A[10] >>> (64 - 6)); - A[13] = (A[13] << 43) | (A[13] >>> (64 - 43)); - A[11] = (A[11] << 15) | (A[11] >>> (64 - 15)); - A[14] = (A[14] << 61) | (A[14] >>> (64 - 61)); - A[18] = (A[18] << 28) | (A[18] >>> (64 - 28)); - A[16] = (A[16] << 55) | (A[16] >>> (64 - 55)); - A[19] = (A[19] << 25) | (A[19] >>> (64 - 25)); - A[17] = (A[17] << 21) | (A[17] >>> (64 - 21)); - A[15] = (A[15] << 56) | (A[15] >>> (64 - 56)); - A[24] = (A[24] << 27) | (A[24] >>> (64 - 27)); - A[22] = (A[22] << 20) | (A[22] >>> (64 - 20)); - A[20] = (A[20] << 39) | (A[20] >>> (64 - 39)); - A[23] = (A[23] << 8) | (A[23] >>> (64 - 8)); - A[21] = (A[21] << 14) | (A[21] >>> (64 - 14)); - bnn = ~A[13]; - kt = A[9] | A[13]; - c0 = A[0] ^ kt; - kt = bnn | A[17]; - c1 = A[9] ^ kt; - kt = A[17] & A[21]; - c2 = A[13] ^ kt; - kt = A[21] | A[0]; - c3 = A[17] ^ kt; - kt = A[0] & A[9]; - c4 = A[21] ^ kt; - A[0] = c0; - A[9] = c1; - A[13] = c2; - A[17] = c3; - A[21] = c4; - bnn = ~A[14]; - kt = A[22] | A[1]; - c0 = A[18] ^ kt; - kt = A[1] & A[5]; - c1 = A[22] ^ kt; - kt = A[5] | bnn; - c2 = A[1] ^ kt; - kt = A[14] | A[18]; - c3 = A[5] ^ kt; - kt = A[18] & A[22]; - c4 = A[14] ^ kt; - A[18] = c0; - A[22] = c1; - A[1] = c2; - A[5] = c3; - A[14] = c4; - bnn = ~A[23]; - kt = A[10] | A[19]; - c0 = A[6] ^ kt; - kt = A[19] & A[23]; - c1 = A[10] ^ kt; - kt = bnn & A[2]; - c2 = A[19] ^ kt; - kt = A[2] | A[6]; - c3 = bnn ^ kt; - kt = A[6] & A[10]; - c4 = A[2] ^ kt; - A[6] = c0; - A[10] = c1; - A[19] = c2; - A[23] = c3; - A[2] = c4; - bnn = ~A[11]; - kt = A[3] & A[7]; - c0 = A[24] ^ kt; - kt = A[7] | A[11]; - c1 = A[3] ^ kt; - kt = bnn | A[15]; - c2 = A[7] ^ kt; - kt = A[15] & A[24]; - c3 = bnn ^ kt; - kt = A[24] | A[3]; - c4 = A[15] ^ kt; - A[24] = c0; - A[3] = c1; - A[7] = c2; - A[11] = c3; - A[15] = c4; - bnn = ~A[16]; - kt = bnn & A[20]; - c0 = A[12] ^ kt; - kt = A[20] | A[4]; - c1 = bnn ^ kt; - kt = A[4] & A[8]; - c2 = A[20] ^ kt; - kt = A[8] | A[12]; - c3 = A[4] ^ kt; - kt = A[12] & A[16]; - c4 = A[8] ^ kt; - A[12] = c0; - A[16] = c1; - A[20] = c2; - A[4] = c3; - A[8] = c4; - A[0] = A[0] ^ RC[j + 1]; - t = A[5]; - A[5] = A[18]; - A[18] = A[11]; - A[11] = A[10]; - A[10] = A[6]; - A[6] = A[22]; - A[22] = A[20]; - A[20] = A[12]; - A[12] = A[19]; - A[19] = A[15]; - A[15] = A[24]; - A[24] = A[8]; - A[8] = t; - t = A[1]; - A[1] = A[9]; - A[9] = A[14]; - A[14] = A[2]; - A[2] = A[13]; - A[13] = A[23]; - A[23] = A[4]; - A[4] = A[21]; - A[21] = A[16]; - A[16] = A[3]; - A[3] = A[17]; - A[17] = A[7]; - A[7] = t; - } + A[0] = A[0] ^ t0; + A[3] = A[3] ^ t0; + A[1] = A[1] ^ t0; + A[4] = A[4] ^ t0; + A[2] = A[2] ^ t0; + A[6] = A[6] ^ t1; + A[9] = A[9] ^ t1; + A[7] = A[7] ^ t1; + A[5] = A[5] ^ t1; + A[8] = A[8] ^ t1; + A[12] = A[12] ^ t2; + A[10] = A[10] ^ t2; + A[13] = A[13] ^ t2; + A[11] = A[11] ^ t2; + A[14] = A[14] ^ t2; + A[18] = A[18] ^ t3; + A[16] = A[16] ^ t3; + A[19] = A[19] ^ t3; + A[17] = A[17] ^ t3; + A[15] = A[15] ^ t3; + A[24] = A[24] ^ t4; + A[22] = A[22] ^ t4; + A[20] = A[20] ^ t4; + A[23] = A[23] ^ t4; + A[21] = A[21] ^ t4; + A[3] = (A[3] << 36) | (A[3] >>> (64 - 36)); + A[1] = (A[1] << 3) | (A[1] >>> (64 - 3)); + A[4] = (A[4] << 41) | (A[4] >>> (64 - 41)); + A[2] = (A[2] << 18) | (A[2] >>> (64 - 18)); + A[6] = (A[6] << 1) | (A[6] >>> (64 - 1)); + A[9] = (A[9] << 44) | (A[9] >>> (64 - 44)); + A[7] = (A[7] << 10) | (A[7] >>> (64 - 10)); + A[5] = (A[5] << 45) | (A[5] >>> (64 - 45)); + A[8] = (A[8] << 2) | (A[8] >>> (64 - 2)); + A[12] = (A[12] << 62) | (A[12] >>> (64 - 62)); + A[10] = (A[10] << 6) | (A[10] >>> (64 - 6)); + A[13] = (A[13] << 43) | (A[13] >>> (64 - 43)); + A[11] = (A[11] << 15) | (A[11] >>> (64 - 15)); + A[14] = (A[14] << 61) | (A[14] >>> (64 - 61)); + A[18] = (A[18] << 28) | (A[18] >>> (64 - 28)); + A[16] = (A[16] << 55) | (A[16] >>> (64 - 55)); + A[19] = (A[19] << 25) | (A[19] >>> (64 - 25)); + A[17] = (A[17] << 21) | (A[17] >>> (64 - 21)); + A[15] = (A[15] << 56) | (A[15] >>> (64 - 56)); + A[24] = (A[24] << 27) | (A[24] >>> (64 - 27)); + A[22] = (A[22] << 20) | (A[22] >>> (64 - 20)); + A[20] = (A[20] << 39) | (A[20] >>> (64 - 39)); + A[23] = (A[23] << 8) | (A[23] >>> (64 - 8)); + A[21] = (A[21] << 14) | (A[21] >>> (64 - 14)); + bnn = ~A[13]; + kt = A[9] | A[13]; + c0 = A[0] ^ kt; + kt = bnn | A[17]; + c1 = A[9] ^ kt; + kt = A[17] & A[21]; + c2 = A[13] ^ kt; + kt = A[21] | A[0]; + c3 = A[17] ^ kt; + kt = A[0] & A[9]; + c4 = A[21] ^ kt; + A[0] = c0; + A[9] = c1; + A[13] = c2; + A[17] = c3; + A[21] = c4; + bnn = ~A[14]; + kt = A[22] | A[1]; + c0 = A[18] ^ kt; + kt = A[1] & A[5]; + c1 = A[22] ^ kt; + kt = A[5] | bnn; + c2 = A[1] ^ kt; + kt = A[14] | A[18]; + c3 = A[5] ^ kt; + kt = A[18] & A[22]; + c4 = A[14] ^ kt; + A[18] = c0; + A[22] = c1; + A[1] = c2; + A[5] = c3; + A[14] = c4; + bnn = ~A[23]; + kt = A[10] | A[19]; + c0 = A[6] ^ kt; + kt = A[19] & A[23]; + c1 = A[10] ^ kt; + kt = bnn & A[2]; + c2 = A[19] ^ kt; + kt = A[2] | A[6]; + c3 = bnn ^ kt; + kt = A[6] & A[10]; + c4 = A[2] ^ kt; + A[6] = c0; + A[10] = c1; + A[19] = c2; + A[23] = c3; + A[2] = c4; + bnn = ~A[11]; + kt = A[3] & A[7]; + c0 = A[24] ^ kt; + kt = A[7] | A[11]; + c1 = A[3] ^ kt; + kt = bnn | A[15]; + c2 = A[7] ^ kt; + kt = A[15] & A[24]; + c3 = bnn ^ kt; + kt = A[24] | A[3]; + c4 = A[15] ^ kt; + A[24] = c0; + A[3] = c1; + A[7] = c2; + A[11] = c3; + A[15] = c4; + bnn = ~A[16]; + kt = bnn & A[20]; + c0 = A[12] ^ kt; + kt = A[20] | A[4]; + c1 = bnn ^ kt; + kt = A[4] & A[8]; + c2 = A[20] ^ kt; + kt = A[8] | A[12]; + c3 = A[4] ^ kt; + kt = A[12] & A[16]; + c4 = A[8] ^ kt; + A[12] = c0; + A[16] = c1; + A[20] = c2; + A[4] = c3; + A[8] = c4; + A[0] = A[0] ^ RC[j + 1]; + t = A[5]; + A[5] = A[18]; + A[18] = A[11]; + A[11] = A[10]; + A[10] = A[6]; + A[6] = A[22]; + A[22] = A[20]; + A[20] = A[12]; + A[12] = A[19]; + A[19] = A[15]; + A[15] = A[24]; + A[24] = A[8]; + A[8] = t; + t = A[1]; + A[1] = A[9]; + A[9] = A[14]; + A[14] = A[2]; + A[2] = A[13]; + A[13] = A[23]; + A[23] = A[4]; + A[4] = A[21]; + A[21] = A[16]; + A[16] = A[3]; + A[3] = A[17]; + A[17] = A[7]; + A[7] = t; } + } - protected void doPadding(byte[] out, int off) { - int ptr = flush(); - byte[] buf = getBlockBuffer(); - if ((ptr + 1) == buf.length) { - buf[ptr] = (byte) 0x81; - } else { - buf[ptr] = (byte) 0x01; - for (int i = ptr + 1; i < (buf.length - 1); i++) { - buf[i] = 0; - } - buf[buf.length - 1] = (byte) 0x80; - } - processBlock(buf); - A[1] = ~A[1]; - A[2] = ~A[2]; - A[8] = ~A[8]; - A[12] = ~A[12]; - A[17] = ~A[17]; - A[20] = ~A[20]; - int dlen = engineGetDigestLength(); - for (int i = 0; i < dlen; i += 8) { - encodeLELong(A[i >>> 3], tmpOut, i); - } - System.arraycopy(tmpOut, 0, out, off, dlen); + protected void doPadding(byte[] out, int off) { + int ptr = flush(); + byte[] buf = getBlockBuffer(); + if ((ptr + 1) == buf.length) { + buf[ptr] = (byte) 0x81; + } else { + buf[ptr] = (byte) 0x01; + for (int i = ptr + 1; i < (buf.length - 1); i++) { + buf[i] = 0; + } + buf[buf.length - 1] = (byte) 0x80; } - - protected void doInit() { - A = new long[25]; - tmpOut = new byte[(engineGetDigestLength() + 7) & ~7]; - doReset(); + processBlock(buf); + A[1] = ~A[1]; + A[2] = ~A[2]; + A[8] = ~A[8]; + A[12] = ~A[12]; + A[17] = ~A[17]; + A[20] = ~A[20]; + int dlen = engineGetDigestLength(); + for (int i = 0; i < dlen; i += 8) { + encodeLELong(A[i >>> 3], tmpOut, i); } + System.arraycopy(tmpOut, 0, out, off, dlen); + } - public int getBlockLength() { - return 200 - 2 * engineGetDigestLength(); - } + protected void doInit() { + A = new long[25]; + tmpOut = new byte[(engineGetDigestLength() + 7) & ~7]; + doReset(); + } - private final void doReset() { - for (int i = 0; i < 25; i++) { - A[i] = 0; - } - A[1] = 0xFFFFFFFFFFFFFFFFL; - A[2] = 0xFFFFFFFFFFFFFFFFL; - A[8] = 0xFFFFFFFFFFFFFFFFL; - A[12] = 0xFFFFFFFFFFFFFFFFL; - A[17] = 0xFFFFFFFFFFFFFFFFL; - A[20] = 0xFFFFFFFFFFFFFFFFL; - } + public int getBlockLength() { + return 200 - 2 * engineGetDigestLength(); + } - protected Digest copyState(KeccakCore dst) { - System.arraycopy(A, 0, dst.A, 0, 25); - return super.copyState(dst); + private final void doReset() { + for (int i = 0; i < 25; i++) { + A[i] = 0; } + A[1] = 0xFFFFFFFFFFFFFFFFL; + A[2] = 0xFFFFFFFFFFFFFFFFL; + A[8] = 0xFFFFFFFFFFFFFFFFL; + A[12] = 0xFFFFFFFFFFFFFFFFL; + A[17] = 0xFFFFFFFFFFFFFFFFL; + A[20] = 0xFFFFFFFFFFFFFFFFL; + } - public String toString() { - return "Keccak-" + (engineGetDigestLength() << 3); - } + protected Digest copyState(KeccakCore dst) { + System.arraycopy(A, 0, dst.A, 0, 25); + return super.copyState(dst); + } + + public String toString() { + return "Keccak-" + (engineGetDigestLength() << 3); + } } diff --git a/src/main/java/org/tron/common/crypto/jce/ECAlgorithmParameters.java b/src/main/java/org/tron/common/crypto/jce/ECAlgorithmParameters.java index 4a1a5a0058a..82794754e93 100644 --- a/src/main/java/org/tron/common/crypto/jce/ECAlgorithmParameters.java +++ b/src/main/java/org/tron/common/crypto/jce/ECAlgorithmParameters.java @@ -27,47 +27,48 @@ public final class ECAlgorithmParameters { - public static final String ALGORITHM = "EC"; - public static final String CURVE_NAME = "secp256k1"; + public static final String ALGORITHM = "EC"; + public static final String CURVE_NAME = "secp256k1"; - private ECAlgorithmParameters() { - } + private ECAlgorithmParameters() { + } - public static ECParameterSpec getParameterSpec() { - try { - return Holder.INSTANCE.getParameterSpec(ECParameterSpec.class); - } catch (InvalidParameterSpecException ex) { - throw new AssertionError( - "Assumed correct key spec statically", ex); - } + public static ECParameterSpec getParameterSpec() { + try { + return Holder.INSTANCE.getParameterSpec(ECParameterSpec.class); + } catch (InvalidParameterSpecException ex) { + throw new AssertionError( + "Assumed correct key spec statically", ex); } + } - public static byte[] getASN1Encoding() { - try { - return Holder.INSTANCE.getEncoded(); - } catch (IOException ex) { - throw new AssertionError( - "Assumed algo params has been initialized", ex); - } + public static byte[] getASN1Encoding() { + try { + return Holder.INSTANCE.getEncoded(); + } catch (IOException ex) { + throw new AssertionError( + "Assumed algo params has been initialized", ex); } + } + + private static class Holder { - private static class Holder { - private static final AlgorithmParameters INSTANCE; + private static final AlgorithmParameters INSTANCE; - private static final ECGenParameterSpec SECP256K1_CURVE - = new ECGenParameterSpec(CURVE_NAME); + private static final ECGenParameterSpec SECP256K1_CURVE + = new ECGenParameterSpec(CURVE_NAME); - static { - try { - INSTANCE = AlgorithmParameters.getInstance(ALGORITHM); - INSTANCE.init(SECP256K1_CURVE); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError( - "Assumed the JRE supports EC algorithm params", ex); - } catch (InvalidParameterSpecException ex) { - throw new AssertionError( - "Assumed correct key spec statically", ex); - } - } + static { + try { + INSTANCE = AlgorithmParameters.getInstance(ALGORITHM); + INSTANCE.init(SECP256K1_CURVE); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError( + "Assumed the JRE supports EC algorithm params", ex); + } catch (InvalidParameterSpecException ex) { + throw new AssertionError( + "Assumed correct key spec statically", ex); + } } + } } diff --git a/src/main/java/org/tron/common/crypto/jce/ECKeyAgreement.java b/src/main/java/org/tron/common/crypto/jce/ECKeyAgreement.java index ec0f384c447..ef94579cbf8 100644 --- a/src/main/java/org/tron/common/crypto/jce/ECKeyAgreement.java +++ b/src/main/java/org/tron/common/crypto/jce/ECKeyAgreement.java @@ -18,43 +18,43 @@ package org.tron.common.crypto.jce; -import javax.crypto.KeyAgreement; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; +import javax.crypto.KeyAgreement; public final class ECKeyAgreement { - public static final String ALGORITHM = "ECDH"; + public static final String ALGORITHM = "ECDH"; - private static final String algorithmAssertionMsg = - "Assumed the JRE supports EC key agreement"; + private static final String algorithmAssertionMsg = + "Assumed the JRE supports EC key agreement"; - private ECKeyAgreement() { - } + private ECKeyAgreement() { + } - public static KeyAgreement getInstance() { - try { - return KeyAgreement.getInstance(ALGORITHM); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(algorithmAssertionMsg, ex); - } + public static KeyAgreement getInstance() { + try { + return KeyAgreement.getInstance(ALGORITHM); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(algorithmAssertionMsg, ex); } - - public static KeyAgreement getInstance(final String provider) throws - NoSuchProviderException { - try { - return KeyAgreement.getInstance(ALGORITHM, provider); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(algorithmAssertionMsg, ex); - } + } + + public static KeyAgreement getInstance(final String provider) throws + NoSuchProviderException { + try { + return KeyAgreement.getInstance(ALGORITHM, provider); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(algorithmAssertionMsg, ex); } + } - public static KeyAgreement getInstance(final Provider provider) { - try { - return KeyAgreement.getInstance(ALGORITHM, provider); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(algorithmAssertionMsg, ex); - } + public static KeyAgreement getInstance(final Provider provider) { + try { + return KeyAgreement.getInstance(ALGORITHM, provider); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(algorithmAssertionMsg, ex); } + } } diff --git a/src/main/java/org/tron/common/crypto/jce/ECKeyFactory.java b/src/main/java/org/tron/common/crypto/jce/ECKeyFactory.java index 3b396cc700a..8bae0c2cdd5 100644 --- a/src/main/java/org/tron/common/crypto/jce/ECKeyFactory.java +++ b/src/main/java/org/tron/common/crypto/jce/ECKeyFactory.java @@ -25,44 +25,45 @@ public final class ECKeyFactory { - public static final String ALGORITHM = "EC"; + public static final String ALGORITHM = "EC"; - private static final String algorithmAssertionMsg = - "Assumed the JRE supports EC key factories"; + private static final String algorithmAssertionMsg = + "Assumed the JRE supports EC key factories"; - private ECKeyFactory() { - } + private ECKeyFactory() { + } - public static KeyFactory getInstance() { - return Holder.INSTANCE; - } + public static KeyFactory getInstance() { + return Holder.INSTANCE; + } - public static KeyFactory getInstance(final String provider) throws - NoSuchProviderException { - try { - return KeyFactory.getInstance(ALGORITHM, provider); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(algorithmAssertionMsg, ex); - } + public static KeyFactory getInstance(final String provider) throws + NoSuchProviderException { + try { + return KeyFactory.getInstance(ALGORITHM, provider); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(algorithmAssertionMsg, ex); } + } - public static KeyFactory getInstance(final Provider provider) { - try { - return KeyFactory.getInstance(ALGORITHM, provider); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(algorithmAssertionMsg, ex); - } + public static KeyFactory getInstance(final Provider provider) { + try { + return KeyFactory.getInstance(ALGORITHM, provider); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(algorithmAssertionMsg, ex); } + } + + private static class Holder { - private static class Holder { - private static final KeyFactory INSTANCE; + private static final KeyFactory INSTANCE; - static { - try { - INSTANCE = KeyFactory.getInstance(ALGORITHM); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(algorithmAssertionMsg, ex); - } - } + static { + try { + INSTANCE = KeyFactory.getInstance(ALGORITHM); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(algorithmAssertionMsg, ex); + } } + } } diff --git a/src/main/java/org/tron/common/crypto/jce/ECKeyPairGenerator.java b/src/main/java/org/tron/common/crypto/jce/ECKeyPairGenerator.java index d371539f364..61a5b90faec 100644 --- a/src/main/java/org/tron/common/crypto/jce/ECKeyPairGenerator.java +++ b/src/main/java/org/tron/common/crypto/jce/ECKeyPairGenerator.java @@ -18,70 +18,77 @@ package org.tron.common.crypto.jce; -import java.security.*; +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Provider; +import java.security.SecureRandom; import java.security.spec.ECGenParameterSpec; public final class ECKeyPairGenerator { - public static final String ALGORITHM = "EC"; - public static final String CURVE_NAME = "secp256k1"; + public static final String ALGORITHM = "EC"; + public static final String CURVE_NAME = "secp256k1"; - private static final String algorithmAssertionMsg = - "Assumed JRE supports EC key pair generation"; + private static final String algorithmAssertionMsg = + "Assumed JRE supports EC key pair generation"; - private static final String keySpecAssertionMsg = - "Assumed correct key spec statically"; + private static final String keySpecAssertionMsg = + "Assumed correct key spec statically"; - private static final ECGenParameterSpec SECP256K1_CURVE - = new ECGenParameterSpec(CURVE_NAME); + private static final ECGenParameterSpec SECP256K1_CURVE + = new ECGenParameterSpec(CURVE_NAME); - private ECKeyPairGenerator() { - } + private ECKeyPairGenerator() { + } - public static KeyPair generateKeyPair() { - return Holder.INSTANCE.generateKeyPair(); - } + public static KeyPair generateKeyPair() { + return Holder.INSTANCE.generateKeyPair(); + } - public static KeyPairGenerator getInstance(final String provider, final - SecureRandom random) throws NoSuchProviderException { - try { - final KeyPairGenerator gen = KeyPairGenerator.getInstance - (ALGORITHM, provider); - gen.initialize(SECP256K1_CURVE, random); - return gen; - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(algorithmAssertionMsg, ex); - } catch (InvalidAlgorithmParameterException ex) { - throw new AssertionError(keySpecAssertionMsg, ex); - } + public static KeyPairGenerator getInstance(final String provider, final + SecureRandom random) throws NoSuchProviderException { + try { + final KeyPairGenerator gen = KeyPairGenerator.getInstance + (ALGORITHM, provider); + gen.initialize(SECP256K1_CURVE, random); + return gen; + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(algorithmAssertionMsg, ex); + } catch (InvalidAlgorithmParameterException ex) { + throw new AssertionError(keySpecAssertionMsg, ex); } + } - public static KeyPairGenerator getInstance(final Provider provider, final - SecureRandom random) { - try { - final KeyPairGenerator gen = KeyPairGenerator.getInstance - (ALGORITHM, provider); - gen.initialize(SECP256K1_CURVE, random); - return gen; - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(algorithmAssertionMsg, ex); - } catch (InvalidAlgorithmParameterException ex) { - throw new AssertionError(keySpecAssertionMsg, ex); - } + public static KeyPairGenerator getInstance(final Provider provider, final + SecureRandom random) { + try { + final KeyPairGenerator gen = KeyPairGenerator.getInstance + (ALGORITHM, provider); + gen.initialize(SECP256K1_CURVE, random); + return gen; + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(algorithmAssertionMsg, ex); + } catch (InvalidAlgorithmParameterException ex) { + throw new AssertionError(keySpecAssertionMsg, ex); } + } + + private static class Holder { - private static class Holder { - private static final KeyPairGenerator INSTANCE; + private static final KeyPairGenerator INSTANCE; - static { - try { - INSTANCE = KeyPairGenerator.getInstance(ALGORITHM); - INSTANCE.initialize(SECP256K1_CURVE); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(algorithmAssertionMsg, ex); - } catch (InvalidAlgorithmParameterException ex) { - throw new AssertionError(keySpecAssertionMsg, ex); - } - } + static { + try { + INSTANCE = KeyPairGenerator.getInstance(ALGORITHM); + INSTANCE.initialize(SECP256K1_CURVE); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(algorithmAssertionMsg, ex); + } catch (InvalidAlgorithmParameterException ex) { + throw new AssertionError(keySpecAssertionMsg, ex); + } } + } } diff --git a/src/main/java/org/tron/common/crypto/jce/ECSignatureFactory.java b/src/main/java/org/tron/common/crypto/jce/ECSignatureFactory.java index 5caa7b3f886..9953e0ebf70 100644 --- a/src/main/java/org/tron/common/crypto/jce/ECSignatureFactory.java +++ b/src/main/java/org/tron/common/crypto/jce/ECSignatureFactory.java @@ -25,36 +25,36 @@ public final class ECSignatureFactory { - public static final String RAW_ALGORITHM = "NONEwithECDSA"; + public static final String RAW_ALGORITHM = "NONEwithECDSA"; - private static final String rawAlgorithmAssertionMsg = - "Assumed the JRE supports NONEwithECDSA signatures"; + private static final String rawAlgorithmAssertionMsg = + "Assumed the JRE supports NONEwithECDSA signatures"; - private ECSignatureFactory() { - } + private ECSignatureFactory() { + } - public static Signature getRawInstance() { - try { - return Signature.getInstance(RAW_ALGORITHM); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(rawAlgorithmAssertionMsg, ex); - } + public static Signature getRawInstance() { + try { + return Signature.getInstance(RAW_ALGORITHM); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(rawAlgorithmAssertionMsg, ex); } - - public static Signature getRawInstance(final String provider) throws - NoSuchProviderException { - try { - return Signature.getInstance(RAW_ALGORITHM, provider); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(rawAlgorithmAssertionMsg, ex); - } + } + + public static Signature getRawInstance(final String provider) throws + NoSuchProviderException { + try { + return Signature.getInstance(RAW_ALGORITHM, provider); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(rawAlgorithmAssertionMsg, ex); } + } - public static Signature getRawInstance(final Provider provider) { - try { - return Signature.getInstance(RAW_ALGORITHM, provider); - } catch (NoSuchAlgorithmException ex) { - throw new AssertionError(rawAlgorithmAssertionMsg, ex); - } + public static Signature getRawInstance(final Provider provider) { + try { + return Signature.getInstance(RAW_ALGORITHM, provider); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionError(rawAlgorithmAssertionMsg, ex); } + } } diff --git a/src/main/java/org/tron/common/crypto/jce/TronCastleProvider.java b/src/main/java/org/tron/common/crypto/jce/TronCastleProvider.java index 7639420573e..9132fe2536e 100644 --- a/src/main/java/org/tron/common/crypto/jce/TronCastleProvider.java +++ b/src/main/java/org/tron/common/crypto/jce/TronCastleProvider.java @@ -18,29 +18,29 @@ package org.tron.common.crypto.jce; -import org.spongycastle.jce.provider.BouncyCastleProvider; - import java.security.Provider; import java.security.Security; +import org.spongycastle.jce.provider.BouncyCastleProvider; public final class TronCastleProvider { - public static Provider getInstance() { - return Holder.INSTANCE; - } + public static Provider getInstance() { + return Holder.INSTANCE; + } + + private static class Holder { - private static class Holder { - private static final Provider INSTANCE; + private static final Provider INSTANCE; - static { - Provider p = Security.getProvider("SC"); + static { + Provider p = Security.getProvider("SC"); - INSTANCE = (p != null) ? p : new BouncyCastleProvider(); + INSTANCE = (p != null) ? p : new BouncyCastleProvider(); - INSTANCE.put("MessageDigest.TRON-KECCAK-256", "org.tron.common.crypto" + - ".cryptohash.Keccak256"); - INSTANCE.put("MessageDigest.TRON-KECCAK-512", "org.tron.common.crypto" + - ".cryptohash.Keccak512"); - } + INSTANCE.put("MessageDigest.TRON-KECCAK-256", "org.tron.common.crypto" + + ".cryptohash.Keccak256"); + INSTANCE.put("MessageDigest.TRON-KECCAK-512", "org.tron.common.crypto" + + ".cryptohash.Keccak512"); } + } } diff --git a/src/main/java/org/tron/common/overlay/example/LocalNode.java b/src/main/java/org/tron/common/overlay/example/LocalNode.java deleted file mode 100644 index 935b6d27c92..00000000000 --- a/src/main/java/org/tron/common/overlay/example/LocalNode.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.tron.common.overlay.example; - -import org.apache.gossip.GossipSettings; -import org.apache.gossip.LocalMember; -import org.apache.gossip.Member; -import org.apache.gossip.RemoteMember; -import org.apache.gossip.crdt.OrSet; -import org.apache.gossip.manager.GossipManager; -import org.apache.gossip.manager.GossipManagerBuilder; -import org.apache.gossip.model.SharedDataMessage; -import org.tron.common.overlay.Net; -import org.tron.common.overlay.message.Message; -import org.tron.common.overlay.message.Type; - -import java.net.URI; -import java.util.Collections; -import java.util.List; - -import static org.tron.core.Constant.TOPIC_BLOCK; -import static org.tron.core.Constant.TOPIC_TRANSACTION; - -public class LocalNode implements Net { - public static final String INDEX_KEY_FOR_SET = "block"; - - // is the name of the cluster - private String cluster; - - // is a URI object containing IP/hostname and port to use on the default adapter on the - // node's machine - private String uri; - - // is a unique id for this node(you can use any string) - private String id; - - private GossipManager gossipManager = null; - - public LocalNode(String cluster, String uri, String id) { - setCluster(cluster); - setUri(uri); - setId(id); - - initGossipManager(cluster, uri, id); - initGossipService(); - } - - public static void addData(String val, GossipManager gossipService) { - SharedDataMessage m = new SharedDataMessage(); - m.setExpireAt(Long.MAX_VALUE); - m.setKey(INDEX_KEY_FOR_SET); - m.setPayload(new OrSet
- * try (ALock l = wLock.lock()) {
- * // do smth under lock
- * }
+ * try (ALock l = wLock.lock()) { // do smth under lock }
*/
public final class ALock implements AutoCloseable {
+
private final Lock lock;
public ALock(Lock l) {
diff --git a/src/main/java/org/tron/common/utils/BIUtil.java b/src/main/java/org/tron/common/utils/BIUtil.java
index ff7ac496f34..a4ef55f4538 100644
--- a/src/main/java/org/tron/common/utils/BIUtil.java
+++ b/src/main/java/org/tron/common/utils/BIUtil.java
@@ -15,18 +15,19 @@
* You should have received a copy of the GNU Lesser General Public License
* along with the ethereumJ library. If not, see
- * Example. [ 1, 2, 3, 4, 5 ] becomes '\x11\x23\x45'
+ * Turn nibbles to a pretty looking output string Example. [ 1, 2, 3, 4, 5 ] becomes
+ * '\x11\x23\x45'
*
- * @param nibbles - getting byte of data [ 04 ] and turning
- * it to a '\x04' representation
+ * @param nibbles - getting byte of data [ 04 ] and turning it to a '\x04' representation
* @return pretty string of nibbles
*/
public static String nibblesToPrettyString(byte[] nibbles) {
@@ -138,13 +127,12 @@ public static String oneByteToHexString(byte value) {
}
/**
- * Convert a byte-array into a hex String.
- * Limited to Integer.MAX_VALUE: 2^32-1 (4 bytes)
+ * Cast hex encoded value from byte[] to int Limited to Integer.MAX_VALUE: 2^32-1 (4 bytes)
*
* @param b array contains the values
* @return unsigned positive int value.
diff --git a/src/main/java/org/tron/common/utils/CompactEncoder.java b/src/main/java/org/tron/common/utils/CompactEncoder.java
index dd3754fed40..e59544a3931 100644
--- a/src/main/java/org/tron/common/utils/CompactEncoder.java
+++ b/src/main/java/org/tron/common/utils/CompactEncoder.java
@@ -18,125 +18,125 @@
package org.tron.common.utils;
-import java.io.ByteArrayOutputStream;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
import static java.util.Arrays.copyOf;
import static java.util.Arrays.copyOfRange;
import static org.spongycastle.util.Arrays.concatenate;
import static org.spongycastle.util.encoders.Hex.encode;
import static org.tron.common.utils.ByteUtil.appendByte;
+import java.io.ByteArrayOutputStream;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
public class CompactEncoder {
- private final static byte TERMINATOR = 16;
- private final static Map
- * Instead of
- * {@link org.spongycastle.util.BigIntegers#asUnsignedByteArray(BigInteger)}
- *
we use this custom method to avoid an empty array in case of
- * BigInteger.ZERO
+ * Omitting sign indication byte.
Instead of {@link org.spongycastle.util.BigIntegers#asUnsignedByteArray(BigInteger)}
+ *
we use this custom method to avoid an empty array in case of BigInteger.ZERO
*
- * @param value - any big integer number. A null
-value will
- * return null
- * @return A byte array without a leading zero byte if present in the
- * signed encoding.
+ * @param value - any big integer number. A null
-value will return null
+ * @return A byte array without a leading zero byte if present in the signed encoding.
* BigInteger.ZERO will return an array with length 1 and byte-value 0.
*/
public static byte[] bigIntegerToBytes(BigInteger value) {
@@ -112,12 +103,10 @@ public static byte[] appendByte(byte[] bytes, byte b) {
}
/**
- * Turn nibbles to a pretty looking output string
- *
- * Works similar to {@link Hex#toHexString}
- * but allows for null
+ * Convert a byte-array into a hex String.
Works similar to {@link Hex#toHexString} but allows
+ * for null
*
* @param data - byte-array to convert to a hex-string
- * @return hex representation of the data.
- * Returns an empty String if the input is null
+ * @return hex representation of the data.
Returns an empty String if the input is
+ * null
* @see Hex#toHexString
*/
public static String toHexString(byte[] data) {
@@ -152,9 +140,7 @@ public static String toHexString(byte[] data) {
}
/**
- * Cast hex encoded value from byte[] to int
- *