Overhaul crypto/hash, removed samples and switch to spongycastle

This commit is contained in:
nicksavers 2014-05-04 23:26:06 +02:00
parent bd7ff7d470
commit 348ae7617a
59 changed files with 1540 additions and 12065 deletions

View File

@ -1,100 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>EthereumJ</groupId>
<artifactId>EthereumJ</artifactId>
<version>0.0.1-SNAPSHOT</version>
<repositories>
<repository>
<id>repository.jboss.org</id>
<name>JBoss Releases Repository</name>
<url>http://repository.jboss.org/maven2</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>repository.jboss.org</id>
<name>JBoss Releases Repository</name>
<url>http://repository.jboss.org/maven2</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.ethereum</groupId>
<artifactId>EthereumJ</artifactId>
<packaging>jar</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>EthereumJ</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Third-party dependencies -->
<junit.version>4.11</junit.version>
<slf4j.version>1.7.7</slf4j.version>
<leveldb.version>0.7</leveldb.version>
<spongycastle.version>1.50.0.0</spongycastle.version>
<generated.sourceDirectory>gen</generated.sourceDirectory>
</properties>
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.0.17.Final</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpg-jdk15on</artifactId>
<version>1.49</version>
<classifier>sources</classifier>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-ext-jdk15on</artifactId>
<version>1.49</version>
<classifier>sources</classifier>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.49</version>
<classifier>sources</classifier>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- Spongy Castle for SHA3 and SECP256K1 -->
<dependency>
<groupId>com.madgag.spongycastle</groupId>
<artifactId>core</artifactId>
<version>${spongycastle.version}</version>
</dependency>
<dependency>
<groupId>com.fifesoft</groupId>
<artifactId>rsyntaxtextarea</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>com.maxmind.geoip2</groupId>
<artifactId>geoip2</artifactId>
<version>0.6.0</version>
</dependency>
<dependency>
<groupId>com.maxmind.geoip</groupId>
<artifactId>geoip-api</artifactId>
<version>1.2.11</version>
</dependency>
<!--
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr</artifactId>
<version>3.5.2</version>
</dependency>
-->
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr</artifactId>
<version>3.1.3</version>
<!-- <version>3.5.2</version> -->
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>stringtemplate</artifactId>
@ -107,6 +70,20 @@
<version>2.5.3</version>
</dependency>
<!-- Consumers are expected to provide their own SLF4J adapters
such as logback, slf4j-log4j12, slf4j-jcl and so on see http://www.slf4j.org/faq.html -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>${slf4j.version}</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -0,0 +1,661 @@
package org.ethereum.crypto;
/**
* Copyright 2011 Google Inc.
*
* Licensed 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.
*/
import static com.google.common.base.Preconditions.checkNotNull;
import static org.ethereum.util.ByteUtil.bigIntegerToBytes;
import java.io.Serializable;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.security.SecureRandom;
import java.security.SignatureException;
import java.util.Arrays;
import javax.annotation.Nullable;
import org.ethereum.util.ByteUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.asn1.sec.SECNamedCurves;
import org.spongycastle.asn1.x9.X9ECParameters;
import org.spongycastle.asn1.x9.X9IntegerConverter;
import org.spongycastle.crypto.AsymmetricCipherKeyPair;
import org.spongycastle.crypto.digests.SHA256Digest;
import org.spongycastle.crypto.generators.ECKeyPairGenerator;
import org.spongycastle.crypto.params.ECDomainParameters;
import org.spongycastle.crypto.params.ECKeyGenerationParameters;
import org.spongycastle.crypto.params.ECPrivateKeyParameters;
import org.spongycastle.crypto.params.ECPublicKeyParameters;
import org.spongycastle.crypto.signers.ECDSASigner;
import org.spongycastle.crypto.signers.HMacDSAKCalculator;
import org.spongycastle.math.ec.ECAlgorithms;
import org.spongycastle.math.ec.ECCurve;
import org.spongycastle.math.ec.ECPoint;
import org.spongycastle.util.encoders.Base64;
import org.spongycastle.util.encoders.Hex;
import com.google.common.base.Preconditions;
public class ECKey implements Serializable {
private static final Logger log = LoggerFactory.getLogger(ECKey.class);
/** The parameters of the secp256k1 curve that Bitcoin uses. */
public static final ECDomainParameters CURVE;
/**
* Equal to CURVE.getN().shiftRight(1), used for canonicalising the S value of a signature. If you aren't
* sure what this is about, you can ignore it.
*/
public static final BigInteger HALF_CURVE_ORDER;
private static final SecureRandom secureRandom;
private static final long serialVersionUID = -728224901792295832L;
static {
// All clients must agree on the curve to use by agreement. Bitcoin uses secp256k1.
X9ECParameters params = SECNamedCurves.getByName("secp256k1");
CURVE = new ECDomainParameters(params.getCurve(), params.getG(), params.getN(), params.getH());
HALF_CURVE_ORDER = params.getN().shiftRight(1);
secureRandom = new SecureRandom();
}
// 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 BigInteger priv;
protected final ECPoint pub;
// Transient because it's calculated on demand.
transient private byte[] pubKeyHash;
/**
* Generates an entirely new keypair. Point compression is used so the resulting public key will be 33 bytes
* (32 for the co-ordinate and 1 byte to represent the y bit).
*/
public ECKey() {
this(secureRandom);
}
/**
* Generates an entirely new keypair with the given {@link SecureRandom} object. Point compression is used so the
* resulting public key will be 33 bytes (32 for the co-ordinate and 1 byte to represent the y bit).
*/
public ECKey(SecureRandom secureRandom) {
ECKeyPairGenerator generator = new ECKeyPairGenerator();
ECKeyGenerationParameters keygenParams = new ECKeyGenerationParameters(CURVE, secureRandom);
generator.init(keygenParams);
AsymmetricCipherKeyPair keypair = generator.generateKeyPair();
ECPrivateKeyParameters privParams = (ECPrivateKeyParameters) keypair.getPrivate();
ECPublicKeyParameters pubParams = (ECPublicKeyParameters) keypair.getPublic();
priv = privParams.getD();
pub = CURVE.getCurve().decodePoint(pubParams.getQ().getEncoded(true));
}
protected ECKey(@Nullable BigInteger priv, ECPoint pub) {
this.priv = priv;
if(pub == null)
throw new IllegalArgumentException("Public key may not be null");
this.pub = 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.
*/
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.
*/
public static ECPoint decompressPoint(ECPoint compressed) {
return CURVE.getCurve().decodePoint(compressed.getEncoded(false));
}
/**
* Creates an ECKey given the private key only. The public key is calculated from it (this is slow). Note that
* the resulting public key is compressed.
*/
public static ECKey fromPrivate(BigInteger privKey) {
return new ECKey(privKey, compressPoint(CURVE.getG().multiply(privKey)));
}
/**
* Creates an ECKey given the private key only. The public key is calculated from it (this is slow). The resulting
* public key is compressed.
*/
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.
*/
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.
*/
public static ECKey fromPrivateAndPrecalculatedPublic(byte[] priv, byte[] pub) {
checkNotNull(priv);
checkNotNull(pub);
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.
*/
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.
*/
public static ECKey fromPublicOnly(byte[] pub) {
return new ECKey(null, CURVE.getCurve().decodePoint(pub));
}
/**
* 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.
*/
public ECKey decompress() {
if (!pub.isCompressed())
return this;
else
return new ECKey(priv, decompressPoint(pub));
}
/**
* 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).
*/
public boolean isPubKeyOnly() {
return priv == null;
}
/**
* Returns true if this key has access to private key bytes. Does the opposite of
* {@link #isPubKeyOnly()}.
*/
public boolean hasPrivKey() {
return priv != null;
}
/**
* Returns public key bytes from the given private key. To convert a byte array into a BigInteger, use <tt>
* new BigInteger(1, bytes);</tt>
*/
public static byte[] publicKeyFromPrivate(BigInteger privKey, boolean compressed) {
ECPoint point = CURVE.getG().multiply(privKey);
return point.getEncoded(compressed);
}
/** Gets the hash160 form of the public key (as seen in addresses). */
public byte[] getAddress() {
if (pubKeyHash == null) {
byte[] pubBytes = this.pub.getEncoded(false);
pubKeyHash = HashUtil.sha3hash160(Arrays.copyOfRange(pubBytes, 1, pubBytes.length));
}
return pubKeyHash;
}
/**
* Gets the raw public key value. This appears in transaction scriptSigs. Note that this is <b>not</b> the same
* as the pubKeyHash/address.
*/
public byte[] getPubKey() {
return pub.getEncoded();
}
/** Gets the public key in the form of an elliptic curve point object from Bouncy Castle. */
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).
*
* @throws java.lang.IllegalStateException if the private key bytes are not available.
*/
public BigInteger getPrivKey() {
if (priv == null)
throw new MissingPrivateKeyException();
return priv;
}
/**
* Returns whether this key is using the compressed form or not. Compressed pubkeys are only 33 bytes, not 64.
*/
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().
*/
public String toStringWithPrivate() {
StringBuilder b = new StringBuilder();
b.append(toString());
if (priv != null) {
b.append(" priv:").append(Hex.toHexString(priv.toByteArray()));
}
return b.toString();
}
/**
* Groups the two components that make up a signature, and provides a way to encode to DER form, which is
* how ECDSA signatures are represented when embedded in other data structures in the Bitcoin protocol. The raw
* components can be useful for doing further EC maths on them.
*/
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.
*/
public ECDSASignature(BigInteger r, BigInteger s) {
this.r = r;
this.s = s;
}
public static ECDSASignature fromComponents(byte[] r, byte[] s) {
return new ECDSASignature(new BigInteger(r), new BigInteger(s));
}
/**
* Will automatically adjust the S component to be less than or equal to half the curve order, if necessary.
* This is required because for every signature (r,s) the signature (r, -s (mod N)) is a valid signature of
* the same message. However, we dislike the ability to modify the bits of a Bitcoin transaction after it's
* been signed, as that violates various assumed invariants. Thus in future only one of those forms will be
* considered legal and the other will be banned.
*/
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;
}
}
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"));
}
@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;
if (!s.equals(signature.s)) return false;
return true;
}
@Override
public int hashCode() {
int result = r.hashCode();
result = 31 * result + s.hashCode();
return result;
}
}
/**
* Signs the given hash and returns the R and S components as BigIntegers
* and put them in ECDSASignature
*
* @param data to sign
* @return ECDSASignature signature that contains the R and S components
*/
public ECDSASignature doSign(byte[] input) {
// No decryption of private key required.
if (priv == null)
throw new MissingPrivateKeyException();
checkNotNull(priv);
ECDSASigner signer = new ECDSASigner(new HMacDSAKCalculator(new SHA256Digest()));
ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(priv, CURVE);
signer.init(true, privKey);
BigInteger[] components = signer.generateSignature(input);
return new ECDSASignature(components[0], components[1]).toCanonicalised();
}
/**
* Signs a text message using the standard Bitcoin messaging signing format and returns the signature as a base64
* encoded string.
*
* @throws IllegalStateException if this ECKey does not have the private part.
*/
public String signBitcoinMessage(String message) {
byte[] data = ByteUtil.formatForBitcoinSigning(message);
byte[] hash = HashUtil.doubleDigest(data);
return sign(hash).toBase64();
}
/**
* Takes the sha3 hash (32 bytes) of data and returns the ECDSA signature
*
* @throws IllegalStateException if this ECKey does not have the private part.
*/
public ECDSASignature sign(byte[] messageHash) {
if (priv == null)
throw new MissingPrivateKeyException();
ECDSASignature sig = doSign(messageHash);
// Now we have to work backwards to figure out the recId needed to recover the signature.
int recId = -1;
for (int i = 0; i < 4; i++) {
ECKey k = ECKey.recoverFromSignature(i, sig, messageHash, isCompressed());
if (k != null && k.pub.equals(pub)) {
recId = i;
break;
}
}
if (recId == -1)
throw new RuntimeException("Could not construct a recoverable key. This should never happen.");
sig.v = (byte) (recId + 27 + (isCompressed() ? 4 : 0));
return sig;
}
/**
* Given a piece of text and a message signature encoded in base64, returns an ECKey
* containing the public key that was used to sign it. This can then be compared to the expected public key to
* determine if the signature was correct.
*
* @param message a piece of human readable text that was signed
* @param signatureBase64 The Bitcoin-format message signature in base64
* @throws SignatureException If the public key could not be recovered or if there was a signature format error.
*/
public static ECKey signedBitcoinMessageToKey(String message, String signatureBase64) throws SignatureException {
byte[] messageBytes = ByteUtil.formatForBitcoinSigning(message);
// Note that the C++ code doesn't actually seem to specify any character encoding. Presumably it's whatever
// JSON-SPIRIT hands back. Assume UTF-8 for now.
byte[] messageHash = HashUtil.doubleDigest(messageBytes);
return signatureToKey(messageHash, signatureBase64);
}
/**
* Given a piece of text and a message signature encoded in base64, returns an ECKey
* containing the public key that was used to sign it. This can then be compared to the expected public key to
* determine if the signature was correct.
*
* @param message a piece of human readable text that was signed
* @param signatureBase64 The Bitcoin-format message signature in base64
* @throws SignatureException If the public key could not be recovered or if there was a signature format error.
*/
public static ECKey signatureToKey(byte[] messageHash, String signatureBase64) throws SignatureException {
byte[] signatureEncoded;
try {
signatureEncoded = Base64.decode(signatureBase64);
} catch (RuntimeException e) {
// This is what you get 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);
int header = signatureEncoded[0] & 0xFF;
// 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);
BigInteger r = new BigInteger(1, Arrays.copyOfRange(signatureEncoded, 1, 33));
BigInteger s = new BigInteger(1, Arrays.copyOfRange(signatureEncoded, 33, 65));
ECDSASignature sig = new ECDSASignature(r, s);
boolean compressed = false;
if (header >= 31) {
compressed = true;
header -= 4;
}
int recId = header - 27;
ECKey key = ECKey.recoverFromSignature(recId, sig, messageHash, compressed);
if (key == null)
throw new SignatureException("Could not recover public key from signature");
return key;
}
/**
* <p>Verifies the given ECDSA signature against the message bytes using the public key bytes.</p>
*
* <p>When using native ECDSA verification, data must be 32 bytes, and no element may be
* larger than 520 bytes.</p>
*
* @param data Hash of the data to verify.
* @param signature signature.
* @param pub The public key bytes to use.
*/
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 e) {
// 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.
log.error("Caught NPE inside bouncy castle");
e.printStackTrace();
return false;
}
}
/**
* 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.
*/
public static boolean verify(byte[] data, byte[] signature, byte[] pub) {
return verify(data, signature, pub);
}
/**
* 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.
*/
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.
*/
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.
*/
public boolean isPubKeyCanonical() {
return isPubKeyCanonical(pub.getEncoded());
}
/**
* Returns true if the given pubkey is canonical, i.e. the correct length taking into account compression.
*/
public static boolean isPubKeyCanonical(byte[] pubkey) {
if (pubkey[0] == 0x04) {
// Uncompressed pubkey
if (pubkey.length != 65)
return false;
} else if (pubkey[0] == 0x02 || pubkey[0] == 0x03) {
// Compressed pubkey
if (pubkey.length != 33)
return false;
} else
return false;
return true;
}
/**
* Convenience wrapper around {@link ECKey#signedBitcoinMessageToKey(String, String)}. If the key derived from the
* signature is not the same as this one, throws a SignatureException.
*/
public void verifyBitcoinMessage(String message, String signatureBase64) throws SignatureException {
ECKey key = ECKey.signedBitcoinMessageToKey(message, signatureBase64);
if (!key.pub.equals(pub))
throw new SignatureException("Signature did not match for message");
}
/**
* <p>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.</p>
*
* <p>The recId is an index from 0 to 3 which indicates which of the 4 possible keys is the correct one. Because
* the key recovery operation yields multiple potential keys, 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.</p>
*
* <p>If this method returns null it means recovery was not possible and recId should be iterated.</p>
*
* <p>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.</p>
*
* @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.
* @param compressed Whether or not the original pubkey was compressed.
* @return An ECKey containing only the public part, or null if recovery wasn't possible.
*/
@Nullable
public static ECKey recoverFromSignature(int recId, ECDSASignature sig, byte[] messageHash, boolean compressed) {
Preconditions.checkArgument(recId >= 0, "recId must be positive");
Preconditions.checkArgument(sig.r.signum() >= 0, "r must be positive");
Preconditions.checkArgument(sig.s.signum() >= 0, "s must be positive");
Preconditions.checkNotNull(messageHash);
// 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 keys 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 ECKey.fromPublicOnly(q.getEncoded(compressed));
}
/** Decompress a compressed public key (x co-ord and low-bit of y-coord). */
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);
}
/**
* Returns a 32 byte array containing the private key, or null if the key is encrypted or public only
*/
@Nullable
public byte[] getPrivKeyBytes() {
return bigIntegerToBytes(priv, 32);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || !(o instanceof ECKey)) return false;
ECKey ecKey = (ECKey) o;
if (priv != null && !priv.equals(ecKey.priv)) return false;
if (pub != null && !pub.equals(ecKey.pub)) return false;
return true;
}
@Override
public int hashCode() {
// Public keys are random already so we can just use a part of them as the hashcode. Read from the start to
// avoid picking up the type code (compressed vs uncompressed) which is tacked on the end.
byte[] bits = getPubKey();
return (bits[0] & 0xFF) | ((bits[1] & 0xFF) << 8) | ((bits[2] & 0xFF) << 16) | ((bits[3] & 0xFF) << 24);
}
@SuppressWarnings("serial")
public static class MissingPrivateKeyException extends RuntimeException {
}
}

View File

@ -0,0 +1,61 @@
package org.ethereum.crypto;
import static java.util.Arrays.copyOfRange;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.ethereum.util.ByteUtil;
public class HashUtil {
private static final MessageDigest sha256digest;
static {
try {
sha256digest = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e); // Can't happen.
}
}
public static byte[] sha256(byte[] input) {
return sha256digest.digest(input);
}
public static byte[] sha3(byte[] input) {
return SHA3Helper.sha3(input);
}
public static String sha3String(String input) {
return SHA3Helper.sha3String(input);
}
/**
* Calculates RIGTMOST160(SHA3(input)). This is used in address calculations.
*/
public static byte[] sha3hash160(byte[] input) {
byte[] hash = sha3(input);
return copyOfRange(hash, 12, hash.length);
}
/**
* See {@link ByteUtil#doubleDigest(byte[], int, int)}.
*/
public static byte[] doubleDigest(byte[] input) {
return doubleDigest(input, 0, input.length);
}
/**
* Calculates the SHA-256 hash of the given byte range, and then hashes the resulting hash again. This is
* standard procedure in Bitcoin. The resulting hash is in big endian form.
*/
public static byte[] doubleDigest(byte[] input, int offset, int length) {
synchronized (sha256digest) {
sha256digest.reset();
sha256digest.update(input, offset, length);
byte[] first = sha256digest.digest();
return sha256digest.digest(first);
}
}
}

View File

@ -0,0 +1,21 @@
package org.ethereum.crypto;
/**
* <p>Exception to provide the following to {@link EncrypterDecrypterOpenSSL}:</p>
* <ul>
* <li>Provision of encryption / decryption exception</li>
* </ul>
* <p>This base exception acts as a general failure mode not attributable to a specific cause (other than
* that reported in the exception message). Since this is in English, it may not be worth reporting directly
* to the user other than as part of a "general failure to parse" response.</p>
*/
public class KeyCrypterException extends RuntimeException {
private static final long serialVersionUID = -4441989608332681377L;
public KeyCrypterException(String s) {
super(s);
}
public KeyCrypterException(String s, Throwable throwable) {
super(s, throwable);
}
}

View File

@ -0,0 +1,96 @@
package org.ethereum.crypto;
import java.math.BigInteger;
import org.spongycastle.crypto.digests.SHA3Digest;
import org.spongycastle.util.encoders.Hex;
public class SHA3Helper {
private static SHA3Digest DEFAULT_DIGEST_256 = new SHA3Digest(256);
public static String sha3String(String message) {
return sha3String(message, DEFAULT_DIGEST_256, true);
}
public static String sha3String(byte[] message) {
return sha3String(message, DEFAULT_DIGEST_256, true);
}
public static byte[] sha3(String message) {
return sha3(Hex.decode(message), DEFAULT_DIGEST_256, true);
}
public static byte[] sha3(byte[] message) {
return sha3(message, DEFAULT_DIGEST_256, true);
}
protected static String sha3String(String message, Size bitSize) {
SHA3Digest digest = new SHA3Digest(bitSize.bits);
return sha3String(message, digest, true);
}
protected static String sha3String(byte[] message, Size bitSize) {
SHA3Digest digest = new SHA3Digest(bitSize.bits);
return sha3String(message, digest, true);
}
protected static String sha3String(String message, Size bitSize, boolean bouncyencoder) {
SHA3Digest digest = new SHA3Digest(bitSize.bits);
return sha3String(message, digest, bouncyencoder);
}
protected static String sha3string(byte[] message, Size bitSize, boolean bouncyencoder) {
SHA3Digest digest = new SHA3Digest(bitSize.bits);
return sha3String(message, digest, bouncyencoder);
}
private static String sha3String(String message, SHA3Digest digest, boolean bouncyencoder) {
if (message != null) {
return sha3String(Hex.decode(message), digest, bouncyencoder);
}
throw new NullPointerException("Can't hash a NULL value");
}
private static String sha3String(byte[] message, SHA3Digest digest, boolean bouncyencoder) {
byte[] hash = doSha3(message, digest, bouncyencoder);
if (bouncyencoder) {
return Hex.toHexString(hash);
} else {
BigInteger bigInt = new BigInteger(1, hash);
return bigInt.toString(16);
}
}
private static byte[] sha3(byte[] message, SHA3Digest digest, boolean bouncyencoder) {
return doSha3(message, digest, bouncyencoder);
}
private static byte[] doSha3(byte[] message, SHA3Digest digest, boolean bouncyencoder) {
byte[] hash = new byte[digest.getDigestSize()];
if (message.length != 0) {
digest.update(message, 0, message.length);
}
digest.doFinal(hash, 0);
return hash;
}
public enum Size {
S224(224),
S256(256),
S384(384),
S512(512);
int bits = 0;
Size(int bits) {
this.bits = bits;
}
public int getValue() {
return this.bits;
}
}
}

View File

