All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.xwc1125.chain5j.crypto.Keys Maven / Gradle / Ivy

There is a newer version: 4.3.9
Show newest version
package com.xwc1125.chain5j.crypto;

import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.ECGenParameterSpec;
import java.util.Arrays;

import com.xwc1125.chain5j.utils.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import com.xwc1125.chain5j.utils.Numeric;
import com.xwc1125.chain5j.utils.Strings;


/**
 * Crypto key utilities.
 */
public class Keys {

    static final int PRIVATE_KEY_SIZE = 32;
    static final int PUBLIC_KEY_SIZE = 64;

    public static final int ADDRESS_SIZE = 160;
    public static final int ADDRESS_LENGTH_IN_HEX = ADDRESS_SIZE >> 2;
    static final int PUBLIC_KEY_LENGTH_IN_HEX = PUBLIC_KEY_SIZE << 1;
    public static final int PRIVATE_KEY_LENGTH_IN_HEX = PRIVATE_KEY_SIZE << 1;

    static {
        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
            Security.addProvider(new BouncyCastleProvider());
        }
    }

    private Keys() {
    }

    /**
     * Create a keypair using SECP-256k1 curve.
     *
     * 

Private keypairs are encoded using PKCS8 * *

Private keys are encoded using X.509 */ static KeyPair createSecp256k1KeyPair() throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException { return createSecp256k1KeyPair(SecureRandomUtils.secureRandom()); } static KeyPair createSecp256k1KeyPair(SecureRandom random) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDSA", "BC"); ECGenParameterSpec ecGenParameterSpec = new ECGenParameterSpec("secp256k1"); if (random != null) { keyPairGenerator.initialize(ecGenParameterSpec, random); } else { keyPairGenerator.initialize(ecGenParameterSpec); } return keyPairGenerator.generateKeyPair(); } public static ECKeyPair createEcKeyPair() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { return createEcKeyPair(SecureRandomUtils.secureRandom()); } public static ECKeyPair createEcKeyPair(SecureRandom random) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { KeyPair keyPair = createSecp256k1KeyPair(random); return ECKeyPair.create(keyPair); } public static String getAddress(ECKeyPair ecKeyPair) { return getAddress(null, ecKeyPair); } public static String getAddress(String icapPrefix, ECKeyPair ecKeyPair) { return getAddress(icapPrefix, ecKeyPair.getPublicKey()); } public static String getAddress(String icapPrefix, BigInteger publicKey) { return getAddress(icapPrefix, Numeric.toHexStringWithPrefixZeroPadded(publicKey, PUBLIC_KEY_LENGTH_IN_HEX)); } public static String getAddress(String icapPrefix, String publicKey) { String publicKeyNoPrefix = Numeric.cleanHexPrefix(publicKey); if (publicKeyNoPrefix.length() < PUBLIC_KEY_LENGTH_IN_HEX) { publicKeyNoPrefix = Strings.zeros( PUBLIC_KEY_LENGTH_IN_HEX - publicKeyNoPrefix.length()) + publicKeyNoPrefix; } String hash = Hash.sha3(publicKeyNoPrefix); String address = hash.substring(hash.length() - ADDRESS_LENGTH_IN_HEX); address = "0x" + address; if (StringUtils.isNotEmpty(icapPrefix)) { return ICAPUtils.buildICAP(icapPrefix, address); } return address; // right most 160 bits } public static byte[] getAddress(byte[] publicKey) { byte[] hash = Hash.sha3(publicKey); return Arrays.copyOfRange(hash, hash.length - 20, hash.length); // right most 160 bits } /** * Checksum address encoding as per * EIP-55. * * @param address a valid hex encoded address * @return hex encoded checksum address */ public static String toChecksumAddress(String address) { String lowercaseAddress = Numeric.cleanHexPrefix(address).toLowerCase(); String addressHash = Numeric.cleanHexPrefix(Hash.sha3String(lowercaseAddress)); StringBuilder result = new StringBuilder(lowercaseAddress.length() + 2); result.append("0x"); for (int i = 0; i < lowercaseAddress.length(); i++) { if (Integer.parseInt(String.valueOf(addressHash.charAt(i)), 16) >= 8) { result.append(String.valueOf(lowercaseAddress.charAt(i)).toUpperCase()); } else { result.append(lowercaseAddress.charAt(i)); } } return result.toString(); } public static byte[] serialize(ECKeyPair ecKeyPair) { byte[] privateKey = Numeric.toBytesPadded(ecKeyPair.getPrivateKey(), PRIVATE_KEY_SIZE); byte[] publicKey = Numeric.toBytesPadded(ecKeyPair.getPublicKey(), PUBLIC_KEY_SIZE); byte[] result = Arrays.copyOf(privateKey, PRIVATE_KEY_SIZE + PUBLIC_KEY_SIZE); System.arraycopy(publicKey, 0, result, PRIVATE_KEY_SIZE, PUBLIC_KEY_SIZE); return result; } public static ECKeyPair deserialize(byte[] input) { if (input.length != PRIVATE_KEY_SIZE + PUBLIC_KEY_SIZE) { throw new RuntimeException("Invalid input key size"); } BigInteger privateKey = Numeric.toBigInt(input, 0, PRIVATE_KEY_SIZE); BigInteger publicKey = Numeric.toBigInt(input, PRIVATE_KEY_SIZE, PUBLIC_KEY_SIZE); return new ECKeyPair(privateKey, publicKey); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy