Bitcoin Forum
September 24, 2020, 06:04:15 AM *
News: Latest Bitcoin Core release: 0.20.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Getting incorrect public key (in Java's bitcoin's public/private key generator)  (Read 144 times)
Raja_MBZ
Legendary
*
Offline Offline

Activity: 1610
Merit: 1384


Any questions related to my signature site? PM me!


View Profile
February 12, 2019, 05:22:44 PM
Last edit: February 15, 2019, 10:10:46 PM by Raja_MBZ
Merited by bones261 (1), HeRetiK (1)
 #1

EDIT: Got my confusion sorted out, thanks to ETFbitcoin



I'm getting a correct private key, but an incorrect public key, with the following java program:

Quote
import com.google.bitcoin.core.Base58;
import java.io.UnsupportedEncodingException;
import java.security.........

////////////////////////////////////////////////////////////////////////////////////
   
public static String to64(String s) {
    switch(s.length()) {
    case 62: return "00" + s;
    case 63: return "0" + s;
    case 64: return s;
    default:
        throw new IllegalArgumentException("Invalid key: " + s);
        }
}

////////////////////////////////////////////////////////////////////////////////////

public static void main(String[] args) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, UnsupportedEncodingException, NoSuchProviderException {

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
ECGenParameterSpec secp = new ECGenParameterSpec("secp256k1");
keyGen.initialize(secp);
KeyPair kp = keyGen.generateKeyPair();
PublicKey pub = kp.getPublic();
PrivateKey pvt = kp.getPrivate();
       
ECPrivateKey epvt = (ECPrivateKey)pvt;
String sepvt = to64(epvt.getS().toString(16)).toUpperCase();
       
ECPublicKey epub = (ECPublicKey)pub;

ECPoint pt = epub.getW();
String sx = to64(pt.getAffineX().toString(16)).toUpperCase();
String sy = to64(pt.getAffineY().toString(16)).toUpperCase();
String bcPub = "04" + sx + sy;

MessageDigest sha = MessageDigest.getInstance("SHA-256");
byte[] s1 = sha.digest(bcPub.getBytes("UTF-8"));

MessageDigest rmd = MessageDigest.getInstance("RipeMD160", "BC");

byte[] r1 = rmd.digest(s1);
byte[] r2 = new byte[r1.length + 1];

r2[0] = 0;

System.arraycopy(r1, 0, r2, 1, r1.length);

byte[] s2 = sha.digest(r2);
byte[] s3 = sha.digest(s2);
byte[] a1 = new byte[25];

System.arraycopy(r2, 0, a1, 0, r2.length);
System.arraycopy(s3, 0, a1, 20, 5);

System.out.println("Public Key: " + Base58.encode(a1));
System.out.println("Private Key: " + sepvt);}}

For example, instead of:



I should get:

Public key: 1BuXQcCU7eQA6z5N5qqNUubjQLk3vrATVk
Private key: 93B16A46CF1D71E79CA28BFFA8499B6F7412BEB1514CC6FE271AED19F3FAF946

Any idea what I'm doing wrong here?

Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction. Advertise here.
1600927455
Hero Member
*
Offline Offline

Posts: 1600927455

View Profile Personal Message (Offline)

Ignore
1600927455
Reply with quote  #2

1600927455
Report to moderator
ETFbitcoin
Legendary
*
Offline Offline

Activity: 2128
Merit: 2510

Use SegWit and enjoy lower fees.


View Profile WWW
February 12, 2019, 06:21:10 PM
Merited by bones261 (4), pooya87 (2), Raja_MBZ (2)
 #2

I'm pretty sure those are bitcoin addresses, not public key since public key and address uses different format[1]

There are 2 types of public key which are compressed and uncompressed and i think that's the problem/reason you got different bitcoin address from what you expect. But i didn't read the code, so i might be wrong.

Reference :
1. https://en.bitcoin.it/wiki/List_of_address_prefixes

Raja_MBZ
Legendary
*
Offline Offline

Activity: 1610
Merit: 1384


Any questions related to my signature site? PM me!


View Profile
February 12, 2019, 07:13:43 PM
 #3

I'm pretty sure those are bitcoin addresses, not public key since public key and address uses different format[1]

There are 2 types of public key which are compressed and uncompressed and i think that's the problem/reason you got different bitcoin address from what you expect. But i didn't read the code, so i might be wrong.

Reference :
1. https://en.bitcoin.it/wiki/List_of_address_prefixes

That helped, thanks!

pooya87
Legendary
*
Offline Offline

Activity: 2128
Merit: 3111


Remember tonight for it's the beginning of forever


View Profile
February 13, 2019, 04:54:40 AM
Merited by ETFbitcoin (2), bones261 (2), Raja_MBZ (1)
 #4

FWIW you are also making a couple of mistakes in your code too. for starters you are getting the X and Y coordinate of your public key in hexadecimal format then append 0x04 to its beginning but then convert the result to byte array using UTF8! that is why you are getting 1vrHc... as the uncompressed address instead of 1ARcqBL7EkpqEAu8EcTRHvu2fTUaqCoZR2
i am not familiar with Java but i can tell you that the problem is here, you should figure out how to change the bold part from UTF8 to base16 decode in Java
Quote
String sx = to64(pt.getAffineX().toString(16)).toUpperCase();
String sy = to64(pt.getAffineY().toString(16)).toUpperCase(); // <--toString(16) is converting them to hexadecimal aka base16
String bcPub = "04" + sx + sy;

MessageDigest sha = MessageDigest.getInstance("SHA-256");
byte[] s1 = sha.digest(bcPub.getBytes("UTF-8"));

additionally there is an extremely tiny chance that your to64 function can throw an exception because X and Y don't have to be as big as 32 bytes. technically it can be a smaller number so your hex may have less than 62 characters. also i am not sure about this part but toString(16) is not returning values in Two's complement otherwise you may see 00 in front of some of your numbers.

ps. it is best that you work with bytes instead of hex. it works a lot faster and there is less chance of introducing bugs.

Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!