@ -0,0 +1,73 @@
package org.ethereum.gui;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 25/04/14 07:11
*/
public class PeersTableMain extends JFrame{
// Instance attributes used in this example
private JPanel topPanel;
private JTable table;
private JScrollPane scrollPane;
// Constructor of main frame
public PeersTableMain() {
// Set the frame characteristics
setTitle("Ethereum Peers");
setSize(355, 300);
setLocation(815, 80);
setBackground(Color.gray);
java.net.URL url = ClassLoader.getSystemResource("ethereum-icon.png");
Toolkit kit = Toolkit.getDefaultToolkit();
Image img = kit.createImage(url);
this.setIconImage(img);
// Create a panel to hold all other components
topPanel = new JPanel();
topPanel.setLayout(new BorderLayout());
getContentPane().add(topPanel);
// Create a new table instance
table = new JTable();
table.setModel(new PeersTableModel());
table.setFont(new Font("Courier New", Font.PLAIN, 18));
table.setForeground(Color.GRAY);
table.setTableHeader(null);
TableCellRenderer tcr = table.getDefaultRenderer(String.class);
DefaultTableCellRenderer renderer = (DefaultTableCellRenderer) tcr;
renderer.setHorizontalAlignment(SwingConstants.CENTER);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setCellSelectionEnabled(true);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.getColumnModel().getColumn(0).setPreferredWidth(60);
table.getColumnModel().getColumn(1).setPreferredWidth(200);
table.getColumnModel().getColumn(2).setPreferredWidth(60);
table.setRowMargin(3);
table.setRowHeight(50);
// Add the table to a scrolling pane
scrollPane = new JScrollPane(table);
topPanel.add(scrollPane, BorderLayout.CENTER);
}
public static void main(String args[]) {
PeersTableMain mainFrame = new PeersTableMain();
mainFrame.setVisible(true);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

View File

@ -1,8 +1,7 @@
package org.ethereum.gui;
import samples.PeersTableMain;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

View File

@ -6,7 +6,7 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelOption;
import io.netty.channel.FixedRecvByteBufAllocator;
import org.bouncycastle.util.encoders.Hex;
import org.spongycastle.util.encoders.Hex;
import org.ethereum.gui.PeerListener;
import org.ethereum.manager.MainData;
import org.ethereum.net.RLP;
@ -83,8 +83,6 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
System.out.println("No ping answer for [30 sec]");
throw new Error("No ping return for 30 [sec]");
// TODO: shutdown the handler
}

View File

@ -1,6 +1,6 @@
package org.ethereum.net.message;
import org.bouncycastle.util.encoders.Hex;
import org.spongycastle.util.encoders.Hex;
import org.ethereum.net.RLP;
import org.ethereum.net.rlp.RLPItem;
import org.ethereum.net.rlp.RLPList;

View File

@ -1,5 +1,6 @@
package org.ethereum.net.vo;
import org.ethereum.crypto.HashUtil;
import org.ethereum.net.rlp.RLPElement;
import org.ethereum.net.rlp.RLPItem;
import org.ethereum.net.rlp.RLPList;
@ -56,11 +57,10 @@ public class BlockData {
}
// [parent_hash, uncles_hash, coinbase, state_root, tx_list_hash, difficulty, timestamp, extradata, nonce]
private void parseRLP(){
this.hash = Utils.sha3(rawData.getRLPData());
this.hash = HashUtil.sha3(rawData.getRLPData());
List params = ((RLPList) rawData.getElement(0)).getList();

View File

@ -1,11 +1,10 @@
package org.ethereum.net.vo;
import org.bouncycastle.util.encoders.Hex;
import org.spongycastle.util.encoders.Hex;
import org.ethereum.net.rlp.RLPList;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
/**
* www.ethereumJ.com

View File

@ -1,5 +1,6 @@
package org.ethereum.net.vo;
import org.ethereum.crypto.HashUtil;
import org.ethereum.net.rlp.RLPItem;
import org.ethereum.net.rlp.RLPList;
import org.ethereum.util.Utils;
@ -64,7 +65,7 @@ public class TransactionData {
if (rawData.size() == 9){ // Simple transaction
this.hash = Utils.sha3(rawData.getRLPData());
this.hash = HashUtil.sha3(rawData.getRLPData());
this.nonce = ((RLPItem) rawData.getElement(0)).getData();
this.value = ((RLPItem) rawData.getElement(1)).getData();
this.receiveAddress = ((RLPItem) rawData.getElement(2)).getData();
@ -77,7 +78,7 @@ public class TransactionData {
} else if (rawData.size() == 10){ // Contract creation transaction
this.hash = Utils.sha3(rawData.getRLPData());
this.hash = HashUtil.sha3(rawData.getRLPData());
this.nonce = ((RLPItem) rawData.getElement(0)).getData();
this.value = ((RLPItem) rawData.getElement(1)).getData();
this.receiveAddress = ((RLPItem) rawData.getElement(2)).getData();

View File

@ -0,0 +1,127 @@
package org.ethereum.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.util.Arrays;
import com.google.common.primitives.UnsignedInteger;
import com.google.common.primitives.UnsignedLongs;
public class ByteUtil {
/** The string that prefixes all text messages signed using Bitcoin keys. */
public static final String BITCOIN_SIGNED_MESSAGE_HEADER = "Bitcoin Signed Message:\n";
public static final byte[] BITCOIN_SIGNED_MESSAGE_HEADER_BYTES = BITCOIN_SIGNED_MESSAGE_HEADER.getBytes();
/**
* Creates a copy of bytes and appends b to the end of it
*/
public static byte[] appendByte(byte[] bytes, byte b) {
byte[] result = Arrays.copyOf(bytes, bytes.length + 1);
result[result.length - 1] = b;
return result;
}
// /**
// * Returns the given byte array hex encoded.
// */
// public static String bytesToHexString(byte[] bytes) {
// StringBuffer buf = new StringBuffer(bytes.length * 2);
// for (byte b : bytes) {
// String s = Integer.toString(0xFF & b, 16);
// if (s.length() < 2)
// buf.append('0');
// buf.append(s);
// }
// return buf.toString();
// }
/**
* The regular {@link java.math.BigInteger#toByteArray()} method isn't quite what we often need: it appends a
* leading zero to indicate that the number is positive and may need padding.
*
* @param b the integer to format into a byte array
* @param numBytes the desired size of the resulting byte array
* @return numBytes byte long array.
*/
public static byte[] bigIntegerToBytes(BigInteger b, int numBytes) {
if (b == null) {
return null;
}
byte[] bytes = new byte[numBytes];
byte[] biBytes = b.toByteArray();
int start = (biBytes.length == numBytes + 1) ? 1 : 0;
int length = Math.min(biBytes.length, numBytes);
System.arraycopy(biBytes, start, bytes, numBytes - length, length);
return bytes;
}
/**
* <p>Given a textual message, returns a byte buffer formatted as follows:</p>
*
* <tt><p>[24] "Bitcoin Signed Message:\n" [message.length as a varint] message</p></tt>
*/
public static byte[] formatForBitcoinSigning(String message) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write(BITCOIN_SIGNED_MESSAGE_HEADER_BYTES.length);
bos.write(BITCOIN_SIGNED_MESSAGE_HEADER_BYTES);
byte[] messageBytes = message.getBytes(Charset.forName("UTF-8"));
bos.write(encodeInt(messageBytes.length));
bos.write(messageBytes);
return bos.toByteArray();
} catch (IOException e) {
throw new RuntimeException(e); // Cannot happen.
}
}
/**
* <p>Given a textual message, returns a byte buffer formatted as follows:</p>
*/
public static byte[] formatForEthereumSigning(byte[] message) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write(encodeInt(message.length));
bos.write(message);
return bos.toByteArray();
} catch (IOException e) {
throw new RuntimeException(e); // Cannot happen.
}
}
public static byte[] encodeInt(int value) {
if (isLessThanUnsigned(value, 253)) {
return new byte[]{(byte) value};
} else if (isLessThanUnsigned(value, 65536)) {
return new byte[]{(byte) 253, (byte) (value), (byte) (value >> 8)};
} else if (isLessThanUnsigned(value, UnsignedInteger.MAX_VALUE.longValue())) {
byte[] bytes = new byte[5];
bytes[0] = (byte) 254;
uint32ToByteArrayLE(value, bytes, 1);
return bytes;
} else {
byte[] bytes = new byte[9];
bytes[0] = (byte) 255;
uint32ToByteArrayLE(value, bytes, 1);
uint32ToByteArrayLE(value >>> 32, bytes, 5);
return bytes;
}
}
/**
* Work around lack of unsigned types in Java.
*/
public static boolean isLessThanUnsigned(long n1, long n2) {
return UnsignedLongs.compare(n1, n2) < 0;
}
public static void uint32ToByteArrayLE(long val, byte[] out, int offset) {
out[offset + 0] = (byte) (0xFF & (val >> 0));
out[offset + 1] = (byte) (0xFF & (val >> 8));
out[offset + 2] = (byte) (0xFF & (val >> 16));
out[offset + 3] = (byte) (0xFF & (val >> 24));
}
}

View File

@ -1,20 +1,12 @@
package org.ethereum.util;
import org.bouncycastle.asn1.sec.SECNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;
import javax.swing.*;
import java.math.BigInteger;
import java.net.URL;
import java.security.MessageDigest;
import java.security.Security;
import java.util.Arrays;
import java.util.regex.Pattern;
import static java.lang.System.exit;
import javax.swing.ImageIcon;
import org.spongycastle.util.encoders.Hex;
/**
* www.ethereumj.com
@ -31,19 +23,14 @@ public class Utils {
byte[] result = new byte[arrSize];
for (int i = 0; i < arrSize; ++i){
int digit1 = hexSymbols.indexOf( hexString.charAt(i * 3) );
int digit2 = hexSymbols.indexOf( hexString.charAt(i * 3 + 1) );
result[i] = (byte) (digit1 * 16 + digit2);
}
return result;
}
public static String toHexString(byte[] data){
if (data == null) return "null";
else return Hex.toHexString(data);
}
@ -61,7 +48,6 @@ public class Utils {
return (new BigInteger(1, numberBytes)).toString();
}
public static void printHexStringForByte(byte data){
System.out.print("[");
@ -70,16 +56,11 @@ public class Utils {
if (((int) data & 0xFF) < 16) {
hexNum = "0" + hexNum;
}
System.out.print( hexNum );
System.out.print("]");
System.out.println();
}
public static void printHexStringForByteArray(byte[] data){
System.out.print("[");
@ -89,80 +70,17 @@ public class Utils {
if (((int) data[i] & 0xFF) < 16) {
hexNum = "0" + hexNum;
}
System.out.print( hexNum );
System.out.print(" ");
}
System.out.print("]");
System.out.println();
}
private static MessageDigest sha3Digest = null;
private static MessageDigest ripemd160Digest = null;
static {
try{
Security.addProvider(new BouncyCastleProvider());
ripemd160Digest = MessageDigest.getInstance("RIPEMD160", "BC");
sha3Digest = MessageDigest.getInstance("SHA3-256", "BC");
} catch (Throwable th){
th.printStackTrace();
exit(0);
}
}
public static byte[] sha3(byte[] token){
return sha3Digest.digest(token);
}
public static byte[] ripemd160(byte[] token){
return ripemd160Digest.digest(token);
}
static X9ECParameters curvParams = SECNamedCurves.getByName("secp256k1");
public static byte[] privToAddress(byte[] priv){
/* address create howto
token = "cow"
step1 = sha3(token) // generate 256 bit privkey
step2 = privtopub(step1)[1:] // generate 512 bit pubkey with secp256k1
step3 = sha3(step2)[12:]
*/
// TODO: validity checks
BigInteger privKey = new BigInteger(1, priv);
ECPoint Q = curvParams.getG().multiply(privKey);
byte[] pubKey = Q.getEncoded();
// TODO: find a performance improvement here - how to omit creation of new byte[]
byte[] _pubKey = Arrays.copyOfRange(pubKey, 1, pubKey.length);
byte[] _addr = Utils.sha3(_pubKey);
// TODO: find a performance improvement here - how to omit creation of new byte[]
byte[] addr = Arrays.copyOfRange(_addr, 12, _addr.length);
return addr;
}
public static ImageIcon getImageIcon(String resource){
URL imageURL = ClassLoader.getSystemResource(resource);
ImageIcon image = new ImageIcon(imageURL);
return image;
}
}

View File

@ -1,439 +0,0 @@
package samples;
// ==================================================================
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
/**
* Deterministic DSA signature generation. This is a sample
* implementation designed to illustrate how deterministic DSA
* chooses the pseudorandom value k when signing a given message.
* This implementation was NOT optimized or hardened against
* side-channel leaks.
*
* An instance is created with a hash function name, which must be
* supported by the underlying Java virtual machine ("SHA-1" and
* "SHA-256" should work everywhere). The data to sign is input
* through the {@code update()} methods. The private key is set with
* {@link #setPrivateKey}. The signature is obtained by calling
* {@link #sign}; alternatively, {@link #signHash} can be used to
* sign some data that has been externally hashed. The private key
* MUST be set before generating the signature itself, but message
* data can be input before setting the key.
*
* Instances are NOT thread-safe. However, once a signature has
* been generated, the same instance can be used again for another
* signature; {@link #setPrivateKey} need not be called again if the
* private key has not changed. {@link #reset} can also be called to
* cancel previously input data. Generating a signature with {@link
* #sign} (not {@link #signHash}) also implicitly causes a
* reset.
*
* ------------------------------------------------------------------
* Copyright (c) 2013 IETF Trust and the persons identified as
* authors of the code. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, is permitted pursuant to, and subject to the license
* terms contained in, the Simplified BSD License set forth in Section
* 4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
* (http://trustee.ietf.org/license-info).
*
* Technical remarks and questions can be addressed to:
* pornin@bolet.org
* ------------------------------------------------------------------
*/
public class DeterministicDSA {
private String macName;
private MessageDigest dig;
private Mac hmac;
private BigInteger p, q, g, x;
private int qlen, rlen, rolen, holen;
private byte[] bx;
/**
* Create an instance, using the specified hash function.
* The name is used to obtain from the JVM an implementation
* of the hash function and an implementation of HMAC.
*
* @param hashName the hash function name
* @throws IllegalArgumentException on unsupported name
*/
public DeterministicDSA(String hashName)
{
try {
dig = MessageDigest.getInstance(hashName);
} catch (NoSuchAlgorithmException nsae) {
throw new IllegalArgumentException(nsae);
}
if (hashName.indexOf('-') < 0) {
macName = "Hmac" + hashName;
} else {
StringBuilder sb = new StringBuilder();
sb.append("Hmac");
int n = hashName.length();
for (int i = 0; i < n; i ++) {
char c = hashName.charAt(i);
if (c != '-') {
sb.append(c);
}
}
macName = sb.toString();
}
try {
hmac = Mac.getInstance(macName);
} catch (NoSuchAlgorithmException nsae) {
throw new IllegalArgumentException(nsae);
}
holen = hmac.getMacLength();
}
/**
* Set the private key.
*
* @param p key parameter: field modulus
* @param q key parameter: subgroup order
* @param g key parameter: generator
* @param x private key
*/
public void setPrivateKey(BigInteger p, BigInteger q,
BigInteger g, BigInteger x)
{
/*
* Perform some basic sanity checks. We do not
* check primality of p or q because that would
* be too expensive.
*
* We reject keys where q is longer than 999 bits,
* because it would complicate signature encoding.
* Normal DSA keys do not have a q longer than 256
* bits anyway.
*/
if (p == null || q == null || g == null || x == null
|| p.signum() <= 0 || q.signum() <= 0
|| g.signum() <= 0 || x.signum() <= 0
|| x.compareTo(q) >= 0 || q.compareTo(p) >= 0
|| q.bitLength() > 999
|| g.compareTo(p) >= 0 || g.bitLength() == 1
|| g.modPow(q, p).bitLength() != 1) {
throw new IllegalArgumentException(
"invalid DSA private key");
}
this.p = p;
this.q = q;
this.g = g;
this.x = x;
qlen = q.bitLength();
if (q.signum() <= 0 || qlen < 8) {
throw new IllegalArgumentException(
"bad group order: " + q);
}
rolen = (qlen + 7) >>> 3;
rlen = rolen * 8;
/*
* Convert the private exponent (x) into a sequence
* of octets.
*/
bx = int2octets(x);
}
private BigInteger bits2int(byte[] in)
{
BigInteger v = new BigInteger(1, in);
int vlen = in.length * 8;
if (vlen > qlen) {
v = v.shiftRight(vlen - qlen);
}
return v;
}
private byte[] int2octets(BigInteger v)
{
byte[] out = v.toByteArray();
if (out.length < rolen) {
byte[] out2 = new byte[rolen];
System.arraycopy(out, 0,
out2, rolen - out.length,
out.length);
return out2;
} else if (out.length > rolen) {
byte[] out2 = new byte[rolen];
System.arraycopy(out, out.length - rolen,
out2, 0, rolen);
return out2;
} else {
return out;
}
}
private byte[] bits2octets(byte[] in)
{
BigInteger z1 = bits2int(in);
BigInteger z2 = z1.subtract(q);
return int2octets(z2.signum() < 0 ? z1 : z2);
}
/**
Pornin Informational [Page 73]
RFC 6979 Deterministic DSA and ECDSA August 2013
* Set (or reset) the secret key used for HMAC.
*
* @param K the new secret key
*/
private void setHmacKey(byte[] K)
{
try {
hmac.init(new SecretKeySpec(K, macName));
} catch (InvalidKeyException ike) {
throw new IllegalArgumentException(ike);
}
}
/**
* Compute the pseudorandom k for signature generation,
* using the process specified for deterministic DSA.
*
* @param h1 the hashed message
* @return the pseudorandom k to use
*/
private BigInteger computek(byte[] h1)
{
/*
* Convert hash value into an appropriately truncated
* and/or expanded sequence of octets. The private
* key was already processed (into field bx[]).
*/
byte[] bh = bits2octets(h1);
/*
* HMAC is always used with K as key.
* Whenever K is updated, we reset the
* current HMAC key.
*/
/* step b. */
byte[] V = new byte[holen];
for (int i = 0; i < holen; i ++) {
V[i] = 0x01;
}
/* step c. */
byte[] K = new byte[holen];
setHmacKey(K);
/* step d. */
hmac.update(V);
hmac.update((byte)0x00);
hmac.update(bx);
hmac.update(bh);
K = hmac.doFinal();
setHmacKey(K);
/* step e. */
hmac.update(V);
V = hmac.doFinal();
/* step f. */
hmac.update(V);
hmac.update((byte)0x01);
hmac.update(bx);
hmac.update(bh);
K = hmac.doFinal();
setHmacKey(K);
/* step g. */
hmac.update(V);
V = hmac.doFinal();
/* step h. */
byte[] T = new byte[rolen];
for (;;) {
/*
* We want qlen bits, but we support only
* hash functions with an output length
* multiple of 8;acd hence, we will gather
* rlen bits, i.e., rolen octets.
*/
int toff = 0;
while (toff < rolen) {
hmac.update(V);
V = hmac.doFinal();
int cc = Math.min(V.length,
T.length - toff);
System.arraycopy(V, 0, T, toff, cc);
toff += cc;
}
BigInteger k = bits2int(T);
if (k.signum() > 0 && k.compareTo(q) < 0) {
return k;
}
/*
* k is not in the proper range; update
* K and V, and loop.
*/
hmac.update(V);
hmac.update((byte)0x00);
K = hmac.doFinal();
setHmacKey(K);
hmac.update(V);
V = hmac.doFinal();
}
}
/**
* Process one more byte of input data (message to sign).
*
* @param in the extra input byte
*/
public void update(byte in)
{
dig.update(in);
}
/**
* Process some extra bytes of input data (message to sign).
*
* @param in the extra input bytes
*/
public void update(byte[] in)
{
dig.update(in, 0, in.length);
}
/**
* Process some extra bytes of input data (message to sign).
*
* @param in the extra input buffer
* @param off the extra input offset
* @param len the extra input length (in bytes)
*/
public void update(byte[] in, int off, int len)
{
dig.update(in, off, len);
}
/**
* Produce the signature. {@link #setPrivateKey} MUST have
* been called. The signature is computed over the data
* that was input through the {@code update*()} methods.
* This engine is then reset (made ready for a new
* signature generation).
*
Pornin Informational [Page 76]
RFC 6979 Deterministic DSA and ECDSA August 2013
* @return the signature
*/
public byte[] sign()
{
return signHash(dig.digest());
}
/**
* Produce the signature. {@link #setPrivateKey} MUST
* have been called. The signature is computed over the
* provided hash value (data is assumed to have been hashed
* externally). The data that was input through the
* {@code update*()} methods is ignored, but kept.
*
* If the hash output is longer than the subgroup order
* (the length of q, in bits, denoted 'qlen'), then the
* provided value {@code h1} can be truncated, provided that
* at least qlen leading bits are preserved. In other words,
* bit values in {@code h1} beyond the first qlen bits are
* ignored.
*
* @param h1 the hash value
* @return the signature
*/
public byte[] signHash(byte[] h1)
{
if (p == null) {
throw new IllegalStateException(
"no private key set");
}
try {
BigInteger k = computek(h1);
BigInteger r = g.modPow(k, p).mod(q);
BigInteger s = k.modInverse(q).multiply(
bits2int(h1).add(x.multiply(r)))
.mod(q);
/*
* Signature encoding: ASN.1 SEQUENCE of
* two INTEGERs. The conditions on q
* imply that the encoded version of r and
* s is no longer than 127 bytes for each,
* including DER tag and length.
*/
byte[] br = r.toByteArray();
byte[] bs = s.toByteArray();
int ulen = br.length + bs.length + 4;
int slen = ulen + (ulen >= 128 ? 3 : 2);
byte[] sig = new byte[slen];
int i = 0;
sig[i ++] = 0x30;
if (ulen >= 128) {
sig[i ++] = (byte)0x81;
sig[i ++] = (byte)ulen;
} else {
sig[i ++] = (byte)ulen;
}
sig[i ++] = 0x02;
sig[i ++] = (byte)br.length;
System.arraycopy(br, 0, sig, i, br.length);
i += br.length;
sig[i ++] = 0x02;
sig[i ++] = (byte)bs.length;
System.arraycopy(bs, 0, sig, i, bs.length);
return sig;
} catch (ArithmeticException ae) {
throw new IllegalArgumentException(
"DSA error (bad key ?)", ae);
}
}
/**
* Reset this engine. Data input through the {@code
* update*()} methods is discarded. The current private key,
* if one was set, is kept unchanged.
*/
public void reset()
{
dig.reset();
}
}
// ==================================================================

View File

@ -1,191 +0,0 @@
package samples;
import com.maxmind.geoip.LookupService;
import com.maxmind.geoip.Region;
import com.maxmind.geoip.regionName;
import com.maxmind.geoip2.exception.GeoIp2Exception;
import org.ethereum.net.RLP;
import org.ethereum.util.Utils;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.LinkedList;
import java.util.Queue;
/**
* www.openchain.info
* User: Roman Mandeleil
* Created on: 31/03/14 21:06
*/
public class Main1 {
public static void main(String args[]) throws IOException, GeoIp2Exception, URISyntaxException {
try {
URL flagURL = ClassLoader.getSystemResource("GeoLiteCity.dat");
File file = new File(flagURL.toURI());
LookupService cl = new LookupService(file);
System.out.println(cl.getLocation("110.77.217.185"));
} catch (IOException e) {
System.out.println("IO Exception");
}
}
public static void main1(String args[]) throws IOException {
//22400891000000088400000043414243
String helloPacket = "22400891000000088400000043414243";
String pingPacket = "224008910000000102";
System.out.println(helloPacket);
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("localhost", 20202));
socketChannel.configureBlocking(false);
String helloString = "22 40 08 91 00 00 00 79 F8 77 80 0A 80 AD 45 74 " +
"68 65 72 65 75 6D 28 2B 2B 29 2F 5A 65 72 6F 47 " +
"6F 78 2F 76 30 2E 34 2E 31 2F 6E 63 75 72 73 65 " +
"73 2F 4C 69 6E 75 78 2F 67 2B 2B 07 82 76 5F B8 " +
"40 D8 D6 0C 25 80 FA 79 5C FC 03 13 EF DE BA 86 " +
"9D 21 94 E7 9E 7C B2 B5 22 F7 82 FF A0 39 2C BB " +
"AB 8D 1B AC 30 12 08 B1 37 E0 DE 49 98 33 4F 3B " +
"CF 73 FA 11 7E F2 13 F8 74 17 08 9F EA F8 4C 21 " +
"B0 22 40 08 91 00 00 00 02 C1 02 22 40 08 91 00 " +
"00 00 26 E5 14 A0 AB 6B 9A 56 13 97 0F AA 77 1B " +
"12 D4 49 B2 E9 BB 92 5A B7 A3 69 F0 A4 B8 6B 28 " +
"6E 9D 54 00 99 CF 82 01 00 22 40 08 91 00 00 00 " +
"02 C1 16 22 40 08 91 00 00 00 02 C1 01 ";
String getPeersString = "22 40 08 91 00 00 00 02 C1 10 ";
byte[] helloBytes = hexStringToByteArr(helloString);
// Sending
ByteBuffer outBuffer = ByteBuffer.allocate(helloBytes.length);
outBuffer.clear();
outBuffer.put(helloBytes);
outBuffer.flip();
while (outBuffer.hasRemaining()) {
socketChannel.write(outBuffer);
}
outBuffer.clear();
byte[] getPeersBytes = hexStringToByteArr(getPeersString);
// Sending
outBuffer = ByteBuffer.allocate(getPeersBytes.length);
outBuffer.clear();
outBuffer.put(getPeersBytes);
outBuffer.flip();
while (outBuffer.hasRemaining()) {
socketChannel.write(outBuffer);
}
ByteBuffer inBuffer = ByteBuffer.allocate(1);
int bytesRead = socketChannel.read(inBuffer); //read into buffer.
while (bytesRead != -1) {
inBuffer.flip(); //make buffer ready for read
while (inBuffer.hasRemaining()) {
byte oneByte = inBuffer.get();
System.out.print(Integer.toHexString((int) oneByte & 0x00FF)); // read 1 byte at a time
System.out.print(" ");
}
inBuffer.clear(); //make buffer ready for writing
bytesRead = socketChannel.read(inBuffer);
}
// read 4 bytes sync token 0x22400891
// read 4 bytes packet size token, translate to size
// read packet according the size
}
public static byte[] hexStringToByteArr(String hexString) {
String hexSymbols = "0123456789ABCDEF";
int arrSize = (int) (hexString.length() / 3);
byte[] result = new byte[arrSize];
for (int i = 0; i < arrSize; ++i) {
int digit1 = hexSymbols.indexOf(hexString.charAt(i * 3));
int digit2 = hexSymbols.indexOf(hexString.charAt(i * 3 + 1));
result[i] = (byte) (digit1 * 16 + digit2);
}
return result;
}
public static void main2(String args[]) {
String helloPacket =
"F8 77 80 0B 80 AD 45 74 68 65 72 65 75 6D 28 2B 2B 29 " +
"2F 5A 65 72 6F 47 6F 78 2F 76 30 2E 34 2E 32 2F " +
"6E 63 75 72 73 65 73 2F 4C 69 6E 75 78 2F 67 2B " +
"2B 07 82 76 5F B8 40 80 7D 3E D5 E7 7C BA 05 8D " +
"C0 55 4A E0 90 98 9E FE EA 55 33 52 B3 1A DF DB " +
"80 5E 2A 1A 7D F7 9D 14 FE 8D 9D 2C CE AA D8 E9 " +
"4B 09 37 47 F1 33 C3 EE F3 98 83 96 20 1D 24 17 " +
"93 83 5D 38 70 FF D4";
String peersPacket = "F8 4E 11 F8 4B C5 36 81 " +
"CC 0A 29 82 76 5F B8 40 D8 D6 0C 25 80 FA 79 5C " +
"FC 03 13 EF DE BA 86 9D 21 94 E7 9E 7C B2 B5 22 " +
"F7 82 FF A0 39 2C BB AB 8D 1B AC 30 12 08 B1 37 " +
"E0 DE 49 98 33 4F 3B CF 73 FA 11 7E F2 13 F8 74 " +
"17 08 9F EA F8 4C 21 B0";
byte[] payload = Utils.hexStringToByteArr(peersPacket);
Utils.printHexStringForByteArray(payload);
Queue<Integer> index = new LinkedList<Integer>();
RLP.fullTraverse(payload, 0, 0, payload.length, 1, index);
// for (Integer item : index) System.out.println("ind --> " + item);
// Message newMessage = MessageFactory.createMessage(payload, index);
// System.out.println(newMessage.toString());
}
}

