package jstellarapi.core;
import java.math.BigInteger;
import java.util.Arrays;
import jstellarapi.keys.StellarDeterministicKeyGenerator;
import net.i2p.crypto.eddsa.math.GroupElement;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.math.ec.ECPoint;
public class StellarPrivateKey extends StellarIdentifier {
StellarPublicKey publicKey;
public StellarPrivateKey(byte[] privateKeyBytes) {
super(privateKeyBytes, 101);
if(privateKeyBytes.length!=32){
throw new RuntimeException("The private key must be of length 32 bytes");
}
}
public StellarPrivateKey(byte[] privateKeyBytes, byte[] publicKeyBytes) {
super(privateKeyBytes, 101);
if(privateKeyBytes.length!=32){
throw new RuntimeException("The private key must be of length 32 bytes");
}
publicKey=new StellarPublicKey(publicKeyBytes);
}
public static byte[] bigIntegerToBytes(BigInteger biToConvert, int nbBytesToReturn){
//toArray will return the minimum number of bytes required to encode the biginteger in two's complement.
//Could be less than the expected number of bytes
byte[] twosComplement = biToConvert.toByteArray();
byte[] bytesToReturn=new byte[nbBytesToReturn];
if((biToConvert.bitLength()+7)/8!=twosComplement.length){
//Two's complement representation has a sign bit set on the most significant byte
byte[] twosComplementWithoutSign = new byte[twosComplement.length-1];
System.arraycopy(twosComplement, 1, twosComplementWithoutSign, 0, twosComplementWithoutSign.length);
twosComplement=twosComplementWithoutSign;
}
int nbBytesOfPaddingRequired=nbBytesToReturn-twosComplement.length;
if(nbBytesOfPaddingRequired<0){
throw new RuntimeException("nbBytesToReturn "+nbBytesToReturn+" is too small");
}
System.arraycopy(twosComplement, 0, bytesToReturn, nbBytesOfPaddingRequired, twosComplement.length);
return bytesToReturn;
}
public StellarPrivateKey(BigInteger privateKeyForAccount) {
super(bigIntegerToBytes(privateKeyForAccount, 32), 34);
}
public StellarPublicKey getPublicKey(){
if(publicKey!=null){
return publicKey;
}
GroupElement A = StellarPublicKey.ed25519.getB().scalarMultiply(payloadBytes);
byte[] encodedAndCompressedPublicKeyBytes=A.toByteArray();
publicKey = new StellarPublicKey(encodedAndCompressedPublicKeyBytes);
return publicKey;
}
public ECPrivateKeyParameters getECPrivateKey(){
//Or return the BigInteger instead?
BigInteger privateBI=new BigInteger(1, this.payloadBytes);
ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(privateBI, StellarDeterministicKeyGenerator.SECP256K1_PARAMS);
return privKey;
}
}