Browse Source

Move some crypto methods from Public/PrivateKeyAccount to Crypto for reuse by new network handshaking

pull/67/head
catbref 4 years ago
parent
commit
b262044a52
  1. 24
      src/main/java/org/qortal/account/PrivateKeyAccount.java
  2. 11
      src/main/java/org/qortal/account/PublicKeyAccount.java
  3. 47
      src/main/java/org/qortal/crypto/Crypto.java

24
src/main/java/org/qortal/account/PrivateKeyAccount.java

@ -2,18 +2,11 @@ package org.qortal.account;
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
import org.bouncycastle.crypto.params.X25519PrivateKeyParameters;
import org.bouncycastle.crypto.params.X25519PublicKeyParameters;
import org.bouncycastle.math.ec.rfc8032.Ed25519;
import org.qortal.crypto.BouncyCastle25519;
import org.qortal.crypto.Crypto; import org.qortal.crypto.Crypto;
import org.qortal.repository.Repository; import org.qortal.repository.Repository;
public class PrivateKeyAccount extends PublicKeyAccount { public class PrivateKeyAccount extends PublicKeyAccount {
private static final int SIGNATURE_LENGTH = 64;
private static final int SHARED_SECRET_LENGTH = 32;
private final byte[] privateKey; private final byte[] privateKey;
private final Ed25519PrivateKeyParameters edPrivateKeyParams; private final Ed25519PrivateKeyParameters edPrivateKeyParams;
@ -49,24 +42,11 @@ public class PrivateKeyAccount extends PublicKeyAccount {
} }
public byte[] sign(byte[] message) { public byte[] sign(byte[] message) {
byte[] signature = new byte[SIGNATURE_LENGTH]; return Crypto.sign(this.edPrivateKeyParams, message);
this.edPrivateKeyParams.sign(Ed25519.Algorithm.Ed25519, edPublicKeyParams, null, message, 0, message.length, signature, 0);
return signature;
} }
public byte[] getSharedSecret(byte[] publicKey) { public byte[] getSharedSecret(byte[] publicKey) {
byte[] x25519PrivateKey = BouncyCastle25519.toX25519PrivateKey(this.privateKey); return Crypto.getSharedSecret(this.privateKey, publicKey);
X25519PrivateKeyParameters xPrivateKeyParams = new X25519PrivateKeyParameters(x25519PrivateKey, 0);
byte[] x25519PublicKey = BouncyCastle25519.toX25519PublicKey(publicKey);
X25519PublicKeyParameters xPublicKeyParams = new X25519PublicKeyParameters(x25519PublicKey, 0);
byte[] sharedSecret = new byte[SHARED_SECRET_LENGTH];
xPrivateKeyParams.generateSecret(xPublicKeyParams, sharedSecret, 0);
return sharedSecret;
} }
public byte[] getRewardSharePrivateKey(byte[] publicKey) { public byte[] getRewardSharePrivateKey(byte[] publicKey) {

11
src/main/java/org/qortal/account/PublicKeyAccount.java

@ -1,7 +1,6 @@
package org.qortal.account; package org.qortal.account;
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
import org.bouncycastle.math.ec.rfc8032.Ed25519;
import org.qortal.crypto.Crypto; import org.qortal.crypto.Crypto;
import org.qortal.data.account.AccountData; import org.qortal.data.account.AccountData;
import org.qortal.repository.Repository; import org.qortal.repository.Repository;
@ -46,15 +45,7 @@ public class PublicKeyAccount extends Account {
} }
public boolean verify(byte[] signature, byte[] message) { public boolean verify(byte[] signature, byte[] message) {
return PublicKeyAccount.verify(this.publicKey, signature, message); return Crypto.verify(this.publicKey, signature, message);
}
public static boolean verify(byte[] publicKey, byte[] signature, byte[] message) {
try {
return Ed25519.verify(signature, 0, publicKey, 0, message, 0, message.length);
} catch (Exception e) {
return false;
}
} }
public static String getAddress(byte[] publicKey) { public static String getAddress(byte[] publicKey) {

47
src/main/java/org/qortal/crypto/Crypto.java

@ -4,15 +4,23 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Arrays; import java.util.Arrays;
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
import org.bouncycastle.crypto.params.X25519PrivateKeyParameters;
import org.bouncycastle.crypto.params.X25519PublicKeyParameters;
import org.bouncycastle.math.ec.rfc8032.Ed25519;
import org.qortal.account.Account; import org.qortal.account.Account;
import org.qortal.utils.Base58; import org.qortal.utils.Base58;
import com.google.common.primitives.Bytes; import com.google.common.primitives.Bytes;
public class Crypto { public abstract class Crypto {
public static final byte ADDRESS_VERSION = 58; public static final int SIGNATURE_LENGTH = 64;
public static final byte AT_ADDRESS_VERSION = 23; public static final int SHARED_SECRET_LENGTH = 32;
public static final byte ADDRESS_VERSION = 58; // Q
public static final byte AT_ADDRESS_VERSION = 23; // A
public static final byte NODE_ADDRESS_VERSION = 53; // N
/** /**
* Returns 32-byte SHA-256 digest of message passed in input. * Returns 32-byte SHA-256 digest of message passed in input.
@ -108,6 +116,10 @@ public class Crypto {
return toAddress(AT_ADDRESS_VERSION, signature); return toAddress(AT_ADDRESS_VERSION, signature);
} }
public static String toNodeAddress(byte[] publicKey) {
return toAddress(NODE_ADDRESS_VERSION, publicKey);
}
public static boolean isValidAddress(String address) { public static boolean isValidAddress(String address) {
return isValidTypedAddress(address, ADDRESS_VERSION, AT_ADDRESS_VERSION); return isValidTypedAddress(address, ADDRESS_VERSION, AT_ADDRESS_VERSION);
} }
@ -154,4 +166,33 @@ public class Crypto {
return false; return false;
} }
public static boolean verify(byte[] publicKey, byte[] signature, byte[] message) {
try {
return Ed25519.verify(signature, 0, publicKey, 0, message, 0, message.length);
} catch (Exception e) {
return false;
}
}
public static byte[] sign(Ed25519PrivateKeyParameters edPrivateKeyParams, byte[] message) {
byte[] signature = new byte[SIGNATURE_LENGTH];
edPrivateKeyParams.sign(Ed25519.Algorithm.Ed25519, edPrivateKeyParams.generatePublicKey(), null, message, 0, message.length, signature, 0);
return signature;
}
public static byte[] getSharedSecret(byte[] privateKey, byte[] publicKey) {
byte[] x25519PrivateKey = BouncyCastle25519.toX25519PrivateKey(privateKey);
X25519PrivateKeyParameters xPrivateKeyParams = new X25519PrivateKeyParameters(x25519PrivateKey, 0);
byte[] x25519PublicKey = BouncyCastle25519.toX25519PublicKey(publicKey);
X25519PublicKeyParameters xPublicKeyParams = new X25519PublicKeyParameters(x25519PublicKey, 0);
byte[] sharedSecret = new byte[SHARED_SECRET_LENGTH];
xPrivateKeyParams.generateSecret(xPublicKeyParams, sharedSecret, 0);
return sharedSecret;
}
} }

Loading…
Cancel
Save