View File

@ -1,84 +0,0 @@
package samples;
import org.ethereum.net.client.ClientPeer;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 10/04/14 12:50
*/
public class Main2 {
public static void main(String args[]){
// 66.49.191.123
// 54.204.10.41
// 130.88.0.226
// 85.65.126.45
// 54.72.31.55
// new ClientPeer().connect("66.49.191.123", 30303);
// new ClientPeer().connect("66.49.191.123", 30303);
// new ClientPeer().connect("54.72.31.55", 30303);
String ip_1 = "131.104.252.4";
String ip_2 = "107.170.57.247";
String ip_3 = "68.48.173.163";
String ip_4 = "86.183.231.205";
String ip_5 = "68.185.234.64";
String ip_6 = "207.219.69.154";
// new ClientPeer().connect("192.168.1.102", 30303);
// new ClientPeer().connect("83.172.226.79", 30303);
// new ClientPeer().connect("68.48.173.163", 31313);
// new ClientPeer().connect("86.150.41.127", 30303);
// new ClientPeer().connect("82.217.72.169", 30303); nicksavers
// new ClientPeer().connect("94.197.120.80", 30303); stephan (ursium)
// new ClientPeer().connect("54.72.31.55", 30303); // peer discovery: capability = 4
new ClientPeer().connect("54.201.28.117", 30303); // poc-5
// new ClientPeer().connect("94.210.200.192", 30303); // poc-5
// new ClientPeer().connect("62.78.198.208", 30303); // poc-5 not stable
}
}
/* POC - 5
Hello: [/206.223.168.190] Canada
Hello: [/94.210.200.192] Netherlands
Hello: [/88.69.198.198] Germany
Hello: [/24.157.83.122] Canada
Hello: [/71.202.162.40] United States
Hello: [/64.231.10.208] Canada
Hello: [/85.65.126.45] Israel
Hello: [/62.78.198.208] Finland
Hello: [/50.133.12.228] United States
Hello: [/77.166.77.107] Netherlands
Hello: [/110.77.217.185] Thailand
Hello: [/64.231.9.30] Canada
Hello: [/213.100.250.57] Sweden
Hello: [/162.243.203.121] United States
Hello: [/82.217.72.169] Netherlands
Hello: [/99.231.80.166] Canada
Hello: [/131.104.252.4] Canada
Hello: [/54.204.10.41] United States
Hello: [/54.201.28.117] United States
Hello: [/67.204.1.162] Canada
Hello: [/82.240.16.5] France
Hello: [/74.79.23.119] United States
*/

View File

@ -1,48 +0,0 @@
package samples;
import org.bouncycastle.jce.ECPointUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPrivateKeySpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.util.encoders.Hex;
import java.io.IOException;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.ECFieldF2m;
import java.security.spec.EllipticCurve;
import java.util.Arrays;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 17/04/14 09:37
*/
public class Main3 {
static private byte[] shortMsg = Hex.decode("54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F67");
public static void main(String args[]) throws NoSuchProviderException, NoSuchAlgorithmException, IOException {
Security.addProvider(new BouncyCastleProvider());
MessageDigest digest = MessageDigest.getInstance("SHA3-256", "BC");
byte[] result = digest.digest(shortMsg);
byte[] expected = Hex.decode("4D741B6F1EB29CB2A9B9911C82F56FA8D73B04959D3D9D222895DF6C0B28AA15");
if (Arrays.equals(expected, result)){
System.out.println("equal !!!");
} else {
Hex.encode(result, System.out);
System.out.flush();
}
}
}

View File

@ -1,64 +0,0 @@
package samples;
import org.bouncycastle.jce.ECPointUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
import org.ethereum.util.Utils;
import java.io.IOException;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.*;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 17/04/14 09:37
*/
public class Main4 {
static private byte[] shortMsg = Hex.decode("54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F67");
public static void main(String args[]) throws NoSuchProviderException, NoSuchAlgorithmException, IOException, InvalidKeySpecException {
Security.addProvider(new BouncyCastleProvider());
EllipticCurve curve = new EllipticCurve(
new ECFieldF2m(239, // m
new int[] { 36 }), // k
new BigInteger("32010857077C5431123A46B808906756F543423E8D27877578125778AC76", 16), // a
new BigInteger("790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", 16)); // b
ECParameterSpec params = new ECParameterSpec(
curve,
ECPointUtil.decodePoint(curve,
Hex.decode("0457927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305")), // G
new BigInteger("220855883097298041197912187592864814557886993776713230936715041207411783"), // n
4); // h
ECPrivateKeySpec priKeySpec = new ECPrivateKeySpec(
new BigInteger("145642755521911534651321230007534120304391871461646461466464667494947990"), // d
params);
ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(
ECPointUtil.decodePoint(curve, Hex.decode("045894609CCECF9A92533F630DE713A958E96C97CCB8F5ABB5A688A238DEED6DC2D9D0C94EBFB7D526BA6A61764175B99CB6011E2047F9F067293F57F5")), // Q
params);
Signature sgr = Signature.getInstance("ECDSA", "BC");
KeyFactory f = KeyFactory.getInstance("ECDSA", "BC");
PrivateKey sKey = f.generatePrivate(priKeySpec);
PublicKey vKey = f.generatePublic(pubKeySpec);
// System.out.println(vKey);
System.out.println(Hex.toHexString(Utils.sha3("coinbase".getBytes())));
// toAddress(sha3("coinbase"));
// toAddress(76ec948a9207fdea26dcba91086bcdd181920ff52a539b0d1eb28e73b4cd92af);
}
}

View File

@ -1,81 +0,0 @@
package samples;
import org.ethereum.gui.PeersTableModel;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 25/04/14 07:11
*/
public class PeersTableMain extends JFrame{
// Instance attributes used in this example
private JPanel topPanel;
private JTable table;
private JScrollPane scrollPane;
// Constructor of main frame
public PeersTableMain()
{
// Set the frame characteristics
setTitle( "Ethereum Peers" );
setSize( 355, 300 );
setLocation(815, 80);
setBackground( Color.gray );
java.net.URL url = ClassLoader.getSystemResource("ethereum-icon.png");
Toolkit kit = Toolkit.getDefaultToolkit();
Image img = kit.createImage(url);
this.setIconImage(img);
// Create a panel to hold all other components
topPanel = new JPanel();
topPanel.setLayout( new BorderLayout() );
getContentPane().add( topPanel );
// Create a new table instance
table = new JTable( );
table.setModel(new PeersTableModel());
table.setFont(new Font("Courier New", Font.PLAIN, 18));
table.setForeground(Color.GRAY);
table.setTableHeader(null);
TableCellRenderer tcr = table.getDefaultRenderer(String.class);
DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)tcr;
renderer.setHorizontalAlignment(SwingConstants.CENTER);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setCellSelectionEnabled(true);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.getColumnModel().getColumn(0).setPreferredWidth(60);
table.getColumnModel().getColumn(1).setPreferredWidth(200);
table.getColumnModel().getColumn(2).setPreferredWidth(60);
table.setRowMargin(3);
table.setRowHeight(50);
// Add the table to a scrolling pane
scrollPane = new JScrollPane( table );
topPanel.add( scrollPane, BorderLayout.CENTER );
}
public static void main(String args[]){
PeersTableMain mainFrame = new PeersTableMain();
mainFrame.setVisible( true );
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

View File

@ -1,17 +0,0 @@
package samples.antlr;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 25/04/14 17:06
*/
public class GenParser {
public static void main(String args[]){
String userDir = System.getProperty("user.dir");
String grammarFile = userDir + "\\src\\main\\java\\samples\\antlr\\Sample.g";
org.antlr.Tool.main(new String[]{grammarFile});
}
}

View File

@ -1,105 +0,0 @@
grammar PyEsque;
options {
language = Java;
output = AST;
//output=template;
}
tokens {
BLOCK;
}
@header {
package samples.antlr;
}
@lexer::header {
package samples.antlr;
}
@lexer::members {
private int previousIndents = -1;
private int indentLevel = 0;
java.util.Queue<Token> tokens = new java.util.LinkedList<Token>();
@Override
public void emit(Token t) {
state.token = t;
tokens.offer(t);
}
@Override
public Token nextToken() {
super.nextToken();
return tokens.isEmpty() ? getEOFToken() : tokens.poll();
}
private void jump(int ttype) {
indentLevel += (ttype == Dedent ? -1 : 1);
emit(new CommonToken(ttype, "level=" + indentLevel));
}
}
parse
: block EOF -> block
;
block
: Indent block_atoms Dedent -> ^(BLOCK block_atoms)
;
block_atoms
: (Id | block)+
;
NewLine
: NL SP?
{
int n = $SP.text == null ? 0 : $SP.text.length();
if(n > previousIndents) {
jump(Indent);
previousIndents = n;
}
else if(n < previousIndents) {
jump(Dedent);
previousIndents = n;
}
else if(input.LA(1) == EOF) {
while(indentLevel > 0) {
jump(Dedent);
}
}
else {
skip();
}
}
;
Id
: ('a'..'z' | 'A'..'Z')+
;
SpaceChars
: SP {skip();}
;
fragment NL : '\r'? '\n' | '\r';
fragment SP : (' ' | '\t')+;
fragment Indent : ;
fragment Dedent : ;
expression
: INTEGER*
;
fragment DIGIT : '0'..'9';
INTEGER : DIGIT+ ;

View File

@ -1,547 +0,0 @@
// $ANTLR 3.5.2 E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g 2014-05-01 16:36:17
package samples.antlr;
import org.antlr.runtime.*;
import java.util.Stack;
import java.util.List;
import java.util.ArrayList;
@SuppressWarnings("all")
public class PyEsqueLexer extends Lexer {
public static final int EOF=-1;
public static final int BLOCK=4;
public static final int DIGIT=5;
public static final int Dedent=6;
public static final int INTEGER=7;
public static final int Id=8;
public static final int Indent=9;
public static final int NL=10;
public static final int NewLine=11;
public static final int SP=12;
public static final int SpaceChars=13;
private int previousIndents = -1;
private int indentLevel = 0;
java.util.Queue<Token> tokens = new java.util.LinkedList<Token>();
@Override
public void emit(Token t) {
state.token = t;
tokens.offer(t);
}
@Override
public Token nextToken() {
super.nextToken();
return tokens.isEmpty() ? getEOFToken() : tokens.poll();
}
private void jump(int ttype) {
indentLevel += (ttype == Dedent ? -1 : 1);
emit(new CommonToken(ttype, "level=" + indentLevel));
}
// delegates
// delegators
public Lexer[] getDelegates() {
return new Lexer[] {};
}
public PyEsqueLexer() {}
public PyEsqueLexer(CharStream input) {
this(input, new RecognizerSharedState());
}
public PyEsqueLexer(CharStream input, RecognizerSharedState state) {
super(input,state);
}
@Override public String getGrammarFileName() { return "E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g"; }
// $ANTLR start "NewLine"
public final void mNewLine() throws RecognitionException {
try {
int _type = NewLine;
int _channel = DEFAULT_TOKEN_CHANNEL;
CommonToken SP1=null;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:61:2: ( NL ( SP )? )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:61:4: NL ( SP )?
{
mNL();
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:61:7: ( SP )?
int alt1=2;
int LA1_0 = input.LA(1);
if ( (LA1_0=='\t'||LA1_0==' ') ) {
alt1=1;
}
switch (alt1) {
case 1 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:61:7: SP
{
int SP1Start39 = getCharIndex();
int SP1StartLine39 = getLine();
int SP1StartCharPos39 = getCharPositionInLine();
mSP();
SP1 = new CommonToken(input, Token.INVALID_TOKEN_TYPE, Token.DEFAULT_CHANNEL, SP1Start39, getCharIndex()-1);
SP1.setLine(SP1StartLine39);
SP1.setCharPositionInLine(SP1StartCharPos39);
}
break;
}
int n = (SP1!=null?SP1.getText():null) == null ? 0 : (SP1!=null?SP1.getText():null).length();
if(n > previousIndents) {
jump(Indent);
previousIndents = n;
}
else if(n < previousIndents) {
jump(Dedent);
previousIndents = n;
}
else if(input.LA(1) == EOF) {
while(indentLevel > 0) {
jump(Dedent);
}
}
else {
skip();
}
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "NewLine"
// $ANTLR start "Id"
public final void mId() throws RecognitionException {
try {
int _type = Id;
int _channel = DEFAULT_TOKEN_CHANNEL;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:85:2: ( ( 'a' .. 'z' | 'A' .. 'Z' )+ )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:85:4: ( 'a' .. 'z' | 'A' .. 'Z' )+
{
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:85:4: ( 'a' .. 'z' | 'A' .. 'Z' )+
int cnt2=0;
loop2:
while (true) {
int alt2=2;
int LA2_0 = input.LA(1);
if ( ((LA2_0 >= 'A' && LA2_0 <= 'Z')||(LA2_0 >= 'a' && LA2_0 <= 'z')) ) {
alt2=1;
}
switch (alt2) {
case 1 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:
{
if ( (input.LA(1) >= 'A' && input.LA(1) <= 'Z')||(input.LA(1) >= 'a' && input.LA(1) <= 'z') ) {
input.consume();
}
else {
MismatchedSetException mse = new MismatchedSetException(null,input);
recover(mse);
throw mse;
}
}
break;
default :
if ( cnt2 >= 1 ) break loop2;
EarlyExitException eee = new EarlyExitException(2, input);
throw eee;
}
cnt2++;
}
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "Id"
// $ANTLR start "SpaceChars"
public final void mSpaceChars() throws RecognitionException {
try {
int _type = SpaceChars;
int _channel = DEFAULT_TOKEN_CHANNEL;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:89:2: ( SP )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:89:4: SP
{
mSP();
skip();
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "SpaceChars"
// $ANTLR start "NL"
public final void mNL() throws RecognitionException {
try {
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:92:17: ( ( '\\r' )? '\\n' | '\\r' )
int alt4=2;
int LA4_0 = input.LA(1);
if ( (LA4_0=='\r') ) {
int LA4_1 = input.LA(2);
if ( (LA4_1=='\n') ) {
alt4=1;
}
else {
alt4=2;
}
}
else if ( (LA4_0=='\n') ) {
alt4=1;
}
else {
NoViableAltException nvae =
new NoViableAltException("", 4, 0, input);
throw nvae;
}
switch (alt4) {
case 1 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:92:19: ( '\\r' )? '\\n'
{
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:92:19: ( '\\r' )?
int alt3=2;
int LA3_0 = input.LA(1);
if ( (LA3_0=='\r') ) {
alt3=1;
}
switch (alt3) {
case 1 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:92:19: '\\r'
{
match('\r');
}
break;
}
match('\n');
}
break;
case 2 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:92:32: '\\r'
{
match('\r');
}
break;
}
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "NL"
// $ANTLR start "SP"
public final void mSP() throws RecognitionException {
try {
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:93:17: ( ( ' ' | '\\t' )+ )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:93:19: ( ' ' | '\\t' )+
{
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:93:19: ( ' ' | '\\t' )+
int cnt5=0;
loop5:
while (true) {
int alt5=2;
int LA5_0 = input.LA(1);
if ( (LA5_0=='\t'||LA5_0==' ') ) {
alt5=1;
}
switch (alt5) {
case 1 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:
{
if ( input.LA(1)=='\t'||input.LA(1)==' ' ) {
input.consume();
}
else {
MismatchedSetException mse = new MismatchedSetException(null,input);
recover(mse);
throw mse;
}
}
break;
default :
if ( cnt5 >= 1 ) break loop5;
EarlyExitException eee = new EarlyExitException(5, input);
throw eee;
}
cnt5++;
}
}
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "SP"
// $ANTLR start "Indent"
public final void mIndent() throws RecognitionException {
try {
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:94:17: ()
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:94:19:
{
}
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "Indent"
// $ANTLR start "Dedent"
public final void mDedent() throws RecognitionException {
try {
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:95:17: ()
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:95:19:
{
}
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "Dedent"
// $ANTLR start "DIGIT"
public final void mDIGIT() throws RecognitionException {
try {
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:104:16: ( '0' .. '9' )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:
{
if ( (input.LA(1) >= '0' && input.LA(1) <= '9') ) {
input.consume();
}
else {
MismatchedSetException mse = new MismatchedSetException(null,input);
recover(mse);
throw mse;
}
}
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "DIGIT"
// $ANTLR start "INTEGER"
public final void mINTEGER() throws RecognitionException {
try {
int _type = INTEGER;
int _channel = DEFAULT_TOKEN_CHANNEL;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:105:9: ( ( DIGIT )+ )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:105:11: ( DIGIT )+
{
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:105:11: ( DIGIT )+
int cnt6=0;
loop6:
while (true) {
int alt6=2;
int LA6_0 = input.LA(1);
if ( ((LA6_0 >= '0' && LA6_0 <= '9')) ) {
alt6=1;
}
switch (alt6) {
case 1 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:
{
if ( (input.LA(1) >= '0' && input.LA(1) <= '9') ) {
input.consume();
}
else {
MismatchedSetException mse = new MismatchedSetException(null,input);
recover(mse);
throw mse;
}
}
break;
default :
if ( cnt6 >= 1 ) break loop6;
EarlyExitException eee = new EarlyExitException(6, input);
throw eee;
}
cnt6++;
}
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "INTEGER"
@Override
public void mTokens() throws RecognitionException {
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:1:8: ( NewLine | Id | SpaceChars | INTEGER )
int alt7=4;
switch ( input.LA(1) ) {
case '\n':
case '\r':
{
alt7=1;
}
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
{
alt7=2;
}
break;
case '\t':
case ' ':
{
alt7=3;
}
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{
alt7=4;
}
break;
default:
NoViableAltException nvae =
new NoViableAltException("", 7, 0, input);
throw nvae;
}
switch (alt7) {
case 1 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:1:10: NewLine
{
mNewLine();
}
break;
case 2 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:1:18: Id
{
mId();
}
break;
case 3 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:1:21: SpaceChars
{
mSpaceChars();
}
break;
case 4 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:1:32: INTEGER
{
mINTEGER();
}
break;
}
}
}

View File

@ -1,394 +0,0 @@
// $ANTLR 3.5.2 E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g 2014-05-01 16:36:17
package samples.antlr;
import org.antlr.runtime.*;
import java.util.Stack;
import java.util.List;
import java.util.ArrayList;
import org.antlr.runtime.tree.*;
@SuppressWarnings("all")
public class PyEsqueParser extends Parser {
public static final String[] tokenNames = new String[] {
"<invalid>", "<EOR>", "<DOWN>", "<UP>", "BLOCK", "DIGIT", "Dedent", "INTEGER",
"Id", "Indent", "NL", "NewLine", "SP", "SpaceChars"
};
public static final int EOF=-1;
public static final int BLOCK=4;
public static final int DIGIT=5;
public static final int Dedent=6;
public static final int INTEGER=7;
public static final int Id=8;
public static final int Indent=9;
public static final int NL=10;
public static final int NewLine=11;
public static final int SP=12;
public static final int SpaceChars=13;
// delegates
public Parser[] getDelegates() {
return new Parser[] {};
}
// delegators
public PyEsqueParser(TokenStream input) {
this(input, new RecognizerSharedState());
}
public PyEsqueParser(TokenStream input, RecognizerSharedState state) {
super(input, state);
}
protected TreeAdaptor adaptor = new CommonTreeAdaptor();
public void setTreeAdaptor(TreeAdaptor adaptor) {
this.adaptor = adaptor;
}
public TreeAdaptor getTreeAdaptor() {
return adaptor;
}
@Override public String[] getTokenNames() { return PyEsqueParser.tokenNames; }
@Override public String getGrammarFileName() { return "E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g"; }
public static class parse_return extends ParserRuleReturnScope {
Object tree;
@Override
public Object getTree() { return tree; }
};
// $ANTLR start "parse"
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:48:1: parse : block EOF -> block ;
public final parse_return parse() throws RecognitionException {
parse_return retval = new parse_return();
retval.start = input.LT(1);
Object root_0 = null;
Token EOF2=null;
ParserRuleReturnScope block1 =null;
Object EOF2_tree=null;
RewriteRuleTokenStream stream_EOF=new RewriteRuleTokenStream(adaptor,"token EOF");
RewriteRuleSubtreeStream stream_block=new RewriteRuleSubtreeStream(adaptor,"rule block");
try {
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:49:2: ( block EOF -> block )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:49:4: block EOF
{
pushFollow(FOLLOW_block_in_parse74);
block1=block();
state._fsp--;
stream_block.add(block1.getTree());
EOF2=(Token)match(input,EOF,FOLLOW_EOF_in_parse76);
stream_EOF.add(EOF2);
// AST REWRITE
// elements: block
// token labels:
// rule labels: retval
// token list labels:
// rule list labels:
// wildcard labels:
retval.tree = root_0;
RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.getTree():null);
root_0 = (Object)adaptor.nil();
// 49:14: -> block
{
adaptor.addChild(root_0, stream_block.nextTree());
}
retval.tree = root_0;
}
retval.stop = input.LT(-1);
retval.tree = (Object)adaptor.rulePostProcessing(root_0);
adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
}
catch (RecognitionException re) {
reportError(re);
recover(input,re);
retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);
}
finally {
// do for sure before leaving
}
return retval;
}
// $ANTLR end "parse"
public static class block_return extends ParserRuleReturnScope {
Object tree;
@Override
public Object getTree() { return tree; }
};
// $ANTLR start "block"
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:52:1: block : Indent block_atoms Dedent -> ^( BLOCK block_atoms ) ;
public final block_return block() throws RecognitionException {
block_return retval = new block_return();
retval.start = input.LT(1);
Object root_0 = null;
Token Indent3=null;
Token Dedent5=null;
ParserRuleReturnScope block_atoms4 =null;
Object Indent3_tree=null;
Object Dedent5_tree=null;
RewriteRuleTokenStream stream_Indent=new RewriteRuleTokenStream(adaptor,"token Indent");
RewriteRuleTokenStream stream_Dedent=new RewriteRuleTokenStream(adaptor,"token Dedent");
RewriteRuleSubtreeStream stream_block_atoms=new RewriteRuleSubtreeStream(adaptor,"rule block_atoms");
try {
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:53:2: ( Indent block_atoms Dedent -> ^( BLOCK block_atoms ) )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:53:4: Indent block_atoms Dedent
{
Indent3=(Token)match(input,Indent,FOLLOW_Indent_in_block91);
stream_Indent.add(Indent3);
pushFollow(FOLLOW_block_atoms_in_block93);
block_atoms4=block_atoms();
state._fsp--;
stream_block_atoms.add(block_atoms4.getTree());
Dedent5=(Token)match(input,Dedent,FOLLOW_Dedent_in_block95);
stream_Dedent.add(Dedent5);
// AST REWRITE
// elements: block_atoms
// token labels:
// rule labels: retval
// token list labels:
// rule list labels:
// wildcard labels:
retval.tree = root_0;
RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"rule retval",retval!=null?retval.getTree():null);
root_0 = (Object)adaptor.nil();
// 53:30: -> ^( BLOCK block_atoms )
{
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:53:33: ^( BLOCK block_atoms )
{
Object root_1 = (Object)adaptor.nil();
root_1 = (Object)adaptor.becomeRoot((Object)adaptor.create(BLOCK, "BLOCK"), root_1);
adaptor.addChild(root_1, stream_block_atoms.nextTree());
adaptor.addChild(root_0, root_1);
}
}
retval.tree = root_0;
}
retval.stop = input.LT(-1);
retval.tree = (Object)adaptor.rulePostProcessing(root_0);
adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
}
catch (RecognitionException re) {
reportError(re);
recover(input,re);
retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);
}
finally {
// do for sure before leaving
}
return retval;
}
// $ANTLR end "block"
public static class block_atoms_return extends ParserRuleReturnScope {
Object tree;
@Override
public Object getTree() { return tree; }
};
// $ANTLR start "block_atoms"
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:56:1: block_atoms : ( Id | block )+ ;
public final block_atoms_return block_atoms() throws RecognitionException {
block_atoms_return retval = new block_atoms_return();
retval.start = input.LT(1);
Object root_0 = null;
Token Id6=null;
ParserRuleReturnScope block7 =null;
Object Id6_tree=null;
try {
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:57:2: ( ( Id | block )+ )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:57:5: ( Id | block )+
{
root_0 = (Object)adaptor.nil();
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:57:5: ( Id | block )+
int cnt1=0;
loop1:
while (true) {
int alt1=3;
int LA1_0 = input.LA(1);
if ( (LA1_0==Id) ) {
alt1=1;
}
else if ( (LA1_0==Indent) ) {
alt1=2;
}
switch (alt1) {
case 1 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:57:6: Id
{
Id6=(Token)match(input,Id,FOLLOW_Id_in_block_atoms116);
Id6_tree = (Object)adaptor.create(Id6);
adaptor.addChild(root_0, Id6_tree);
}
break;
case 2 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:57:11: block
{
pushFollow(FOLLOW_block_in_block_atoms120);
block7=block();
state._fsp--;
adaptor.addChild(root_0, block7.getTree());
}
break;
default :
if ( cnt1 >= 1 ) break loop1;
EarlyExitException eee = new EarlyExitException(1, input);
throw eee;
}
cnt1++;
}
}
retval.stop = input.LT(-1);
retval.tree = (Object)adaptor.rulePostProcessing(root_0);
adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
}
catch (RecognitionException re) {
reportError(re);
recover(input,re);
retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);
}
finally {
// do for sure before leaving
}
return retval;
}
// $ANTLR end "block_atoms"
public static class expression_return extends ParserRuleReturnScope {
Object tree;
@Override
public Object getTree() { return tree; }
};
// $ANTLR start "expression"
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:98:1: expression : ( INTEGER )* ;
public final expression_return expression() throws RecognitionException {
expression_return retval = new expression_return();
retval.start = input.LT(1);
Object root_0 = null;
Token INTEGER8=null;
Object INTEGER8_tree=null;
try {
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:99:2: ( ( INTEGER )* )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:99:4: ( INTEGER )*
{
root_0 = (Object)adaptor.nil();
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:99:4: ( INTEGER )*
loop2:
while (true) {
int alt2=2;
int LA2_0 = input.LA(1);
if ( (LA2_0==INTEGER) ) {
alt2=1;
}
switch (alt2) {
case 1 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\antlr\\PyEsque.g:99:4: INTEGER
{
INTEGER8=(Token)match(input,INTEGER,FOLLOW_INTEGER_in_expression246);
INTEGER8_tree = (Object)adaptor.create(INTEGER8);
adaptor.addChild(root_0, INTEGER8_tree);
}
break;
default :
break loop2;
}
}
}
retval.stop = input.LT(-1);
retval.tree = (Object)adaptor.rulePostProcessing(root_0);
adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
}
catch (RecognitionException re) {
reportError(re);
recover(input,re);
retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re);
}
finally {
// do for sure before leaving
}
return retval;
}
// $ANTLR end "expression"
// Delegated rules
public static final BitSet FOLLOW_block_in_parse74 = new BitSet(new long[]{0x0000000000000000L});
public static final BitSet FOLLOW_EOF_in_parse76 = new BitSet(new long[]{0x0000000000000002L});
public static final BitSet FOLLOW_Indent_in_block91 = new BitSet(new long[]{0x0000000000000300L});
public static final BitSet FOLLOW_block_atoms_in_block93 = new BitSet(new long[]{0x0000000000000040L});
public static final BitSet FOLLOW_Dedent_in_block95 = new BitSet(new long[]{0x0000000000000002L});
public static final BitSet FOLLOW_Id_in_block_atoms116 = new BitSet(new long[]{0x0000000000000302L});
public static final BitSet FOLLOW_block_in_block_atoms120 = new BitSet(new long[]{0x0000000000000302L});
public static final BitSet FOLLOW_INTEGER_in_expression246 = new BitSet(new long[]{0x0000000000000082L});
}

View File

@ -1,611 +0,0 @@
/*
[The 'BSD licence']
Copyright (c) 2004 Terence Parr and Loring Craymer
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** Python 2.3.3 Grammar
*
* Terence Parr and Loring Craymer
* February 2004
*
* Converted to ANTLR v3 November 2005 by Terence Parr.
*
* This grammar was derived automatically from the Python 2.3.3
* parser grammar to get a syntactically correct ANTLR grammar
* for Python. Then Terence hand tweaked it to be semantically
* correct; i.e., removed lookahead issues etc... It is LL(1)
* except for the (sometimes optional) trailing commas and semi-colons.
* It needs two symbols of lookahead in this case.
*
* Starting with Loring's preliminary lexer for Python, I modified it
* to do my version of the whole nasty INDENT/DEDENT issue just so I
* could understand the problem better. This grammar requires
* PythonTokenStream.java to work. Also I used some rules from the
* semi-formal grammar on the web for Python (automatically
* translated to ANTLR format by an ANTLR grammar, naturally <grin>).
* The lexical rules for python are particularly nasty and it took me
* a long time to get it 'right'; i.e., think about it in the proper
* way. Resist changing the lexer unless you've used ANTLR a lot. ;)
*
* I (Terence) tested this by running it on the jython-2.1/Lib
* directory of 40k lines of Python.
*
* REQUIRES ANTLR v3
*/
grammar Python;
tokens {
INDENT;
DEDENT;
}
@lexer::members {
/** Handles context-sensitive lexing of implicit line joining such as
* the case where newline is ignored in cases like this:
* a = [3,
* 4]
*/
int implicitLineJoiningLevel = 0;
int startPos=-1;
}
@header {
package org.ethereum.serpent;
}
@lexer::header {
package org.ethereum.serpent;
}
single_input
: NEWLINE
| simple_stmt
| compound_stmt NEWLINE
;
file_input
: (NEWLINE | stmt)*
;
eval_input
: (NEWLINE)* testlist (NEWLINE)*
;
funcdef
: 'def' NAME parameters COLON suite
{System.out.println("found method def "+$NAME.text);}
;
parameters
: LPAREN (varargslist)? RPAREN
;
varargslist
: defparameter (options {greedy=true;}:COMMA defparameter)*
(COMMA
( STAR NAME (COMMA DOUBLESTAR NAME)?
| DOUBLESTAR NAME
)?
)?
| STAR NAME (COMMA DOUBLESTAR NAME)?
| DOUBLESTAR NAME
;
defparameter
: fpdef (ASSIGN test)?
;
fpdef
: NAME
| LPAREN fplist RPAREN
;
fplist
: fpdef (options {greedy=true;}:COMMA fpdef)* (COMMA)?
;
stmt: simple_stmt
| compound_stmt
;
simple_stmt
: small_stmt (options {greedy=true;}:SEMI small_stmt)* (SEMI)? NEWLINE
;
small_stmt: expr_stmt
| print_stmt
| del_stmt
| pass_stmt
| flow_stmt
| import_stmt
| global_stmt
| exec_stmt
| assert_stmt
;
expr_stmt
: testlist
( augassign testlist
| (ASSIGN testlist)+
)?
;
augassign
: PLUSEQUAL
| MINUSEQUAL
| STAREQUAL
| SLASHEQUAL
| PERCENTEQUAL
| AMPEREQUAL
| VBAREQUAL
| CIRCUMFLEXEQUAL
| LEFTSHIFTEQUAL
| RIGHTSHIFTEQUAL
| DOUBLESTAREQUAL
| DOUBLESLASHEQUAL
;
print_stmt:
'print'
( testlist
| RIGHTSHIFT testlist
)?
;
del_stmt: 'del' exprlist
;
pass_stmt: 'pass'
;
flow_stmt: break_stmt
| continue_stmt
| return_stmt
| raise_stmt
| yield_stmt
;
break_stmt: 'break'
;
continue_stmt: 'continue'
;
return_stmt: 'return' (testlist)?
;
yield_stmt: 'yield' testlist
;
raise_stmt: 'raise' (test (COMMA test (COMMA test)?)?)?
;
import_stmt
: 'import' dotted_as_name (COMMA dotted_as_name)*
| 'from' dotted_name 'import'
(STAR | import_as_name (COMMA import_as_name)*)
;
import_as_name
: NAME (NAME NAME)?
;
dotted_as_name: dotted_name (NAME NAME)?
;
dotted_name: NAME (DOT NAME)*
;
global_stmt: 'global' NAME (COMMA NAME)*
;
exec_stmt: 'exec' expr ('in' test (COMMA test)?)?
;
assert_stmt: 'assert' test (COMMA test)?
;
compound_stmt: if_stmt
| while_stmt
| for_stmt
| try_stmt
| funcdef
| classdef
;
if_stmt: 'if' test COLON suite ('elif' test COLON suite)* ('else' COLON suite)?
;
while_stmt: 'while' test COLON suite ('else' COLON suite)?
;
for_stmt: 'for' exprlist 'in' testlist COLON suite ('else' COLON suite)?
;
try_stmt
: 'try' COLON suite
( (except_clause COLON suite)+ ('else' COLON suite)?
| 'finally' COLON suite
)
;
except_clause: 'except' (test (COMMA test)?)?
;
suite: simple_stmt
| NEWLINE INDENT (stmt)+ DEDENT
;
test: and_test ('or' and_test)*
| lambdef
;
and_test
: not_test ('and' not_test)*
;
not_test
: 'not' not_test
| comparison
;
comparison: expr (comp_op expr)*
;
comp_op: LESS
|GREATER
|EQUAL
|GREATEREQUAL
|LESSEQUAL
|ALT_NOTEQUAL
|NOTEQUAL
|'in'
|'not' 'in'
|'is'
|'is' 'not'
;
expr: xor_expr (VBAR xor_expr)*
;
xor_expr: and_expr (CIRCUMFLEX and_expr)*
;
and_expr: shift_expr (AMPER shift_expr)*
;
shift_expr: arith_expr ((LEFTSHIFT|RIGHTSHIFT) arith_expr)*
;
arith_expr: term ((PLUS|MINUS) term)*
;
term: factor ((STAR | SLASH | PERCENT | DOUBLESLASH ) factor)*
;
factor
: (PLUS|MINUS|TILDE) factor
| power
;
power
: atom (trailer)* (options {greedy=true;}:DOUBLESTAR factor)?
;
atom: LPAREN (testlist)? RPAREN
| LBRACK (listmaker)? RBRACK
| LCURLY (dictmaker)? RCURLY
| BACKQUOTE testlist BACKQUOTE
| NAME
| INT
| LONGINT
| FLOAT
| COMPLEX
| (STRING)+
;
listmaker: test ( list_for | (options {greedy=true;}:COMMA test)* ) (COMMA)?
;
lambdef: 'lambda' (varargslist)? COLON test
;
trailer: LPAREN (arglist)? RPAREN
| LBRACK subscriptlist RBRACK
| DOT NAME
;
subscriptlist
: subscript (options {greedy=true;}:COMMA subscript)* (COMMA)?
;
subscript
: DOT DOT DOT
| test (COLON (test)? (sliceop)?)?
| COLON (test)? (sliceop)?
;
sliceop: COLON (test)?
;
exprlist
: expr (options {k=2;}:COMMA expr)* (COMMA)?
;
testlist
: test (options {k=2;}: COMMA test)* (COMMA)?
;
dictmaker
: test COLON test
(options {k=2;}:COMMA test COLON test)* (COMMA)?
;
classdef: 'class' NAME (LPAREN testlist RPAREN)? COLON suite
{System.out.println("found class def "+$NAME.text);}
;
arglist: argument (COMMA argument)*
( COMMA
( STAR test (COMMA DOUBLESTAR test)?
| DOUBLESTAR test
)?
)?
| STAR test (COMMA DOUBLESTAR test)?
| DOUBLESTAR test
;
argument : test (ASSIGN test)?
;
list_iter: list_for
| list_if
;
list_for: 'for' exprlist 'in' testlist (list_iter)?
;
list_if: 'if' test (list_iter)?
;
LPAREN : '(' {implicitLineJoiningLevel++;} ;
RPAREN : ')' {implicitLineJoiningLevel--;} ;
LBRACK : '[' {implicitLineJoiningLevel++;} ;
RBRACK : ']' {implicitLineJoiningLevel--;} ;
COLON : ':' ;
COMMA : ',' ;
SEMI : ';' ;
PLUS : '+' ;
MINUS : '-' ;
STAR : '*' ;
SLASH : '/' ;
VBAR : '|' ;
AMPER : '&' ;
LESS : '<' ;
GREATER : '>' ;
ASSIGN : '=' ;
PERCENT : '%' ;
BACKQUOTE : '`' ;
LCURLY : '{' {implicitLineJoiningLevel++;} ;
RCURLY : '}' {implicitLineJoiningLevel--;} ;
CIRCUMFLEX : '^' ;
TILDE : '~' ;
EQUAL : '==' ;
NOTEQUAL : '!=' ;
ALT_NOTEQUAL: '<>' ;
LESSEQUAL : '<=' ;
LEFTSHIFT : '<<' ;
GREATEREQUAL : '>=' ;
RIGHTSHIFT : '>>' ;
PLUSEQUAL : '+=' ;
MINUSEQUAL : '-=' ;
DOUBLESTAR : '**' ;
STAREQUAL : '*=' ;
DOUBLESLASH : '//' ;
SLASHEQUAL : '/=' ;
VBAREQUAL : '|=' ;
PERCENTEQUAL : '%=' ;
AMPEREQUAL : '&=' ;
CIRCUMFLEXEQUAL : '^=' ;
LEFTSHIFTEQUAL : '<<=' ;
RIGHTSHIFTEQUAL : '>>=' ;
DOUBLESTAREQUAL : '**=' ;
DOUBLESLASHEQUAL : '//=' ;
DOT : '.' ;
FLOAT
: '.' DIGITS (Exponent)?
| DIGITS ('.' (DIGITS (Exponent)?)? | Exponent)
;
LONGINT
: INT ('l'|'L')
;
fragment
Exponent
: ('e' | 'E') ( '+' | '-' )? DIGITS
;
INT : // Hex
'0' ('x' | 'X') ( '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' )+
('l' | 'L')?
| // Octal
'0' DIGITS*
| '1'..'9' DIGITS*
;
COMPLEX
: INT ('j'|'J')
| FLOAT ('j'|'J')
;
fragment
DIGITS : ( '0' .. '9' )+ ;
NAME: ( 'a' .. 'z' | 'A' .. 'Z' | '_')
( 'a' .. 'z' | 'A' .. 'Z' | '_' | '0' .. '9' )*
;
/** Match various string types. Note that greedy=false implies '''
* should make us exit loop not continue.
*/
STRING
: ('r'|'u'|'ur')?
( '\'\'\'' (options {greedy=false;}:.)* '\'\'\''
| '"""' (options {greedy=false;}:.)* '"""'
| '"' (ESC|~('\\'|'\n'|'"'))* '"'
| '\'' (ESC|~('\\'|'\n'|'\''))* '\''
)
;
fragment
ESC
: '\\' .
;
/** Consume a newline and any whitespace at start of next line */
CONTINUED_LINE
: '\\' ('\r')? '\n' (' '|'\t')* { $channel=HIDDEN; }
;
/** Treat a sequence of blank lines as a single blank line. If
* nested within a (..), {..}, or [..], then ignore newlines.
* If the first newline starts in column one, they are to be ignored.
*/
NEWLINE
: (('\r')? '\n' )+
{if ( startPos==0 || implicitLineJoiningLevel>0 )
$channel=HIDDEN;
}
;
WS : {startPos>0}?=> (' '|'\t')+ {$channel=HIDDEN;}
;
/** Grab everything before a real symbol. Then if newline, kill it
* as this is a blank line. If whitespace followed by comment, kill it
* as it's a comment on a line by itself.
*
* Ignore leading whitespace when nested in [..], (..), {..}.
*/
LEADING_WS
@init {
int spaces = 0;
}
: {startPos==0}?=>
( {implicitLineJoiningLevel>0}? ( ' ' | '\t' )+ {$channel=HIDDEN;}
| ( ' ' { spaces++; }
| '\t' { spaces += 8; spaces -= (spaces \% 8); }
)+
{
// make a string of n spaces where n is column number - 1
char[] indentation = new char[spaces];
for (int i=0; i<spaces; i++) {
indentation[i] = ' ';
}
String s = new String(indentation);
emit(new ClassicToken(LEADING_WS,new String(indentation)));
}
// kill trailing newline if present and then ignore
( ('\r')? '\n' {if (state.token!=null) state.token.setChannel(HIDDEN); else $channel=HIDDEN;})*
// {token.setChannel(99); }
)
;
/** Comments not on line by themselves are turned into newlines.
b = a # end of line comment
or
a = [1, # weird
2]
This rule is invoked directly by nextToken when the comment is in
first column or when comment is on end of nonwhitespace line.
Only match \n here if we didn't start on left edge; let NEWLINE return that.
Kill if newlines if we live on a line by ourselves
Consume any leading whitespace if it starts on left edge.
*/
COMMENT
@init {
$channel=HIDDEN;
}
: {startPos==0}?=> (' '|'\t')* '#' (~'\n')* '\n'+
| {startPos>0}?=> '#' (~'\n')* // let NEWLINE handle \n unless char pos==0 for '#'
;

View File

@ -1,201 +0,0 @@
/*******************************************************************************
* Copyright (c) 2009 Scott Stanchfield
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
grammar Sample;
options {
language = Java;
output = AST;
output=template;
}
@header {
package samples.antlr;
}
@lexer::header {
package samples.antlr;
}
program
: 'program' IDENT '='
(constant | variable | function | procedure | typeDecl)*
'begin'
statement*
'end' IDENT '.'
;
constant
: 'constant' IDENT ':' type ':=' expression ';'
;
variable
: 'var' IDENT (',' IDENT)* ':' type (':=' expression)? ';'
;
type
: 'Integer'
| 'Boolean'
| 'String'
| 'Char'
| IDENT
| typeSpec
;
typeDecl
: 'type' IDENT '=' typeSpec ';'
;
typeSpec
: arrayType
| recordType
| enumType
;
arrayType
: 'array' '[' INTEGER '..' INTEGER ']' 'of' type
;
recordType
: 'record' field* 'end' 'record'
;
field
: IDENT ':' type ';'
;
enumType
: '<' IDENT (',' IDENT)* '>'
;
statement
: assignmentStatement
| ifStatement
| loopStatement
| whileStatement
| procedureCallStatement
;
procedureCallStatement
: IDENT '(' actualParameters? ')' ';'
;
actualParameters
: expression (',' expression)*
;
ifStatement
: 'if' expression 'then' statement+
('elsif' expression 'then' statement+)*
('else' statement+)?
'end' 'if' ';'
;
assignmentStatement
: IDENT ':=' expression ';'
;
exitStatement
: 'exit' 'when' expression ';'
;
whileStatement
: 'while' expression 'loop'
(statement|exitStatement)*
'end' 'loop' ';'
;
loopStatement
: 'loop' (statement|exitStatement)* 'end' 'loop' ';'
;
returnStatement
: 'return' expression ';'
;
procedure
: 'procedure' IDENT '(' parameters? ')' '='
(constant | variable)*
'begin'
statement*
'end' IDENT '.'
;
function
: 'function' IDENT '(' parameters? ')' ':' type '='
(constant | variable)*
'begin'
(statement|returnStatement)*
'end' IDENT '.'
;
parameters
: parameter (',' parameter)*
;
parameter
: 'var'? IDENT ':' type
;
// expressions -- fun time!
term
: IDENT
| '(' expression ')'
| INTEGER
| STRING_LITERAL
| CHAR_LITERAL
| IDENT '(' actualParameters ')'
;
negation
: 'not'* term
;
unary
: ('+' | '-')* negation
;
mult
: unary (('*' | '/' | 'mod') unary)*
;
add
: mult (('+' | '-') mult)*
;
relation
: add (('=' | '/=' | '<' | '<=' | '>=' | '>') add)*
;
expression
: relation (('and' | 'or') relation)*
;
MULTILINE_COMMENT : '/*' .* '*/' {$channel = HIDDEN;} ;
STRING_LITERAL
: '"'
{ StringBuilder b = new StringBuilder(); }
( '"' '"' { b.appendCodePoint('"');}
| c=~('"'|'\r'|'\n') { b.appendCodePoint(c);}
)*
'"'
{ setText(b.toString()); }
;
CHAR_LITERAL
: '\'' . '\'' {setText(getText().substring(1,2));}
;
fragment LETTER : ('a'..'z' | 'A'..'Z') ;
fragment DIGIT : '0'..'9';
INTEGER : DIGIT+ ;
IDENT : LETTER (LETTER | DIGIT)*;
WS : (' ' | '\t' | '\n' | '\r' | '\f')+ {$channel = HIDDEN;};
COMMENT : '//' .* ('\n'|'\r') {$channel = HIDDEN;};

View File

@ -1,10 +0,0 @@
/** https://github.com/rollxx/antlr-php-runtime/blob/master/examples/cminus/Bytecode.stg */
variable(type,name) ::= ".var is <name> <type><\n>"
type_int() ::= "I"
type_char() ::= "C"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,81 +0,0 @@
/*******************************************************************************
* Copyright (c) 2009 Scott Stanchfield
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package samples.antlr;
import org.antlr.runtime.*;
import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.DOTTreeGenerator;
import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup;
public class Test1 {
public static void main(String[] args) throws RecognitionException {
CharStream stream =
new ANTLRStringStream("program XLSample1 =\r\n" +
"/*\r\n" +
" constant one : Integer := 1;\r\n" +
" constant two : Integer := 2 * 3;\r\n" +
" var x, y, z : Integer := 42;\r\n" +
"*/\r\n" +
"\r\n" +
" procedure foo() =\r\n" +
" var x : Integer := 2;\r\n" +
" begin\r\n" +
" end foo.\r\n" +
" procedure fee(y : Integer) =\r\n" +
" var x : Integer := 2;\r\n" +
" begin\r\n" +
" end fee.\r\n" +
" function fie(y : Integer) : Integer =\r\n" +
" var x : Integer := 2;\r\n" +
" begin\r\n" +
" return y;\r\n" +
" end fie.\r\n" +
"begin\r\n" +
"end XLSample1.");
SampleLexer lexer = new SampleLexer(stream);
TokenStream tokenStream = new CommonTokenStream(lexer);
SampleParser parser = new SampleParser(tokenStream);
CommonTree astTree = (CommonTree) parser.program().getTree();
DOTTreeGenerator gen = new DOTTreeGenerator();
StringTemplate st = gen.toDOT(astTree);
String userDir = System.getProperty("user.dir");
String stgFile = userDir + "\\src\\main\\java\\samples\\antlr\\Sample2Asm.stg";
StringTemplateGroup stg = new StringTemplateGroup(stgFile);
parser.setTemplateLib(stg);
RuleReturnScope r = parser.program();
// System.out.println(r.getTemplate().toString());
// System.out.println(st);
/*
Lexical Analysis (scanning)
Semantic Analysis (parsing)
Tree Generation ==> Abstract Syntax Tree (AST)
Code Generation ==> using stg file
Interpretation
*/
System.out.println("ok");
}
}

View File

@ -1,51 +0,0 @@
package samples.netty;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import java.nio.channels.SocketChannel;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 10/04/14 08:20
*/
public class Client {
public static void main(String[] args) throws Exception {
String host = "85.65.126.45";
int port = 10101;
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(workerGroup);
b.channel(NioSocketChannel.class);
b.option(ChannelOption.SO_KEEPALIVE, true);
b.handler(new ChannelInitializer<NioSocketChannel>() {
@Override
public void initChannel(NioSocketChannel ch) throws Exception {
ch.pipeline().addLast(new ClientMessageHandler());
}
});
// Start the client.
ChannelFuture f = b.connect(host, port).sync(); // (5)
// Wait until the connection is closed.
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
}
}
}

View File

@ -1,70 +0,0 @@
package samples.netty;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 10/04/14 08:19
*/
public class ClientMessageHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf input = ((ByteBuf)msg);
try {
int inputSize = input.readableBytes();
byte[] payload = new byte[inputSize];
input.readBytes(payload);
if (payload.length < 5){
System.out.println("Not a Roman server disconnect");
ctx.close();
}
String prefix = new String(payload, 0, 5);
if (!prefix.equals("9191-")){
System.out.println("Not a Roman server disconnect");
ctx.close();
}
String newMessage = new String(payload);
System.out.println(newMessage);
Thread.sleep(1000);
String answer = RomanProtocol.getAnswer(newMessage);
final ByteBuf buffer = ctx.alloc().buffer(answer.length());
buffer.writeBytes(answer.getBytes());
ctx.writeAndFlush(buffer);
// String answer2 = "cool sir 2!!!";
// final ByteBuf helloMessage2 = ctx.alloc().buffer(answer2.length());
// helloMessage2.writeBytes(answer2.getBytes());
// ctx.writeAndFlush(helloMessage2);
} finally {
ReferenceCountUtil.release(input);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}

View File

@ -1,47 +0,0 @@
package samples.netty;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 10/04/14 11:19
*/
public class RomanProtocol {
public static String getAnswer(String msg){
if (msg.equals("9191-Hello"))
return ("9191-Good day sir");
if (msg.equals("9191-Good day sir"))
return ("9191-What is you name");
if (msg.equals("9191-What is you name"))
return ("9191-My Name is Ethereum");
if (msg.matches("9191-My Name is ([\\w])*")) {
String name = msg.substring(16);
return ("9191-Good to see you: " + name);
}
if (msg.matches("9191-Good to see you: ([\\w])*")) {
return ("9191-Hello");
}
return "9191-Sorry I don't understand you";
}
public static void main(String args[]){
System.out.println(getAnswer("9191-My Name is Vasia"));
// 1800-0770-77
}
}

View File

@ -1,69 +0,0 @@
package samples.netty;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 10/04/14 08:20
*/
public class Server {
int port;
public Server(int port) {
this.port = port;
}
public void start(){
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<NioSocketChannel>() {
public void initChannel(NioSocketChannel channel){
channel.pipeline().addLast(new ServerMessageHandler());
};
}).option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
try {
System.out.println("Server started");
ChannelFuture future = bootstrap.bind(port).sync();
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
public static void main(String args[]){
new Server(10101).start();
}
}

View File

@ -1,65 +0,0 @@
package samples.netty;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.util.ReferenceCountUtil;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 10/04/14 08:19
*/
public class ServerMessageHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(final ChannelHandlerContext ctx) {
String helloString = "9191-Hello";
final ByteBuf helloMessage = ctx.alloc().buffer(helloString.length());
helloMessage.writeBytes(helloString.getBytes());
final ChannelFuture channelFuture = ctx.writeAndFlush(helloMessage);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf input = ((ByteBuf)msg);
try {
int inputSize = input.readableBytes();
byte[] payload = new byte[inputSize];
input.readBytes(payload);
String newMessage = new String(payload);
System.out.println(newMessage);
Thread.sleep(1000);
String answer = RomanProtocol.getAnswer(newMessage);
final ByteBuf buffer = ctx.alloc().buffer(answer.length());
buffer.writeBytes(answer.getBytes());
ctx.writeAndFlush(buffer);
} finally {
ReferenceCountUtil.release(input);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.out.println("Client disconnected");
// cause.printStackTrace();
ctx.close();
}
}

View File

@ -1,18 +0,0 @@
package samples.niotut;
import java.nio.channels.SocketChannel;
public class ChangeRequest {
public static final int REGISTER = 1;
public static final int CHANGEOPS = 2;
public SocketChannel socket;
public int type;
public int ops;
public ChangeRequest(SocketChannel socket, int type, int ops) {
this.socket = socket;
this.type = type;
this.ops = ops;
}
}

View File

@ -1,38 +0,0 @@
package samples.niotut;
import java.nio.channels.SocketChannel;
import java.util.LinkedList;
import java.util.List;
public class EchoWorker implements Runnable {
private List queue = new LinkedList();
public void processData(NioServer server, SocketChannel socket, byte[] data, int count) {
byte[] dataCopy = new byte[count];
System.arraycopy(data, 0, dataCopy, 0, count);
synchronized(queue) {
queue.add(new ServerDataEvent(server, socket, dataCopy));
queue.notify();
}
}
public void run() {
ServerDataEvent dataEvent;
while(true) {
// Wait for data to become available
synchronized(queue) {
while(queue.isEmpty()) {
try {
queue.wait();
} catch (InterruptedException e) {
}
}
dataEvent = (ServerDataEvent) queue.remove(0);
}
// Return to sender
dataEvent.server.send(dataEvent.socket, dataEvent.data);
}
}
}

View File

@ -1,403 +0,0 @@
package samples.niotut;
/* BASED ON: http://rox-xmlrpc.sourceforge.net/niotut/#The client */
import org.ethereum.util.Utils;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.util.*;
public class NioClient implements Runnable {
// The host:port combination to connect to
private InetAddress hostAddress;
private int port;
// The selector we'll be monitoring
private Selector selector;
// The buffer into which we'll read data when it's available
private ByteBuffer readBuffer = ByteBuffer.allocate(8192);
// A list of PendingChange instances
private List pendingChanges = new LinkedList();
// Maps a SocketChannel to a list of ByteBuffer instances
private Map pendingData = new HashMap();
// Maps a SocketChannel to a RspHandler
private Map rspHandlers = Collections.synchronizedMap(new HashMap());
public SocketChannel socket;
public RspHandler handler;
public static final String helloString = "22 40 08 91 00 00 00 79 F8 77 80 0B 80 AD 45 74 " +
"68 65 72 65 75 6D 28 2B 2B 29 2F 5A 65 72 6F 47 " +
"6F 78 2F 76 30 2E 34 2E 31 2F 6E 63 75 72 73 65 " +
"73 2F 4C 69 6E 75 78 2F 67 2B 2B 07 82 76 5F B8 " +
"40 D8 D6 0C 25 80 FA 79 5C FC 03 13 EF DE BA 86 " +
"9D 21 94 E7 9E 7C B2 B5 22 F7 82 FF A0 39 2C BB " +
"AB 8D 1B AC 30 12 08 B1 37 E0 DE 49 98 33 4F 3B " +
"CF 73 FA 11 7E F2 13 F8 74 17 08 9F EA F8 4C 21 " +
"B0 ";
public static final String pingString = "22 40 08 91 00 00 00 02 C1 02 ";
public static final String pongString = "22 40 08 91 00 00 00 02 C1 03 ";
public static final String getPeersString = "22 40 08 91 00 00 00 02 C1 10 ";
public static final String getTransactions = "22 40 08 91 00 00 00 02 C1 16 ";
public static final String getChain = "22 40 08 91 00 00 00 26 F8 24 14 " +
"AB 6B 9A 56 13 97 0F AA 77 1B 12 D4 49 B2 E9 BB 92 5A B7 A3 69 F0 A4 B8 6B 28 6E 9D 54 00 99 CF " +
"82 01 00 ";
public static final String getTxString = "22 40 08 91 00 00 00 02 C1 16 ";
public NioClient(InetAddress hostAddress, int port) throws IOException {
this.hostAddress = hostAddress;
this.port = port;
this.selector = this.initSelector();
// Start a new connection
this.socket = this.initiateConnection();
// Register the response handler
this.handler = new RspHandler();
this.rspHandlers.put(socket, handler);
}
public void send(byte[] data) throws IOException {
// And queue the data we want written
synchronized (this.pendingData) {
List queue = (List) this.pendingData.get(socket);
if (queue == null) {
queue = new ArrayList();
this.pendingData.put(socket, queue);
}
queue.add(ByteBuffer.wrap(data));
}
// Finally, wake up our selecting thread so it can make the required changes
this.selector.wakeup();
}
public void run() {
while (true) {
try {
// Process any pending changes
synchronized (this.pendingChanges) {
Iterator changes = this.pendingChanges.iterator();
while (changes.hasNext()) {
ChangeRequest change = (ChangeRequest) changes.next();
switch (change.type) {
case ChangeRequest.CHANGEOPS:
SelectionKey key = change.socket.keyFor(this.selector);
key.interestOps(change.ops);
break;
case ChangeRequest.REGISTER:
change.socket.register(this.selector, change.ops);
break;
}
}
this.pendingChanges.clear();
}
// Wait for an event one of the registered channels
// THIS ONE ACTUALLY BLOCKS AND SHOULD AWAKE WHEN SOME I/O HAPPENS
this.selector.select();
// Iterate over the set of keys for which events are available
Iterator selectedKeys = this.selector.selectedKeys().iterator();
while (selectedKeys.hasNext()) {
SelectionKey key = (SelectionKey) selectedKeys.next();
selectedKeys.remove();
if (!key.isValid()) {
continue;
}
// Check what event is available and deal with it
if (key.isConnectable()) {
this.establishConnection(key);
} else if (key.isReadable()) {
this.read(key);
} else if (key.isWritable()) {
this.write(key);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void read(SelectionKey key) throws IOException {
SocketChannel socketChannel = (SocketChannel) key.channel();
// Clear out our read buffer so it's ready for new data
this.readBuffer.clear();
// Attempt to read off the channel
int numRead;
try {
numRead = socketChannel.read(this.readBuffer);
System.out.println("reading: " + numRead);
// key.interestOps(SelectionKey.OP_WRITE);
} catch (IOException e) {
// The remote forcibly closed the connection, cancel
// the selection key and close the channel.
key.cancel();
socketChannel.close();
return;
}
if (numRead == -1) {
// Remote entity shut the socket down cleanly. Do the
// same from our end and cancel the channel.
// key.channel().close();
// key.cancel();
return;
}
// Handle the response
this.handleResponse(socketChannel, this.readBuffer.array(), numRead);
}
private void handleResponse(SocketChannel socketChannel, byte[] data, int numRead) throws IOException {
// Make a correctly sized copy of the data before handing it
// to the client
byte[] rspData = new byte[numRead];
System.arraycopy(data, 0, rspData, 0, numRead);
// Look up the handler for this channel
RspHandler handler = (RspHandler) this.rspHandlers.get(socketChannel);
// And pass the response to it
if (handler.handleResponse(rspData)) {
// The handler has seen enough, close the connection
// socketChannel.close();
// socketChannel.keyFor(this.selector).cancel();
}
}
private void write(SelectionKey key) throws IOException {
SocketChannel socketChannel = (SocketChannel) key.channel();
synchronized (this.pendingData) {
List queue = (List) this.pendingData.get(socketChannel);
// Write until there's not more data ...
while (queue != null && !queue.isEmpty()) {
ByteBuffer buf = (ByteBuffer) queue.get(0);
byte[] packet = buf.array();
System.out.print("write: ");
Utils.printHexStringForByteArray(packet);
socketChannel.write(buf);
if (buf.remaining() > 0) {
// ... or the socket's buffer fills up
break;
}
queue.remove(0);
}
// key.interestOps(SelectionKey.OP_READ);
if (queue == null || queue.isEmpty()) {
// We wrote away all data, so we're no longer interested
// in writing on this socket. Switch back to waiting for
// data.
key.interestOps(SelectionKey.OP_READ);
}
}
}
private void establishConnection(SelectionKey key) throws IOException {
SocketChannel socketChannel = (SocketChannel) key.channel();
// Finish the connection. If the connection operation failed
// this will raise an IOException.
try {
socketChannel.finishConnect();
} catch (IOException e) {
// Cancel the channel's registration with our selector
System.out.println(e);
key.cancel();
return;
}
// Register an interest in writing on this channel
key.interestOps(SelectionKey.OP_WRITE);
}
private SocketChannel initiateConnection() throws IOException {
// Create a non-blocking socket channel
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
// Kick off connection establishment
socketChannel.connect(new InetSocketAddress(this.hostAddress, this.port));
// Queue a channel registration since the caller is not the
// selecting thread. As part of the registration we'll register
// an interest in connection events. These are raised when a channel
// is ready to complete connection establishment.
synchronized(this.pendingChanges) {
this.pendingChanges.add(new ChangeRequest(socketChannel,
ChangeRequest.REGISTER, SelectionKey.OP_CONNECT));
}
return socketChannel;
}
private Selector initSelector() throws IOException {
// Create a new selector
return SelectorProvider.provider().openSelector();
}
public static void main(String[] args) {
try {
NioClient client = new NioClient(InetAddress.getByName("localhost"), 20202);
Thread t = new Thread(client, "ClientThread");
t.setDaemon(true);
t.start();
// client.send(new byte[0]);
// client.handler.waitForResponse();
Thread.sleep(2000);
System.out.println("\nsending HELLO");
client.enableWriting();
// client.send(hexStringToByteArr(helloString));
Thread.sleep(100);
System.out.println("\nsending PONG");
// client.enableWriting();
// client.send(hexStringToByteArr(pongString));
Thread.sleep(100);
System.out.println("\nsending GETCHAIN");
// client.enableWriting();
// client.send(hexStringToByteArr(getChain));
// System.out.println("\nsending PING");
// client.send(hexStringToByteArr(pingString));
// client.handler.waitForResponse();
System.out.println("SLEEPING");
Thread.sleep(5000);
client.handler.waitForResponse();
// System.out.println("\nsending GETCHAIN");
// client.send(hexStringToByteArr(getChain));
// client.handler.waitForResponse();
// System.out.println("\nsending GETPEERS");
// client.send(hexStringToByteArr(getPeersString));
// client.handler.waitForResponse();
// client.handler.waitForResponse();
// System.out.println("\nsending GETTRANSACTIONS");
// client.send(hexStringToByteArr(getTransactions));
System.out.println("\nsleeping 5 secs before death");
Thread.sleep(5000);
client.socket.close();
/*
client.send(hexStringToByteArr(helloString));
client.handler.waitForResponse();
System.out.println("");
client.send(hexStringToByteArr(getPeersString));
client.handler.waitForResponse();
System.out.println("");
client.handler.waitForResponse();
System.out.println("");
client.handler.waitForResponse();
*/
} catch (Exception e) {
e.printStackTrace();
}
}
public static byte[] hexStringToByteArr(String hexString){
String hexSymbols = "0123456789ABCDEF";
int arrSize = (int) (hexString.length() / 3);
byte[] result = new byte[arrSize];
for (int i = 0; i < arrSize; ++i){
int digit1 = hexSymbols.indexOf( hexString.charAt(i * 3) );
int digit2 = hexSymbols.indexOf( hexString.charAt(i * 3 + 1) );
result[i] = (byte) (digit1 * 16 + digit2);
}
return result;
}
public void enableWriting(){
SelectionKey key = this.socket.keyFor(this.selector);
key.interestOps(SelectionKey.OP_WRITE | SelectionKey.OP_READ);
}
public void enableOnlyReading(){
SelectionKey key = this.socket.keyFor(this.selector);
key.interestOps(SelectionKey.OP_READ);
}
}

View File

@ -1,213 +0,0 @@
package samples.niotut;
/* BASED ON: http://rox-xmlrpc.sourceforge.net/niotut/#The client */
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.util.*;
public class NioServer implements Runnable {
// The host:port combination to listen on
private InetAddress hostAddress;
private int port;
// The channel on which we'll accept connections
private ServerSocketChannel serverChannel;
// The selector we'll be monitoring
private Selector selector;
// The buffer into which we'll read data when it's available
private ByteBuffer readBuffer = ByteBuffer.allocate(8192);
private EchoWorker worker;
// A list of PendingChange instances
private List pendingChanges = new LinkedList();
// Maps a SocketChannel to a list of ByteBuffer instances
private Map pendingData = new HashMap();
public NioServer(InetAddress hostAddress, int port, EchoWorker worker) throws IOException {
this.hostAddress = hostAddress;
this.port = port;
this.selector = this.initSelector();
this.worker = worker;
}
public void send(SocketChannel socket, byte[] data) {
synchronized (this.pendingChanges) {
// Indicate we want the interest ops set changed
this.pendingChanges.add(new ChangeRequest(socket, ChangeRequest.CHANGEOPS, SelectionKey.OP_WRITE));
// And queue the data we want written
synchronized (this.pendingData) {
List queue = (List) this.pendingData.get(socket);
if (queue == null) {
queue = new ArrayList();
this.pendingData.put(socket, queue);
}
queue.add(ByteBuffer.wrap(data));
}
}
// Finally, wake up our selecting thread so it can make the required changes
this.selector.wakeup();
}
public void run() {
while (true) {
try {
// Process any pending changes
synchronized (this.pendingChanges) {
Iterator changes = this.pendingChanges.iterator();
while (changes.hasNext()) {
ChangeRequest change = (ChangeRequest) changes.next();
switch (change.type) {
case ChangeRequest.CHANGEOPS:
SelectionKey key = change.socket.keyFor(this.selector);
key.interestOps(change.ops);
}
}
this.pendingChanges.clear();
}
// Wait for an event one of the registered channels
System.out.println("accepting");
this.selector.select();
// Iterate over the set of keys for which events are available
Iterator selectedKeys = this.selector.selectedKeys().iterator();
while (selectedKeys.hasNext()) {
SelectionKey key = (SelectionKey) selectedKeys.next();
selectedKeys.remove();
if (!key.isValid()) {
continue;
}
// Check what event is available and deal with it
if (key.isAcceptable()) {
System.out.println("new channel");
this.accept(key);
} else if (key.isReadable()) {
System.out.println("reading");
this.read(key);
} else if (key.isWritable()) {
System.out.println("writing");
this.write(key);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void accept(SelectionKey key) throws IOException {
// For an accept to be pending the channel must be a server socket channel.
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
// Accept the connection and make it non-blocking
SocketChannel socketChannel = serverSocketChannel.accept();
Socket socket = socketChannel.socket();
socketChannel.configureBlocking(false);
// Register the new SocketChannel with our Selector, indicating
// we'd like to be notified when there's data waiting to be read
socketChannel.register(this.selector, SelectionKey.OP_READ);
}
private void read(SelectionKey key) throws IOException {
SocketChannel socketChannel = (SocketChannel) key.channel();
// Clear out our read buffer so it's ready for new data
this.readBuffer.clear();
// Attempt to read off the channel
int numRead;
try {
numRead = socketChannel.read(this.readBuffer);
} catch (IOException e) {
// The remote forcibly closed the connection, cancel
// the selection key and close the channel.
key.cancel();
socketChannel.close();
return;
}
if (numRead == -1) {
// Remote entity shut the socket down cleanly. Do the
// same from our end and cancel the channel.
key.channel().close();
key.cancel();
return;
}
// Hand the data off to our worker thread
this.worker.processData(this, socketChannel, this.readBuffer.array(), numRead);
}
private void write(SelectionKey key) throws IOException {
SocketChannel socketChannel = (SocketChannel) key.channel();
synchronized (this.pendingData) {
List queue = (List) this.pendingData.get(socketChannel);
// Write until there's not more data ...
while (!queue.isEmpty()) {
ByteBuffer buf = (ByteBuffer) queue.get(0);
socketChannel.write(buf);
if (buf.remaining() > 0) {
// ... or the socket's buffer fills up
break;
}
queue.remove(0);
}
if (queue.isEmpty()) {
// We wrote away all data, so we're no longer interested
// in writing on this socket. Switch back to waiting for
// data.
key.interestOps(SelectionKey.OP_READ);
}
}
}
private Selector initSelector() throws IOException {
// Create a new selector
Selector socketSelector = SelectorProvider.provider().openSelector();
// Create a new non-blocking server socket channel
this.serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
// Bind the server socket to the specified address and port
InetSocketAddress isa = new InetSocketAddress(this.hostAddress, this.port);
serverChannel.socket().bind(isa);
// Register the server socket channel, indicating an interest in
// accepting new connections
serverChannel.register(socketSelector, SelectionKey.OP_ACCEPT);
return socketSelector;
}
public static void main(String[] args) {
try {
EchoWorker worker = new EchoWorker();
new Thread(worker).start();
new Thread(new NioServer(null, 9090, worker)).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -1,107 +0,0 @@
package samples.niotut;
import org.ethereum.net.RLP;
import org.ethereum.util.Utils;
import java.util.LinkedList;
import java.util.Queue;
public class RspHandler {
public Queue<byte[]> packetsRecived = new LinkedList<byte[]>();
public synchronized boolean handleResponse(byte[] rsp) {
packetsRecived.add(rsp);
this.notify();
return true;
}
public synchronized void waitForResponse() {
while(packetsRecived.isEmpty()) {
try {
this.wait();
} catch (InterruptedException e) {
}
}
while (!packetsRecived.isEmpty()) {
byte[] rsp = packetsRecived.remove();
Utils.printHexStringForByteArray(rsp);
if (rsp.length < 9){
// Can't be any ether packet
}
boolean noMoreMessages = false;
// 22 40 08 91 - magic packet
if ((rsp[0] & 0xFF) == 0x22 &&
(rsp[1] & 0xFF) == 0x40 &&
(rsp[2] & 0xFF) == 0x08 &&
(rsp[3] & 0xFF) == 0x91 ){
// Got ethereum message
}
int numMessages = 0;
// count number of messages in the packet
for (int i = 0; i < rsp.length - 3; ++i){
if ( (rsp[i + 0] & 0xFF) == 0x22 &&
(rsp[i + 1] & 0xFF) == 0x40 &&
(rsp[i + 2] & 0xFF) == 0x08 &&
(rsp[i + 3] & 0xFF) == 0x91 ){
++numMessages;
}
}
System.out.println("This packet contains: " + numMessages + " messages");
for (int i = 0; i < numMessages; ++i){
// Callc message length
int messageLength = ((rsp[4] & 0xFF) << 24) +
((rsp[5] & 0xFF) << 16) +
((rsp[6] & 0xFF) << 8) +
((rsp[7] & 0xFF));
byte[] msgPayload = new byte[messageLength];
System.out.println("payload size: " + msgPayload.length );
System.out.println("packet size: " + messageLength );
System.arraycopy(rsp, 8, msgPayload, 0, messageLength);
Utils.printHexStringForByteArray(msgPayload);
Queue<Integer> index = new LinkedList<Integer>();
RLP.fullTraverse(msgPayload, 0, 0, msgPayload.length, 1, index);
// Message msg = MessageFactory.createMessage(msgPayload, index);
// System.out.println("msg: " + msg);
// shift next message to the start of the packet array
if (i + 1 < numMessages){
System.arraycopy(rsp, msgPayload.length + 8, rsp, 0, rsp.length - msgPayload.length - 8);
}
}
System.out.println();
}
}
}

View File

@ -1,16 +0,0 @@
package samples.niotut;
import java.nio.channels.SocketChannel;
class ServerDataEvent {
public NioServer server;
public SocketChannel socket;
public byte[] data;
public ServerDataEvent(NioServer server, SocketChannel socket, byte[] data) {
this.server = server;
this.socket = socket;
this.data = data;
}
}

View File

@ -1,74 +0,0 @@
group Bytecode;
program(globals,functions) ::= <<
.class public Wrapper
.super java/lang/Object
<globals>
<functions>
>>
variable(type,name) ::= ".var is <name> <type><\n>"
globalVariable(type,name) ::= ".field <name> <type><\n>"
function(type,name,args,locals,stats) ::= <<
.method <name>(<args:{<it.type>}>)<type>
<locals>
<stats; separator="\n">
return
.end method
>>
type_int() ::= "I"
type_char() ::= "C"
type_user_object(name) ::= "L<name>;"
parameter(type,name) ::= "<type> <name>"
statement(expr) ::= "<expr>"
statementList(locals,stats) ::= <<
<locals>
<stats; separator="\n">
>>
forLoop(e1,e2,e3,locals,stats) ::= <<
<e1>
start:
<e2>
bf exit
<locals>
<stats; separator="\n">
<e3>
goto start
exit:
>>
assign(lhs,rhs) ::= <<
<rhs>
store <lhs>
>>
equals(left,right) ::= <<
<left>
<right>
equals
>>
lessThan(left,right) ::= <<
<left>
<right>
lt
>>
add(left,right) ::= <<
<left>
<right>
add
>>
refVar(id) ::= "push <id>"
iconst(value) ::= "iconst <value>"

View File

@ -1,152 +0,0 @@
grammar CMinus;
options {output=template;}
scope slist {
List locals; // must be defined one per semicolon
List stats;
}
/*
@slist::init {
locals = new ArrayList();
stats = new ArrayList();
}
*/
@header {
package samples.stg;
import org.antlr.stringtemplate.*;
}
@lexer::header {
package samples.stg;
}
program
scope {
List globals;
List functions;
}
@init {
$program::globals = new ArrayList();
$program::functions = new ArrayList();
}
: declaration+
-> program(globals={$program::globals},functions={$program::functions})
;
declaration
: variable {$program::globals.add($variable.st);}
| f=function {$program::functions.add($f.st);}
;
// ack is $function.st ambig? It can mean the rule's dyn scope or
// the ref in this rule. Ack.
variable
: type declarator ';'
-> {$function.size()>0 && $function::name==null}?
globalVariable(type={$type.st},name={$declarator.st})
-> variable(type={$type.st},name={$declarator.st})
;
declarator
: ID -> {new StringTemplate($ID.text)}
;
function
scope {
String name;
}
scope slist;
@init {
$slist::locals = new ArrayList();
$slist::stats = new ArrayList();
}
: type ID {$function::name=$ID.text;}
'(' ( p+=formalParameter ( ',' p+=formalParameter )* )? ')'
block
-> function(type={$type.st}, name={$function::name},
locals={$slist::locals},
stats={$slist::stats},
args={$p})
;
formalParameter
: type declarator
-> parameter(type={$type.st},name={$declarator.st})
;
type
: 'int' -> type_int()
| 'char' -> type_char()
| ID -> type_user_object(name={$ID.text})
;
block
: '{'
( variable {$slist::locals.add($variable.st);} )*
( stat {$slist::stats.add($stat.st);})*
'}'
;
stat
scope slist;
@init {
$slist::locals = new ArrayList();
$slist::stats = new ArrayList();
}
: forStat -> {$forStat.st}
| expr ';' -> statement(expr={$expr.st})
| block -> statementList(locals={$slist::locals}, stats={$slist::stats})
| assignStat ';' -> {$assignStat.st}
| ';' -> {new StringTemplate(";")}
;
forStat
scope slist;
@init {
$slist::locals = new ArrayList();
$slist::stats = new ArrayList();
}
: 'for' '(' e1=assignStat ';' e2=expr ';' e3=assignStat ')' block
-> forLoop(e1={$e1.st},e2={$e2.st},e3={$e3.st},
locals={$slist::locals}, stats={$slist::stats})
;
assignStat
: ID '=' expr -> assign(lhs={$ID.text}, rhs={$expr.st})
;
expr: condExpr -> {$condExpr.st}
;
condExpr
: a=aexpr
( ( '==' b=aexpr -> equals(left={$a.st},right={$b.st})
| '<' b=aexpr -> lessThan(left={$a.st},right={$b.st})
)
| -> {$a.st} // else just aexpr
)
;
aexpr
: (a=atom -> {$a.st})
( '+' b=atom -> add(left={$aexpr.st}, right={$b.st}) )*
;
atom
: ID -> refVar(id={$ID.text})
| INT -> iconst(value={$INT.text})
| '(' expr ')' -> {$expr.st}
;
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
INT : ('0'..'9')+
;
WS : (' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;}
;

View File

@ -1,824 +0,0 @@
// $ANTLR 3.5.2 E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g 2014-04-27 13:24:16
package samples.stg;
import org.antlr.runtime.*;
import java.util.Stack;
import java.util.List;
import java.util.ArrayList;
@SuppressWarnings("all")
public class CMinusLexer extends Lexer {
public static final int EOF=-1;
public static final int T__7=7;
public static final int T__8=8;
public static final int T__9=9;
public static final int T__10=10;
public static final int T__11=11;
public static final int T__12=12;
public static final int T__13=13;
public static final int T__14=14;
public static final int T__15=15;
public static final int T__16=16;
public static final int T__17=17;
public static final int T__18=18;
public static final int T__19=19;
public static final int ID=4;
public static final int INT=5;
public static final int WS=6;
// delegates
// delegators
public Lexer[] getDelegates() {
return new Lexer[] {};
}
public CMinusLexer() {}
public CMinusLexer(CharStream input) {
this(input, new RecognizerSharedState());
}
public CMinusLexer(CharStream input, RecognizerSharedState state) {
super(input,state);
}
@Override public String getGrammarFileName() { return "E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g"; }
// $ANTLR start "T__7"
public final void mT__7() throws RecognitionException {
try {
int _type = T__7;
int _channel = DEFAULT_TOKEN_CHANNEL;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:6:6: ( '(' )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:6:8: '('
{
match('(');
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "T__7"
// $ANTLR start "T__8"
public final void mT__8() throws RecognitionException {
try {
int _type = T__8;
int _channel = DEFAULT_TOKEN_CHANNEL;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:7:6: ( ')' )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:7:8: ')'
{
match(')');
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "T__8"
// $ANTLR start "T__9"
public final void mT__9() throws RecognitionException {
try {
int _type = T__9;
int _channel = DEFAULT_TOKEN_CHANNEL;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:8:6: ( '+' )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:8:8: '+'
{
match('+');
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "T__9"
// $ANTLR start "T__10"
public final void mT__10() throws RecognitionException {
try {
int _type = T__10;
int _channel = DEFAULT_TOKEN_CHANNEL;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:9:7: ( ',' )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:9:9: ','
{
match(',');
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "T__10"
// $ANTLR start "T__11"
public final void mT__11() throws RecognitionException {
try {
int _type = T__11;
int _channel = DEFAULT_TOKEN_CHANNEL;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:10:7: ( ';' )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:10:9: ';'
{
match(';');
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "T__11"
// $ANTLR start "T__12"
public final void mT__12() throws RecognitionException {
try {
int _type = T__12;
int _channel = DEFAULT_TOKEN_CHANNEL;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:11:7: ( '<' )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:11:9: '<'
{
match('<');
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "T__12"
// $ANTLR start "T__13"
public final void mT__13() throws RecognitionException {
try {
int _type = T__13;
int _channel = DEFAULT_TOKEN_CHANNEL;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:12:7: ( '=' )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:12:9: '='
{
match('=');
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "T__13"
// $ANTLR start "T__14"
public final void mT__14() throws RecognitionException {
try {
int _type = T__14;
int _channel = DEFAULT_TOKEN_CHANNEL;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:13:7: ( '==' )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:13:9: '=='
{
match("==");
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "T__14"
// $ANTLR start "T__15"
public final void mT__15() throws RecognitionException {
try {
int _type = T__15;
int _channel = DEFAULT_TOKEN_CHANNEL;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:14:7: ( 'char' )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:14:9: 'char'
{
match("char");
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "T__15"
// $ANTLR start "T__16"
public final void mT__16() throws RecognitionException {
try {
int _type = T__16;
int _channel = DEFAULT_TOKEN_CHANNEL;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:15:7: ( 'for' )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:15:9: 'for'
{
match("for");
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "T__16"
// $ANTLR start "T__17"
public final void mT__17() throws RecognitionException {
try {
int _type = T__17;
int _channel = DEFAULT_TOKEN_CHANNEL;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:16:7: ( 'int' )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:16:9: 'int'
{
match("int");
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "T__17"
// $ANTLR start "T__18"
public final void mT__18() throws RecognitionException {
try {
int _type = T__18;
int _channel = DEFAULT_TOKEN_CHANNEL;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:17:7: ( '{' )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:17:9: '{'
{
match('{');
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "T__18"
// $ANTLR start "T__19"
public final void mT__19() throws RecognitionException {
try {
int _type = T__19;
int _channel = DEFAULT_TOKEN_CHANNEL;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:18:7: ( '}' )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:18:9: '}'
{
match('}');
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "T__19"
// $ANTLR start "ID"
public final void mID() throws RecognitionException {
try {
int _type = ID;
int _channel = DEFAULT_TOKEN_CHANNEL;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:145:5: ( ( 'a' .. 'z' | 'A' .. 'Z' | '_' ) ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )* )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:145:9: ( 'a' .. 'z' | 'A' .. 'Z' | '_' ) ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )*
{
if ( (input.LA(1) >= 'A' && input.LA(1) <= 'Z')||input.LA(1)=='_'||(input.LA(1) >= 'a' && input.LA(1) <= 'z') ) {
input.consume();
}
else {
MismatchedSetException mse = new MismatchedSetException(null,input);
recover(mse);
throw mse;
}
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:145:33: ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' )*
loop1:
while (true) {
int alt1=2;
int LA1_0 = input.LA(1);
if ( ((LA1_0 >= '0' && LA1_0 <= '9')||(LA1_0 >= 'A' && LA1_0 <= 'Z')||LA1_0=='_'||(LA1_0 >= 'a' && LA1_0 <= 'z')) ) {
alt1=1;
}
switch (alt1) {
case 1 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:
{
if ( (input.LA(1) >= '0' && input.LA(1) <= '9')||(input.LA(1) >= 'A' && input.LA(1) <= 'Z')||input.LA(1)=='_'||(input.LA(1) >= 'a' && input.LA(1) <= 'z') ) {
input.consume();
}
else {
MismatchedSetException mse = new MismatchedSetException(null,input);
recover(mse);
throw mse;
}
}
break;
default :
break loop1;
}
}
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "ID"
// $ANTLR start "INT"
public final void mINT() throws RecognitionException {
try {
int _type = INT;
int _channel = DEFAULT_TOKEN_CHANNEL;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:148:5: ( ( '0' .. '9' )+ )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:148:7: ( '0' .. '9' )+
{
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:148:7: ( '0' .. '9' )+
int cnt2=0;
loop2:
while (true) {
int alt2=2;
int LA2_0 = input.LA(1);
if ( ((LA2_0 >= '0' && LA2_0 <= '9')) ) {
alt2=1;
}
switch (alt2) {
case 1 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:
{
if ( (input.LA(1) >= '0' && input.LA(1) <= '9') ) {
input.consume();
}
else {
MismatchedSetException mse = new MismatchedSetException(null,input);
recover(mse);
throw mse;
}
}
break;
default :
if ( cnt2 >= 1 ) break loop2;
EarlyExitException eee = new EarlyExitException(2, input);
throw eee;
}
cnt2++;
}
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "INT"
// $ANTLR start "WS"
public final void mWS() throws RecognitionException {
try {
int _type = WS;
int _channel = DEFAULT_TOKEN_CHANNEL;
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:151:5: ( ( ' ' | '\\t' | '\\r' | '\\n' )+ )
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:151:9: ( ' ' | '\\t' | '\\r' | '\\n' )+
{
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:151:9: ( ' ' | '\\t' | '\\r' | '\\n' )+
int cnt3=0;
loop3:
while (true) {
int alt3=2;
int LA3_0 = input.LA(1);
if ( ((LA3_0 >= '\t' && LA3_0 <= '\n')||LA3_0=='\r'||LA3_0==' ') ) {
alt3=1;
}
switch (alt3) {
case 1 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:
{
if ( (input.LA(1) >= '\t' && input.LA(1) <= '\n')||input.LA(1)=='\r'||input.LA(1)==' ' ) {
input.consume();
}
else {
MismatchedSetException mse = new MismatchedSetException(null,input);
recover(mse);
throw mse;
}
}
break;
default :
if ( cnt3 >= 1 ) break loop3;
EarlyExitException eee = new EarlyExitException(3, input);
throw eee;
}
cnt3++;
}
_channel=HIDDEN;
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "WS"
@Override
public void mTokens() throws RecognitionException {
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:8: ( T__7 | T__8 | T__9 | T__10 | T__11 | T__12 | T__13 | T__14 | T__15 | T__16 | T__17 | T__18 | T__19 | ID | INT | WS )
int alt4=16;
switch ( input.LA(1) ) {
case '(':
{
alt4=1;
}
break;
case ')':
{
alt4=2;
}
break;
case '+':
{
alt4=3;
}
break;
case ',':
{
alt4=4;
}
break;
case ';':
{
alt4=5;
}
break;
case '<':
{
alt4=6;
}
break;
case '=':
{
int LA4_7 = input.LA(2);
if ( (LA4_7=='=') ) {
alt4=8;
}
else {
alt4=7;
}
}
break;
case 'c':
{
int LA4_8 = input.LA(2);
if ( (LA4_8=='h') ) {
int LA4_18 = input.LA(3);
if ( (LA4_18=='a') ) {
int LA4_21 = input.LA(4);
if ( (LA4_21=='r') ) {
int LA4_24 = input.LA(5);
if ( ((LA4_24 >= '0' && LA4_24 <= '9')||(LA4_24 >= 'A' && LA4_24 <= 'Z')||LA4_24=='_'||(LA4_24 >= 'a' && LA4_24 <= 'z')) ) {
alt4=14;
}
else {
alt4=9;
}
}
else {
alt4=14;
}
}
else {
alt4=14;
}
}
else {
alt4=14;
}
}
break;
case 'f':
{
int LA4_9 = input.LA(2);
if ( (LA4_9=='o') ) {
int LA4_19 = input.LA(3);
if ( (LA4_19=='r') ) {
int LA4_22 = input.LA(4);
if ( ((LA4_22 >= '0' && LA4_22 <= '9')||(LA4_22 >= 'A' && LA4_22 <= 'Z')||LA4_22=='_'||(LA4_22 >= 'a' && LA4_22 <= 'z')) ) {
alt4=14;
}
else {
alt4=10;
}
}
else {
alt4=14;
}
}
else {
alt4=14;
}
}
break;
case 'i':
{
int LA4_10 = input.LA(2);
if ( (LA4_10=='n') ) {
int LA4_20 = input.LA(3);
if ( (LA4_20=='t') ) {
int LA4_23 = input.LA(4);
if ( ((LA4_23 >= '0' && LA4_23 <= '9')||(LA4_23 >= 'A' && LA4_23 <= 'Z')||LA4_23=='_'||(LA4_23 >= 'a' && LA4_23 <= 'z')) ) {
alt4=14;
}
else {
alt4=11;
}
}
else {
alt4=14;
}
}
else {
alt4=14;
}
}
break;
case '{':
{
alt4=12;
}
break;
case '}':
{
alt4=13;
}
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case '_':
case 'a':
case 'b':
case 'd':
case 'e':
case 'g':
case 'h':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
{
alt4=14;
}
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{
alt4=15;
}
break;
case '\t':
case '\n':
case '\r':
case ' ':
{
alt4=16;
}
break;
default:
NoViableAltException nvae =
new NoViableAltException("", 4, 0, input);
throw nvae;
}
switch (alt4) {
case 1 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:10: T__7
{
mT__7();
}
break;
case 2 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:15: T__8
{
mT__8();
}
break;
case 3 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:20: T__9
{
mT__9();
}
break;
case 4 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:25: T__10
{
mT__10();
}
break;
case 5 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:31: T__11
{
mT__11();
}
break;
case 6 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:37: T__12
{
mT__12();
}
break;
case 7 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:43: T__13
{
mT__13();
}
break;
case 8 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:49: T__14
{
mT__14();
}
break;
case 9 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:55: T__15
{
mT__15();
}
break;
case 10 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:61: T__16
{
mT__16();
}
break;
case 11 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:67: T__17
{
mT__17();
}
break;
case 12 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:73: T__18
{
mT__18();
}
break;
case 13 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:79: T__19
{
mT__19();
}
break;
case 14 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:85: ID
{
mID();
}
break;
case 15 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:88: INT
{
mINT();
}
break;
case 16 :
// E:\\WorkingArea\\ethereumJ\\src\\main\\java\\samples\\stg\\CMinus.g:1:92: WS
{
mWS();
}
break;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +0,0 @@
package samples.stg;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 25/04/14 17:06
*/
public class GenParser {
public static void main(String args[]){
String userDir = System.getProperty("user.dir");
org.antlr.Tool.main(new String[]{userDir + "\\src\\main\\java\\samples\\stg\\CMinus.g"});
}
}

View File

@ -1,55 +0,0 @@
group Java;
program(globals,functions) ::= <<
class Wrapper {
<globals; separator="\n">
<functions; separator="\n">
}
>>
variable(type,name) ::= "<type> <name>;"
globalVariable ::= variable
function(type,name,args,locals,stats) ::= <<
<type> <name>(<args; separator=", ">) {
<locals; separator="\n">
<stats; separator="\n">
}
>>
type_int() ::= "int"
type_char() ::= "char"
type_user_object(name) ::= "<name>"
parameter(type,name) ::= "<type> <name>"
statement(expr) ::= "<expr>;"
statementList(locals,stats) ::= <<
{
<locals; separator="\n">
<stats; separator="\n">
}<\n>
>>
forLoop(e1,e2,e3,locals,stats) ::= <<
for (<e1> <e2>; <e3>) {
<locals; separator="\n">
<stats; separator="\n">
}
>>
assign(lhs,rhs) ::= "<lhs> = <rhs>;"
equals(left,right) ::= "<left> == <right>"
lessThan(left,right) ::= "<left> \< <right>"
add(left,right) ::= "<left> + <right>"
refVar(id) ::= "<id>"
iconst(value) ::= "<value>"

View File

@ -1,30 +0,0 @@
package samples.stg;
import java.io.*;
import org.antlr.runtime.*;
import org.antlr.stringtemplate.*;
import org.antlr.stringtemplate.language.*;
public class Main {
public static StringTemplateGroup templates;
public static void main(String[] args) throws Exception {
String templateFileName;
String userDir = System.getProperty("user.dir");
templateFileName = userDir + "\\src\\main\\java\\samples\\stg\\Bytecode.stg";
templates = new StringTemplateGroup(new FileReader(templateFileName),
AngleBracketTemplateLexer.class);
String srcFile = userDir + "\\src\\main\\java\\samples\\stg\\input";
CharStream input = new ANTLRFileStream(srcFile);
CMinusLexer lexer = new CMinusLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
CMinusParser parser = new CMinusParser(tokens);
parser.setTemplateLib(templates);
RuleReturnScope r = parser.program();
System.out.println(r.getTemplate().toString());
}
}

View File

@ -1,48 +0,0 @@
group Python;
program(globals,functions) ::= <<
<functions; separator="\n">
>>
variable(type,name) ::= " "
globalVariable ::= variable
function(type,name,args,locals,stats) ::= <<
def <name>(<args; separator=", ">):
<stats>
>>
type_int() ::= "int"
type_char() ::= "char"
type_user_object(name) ::= "<name>"
parameter(type,name) ::= "<name>"
statement(expr) ::= "<expr>"
statementList(locals,stats) ::= <<
<stats; separator="\n">
>>
// python has a weird FOR, use a WHILE. :)
forLoop(e1,e2,e3,locals,stats) ::= <<
<e1>
while ( <e2> ):
<stats; separator="\n">
<e3>
>>
assign(lhs,rhs) ::= "<lhs> = <rhs>"
equals(left,right) ::= "<left> == <right>"
lessThan(left,right) ::= "<left> \< <right>"
add(left,right) ::= "<left> + <right>"
refVar(id) ::= "<id>"
iconst(value) ::= "<value>"

View File

@ -1,7 +0,0 @@
Java.stg
Bytecode.stg
Python.stg
Main.java
CMinus.g
input
output

View File

@ -1,9 +0,0 @@
char c;
int x;
int foo(int y, char d) {
int i;
for (i=0; i<3; i=i+1) {
x=3;
y=5;
}
}

View File

@ -1,11 +0,0 @@
class Wrapper {
char c;
int x;
int foo(int y, char d) {
int i;
for (i = 0; i < 3; i = i + 1;) {
x = 3;
y = 5;
}
}
}

View File

@ -1,20 +1,15 @@
package org.ethereum.block;
import org.bouncycastle.util.encoders.Hex;
import org.spongycastle.util.encoders.Hex;
import org.ethereum.crypto.HashUtil;
import org.ethereum.net.RLP;
import org.ethereum.net.rlp.RLPList;
import org.ethereum.net.vo.BlockData;
import org.ethereum.util.Utils;
import org.junit.Test;
import java.io.IOException;
import java.math.BigInteger;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 19/04/14 13:30
*/
public class BlockTest {
@Test /* Creating genesis hash not ready yet */
@ -37,8 +32,6 @@ public class BlockTest {
*/
/*
( 0(256) - parentHash
SHA3(RLP(emptyList)) - hashes of transactions
0(160) - coinbase
@ -56,15 +49,10 @@ public class BlockTest {
block.appendRaw(RLPEmptyList);
block.appendRaw(RLPEmptyList);
*/
// gennesis hash
//ab6b9a5613970faa771b12d449b2e9bb925ab7a369f0a4b86b286e9d540099cf
/* 1 */ byte[] prevHash =
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -72,7 +60,7 @@ public class BlockTest {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
prevHash = RLP.encodeElement(prevHash);
/* 2 */ byte[] uncleList = RLP.encodeElement(Utils.sha3(RLP.encodeList(new byte[]{})));
/* 2 */ byte[] uncleList = RLP.encodeElement(HashUtil.sha3(RLP.encodeList(new byte[]{})));
/* 3 */ byte[] coinbase =
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -86,7 +74,7 @@ public class BlockTest {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
rootState = RLP.encodeElement(rootState);
/* 5 */ byte[] transactionsRoot = RLP.encodeElement(Utils.sha3(RLP.encodeList(new byte[]{})));
/* 5 */ byte[] transactionsRoot = RLP.encodeElement(HashUtil.sha3(RLP.encodeList(new byte[]{})));
/* 6 */ BigInteger difficulty = new BigInteger("2");
difficulty = difficulty.pow(22);
@ -99,9 +87,7 @@ public class BlockTest {
extradata = RLP.encodeElement(extradata);
/* 9 */ byte[] nonce = {42};
nonce = RLP.encodeElement( Utils.sha3(nonce) );
nonce = RLP.encodeElement(HashUtil.sha3(nonce));
byte[] header = RLP.encodeList( prevHash,
uncleList,
@ -115,14 +101,13 @@ public class BlockTest {
// block.appendList(9) << h256() << sha3EmptyList << h160() << stateRoot << sha3EmptyList << c_genesisDifficulty << (uint)0 << string() << sha3(bytes(1, 42));
byte[] txList = RLP.encodeList(new byte[]{});
byte[] unclesList = RLP.encodeList(new byte[]{});
byte[] genesis = RLP.encodeList(header, txList, unclesList);
System.out.println(Hex.toHexString(genesis));
byte[] hash = Utils.sha3(genesis);
byte[] hash = HashUtil.sha3(genesis);
System.out.println(Hex.toHexString(hash));
@ -133,10 +118,9 @@ public class BlockTest {
public void test2(){
byte[] goGenesisBytes = Hex.decode("f8a4f8a0a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794000000000000000000000000000000000000000080a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347834000008080a004994f67dc55b09e814ab7ffc8df3686b4afb2bb53e60eae97ef043fe03fb829c0c0");
System.out.println( Hex.toHexString( Utils.sha3(goGenesisBytes) ) );
System.out.println( Hex.toHexString( HashUtil.sha3(goGenesisBytes) ) );
}
@Test /* create BlockData from part of real RLP BLOCKS message */
public void test3(){
@ -148,14 +132,10 @@ public class BlockTest {
RLP.parseObjects(payload, rlpList);
BlockData blockData = new BlockData(rlpList);
RLPList.recursivePrint(rlpList);
}
}
/*
[[ab6b9a5613970faa771b12d449b2e9bb925ab7a369f0a4b86b286e9d540099cf, 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347, 3854aaf203ba5f8d49b1ec221329c7aebcf050d3, 990dc3b5acbee04124361d958fe51acb582593613fc290683940a0769549d3ed, 9bfe4817d274ea3eb8672e9fe848c3885b53bbbd1d7c26e6039f90fb96b942b0, 3ff000, 533f16b7, null, 00000000000000000000000000000000000000000000000077377adff6c227db, ]
[

View File

@ -1,109 +1,78 @@
package org.ethereum.crypto;
import junit.framework.Assert;
import org.bouncycastle.util.encoders.Hex;
import org.spongycastle.util.encoders.Hex;
import org.ethereum.util.Utils;
import org.junit.Test;
import static org.junit.Assert.*;
import java.math.BigInteger;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 17/04/14 15:02
*/
public class CryptoTest {
@Test
public void test1(){
byte[] result = Utils.sha3("horse".getBytes());
byte[] result = HashUtil.sha3("horse".getBytes());
Assert.assertEquals("c87f65ff3f271bf5dc8643484f66b200109caffe4bf98c4cb393dc35740b28c0",
assertEquals("c87f65ff3f271bf5dc8643484f66b200109caffe4bf98c4cb393dc35740b28c0",
Hex.toHexString(result));
result = Utils.sha3("cow".getBytes());
result = HashUtil.sha3("cow".getBytes());
Assert.assertEquals("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4",
assertEquals("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4",
Hex.toHexString(result));
}
@Test
public void test2(){
byte[] result = Utils.ripemd160("c87f65ff3f271bf5dc8643484f66b200109caffe4bf98c4cb393dc35740b28c0".getBytes());
System.out.println(Hex.toHexString(result));
}
@Test
public void test3(){
BigInteger privKey = new BigInteger("cd244b3015703ddf545595da06ada5516628c5feadbf49dc66049c4b370cc5d8", 16);
byte[] addr = Utils.privToAddress(privKey.toByteArray());
Assert.assertEquals("89b44e4d3c81ede05d0f5de8d1a68f754d73d997", Hex.toHexString(addr));
byte[] addr = ECKey.fromPrivate(privKey).getAddress();
assertEquals("89b44e4d3c81ede05d0f5de8d1a68f754d73d997", Hex.toHexString(addr));
}
@Test
public void test4(){
byte[] cowBytes = Utils.sha3("cow".getBytes());
byte[] addr = Utils.privToAddress(cowBytes);
Assert.assertEquals("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826", Hex.toHexString(addr).toUpperCase());
byte[] cowBytes = HashUtil.sha3("cow".getBytes());
byte[] addr = ECKey.fromPrivate(cowBytes).getAddress();
assertEquals("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826", Hex.toHexString(addr).toUpperCase());
}
@Test
public void test5(){
byte[] horseBytes = Utils.sha3("horse".getBytes());
byte[] addr = Utils.privToAddress(horseBytes);
Assert.assertEquals("13978AEE95F38490E9769C39B2773ED763D9CD5F", Hex.toHexString(addr).toUpperCase());
byte[] horseBytes = HashUtil.sha3("horse".getBytes());
byte[] addr = ECKey.fromPrivate(horseBytes).getAddress();
assertEquals("13978AEE95F38490E9769C39B2773ED763D9CD5F", Hex.toHexString(addr).toUpperCase());
}
@Test /* performance test */
public void test6(){
long firstTime = System.currentTimeMillis();
System.out.println(firstTime);
for (int i = 0; i < 1000; ++i){
byte[] horseBytes = Utils.sha3("horse".getBytes());
byte[] addr = Utils.privToAddress(horseBytes);
Assert.assertEquals("13978AEE95F38490E9769C39B2773ED763D9CD5F", Hex.toHexString(addr).toUpperCase());
byte[] horseBytes = HashUtil.sha3("horse".getBytes());
byte[] addr = ECKey.fromPrivate(horseBytes).getAddress();
assertEquals("13978AEE95F38490E9769C39B2773ED763D9CD5F", Hex.toHexString(addr).toUpperCase());
}
long secondTime = System.currentTimeMillis();
System.out.println(secondTime);
System.out.println(secondTime - firstTime + " millisec");
// 1) result: ~52 address calculation every second
}
@Test /* real tx hash calc */
public void test7(){
String txRaw = "F89D80809400000000000000000000000000000000000000008609184E72A000822710B3606956330C0D630000003359366000530A0D630000003359602060005301356000533557604060005301600054630000000C5884336069571CA07F6EB94576346488C6253197BDE6A7E59DDC36F2773672C849402AA9C402C3C4A06D254E662BF7450DD8D835160CBB053463FED0B53F2CDD7F3EA8731919C8E8CC";
byte[] txHashB = Utils.sha3(Hex.decode(txRaw));
byte[] txHashB = HashUtil.sha3(Hex.decode(txRaw));
String txHash = Utils.toHexString(txHashB);
Assert.assertEquals("4b7d9670a92bf120d5b43400543b69304a14d767cf836a7f6abff4edde092895", txHash);
assertEquals("4b7d9670a92bf120d5b43400543b69304a14d767cf836a7f6abff4edde092895", txHash);
}
@Test /* real block hash calc */
@ -111,23 +80,14 @@ public class CryptoTest {
String blockRaw = "F885F8818080A01DCC4DE8DEC75D7AAB85B567B6CCD41AD312451B948A7413F0A142FD40D49347940000000000000000000000000000000000000000A0BCDDD284BF396739C224DBA0411566C891C32115FEB998A3E2B4E61F3F35582AA01DCC4DE8DEC75D7AAB85B567B6CCD41AD312451B948A7413F0A142FD40D4934783800000808080C0C0";
byte[] blockHashB = Utils.sha3(Hex.decode(blockRaw));
byte[] blockHashB = HashUtil.sha3(Hex.decode(blockRaw));
String blockHash = Utils.toHexString(blockHashB);
System.out.println(blockHash);
}
@Test
public void test9(){
// todo: https://tools.ietf.org/html/rfc6979#section-2.2
// todo: https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java
}
//
}

View File

@ -0,0 +1,292 @@
package org.ethereum.crypto;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.junit.Assert.*;
import java.io.IOException;
import java.math.BigInteger;
import java.security.SignatureException;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import org.ethereum.crypto.ECKey.ECDSASignature;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.util.encoders.Hex;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
public class ECKeyTest {
private static final Logger log = LoggerFactory.getLogger(ECKeyTest.class);
private String privString = "3ecb44df2159c26e0f995712d4f39b6f6e499b40749b1cf1246c37f9516cb6a4";
private BigInteger privateKey = new BigInteger(Hex.decode(privString));
private String pubString = "0497466f2b32bc3bb76d4741ae51cd1d8578b48d3f1e68da206d47321aec267ce78549b514e4453d74ef11b0cd5e4e4c364effddac8b51bcfc8de80682f952896f";
private String compressedPubString = "0397466f2b32bc3bb76d4741ae51cd1d8578b48d3f1e68da206d47321aec267ce7";
private byte[] pubKey = Hex.decode(pubString);
private byte[] compressedPubKey = Hex.decode(compressedPubString);
private String address = "8a40bfaa73256b60764c1bf40675a99083efb075";
private String exampleMessage = new String("This is an example of a signed message.");
private String bitcoinSigBase64 = "HIb1Pb2tCwt/f15R9c/nlCgQrFTAxIt7TooOqG4B8ODNSaUdTtcW1N2E9bH+mF9HGjfd88H8QOyG0sPZtp2uaCQ=";
private String ethereumSigBase64 = "HD5AsBr4wuH6UU9tXuSJhUvgfGayfwoY0cKT03sFUjnpQsupHznd/3mCIRfLuNHlRCVGdAyHecdyM8IVZMtc1I8=";
@Test
public void testHashCode() {
fail("Not yet implemented");
}
@Test
public void testECKey() {
ECKey key = new ECKey();
assertTrue(key.isPubKeyCanonical());
assertNotNull(key.getPubKey());
assertNotNull(key.getPrivKeyBytes());
log.debug(Hex.toHexString(key.getPrivKeyBytes()) + " :Generated privkey");
log.debug(Hex.toHexString(key.getPubKey()) + " :Generated pubkey");
}
@Test
public void testFromPrivateKey() {
ECKey key = ECKey.fromPrivate(privateKey).decompress();
assertTrue(key.isPubKeyCanonical());
assertTrue(key.hasPrivKey());
assertArrayEquals(pubKey, key.getPubKey());
}
@Test(expected=IllegalArgumentException.class)
public void testPrivatePublicKeyBytesNoArg() {
new ECKey(null, null);
fail("Expecting an IllegalArgumentException for using only null-parameters");
}
@Test
public void testIsPubKeyOnly() {
ECKey key = ECKey.fromPublicOnly(pubKey);
assertTrue(key.isPubKeyCanonical());
assertTrue(key.isPubKeyOnly());
assertArrayEquals(key.getPubKey(), pubKey);
}
@Test
public void testPublicKeyFromPrivate() {
byte[] pubFromPriv = ECKey.publicKeyFromPrivate(privateKey, false);
assertArrayEquals(pubKey, pubFromPriv);
}
@Test
public void testPublicKeyFromPrivateCompressed() {
byte[] pubFromPriv = ECKey.publicKeyFromPrivate(privateKey, true);
assertArrayEquals(compressedPubKey, pubFromPriv);
}
@Test
public void testGetAddress() {
ECKey key = ECKey.fromPublicOnly(pubKey);
assertArrayEquals(Hex.decode(address), key.getAddress());
}
@Test
public void testToString() {
ECKey key = ECKey.fromPrivate(BigInteger.TEN); // An example private key.
assertEquals("pub:04a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7893aba425419bc27a3b6c7e693a24c696f794c2ed877a1593cbee53b037368d7", key.toString());
}
@Test
public void testSignBitcoin() throws IOException {
// TODO: Understand why key must be decompressed for this to work
ECKey key = ECKey.fromPrivate(privateKey).decompress();
System.out.println("Secret: " + Hex.toHexString(key.getPrivKeyBytes()));
System.out.println("Pubkey: " + Hex.toHexString(key.getPubKey()));
String output = key.signBitcoinMessage(exampleMessage);
System.out.println("Signtr: " + output + " (Base64) - length: " + output.length());
assertEquals(bitcoinSigBase64, output);
}
@Test
public void testEthereumSign() throws IOException {
// TODO: Understand why key must be decompressed for this to work
ECKey key = ECKey.fromPrivate(privateKey).decompress();
System.out.println("Secret\t: " + Hex.toHexString(key.getPrivKeyBytes()));
System.out.println("Pubkey\t: " + Hex.toHexString(key.getPubKey()));
System.out.println("Data\t: " + exampleMessage);
byte[] messageHash = HashUtil.sha3(exampleMessage.getBytes());
ECDSASignature signature = key.sign(messageHash);
String output = signature.toBase64();
System.out.println("Signtr\t: " + output + " (Base64, length: " + output.length() + ")");
assertEquals(ethereumSigBase64, output);
}
@Test
public void testVerifySignature1() {
ECKey key = ECKey.fromPublicOnly(pubKey);
BigInteger r = new BigInteger("28157690258821599598544026901946453245423343069728565040002908283498585537001");
BigInteger s = new BigInteger("30212485197630673222315826773656074299979444367665131281281249560925428307087");
ECDSASignature sig = ECDSASignature.fromComponents(r.toByteArray(), s.toByteArray());
sig.v = 28;
key.verify(HashUtil.sha3(exampleMessage.getBytes()), sig);
}
@Test
public void testVerifySignature2() {
BigInteger r = new BigInteger("c52c114d4f5a3ba904a9b3036e5e118fe0dbb987fe3955da20f2cd8f6c21ab9c", 16);
BigInteger s = new BigInteger("6ba4c2874299a55ad947dbc98a25ee895aabf6b625c26c435e84bfd70edf2f69", 16);
ECDSASignature sig = ECDSASignature.fromComponents(r.toByteArray(), s.toByteArray());
sig.v = 0x1b;
byte[] rawtx = Hex.decode("f82804881bc16d674ec8000094cd2a3d9f938e13cd947ec05abc7fe734df8dd8268609184e72a0006480");
try {
ECKey key = ECKey.signatureToKey(HashUtil.sha3(rawtx), sig.toBase64());
System.out.println("Signature public key\t: " + Hex.toHexString(key.getPubKey()));
System.out.println("Sender is\t\t: " + Hex.toHexString(key.getAddress()));
assertEquals("cd2a3d9f938e13cd947ec05abc7fe734df8dd826", Hex.toHexString(key.getAddress()));
key.verify(HashUtil.sha3(rawtx), sig);
} catch (SignatureException e) {
fail();
}
}
@Test
public void testVerifyBitcoinMessage() {
ECKey key = ECKey.fromPublicOnly(pubKey);
try {
key.verifyBitcoinMessage(exampleMessage, bitcoinSigBase64);
} catch (SignatureException e) {
fail();
}
}
@Test
public void testSValue() throws Exception {
// Check that we never generate an S value that is larger than half the curve order. This avoids a malleability
// issue that can allow someone to change a transaction [hash] without invalidating the signature.
final int ITERATIONS = 10;
ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(ITERATIONS));
List<ListenableFuture<ECKey.ECDSASignature>> sigFutures = Lists.newArrayList();
final ECKey key = new ECKey();
for (byte i = 0; i < ITERATIONS; i++) {
final byte[] hash = HashUtil.sha3(new byte[]{i});
sigFutures.add(executor.submit(new Callable<ECKey.ECDSASignature>() {
@Override
public ECKey.ECDSASignature call() throws Exception {
return key.doSign(hash);
}
}));
}
List<ECKey.ECDSASignature> sigs = Futures.allAsList(sigFutures).get();
for (ECKey.ECDSASignature signature : sigs) {
assertTrue(signature.s.compareTo(ECKey.HALF_CURVE_ORDER) <= 0);
}
final ECKey.ECDSASignature duplicate = new ECKey.ECDSASignature(sigs.get(0).r, sigs.get(0).s);
assertEquals(sigs.get(0), duplicate);
assertEquals(sigs.get(0).hashCode(), duplicate.hashCode());
}
@Test
public void testSignVerify() {
ECKey key = ECKey.fromPrivate(privateKey);
String message = new String("This is an example of a signed message.");
ECDSASignature output = key.doSign(message.getBytes());
assertTrue(key.verify(message.getBytes(), output));
}
@Test
public void testIsPubKeyCanonicalCorect() {
// Test correct prefix 4, right length 65
byte[] canonicalPubkey1 = new byte[65]; canonicalPubkey1[0] = 0x04;
assertTrue(ECKey.isPubKeyCanonical(canonicalPubkey1));
// Test correct prefix 2, right length 33
byte[] canonicalPubkey2 = new byte[33]; canonicalPubkey2[0] = 0x02;
assertTrue(ECKey.isPubKeyCanonical(canonicalPubkey2));
// Test correct prefix 3, right length 33
byte[] canonicalPubkey3 = new byte[33]; canonicalPubkey3[0] = 0x03;
assertTrue(ECKey.isPubKeyCanonical(canonicalPubkey3));
}
@Test
public void testIsPubKeyCanonicalWrongLength() {
// Test correct prefix 4, but wrong length !65
byte[] nonCanonicalPubkey1 = new byte[64]; nonCanonicalPubkey1[0] = 0x04;
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey1));
// Test correct prefix 2, but wrong length !33
byte[] nonCanonicalPubkey2 = new byte[32]; nonCanonicalPubkey2[0] = 0x02;
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey2));
// Test correct prefix 3, but wrong length !33
byte[] nonCanonicalPubkey3 = new byte[32]; nonCanonicalPubkey3[0] = 0x03;
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey3));
}
@Test
public void testIsPubKeyCanonicalWrongPrefix() {
// Test wrong prefix 4, right length 65
byte[] nonCanonicalPubkey4 = new byte[65];
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey4));
// Test wrong prefix 2, right length 33
byte[] nonCanonicalPubkey5 = new byte[33];
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey5));
// Test wrong prefix 3, right length 33
byte[] nonCanonicalPubkey6 = new byte[33];
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey6));
}
@Test
public void keyRecovery() throws Exception {
ECKey key = new ECKey();
String message = "Hello World!";
byte[] hash = HashUtil.sha256(message.getBytes());
ECKey.ECDSASignature sig = key.doSign(hash);
key = ECKey.fromPublicOnly(key.getPubKeyPoint());
boolean found = false;
for (int i = 0; i < 4; i++) {
ECKey key2 = ECKey.recoverFromSignature(i, sig, hash, true);
checkNotNull(key2);
if (key.equals(key2)) {
found = true;
break;
}
}
assertTrue(found);
}
@Test
public void testSignedBitcoinMessageToKey() throws SignatureException {
ECKey key = ECKey.signedBitcoinMessageToKey("This is an example of a signed message.", bitcoinSigBase64);
assertNotNull(key);
assertArrayEquals(pubKey, key.getPubKey());
}
@Test
public void testSignedMessageToKey() throws SignatureException {
byte[] messageHash = HashUtil.sha3(exampleMessage.getBytes());
ECKey key = ECKey.signatureToKey(messageHash, ethereumSigBase64);
assertNotNull(key);
assertArrayEquals(pubKey, key.getPubKey());
}
@Test
public void testGetPrivKeyBytes() {
ECKey key = new ECKey();
assertNotNull(key.getPrivKeyBytes());
assertEquals(32, key.getPrivKeyBytes().length);
}
@Test
public void testEqualsObject() {
ECKey key0 = new ECKey();
ECKey key1 = ECKey.fromPrivate(privateKey);
ECKey key2 = ECKey.fromPrivate(privateKey);
assertFalse(key0.equals(key1));
assertTrue(key1.equals(key1));
assertTrue(key1.equals(key2));
}
}

View File

@ -1,7 +1,6 @@
package org.ethereum.net;
import junit.framework.Assert;
import org.bouncycastle.util.encoders.Hex;
import org.spongycastle.util.encoders.Hex;
import org.ethereum.net.message.*;
import org.ethereum.net.rlp.RLPList;
import org.ethereum.net.vo.BlockData;
@ -11,17 +10,10 @@ import org.ethereum.util.Utils;
import org.junit.Test;
import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import static org.junit.Assert.*;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 07/04/14 12:57
*/
public class MessagesTest {
/* HELLO_MESSAGE */
@ -46,12 +38,12 @@ public class MessagesTest {
System.out.println(helloMessage);
Assert.assertEquals(12, helloMessage.getProtocolVersion());
Assert.assertEquals(0, helloMessage.getNetworkId());
Assert.assertEquals("Ethereum(++)/ZeroGox/v0.5.1/ncurses/Linux/g++", helloMessage.getClientId());
Assert.assertEquals(7, helloMessage.getCapabilities());
Assert.assertEquals(30303, helloMessage.getPeerPort());
Assert.assertEquals(
assertEquals(12, helloMessage.getProtocolVersion());
assertEquals(0, helloMessage.getNetworkId());
assertEquals("Ethereum(++)/ZeroGox/v0.5.1/ncurses/Linux/g++", helloMessage.getClientId());
assertEquals(7, helloMessage.getCapabilities());
assertEquals(30303, helloMessage.getPeerPort());
assertEquals(
"D8833B83560E0B12170E9169DC43784223A59842DE2359E6D03DB34C30A966C2DE3B4B2552FB0D7595A185D558F2E669B595674F5217C996EE148884828BE0FD",
Utils.toHexString(helloMessage.getPeerId()).toUpperCase() );
}
@ -68,12 +60,12 @@ public class MessagesTest {
helloMessage.parseRLP();
System.out.println(helloMessage);
Assert.assertEquals(11, helloMessage.getProtocolVersion());
Assert.assertEquals(0, helloMessage.getNetworkId());
Assert.assertEquals("Ethereum(++)/v0.4.3/ETH_BUILD_TYPE/ETH_BUILD_PLATFORM", helloMessage.getClientId());
Assert.assertEquals(7, helloMessage.getCapabilities());
Assert.assertEquals(30303, helloMessage.getPeerPort());
Assert.assertEquals(
assertEquals(11, helloMessage.getProtocolVersion());
assertEquals(0, helloMessage.getNetworkId());
assertEquals("Ethereum(++)/v0.4.3/ETH_BUILD_TYPE/ETH_BUILD_PLATFORM", helloMessage.getClientId());
assertEquals(7, helloMessage.getCapabilities());
assertEquals(30303, helloMessage.getPeerPort());
assertEquals(
"E02B18FBA6B887FB9258469C3AF8E445CC9AE2B5386CAC5F60C4170F822086224E3876555C745A7EC8AC181C7F9701776D94A779604EA12651DE5F4A748D29E1",
Utils.toHexString(helloMessage.getPeerId()).toUpperCase() );
}
@ -92,7 +84,7 @@ public class MessagesTest {
DisconnectMessage disconnectMessage = new DisconnectMessage(rlpList);
System.out.println(disconnectMessage);
Assert.assertEquals(disconnectMessage.getReason(),
assertEquals(disconnectMessage.getReason(),
DisconnectMessage.REASON_DISCONNECT_REQUESTED);
}
@ -107,7 +99,7 @@ public class MessagesTest {
DisconnectMessage disconnectMessage = new DisconnectMessage(rlpList);
System.out.println(disconnectMessage);
Assert.assertEquals(disconnectMessage.getReason(),
assertEquals(disconnectMessage.getReason(),
DisconnectMessage.REASON_TCP_ERROR);
}
@ -125,13 +117,13 @@ public class MessagesTest {
PeersMessage peersMessage= new PeersMessage(rlpList);
System.out.println(peersMessage);
Assert.assertEquals(9, peersMessage.getPeers().size());
assertEquals(9, peersMessage.getPeers().size());
PeerData peerData = peersMessage.getPeers().get(3);
Assert.assertEquals("/85.65.126.45", peerData.getInetAddress().toString());
Assert.assertEquals(30303, peerData.getPort());
Assert.assertEquals("82A8A5831D3B4FB76CF130CDC8A2B162A85D005D82A1DCC9B73239035EADE6347EDE2FFC86571ABE348EA38699CE886AA3D425FE58182C433434AB4CFD7B5B88",
assertEquals("/85.65.126.45", peerData.getInetAddress().toString());
assertEquals(30303, peerData.getPort());
assertEquals("82A8A5831D3B4FB76CF130CDC8A2B162A85D005D82A1DCC9B73239035EADE6347EDE2FFC86571ABE348EA38699CE886AA3D425FE58182C433434AB4CFD7B5B88",
Utils.toHexString( peerData.getPeerId() ).toUpperCase());
}
@ -147,20 +139,20 @@ public class MessagesTest {
PeersMessage peersMessage= new PeersMessage(rlpList);
System.out.println(peersMessage);
Assert.assertEquals(77, peersMessage.getPeers().size());
assertEquals(77, peersMessage.getPeers().size());
PeerData peerData = peersMessage.getPeers().get(7);
Assert.assertEquals("/191.234.57.55", peerData.getInetAddress().toString());
Assert.assertEquals(30303, peerData.getPort());
Assert.assertEquals("21780C55B47DB4B11467B5F55B0B555E0887CE36FBD975E224B1C70EAC7AB8E8C2DB37F0A48B90FFDD5A379ADA99B6A0F6429C4A53C25558191A682636AEF4F2",
assertEquals("/191.234.57.55", peerData.getInetAddress().toString());
assertEquals(30303, peerData.getPort());
assertEquals("21780C55B47DB4B11467B5F55B0B555E0887CE36FBD975E224B1C70EAC7AB8E8C2DB37F0A48B90FFDD5A379ADA99B6A0F6429C4A53C25558191A682636AEF4F2",
Utils.toHexString( peerData.getPeerId() ).toUpperCase());
peerData = peersMessage.getPeers().get(75);
Assert.assertEquals("/86.124.82.254", peerData.getInetAddress().toString());
Assert.assertEquals(30303, peerData.getPort());
Assert.assertEquals("F6155F1A60143B7D9D5D1A440D7D52FE6809F69E0C6F1E0024457E0D71DD88ADE3B13AAA940C89AC0610952B48BD832C42E343A13E61FFDB06010CFFC345E053",
assertEquals("/86.124.82.254", peerData.getInetAddress().toString());
assertEquals(30303, peerData.getPort());
assertEquals("F6155F1A60143B7D9D5D1A440D7D52FE6809F69E0C6F1E0024457E0D71DD88ADE3B13AAA940C89AC0610952B48BD832C42E343A13E61FFDB06010CFFC345E053",
Utils.toHexString( peerData.getPeerId() ).toUpperCase());
}
@ -200,42 +192,42 @@ public class MessagesTest {
TransactionsMessage transactionsMessage = new TransactionsMessage(rlpList);
System.out.println(transactionsMessage);
Assert.assertEquals(1, transactionsMessage.getTransactions().size());
assertEquals(1, transactionsMessage.getTransactions().size());
TransactionData tx =
transactionsMessage.getTransactions().get(0);
Assert.assertEquals("558A3797E0DD3FBFAF761F1ADD6749C7D5DB313FDAC5CBA59F40E28AF7BBACD1",
assertEquals("558A3797E0DD3FBFAF761F1ADD6749C7D5DB313FDAC5CBA59F40E28AF7BBACD1",
Utils.toHexString( tx.getHash() ).toUpperCase());
Assert.assertEquals("04",
assertEquals("04",
Utils.toHexString( tx.getNonce() ).toUpperCase());
Assert.assertEquals("1BC16D674EC80000",
assertEquals("1BC16D674EC80000",
Utils.toHexString( tx.getValue() ).toUpperCase());
Assert.assertEquals("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826",
assertEquals("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826",
Utils.toHexString( tx.getReceiveAddress() ).toUpperCase());
Assert.assertEquals("09184E72A000",
assertEquals("09184E72A000",
Utils.toHexString( tx.getGasPrice() ).toUpperCase());
Assert.assertEquals("64",
assertEquals("64",
Utils.toHexString( tx.getGas() ).toUpperCase());
Assert.assertEquals("NULL",
assertEquals("NULL",
Utils.toHexString( tx.getData() ).toUpperCase());
Assert.assertEquals("NULL",
assertEquals("NULL",
Utils.toHexString( tx.getInit() ).toUpperCase());
Assert.assertEquals("1B",
assertEquals("1B",
Utils.toHexString( new byte[] {tx.getSignatureV()} ).toUpperCase());
Assert.assertEquals("5E3868194605F1647593B842725818CCFA6A38651A728715133A8E97CDCFAC54",
assertEquals("5E3868194605F1647593B842725818CCFA6A38651A728715133A8E97CDCFAC54",
Utils.toHexString( tx.getSignatureR() ).toUpperCase());
Assert.assertEquals("0FF91628D04B215EBCCFD5F4FC34CC1B45DF32F6B4609FBB0DE42E8522264467",
assertEquals("0FF91628D04B215EBCCFD5F4FC34CC1B45DF32F6B4609FBB0DE42E8522264467",
Utils.toHexString( tx.getSignatureS() ).toUpperCase());
}
@ -253,79 +245,79 @@ public class MessagesTest {
TransactionsMessage transactionsMessage = new TransactionsMessage(rlpList);
System.out.println(transactionsMessage);
Assert.assertEquals(3, transactionsMessage.getTransactions().size());
assertEquals(3, transactionsMessage.getTransactions().size());
TransactionData tx =
transactionsMessage.getTransactions().get(0);
Assert.assertEquals("4B7D9670A92BF120D5B43400543B69304A14D767CF836A7F6ABFF4EDDE092895",
assertEquals("4B7D9670A92BF120D5B43400543B69304A14D767CF836A7F6ABFF4EDDE092895",
Utils.toHexString( tx.getHash() ).toUpperCase());
Assert.assertEquals("NULL",
assertEquals("NULL",
Utils.toHexString( tx.getNonce() ).toUpperCase());
Assert.assertEquals("NULL",
assertEquals("NULL",
Utils.toHexString( tx.getValue() ).toUpperCase());
Assert.assertEquals("0000000000000000000000000000000000000000",
assertEquals("0000000000000000000000000000000000000000",
Utils.toHexString( tx.getReceiveAddress() ).toUpperCase());
Assert.assertEquals("09184E72A000",
assertEquals("09184E72A000",
Utils.toHexString( tx.getGasPrice() ).toUpperCase());
Assert.assertEquals("2710",
assertEquals("2710",
Utils.toHexString( tx.getGas() ).toUpperCase());
Assert.assertEquals("606956330C0D630000003359366000530A0D630000003359602060005301356000533557604060005301600054630000000C58",
assertEquals("606956330C0D630000003359366000530A0D630000003359602060005301356000533557604060005301600054630000000C58",
Utils.toHexString( tx.getData() ).toUpperCase());
Assert.assertEquals("33606957",
assertEquals("33606957",
Utils.toHexString( tx.getInit() ).toUpperCase());
Assert.assertEquals("1C",
assertEquals("1C",
Utils.toHexString( new byte[] {tx.getSignatureV()} ).toUpperCase());
Assert.assertEquals("7F6EB94576346488C6253197BDE6A7E59DDC36F2773672C849402AA9C402C3C4",
assertEquals("7F6EB94576346488C6253197BDE6A7E59DDC36F2773672C849402AA9C402C3C4",
Utils.toHexString( tx.getSignatureR() ).toUpperCase());
Assert.assertEquals("6D254E662BF7450DD8D835160CBB053463FED0B53F2CDD7F3EA8731919C8E8CC",
assertEquals("6D254E662BF7450DD8D835160CBB053463FED0B53F2CDD7F3EA8731919C8E8CC",
Utils.toHexString( tx.getSignatureS() ).toUpperCase());
tx =
transactionsMessage.getTransactions().get(2);
Assert.assertEquals("B0251A1BB20B44459DB5B5444AB53EDD9E12C46D0BA07FA401A797BEB967D53C",
assertEquals("B0251A1BB20B44459DB5B5444AB53EDD9E12C46D0BA07FA401A797BEB967D53C",
Utils.toHexString( tx.getHash() ).toUpperCase());
Assert.assertEquals("02",
assertEquals("02",
Utils.toHexString( tx.getNonce() ).toUpperCase());
Assert.assertEquals("NULL",
assertEquals("NULL",
Utils.toHexString( tx.getValue() ).toUpperCase());
Assert.assertEquals("CCDEAC59D35627B7DE09332E819D5159E7BB7250",
assertEquals("CCDEAC59D35627B7DE09332E819D5159E7BB7250",
Utils.toHexString( tx.getReceiveAddress() ).toUpperCase());
Assert.assertEquals("09184E72A000",
assertEquals("09184E72A000",
Utils.toHexString( tx.getGasPrice() ).toUpperCase());
Assert.assertEquals("2710",
assertEquals("2710",
Utils.toHexString( tx.getGas() ).toUpperCase());
Assert.assertEquals("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000002D0ACEEE7E5AB874E22CCF8D1A649F59106D74E8",
assertEquals("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000002D0ACEEE7E5AB874E22CCF8D1A649F59106D74E8",
Utils.toHexString( tx.getData() ).toUpperCase());
Assert.assertEquals("NULL",
assertEquals("NULL",
Utils.toHexString( tx.getInit() ).toUpperCase());
Assert.assertEquals("1B",
assertEquals("1B",
Utils.toHexString( new byte[] {tx.getSignatureV()} ).toUpperCase());
Assert.assertEquals("D05887574456C6DE8F7A0D172342C2CBDD4CF7AFE15D9DBB8B75B748BA6791C9",
assertEquals("D05887574456C6DE8F7A0D172342C2CBDD4CF7AFE15D9DBB8B75B748BA6791C9",
Utils.toHexString( tx.getSignatureR() ).toUpperCase());
Assert.assertEquals("1E87172A861F6C37B5A9E3A5D0D7393152A7FBE41530E5BB8AC8F35433E5931B",
assertEquals("1E87172A861F6C37B5A9E3A5D0D7393152A7FBE41530E5BB8AC8F35433E5931B",
Utils.toHexString(tx.getSignatureS()).toUpperCase());
}
@ -347,7 +339,7 @@ public class MessagesTest {
List<BlockData> list = blocksMessage.getBlockDataList();
System.out.println(blocksMessage);
Assert.assertEquals(1, list.size());
assertEquals(1, list.size());
BlockData block = list.get(0);
@ -393,7 +385,7 @@ public class MessagesTest {
System.out.println(blocksMessage);
Assert.assertEquals(32, list.size());
assertEquals(32, list.size());
BlockData block = list.get(31);
@ -474,7 +466,7 @@ public class MessagesTest {
NotInChainMessage notInChainMessage = new NotInChainMessage(rlpList);
System.out.println(notInChainMessage);
Assert.assertEquals("E5E441F0877116011CCDECE2501A50B40C40418377037E16D0282B2B5E347138",
assertEquals("E5E441F0877116011CCDECE2501A50B40C40418377037E16D0282B2B5E347138",
Utils.toHexString(notInChainMessage.getHash()).toUpperCase());
}

View File

@ -1,6 +1,7 @@
package org.ethereum.net;
import org.bouncycastle.util.encoders.Hex;
import org.spongycastle.util.encoders.Hex;
import org.ethereum.crypto.HashUtil;
import org.ethereum.net.rlp.RLPList;
import org.ethereum.util.Utils;
import org.junit.Assert;
@ -15,11 +16,6 @@ import java.util.Queue;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 07/04/14 12:57
*/
public class RLPTest {
@Test
@ -235,7 +231,7 @@ public class RLPTest {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
prevHash = RLP.encodeElement(prevHash);
/* 2 */ byte[] uncleList = Utils.sha3(RLP.encodeList(new byte[]{}));
/* 2 */ byte[] uncleList = HashUtil.sha3(RLP.encodeList(new byte[]{}));
/* 3 */ byte[] coinbase =
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

View File

@ -1,31 +1,21 @@
package org.ethereum.serpent;
import junit.framework.Assert;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.language.AngleBracketTemplateLexer;
import org.bouncycastle.util.encoders.Hex;
import org.ethereum.util.Utils;
import org.junit.Test;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 27/04/14 14:35
*/
import static org.junit.Assert.*;
public class TestCompile {
/* bin_expr
['+', 2, 1, ['<1>', '<0>', 'ADD']], V
['-', 2, 1, ['<1>', '<0>', 'SUB']], V
@ -40,9 +30,7 @@ public class TestCompile {
@Test /* Test one symbol */
public void test0() throws FileNotFoundException, RecognitionException {
CharStream stream =
new ANTLRStringStream("" +
"A");
CharStream stream = new ANTLRStringStream("" + "A");
SerpentLexer lex = new SerpentLexer(stream);
CommonTokenStream tokens = new CommonTokenStream(lex);
@ -58,12 +46,9 @@ public class TestCompile {
SerpentParser.bin_expr_return retVal = parser.bin_expr();
Assert.assertEquals("A", retVal.getTemplate().toString());
assertEquals("A", retVal.getTemplate().toString());
}
@Test /* Test ADD 1*/
public void test1() throws FileNotFoundException, RecognitionException {
@ -85,8 +70,7 @@ public class TestCompile {
SerpentParser.bin_expr_return retVal = parser.bin_expr();
Assert.assertEquals("A B ADD", retVal.getTemplate().toString());
assertEquals("A B ADD", retVal.getTemplate().toString());
}
@Test /* Test ADD 2*/
@ -110,8 +94,7 @@ public class TestCompile {
SerpentParser.bin_expr_return retVal = parser.bin_expr();
Assert.assertEquals("A B ADD C1 ADD", retVal.getTemplate().toString());
assertEquals("A B ADD C1 ADD", retVal.getTemplate().toString());
}
@Test /* Test SUB 1*/
@ -135,8 +118,7 @@ public class TestCompile {
SerpentParser.bin_expr_return retVal = parser.bin_expr();
Assert.assertEquals("A B SUB", retVal.getTemplate().toString());
assertEquals("A B SUB", retVal.getTemplate().toString());
}
@Test /* Test MUL 1*/
@ -150,7 +132,6 @@ public class TestCompile {
CommonTokenStream tokens = new CommonTokenStream(lex);
SerpentParser parser = new SerpentParser(tokens);
String userDir = System.getProperty("user.dir");
String templateFileName = userDir + "\\src\\main\\java\\org\\ethereum\\serpent\\Serpent2Asm.stg";
@ -160,8 +141,7 @@ public class TestCompile {
SerpentParser.bin_expr_return retVal = parser.bin_expr();
Assert.assertEquals("A B MUL", retVal.getTemplate().toString());
assertEquals("A B MUL", retVal.getTemplate().toString());
}
@ -176,7 +156,6 @@ public class TestCompile {
CommonTokenStream tokens = new CommonTokenStream(lex);
SerpentParser parser = new SerpentParser(tokens);
String userDir = System.getProperty("user.dir");
String templateFileName = userDir + "\\src\\main\\java\\org\\ethereum\\serpent\\Serpent2Asm.stg";
@ -186,7 +165,7 @@ public class TestCompile {
SerpentParser.bin_expr_return retVal = parser.bin_expr();
Assert.assertEquals("A B DIV", retVal.getTemplate().toString());
assertEquals("A B DIV", retVal.getTemplate().toString());
}
@ -211,7 +190,7 @@ public class TestCompile {
SerpentParser.bin_expr_return retVal = parser.bin_expr();
Assert.assertEquals("A B EXP", retVal.getTemplate().toString());
assertEquals("A B EXP", retVal.getTemplate().toString());
}
@ -236,7 +215,9 @@ public class TestCompile {
SerpentParser.bin_expr_return retVal = parser.bin_expr();
Assert.assertEquals("A B MOD", retVal.getTemplate().toString());
assertEquals("A B MOD", retVal.getTemplate().toString());
}
@Test /* Test SDIV 1*/
@ -260,7 +241,7 @@ public class TestCompile {
SerpentParser.bin_expr_return retVal = parser.bin_expr();
Assert.assertEquals("A B SDIV", retVal.getTemplate().toString());
assertEquals("A B SDIV", retVal.getTemplate().toString());
}
@ -285,7 +266,7 @@ public class TestCompile {
SerpentParser.bin_expr_return retVal = parser.bin_expr();
Assert.assertEquals("A B SMOD", retVal.getTemplate().toString());
assertEquals("A B SMOD", retVal.getTemplate().toString());
}
@ -311,7 +292,7 @@ public class TestCompile {
SerpentParser.bin_expr_return retVal = parser.bin_expr();
Assert.assertEquals("A B DIV C SUB D ADD ET MUL", retVal.getTemplate().toString());
assertEquals("A B DIV C SUB D ADD ET MUL", retVal.getTemplate().toString());
}
@ -336,7 +317,7 @@ public class TestCompile {
SerpentParser.bin_expr_return retVal = parser.bin_expr();
Assert.assertEquals("A B DIV C SUB D ADD ET MUL ET2 MOD RO EXP RO2 ADD COOL SDIV HOT SMOD",
assertEquals("A B DIV C SUB D ADD ET MUL ET2 MOD RO EXP RO2 ADD COOL SDIV HOT SMOD",
retVal.getTemplate().toString());
}
@ -372,7 +353,7 @@ public class TestCompile {
SerpentParser.cond_expr_return retVal = parser.cond_expr();
Assert.assertEquals("A B ADD B A ADD EQ",
assertEquals("A B ADD B A ADD EQ",
retVal.getTemplate().toString());
}
@ -398,7 +379,7 @@ public class TestCompile {
SerpentParser.cond_expr_return retVal = parser.cond_expr();
Assert.assertEquals("A C ADD C A ADD LT",
assertEquals("A C ADD C A ADD LT",
retVal.getTemplate().toString());
}
@ -424,7 +405,7 @@ public class TestCompile {
SerpentParser.cond_expr_return retVal = parser.cond_expr();
Assert.assertEquals("A C ADD C A ADD GT NOT",
assertEquals("A C ADD C A ADD GT NOT",
retVal.getTemplate().toString());
}
@ -451,7 +432,7 @@ public class TestCompile {
SerpentParser.cond_expr_return retVal = parser.cond_expr();
Assert.assertEquals("A C ADD C A ADD GT",
assertEquals("A C ADD C A ADD GT",
retVal.getTemplate().toString());
}
@ -478,7 +459,7 @@ public class TestCompile {
SerpentParser.cond_expr_return retVal = parser.cond_expr();
Assert.assertEquals("A C ADD C A ADD LT NOT",
assertEquals("A C ADD C A ADD LT NOT",
retVal.getTemplate().toString());
}
@ -504,7 +485,7 @@ public class TestCompile {
SerpentParser.unr_expr_return retVal = parser.unr_expr();
Assert.assertEquals("A NOT",
assertEquals("A NOT",
retVal.getTemplate().toString());
}
@ -531,7 +512,7 @@ public class TestCompile {
SerpentParser.unr_expr_return retVal = parser.unr_expr();
Assert.assertEquals("A NOT NOT",
assertEquals("A NOT NOT",
retVal.getTemplate().toString());
}
@ -557,7 +538,7 @@ public class TestCompile {
SerpentParser.unr_expr_return retVal = parser.unr_expr();
Assert.assertEquals("A NOT NOT",
assertEquals("A NOT NOT",
retVal.getTemplate().toString());
}
@ -583,7 +564,7 @@ public class TestCompile {
SerpentParser.unr_expr_return retVal = parser.unr_expr();
Assert.assertEquals("A NOT",
assertEquals("A NOT",
retVal.getTemplate().toString());
}
@ -610,7 +591,7 @@ public class TestCompile {
SerpentParser.program_return retVal = parser.program();
Assert.assertEquals("10 0 MSTORE 20 32 MSTORE 30 64 MSTORE",
assertEquals("10 0 MSTORE 20 32 MSTORE 30 64 MSTORE",
retVal.getTemplate().toString().trim());
}
@ -636,7 +617,7 @@ public class TestCompile {
SerpentParser.program_return retVal = parser.program();
Assert.assertEquals("10 0 MSTORE 20 32 MSTORE 30 0 MSTORE 40 32 MSTORE",
assertEquals("10 0 MSTORE 20 32 MSTORE 30 0 MSTORE 40 32 MSTORE",
retVal.getTemplate().toString().trim());
}
@ -662,7 +643,7 @@ public class TestCompile {
SerpentParser.if_else_stmt_return retVal = parser.if_else_stmt();
Assert.assertEquals("",
assertEquals("",
retVal.getTemplate().toString().trim());
}
@ -688,7 +669,7 @@ public class TestCompile {
SerpentParser.storage_load_return retVal = parser.storage_load();
Assert.assertEquals("0 SLOAD",
assertEquals("0 SLOAD",
retVal.getTemplate().toString().trim());
}
@ -713,7 +694,7 @@ public class TestCompile {
SerpentParser.storage_load_return retVal = parser.storage_load();
Assert.assertEquals("100 SLOAD",
assertEquals("100 SLOAD",
retVal.getTemplate().toString().trim());
}
@ -738,7 +719,7 @@ public class TestCompile {
SerpentParser.storage_save_return retVal = parser.storage_save();
Assert.assertEquals("200 100 SSTORE",
assertEquals("200 100 SSTORE",
retVal.getTemplate().toString().trim());
}
@ -763,7 +744,7 @@ public class TestCompile {
SerpentParser.storage_save_return retVal = parser.storage_save();
Assert.assertEquals("200 3 4 ADD SSTORE",
assertEquals("200 3 4 ADD SSTORE",
retVal.getTemplate().toString().trim());
}
@ -789,7 +770,7 @@ public class TestCompile {
SerpentParser.storage_save_return retVal = parser.storage_save();
Assert.assertEquals("200 100 ADD 100 SSTORE", // todo: have to optimize it somewhere in the future
assertEquals("200 100 ADD 100 SSTORE", // todo: have to optimize it somewhere in the future
retVal.getTemplate().toString().trim());
}
@ -814,7 +795,7 @@ public class TestCompile {
SerpentParser.msg_load_return retVal = parser.msg_load();
Assert.assertEquals("0 32 MULL CALLDATALOAD",
assertEquals("0 32 MULL CALLDATALOAD",
retVal.getTemplate().toString().trim());
}
@ -839,7 +820,7 @@ public class TestCompile {
SerpentParser.msg_load_return retVal = parser.msg_load();
Assert.assertEquals("10 20 ADD 32 MUL CALLDATALOAD",
assertEquals("10 20 ADD 32 MUL CALLDATALOAD",
retVal.getTemplate().toString().trim());
}
@ -864,7 +845,7 @@ public class TestCompile {
SerpentParser.bin_expr_return retVal = parser.bin_expr();
Assert.assertEquals("0 32 MUL CALLDATALOAD 2 32 MUL CALLDATALOAD ADD",
assertEquals("0 32 MUL CALLDATALOAD 2 32 MUL CALLDATALOAD ADD",
retVal.getTemplate().toString().trim());
}
@ -891,7 +872,7 @@ public class TestCompile {
SerpentParser.storage_save_return retVal = parser.storage_save();
Assert.assertEquals("1 32 MUL CALLDATALOAD 0 32 MUL CALLDATALOAD SSTORE",
assertEquals("1 32 MUL CALLDATALOAD 0 32 MUL CALLDATALOAD SSTORE",
retVal.getTemplate().toString().trim());
}
@ -916,7 +897,7 @@ public class TestCompile {
SerpentParser.unr_expr_return retVal = parser.unr_expr();
Assert.assertEquals("0 32 MUL CALLDATALOAD SLOAD NOT",
assertEquals("0 32 MUL CALLDATALOAD SLOAD NOT",
retVal.getTemplate().toString().trim());
}
@ -941,7 +922,7 @@ public class TestCompile {
SerpentParser.test_1_return retVal = parser.test_1();
Assert.assertEquals("20 0 MSTORE 20 32 MSTORE 32 MLOAD",
assertEquals("20 0 MSTORE 20 32 MSTORE 32 MLOAD",
retVal.getTemplate().toString().trim());
}
@ -966,7 +947,7 @@ public class TestCompile {
SerpentParser.test_1_return retVal = parser.test_1();
Assert.assertEquals("20 0 MSTORE 20 32 MSTORE 20 64 MSTORE 64 MLOAD",
assertEquals("20 0 MSTORE 20 32 MSTORE 20 64 MSTORE 64 MLOAD",
retVal.getTemplate().toString().trim());
}
@ -996,7 +977,7 @@ public class TestCompile {
SerpentParser.if_else_stmt_return retVal = parser.if_else_stmt();
Assert.assertEquals("",
assertEquals("",
retVal.getTemplate().toString().trim());
}
@ -1038,7 +1019,7 @@ public class TestCompile {
SerpentParser.gen_body_return retVal = parser.gen_body();
Assert.assertEquals("",
assertEquals("",
retVal.getTemplate().toString().trim());
}
@ -1065,16 +1046,7 @@ public class TestCompile {
SerpentParser.hex_num_return retVal = parser.hex_num();
Assert.assertEquals(Utils.hexStringToDecimalString(hexNum),
assertEquals(Utils.hexStringToDecimalString(hexNum),
retVal.getTemplate().toString().trim());
}
}

View File

@ -1,114 +1,44 @@
package org.ethereum.transaction;
import org.bouncycastle.asn1.sec.SECNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.util.encoders.Hex;
import org.ethereum.util.Utils;
import org.junit.Test;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 20/04/14 14:21
*/
import org.ethereum.crypto.ECKey;
import org.ethereum.crypto.HashUtil;
import org.junit.Test;
import org.spongycastle.util.encoders.Hex;
public class TransactionTest {
@Test /* sign transaction https://tools.ietf.org/html/rfc6979 */
public void test1() throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException, IOException {
//python taken exact data
String txRLPRawData = "a9e880872386f26fc1000085e8d4a510008203e89413978aee95f38490e9769c39b2773ed763d9cd5f80";
// String txRLPRawData = "f82804881bc16d674ec8000094cd2a3d9f938e13cd947ec05abc7fe734df8dd8268609184e72a0006480";
// String txRLPRawData = "f82804881bc16d674ec8000094cd2a3d9f938e13cd947ec05abc7fe734df8dd8268609184e72a0006480";
String cowPrivKey = "c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4";
byte[] cowPrivKey = Hex.decode("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4");
ECKey key = ECKey.fromPrivate(cowPrivKey);
byte[] data = Hex.decode(txRLPRawData);
byte[] privKey = Hex.decode(cowPrivKey);
// step 1: serialize + RLP encode
// step 2: hash = sha3(step1)
byte[] txHash = Utils.sha3(data);
X9ECParameters curvParams = SECNamedCurves.getByName("secp256k1");
// z = hash_to_int(msghash)
// k = deterministic_generate_k(msghash,priv)
BigInteger txHashInt = new BigInteger(1, txHash );
/*
v = '\x01' * 32
k = '\x00' * 32
priv = encode_privkey(priv,'bin')
msghash = encode(hash_to_int(msghash),256,32)
k = hmac.new(k, v+'\x00'+priv+msghash, hashlib.sha256).digest()
v = hmac.new(k, v, hashlib.sha256).digest()
k = hmac.new(k, v+'\x01'+priv+msghash, hashlib.sha256).digest()
v = hmac.new(k, v, hashlib.sha256).digest()
return decode(hmac.new(k, v, hashlib.sha256).digest(),256)
*/
byte[] v = {
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01
};
byte[] k = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
Mac hmac = Mac.getInstance("HMac-SHA256", "BC");
SecretKey secretKey = new SecretKeySpec(k, "HMac-SHA256");
hmac.init(secretKey);
hmac.reset();
ByteArrayOutputStream baos = new ByteArrayOutputStream(v.length + 1 + privKey.length + txHash.length);
baos.write(v);
baos.write(new byte[]{00});
baos.write(privKey);
baos.write(txHash);
hmac.update(baos.toByteArray());
byte[] k_ = hmac.doFinal(secretKey.getEncoded());
System.out.println(Hex.toHexString(k_));
byte[] txHash = HashUtil.sha3(data);
String signature = key.doSign(txHash).toBase64();
System.out.println(signature);
}
@Test /* achieve public key of the sender */
public void test2(){
// http://etherchain.org/#/tx/558a3797e0dd3fbfaf761f1add6749c7d5db313fdac5cba59f40e28af7bbacd1
// f86b04881bc16d674ec8000094cd2a3d9f938e13cd947ec05abc7fe734df8dd8268609184e72a00064801ba05e3868194605f1647593b842725818ccfa6a38651a728715133a8e97cdcfac54a00ff91628d04b215ebccfd5f4fc34cc1b45df32f6b4609fbb0de42e8522264467
// [ 0x12, [ 0x4, 0x1BC16D674EC80000, 0xCD2A3D9F938E13CD947EC05ABC7FE734DF8DD826, 0x9184E72A000, 0x64, 0x0,
// 0x1B, 0x5E3868194605F1647593B842725818CCFA6A38651A728715133A8E97CDCFAC54, 0xFF91628D04B215EBCCFD5F4FC34CC1B45DF32F6B4609FBB0DE42E8522264467 ] ]
// sender: d4bfbf8d0f435c2ee2b4e3680018f1892fc1fba6
String rawTX = "F86B04881BC16D674EC8000094CD2A3D9F938E13CD947EC05ABC7FE734DF8DD8268609184E72A00064801BA05E3868194605F1647593B842725818CCFA6A38651A728715133A8E97CDCFAC54A00FF91628D04B215EBCCFD5F4FC34CC1B45DF32F6B4609FBB0DE42E8522264467";
byte[] rawTxBytes = Hex.decode(rawTX);
String txHash = Hex.toHexString(Utils.sha3(rawTxBytes));
String txHash = Hex.toHexString(HashUtil.sha3(rawTxBytes));
System.out.println(txHash);
}