Author

Topic: Safet - A wallet made in JAVA (WIP - Testing purposes only, so far) (Read 295 times)

jr. member
Activity: 56
Merit: 31
I am currently learning Java. Please can you tell me how long its gonna take base on effort before I can generate wallet address with it and how can I learn  everything about wallet

Hi, congrats! It took me approx. 12-15 hours. I work professionally as a java dev since 2018. I don't think that the java part is difficult. However, understanding the theory was a bit tricky. This website helped me a lot https://learnmeabitcoin.com/
member
Activity: 336
Merit: 76
★Bitvest.io★ Play Plinko or Invest!
I am currently learning Java. Please can you tell me how long its gonna take base on effort before I can generate wallet address with it and how can I learn  everything about wallet
jr. member
Activity: 56
Merit: 31


I added the bech32 address generation, as well as its QR code
jr. member
Activity: 56
Merit: 31
Actually, learnmebitcoin helped toooo much in understanding and developing the simple app that I have developed. What would you say about entropy generation ? Would you only use java's SecureRandom ?

I do not know.
If it is for learning purposes, you may use whatever you want if it only gives you fun. You may experiment with different inputs etc.
For serious usage I would stay with secure solutions understanding what they really do. You call java method, but what does it mean? Depending on system it may use Windows or Linux entropy source etc - that subject is really wide and you may read a lot about it.

If you base your program purely on user input, you will receive nothing else than brainwallet generator.

yes! indeed! thanks! no it's for educational purposes only.
legendary
Activity: 952
Merit: 1367
Actually, learnmebitcoin helped toooo much in understanding and developing the simple app that I have developed. What would you say about entropy generation ? Would you only use java's SecureRandom ?

I do not know.
If it is for learning purposes, you may use whatever you want if it only gives you fun. You may experiment with different inputs etc.
For serious usage I would stay with secure solutions understanding what they really do. You call java method, but what does it mean? Depending on system it may use Windows or Linux entropy source etc - that subject is really wide and you may read a lot about it.

If you base your program purely on user input, you will receive nothing else than brainwallet generator.
jr. member
Activity: 56
Merit: 31
Alright, so if you go to my OP where I have a printed execution example, I could say that my public key starts with 02 and therefore it is compressed, correct ? it must be so, because I used the default method (from bitcoinj) uses a compressed key!

Yes. If you generate many keys, sometimes you will see 02, sometimes 03.
There is great page https://learnmeabitcoin.com/technical/ which could be very helpful for you. All the algorithms are explained there and you may test calculations/examples yourself.

That page is about 2 kinds of public key: https://learnmeabitcoin.com/technical/public-key
Uncompressed public key from your OP would be:
Code:
Private Key: b49bd68e4f1bd220e90871031860009b0b44654268cb1e4dcdca93743fc7961e
04a16995de6cd203c0459a841752fad6941a65ca43a0cbf629f3413d64db7fb24cdcf2530931fba3705b3054de3e16cfacbdfabd32caa9bd2bff42e66e3a45d6ac


Actually, learnmebitcoin helped toooo much in understanding and developing the simple app that I have developed. What would you say about entropy generation ? Would you only use java's SecureRandom ?
legendary
Activity: 952
Merit: 1367
Alright, so if you go to my OP where I have a printed execution example, I could say that my public key starts with 02 and therefore it is compressed, correct ? it must be so, because I used the default method (from bitcoinj) uses a compressed key!

Yes. If you generate many keys, sometimes you will see 02, sometimes 03.
There is great page https://learnmeabitcoin.com/technical/ which could be very helpful for you. All the algorithms are explained there and you may test calculations/examples yourself.

That page is about 2 kinds of public key: https://learnmeabitcoin.com/technical/public-key
Uncompressed public key from your OP would be:
Code:
Private Key: b49bd68e4f1bd220e90871031860009b0b44654268cb1e4dcdca93743fc7961e
04a16995de6cd203c0459a841752fad6941a65ca43a0cbf629f3413d64db7fb24cdcf2530931fba3705b3054de3e16cfacbdfabd32caa9bd2bff42e66e3a45d6ac
jr. member
Activity: 56
Merit: 31
So, can you tell me the difference between an uncompressed and a compressed address ? I don't even know if I am asking the question properly

We say compressed/uncompressed address to say if address was generated from compressed or uncompressed form of public key.

The address is generated exactly the same way - some input is hashed sha256, encoded with base58 etc.
The difference is what the input is. Public key is in fact a point in 2 dimensions, so you may think it is like (x, y). But, all the points are on the given curve, which is symmetrical, we may say if we have point (x, +y), we may also have point (x, -y) [they are not exactly +-,  as symmetry is not on '0 level', but you feel the difference I hope].
So, in the far far past, what was used was point uncompressed, where you hashed XY, and there was prefix 0x04, so content for hash was 04XY. Then, for simplicity, compressed addresses became more popular and now they are almost mandatory (you cannot generate (native)Segwit address from uncompressed public key).
Compressed public key looks like 02X or 03X, where 02 and 03 are 'markers' if you have public key which could be 'extended' to (X, +Y) or (X, -Y).
As for given X it is obvious what Y is, the only question is if it is + or -.



Perfect explanation, thanks.

Alright, so if you go to my OP where I have a printed execution example, I could say that my public key starts with 02 and therefore it is compressed, correct ? it must be so, because I used the default method (from bitcoinj) uses a compressed key!
legendary
Activity: 952
Merit: 1367
So, can you tell me the difference between an uncompressed and a compressed address ? I don't even know if I am asking the question properly

We say compressed/uncompressed address to say if address was generated from compressed or uncompressed form of public key.

The address is generated exactly the same way - some input is hashed sha256, encoded with base58 etc.
The difference is what the input is. Public key is in fact a point in 2 dimensions, so you may think it is like (x, y). But, all the points are on the given curve, which is symmetrical, we may say if we have point (x, +y), we may also have point (x, -y) [they are not exactly +-,  as symmetry is not on '0 level', but you feel the difference I hope].
So, in the far far past, what was used was point uncompressed, where you hashed XY, and there was prefix 0x04, so content for hash was 04XY. Then, for simplicity, compressed addresses became more popular and now they are almost mandatory (you cannot generate (native)Segwit address from uncompressed public key).
Compressed public key looks like 02X or 03X, where 02 and 03 are 'markers' if you have public key which could be 'extended' to (X, +Y) or (X, -Y).
As for given X it is obvious what Y is, the only question is if it is + or -.

jr. member
Activity: 56
Merit: 31
Interesting, I appreciate you work, regardless of its actual usefulness.

Hello. My purpose is to educate myself only. I want to learn... that's all!

Do you use QR code displayed in the console or saved to file?

QR codes are saved as .png files inside the project's classpath.

I think with a very little effort you may add generation of other types of addresses, even legacy uncompressed one, if the purpose is to learn/understand how things work.

Yes! actually to create an uncompressed legacy address, I only have to call one method, like key.decompress() and for the bech32, I already have it ready in my next commit!!

So, can you tell me the difference between an uncompressed and a compressed address ? I don't even know if I am asking the question properly


legendary
Activity: 952
Merit: 1367
Interesting, I appreciate you work, regardless of its actual usefulness.
Do you use QR code displayed in the console or saved to file?
I think with a very little effort you may add generation of other types of addresses, even legacy uncompressed one, if the purpose is to learn/understand how things work.

And of course restore address with a given WIF, but I guess I am not the one to create TODO list, you know what to do Wink
jr. member
Activity: 56
Merit: 31
So I thought it would be better not to rely on one source. Considering that I haven't written SecureRandom library myself and that I am unable to find details on how it works and how it generates entropy, I decided to add two more entropy sources. One that is "decided" by the user and one that is "decided" by time.

Thanks for the explanation. While i understand rationale behind the decision, there are few things i'd like to comment.
1. I have doubt using time improve the security since the attacker (assuming they know how the private key is generated) could reduce search space between time you create this library and first time the address receive Bitcoin.
2. I'm not sure how useful is 52-bit entropy from 2 different source when anything less than 112-bit no longer recommended these days.
3. Some details of Java's SecureRandom can be seen at https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SecureRandomImp.

Are you sure about the second comment though?

btw: I am adding a QR generator for the keys. Please see my original post at the top of the thread, I have updated it.
legendary
Activity: 2828
Merit: 7315
So I thought it would be better not to rely on one source. Considering that I haven't written SecureRandom library myself and that I am unable to find details on how it works and how it generates entropy, I decided to add two more entropy sources. One that is "decided" by the user and one that is "decided" by time.

Thanks for the explanation. While i understand rationale behind the decision, there are few things i'd like to comment.
1. I have doubt using time improve the security since the attacker (assuming they know how the private key is generated) could reduce search space between time you create this library and first time the address receive Bitcoin.
2. I'm not sure how useful is 52-bit entropy from 2 different source when anything less than 112-bit no longer recommended these days.
3. Some details of Java's SecureRandom can be seen at https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SecureRandomImp.
jr. member
Activity: 56
Merit: 31
I use a user input from the keyboard to generate 48 bits of entropy.
I use java's SecureRandom class to generate 204 bits of entropy.
I use current time to generate 4 bits of entropy.

Do you mind explain technical reasoning behind this decision? I have no intention offend you, it's just that i find it's unusual since many wallet would just use single secure source (such as os.urandom on Python).

No offense taken of course! I am Glad you ask because discussions like this can only make things better.

So I thought it would be better not to rely on one source. Considering that I haven't written SecureRandom library myself and that I am unable to find details on how it works and how it generates entropy, I decided to add two more entropy sources. One that is "decided" by the user and one that is "decided" by time.
jr. member
Activity: 56
Merit: 31
How do you generate entropy? How many sources do you use, or what is the main source?

I would love to see the source code, could be very interesting.

Hello! sorry for being late but I have been busy.

So here is the repo link: https://bitbucket.org/vampobit/safet/src/main/

I use a user input from the keyboard to generate 48 bits of entropy.
I use java's SecureRandom class to generate 204 bits of entropy.
I use current time to generate 4 bits of entropy.

A runtime example of the execution is as follows:

Code:
----------------------
| Generating Entropy |
----------------------
Please enter a random sequence of characters from the keyboard:
let's see how this goes... vampobit
Using user input to generate 48 bits of entropy.
Using SecureRandom to generate 204 bits of entropy.
Using Timestamp to generate 4 bits of entropy.
------------------
| Generated Keys |
------------------
Private Key: 170d99345e5f5fd4bf46a580c1a600c71c4a4ed70f8b0c87a0f490b94de918bb
Private Key (WIF): KwzXJ51JTBEj5kp7ZW5YuDL4TZzXTupbsF9mMRJo6K7ahbfeiKf6
Public Key: 02e68a4a2bdac08e797d92ae5364979268dd671dc7f2aa684b5975d16dcca690e5
Legacy Address: 1K8Fs8qCeoRiWbCBeKVGF53WJcMmaRaHqL

Please review it and let me know what you think.

PS1: Actually I believe it's the simplest code I could had written but it really helped me understand the theory behind wallets.
PS2: I know that it generates a non-deterministic wallet!

legendary
Activity: 952
Merit: 1367
How do you generate entropy? How many sources do you use, or what is the main source?

I would love to see the source code, could be very interesting.
jr. member
Activity: 56
Merit: 31
I sent some sats from my mobile's BlueWallet, straight into the address.
You should look into bitcoin's testnet for things like this, so that you can use coins that have no value and can be acquired freely (eg. from a faucet) so losing them (in case of a bug) is not going to cost you anything. You'd also move your test transaction to testnet instead of mainnet (ie. less spam).

https://en.bitcoin.it/wiki/Testnet

Thanks! I did to be honest, but I also tested it on the main net once I was certain my code was functioning correctly.

Would you like to open-source the tool in case someone else finds it useful?

The less people reinventing the wheel, especially in cryptography applications, the better - less bugs and vulnerabilities.

Absolutely! However I am going to mention that it is a WIP so people know that they should try it with caution.

I will suggest that you take a look at this website, which has a nice Javascript implementation:

https://iancoleman.io/bip39/
https://github.com/iancoleman/bip39


Iancoleman's tool is fine but I would argue that any crypto tool written in Java is decisively better than its JS equivalent because Java can already run everywhere, and it doesn't need s browser which is a (admittedly only slightly) larger attack surface than the Java runtime itself.

Well yes I prefer Java for this exact reason. Besides, I am using Java for the past 5 years at work, so it came in more handy.
legendary
Activity: 3402
Merit: 10424
I sent some sats from my mobile's BlueWallet, straight into the address.
You should look into bitcoin's testnet for things like this, so that you can use coins that have no value and can be acquired freely (eg. from a faucet) so losing them (in case of a bug) is not going to cost you anything. You'd also move your test transaction to testnet instead of mainnet (ie. less spam).

https://en.bitcoin.it/wiki/Testnet
legendary
Activity: 1526
Merit: 6442
bitcoincleanup.com / bitmixlist.org
I will suggest that you take a look at this website, which has a nice Javascript implementation:

https://iancoleman.io/bip39/
https://github.com/iancoleman/bip39


Iancoleman's tool is fine but I would argue that any crypto tool written in Java is decisively better than its JS equivalent because Java can already run everywhere, and it doesn't need s browser which is a (admittedly only slightly) larger attack surface than the Java runtime itself.
legendary
Activity: 2212
Merit: 5622
Non-custodial BTC Wallet
Hello people! I have developed a very simple JAVA application that:

1. generates entropy
2. creates a private key and produces its WIF representation
3. produces a public key
4. produces an address

I sent some sats from my mobile's BlueWallet, straight into the address.

Then I loaded up the WIF private key in Electrum and I saw the incoming transaction.

Finally, I sent the sats back.

Everything I have developed is totally custom and I didn't use many external libraries.

Next steps: Create a HD wallet using a seed phrase. I will create a seed using the entropy and a checksum. Then I will translate the binary seed into a seed phrase etc etc.

Thank you all for the assistance!

I will suggest that you take a look at this website, which has a nice Javascript implementation:

https://iancoleman.io/bip39/
https://github.com/iancoleman/bip39
legendary
Activity: 1526
Merit: 6442
bitcoincleanup.com / bitmixlist.org
Would you like to open-source the tool in case someone else finds it useful?

The less people reinventing the wheel, especially in cryptography applications, the better - less bugs and vulnerabilities.
jr. member
Activity: 56
Merit: 31
Hello people! I have developed a very simple JAVA application that:

1. generates entropy
2. creates a private key and produces its WIF representation
3. produces a public key
4. produces an address

I sent some sats from my mobile's BlueWallet, straight into the address.

Then I loaded up the WIF private key in Electrum and I saw the incoming transaction.

Finally, I sent the sats back.

Everything I have developed is totally custom and I didn't use many external libraries.

Next steps: Create a HD wallet using a seed phrase. I will create a seed using the entropy and a checksum. Then I will translate the binary seed into a seed phrase etc etc.

Thank you all for the assistance!
legendary
Activity: 952
Merit: 1367
bitcoinj is all you need.

If you want to see how to generate addresses from a given private key or from seed, take a look at some of my projects:
https://github.com/PawelGorny/WifSolver
https://github.com/PawelGorny/lostword
You will find there code for different address types.
And here https://github.com/PawelGorny/NodeWatcher you will find a very simple example of creating and broadcasting transaction.
jr. member
Activity: 56
Merit: 31
Thank you very much! I am trying to develop it using bitcoinj now. I will test it using Electrum once I have implemented it.
hero member
Activity: 868
Merit: 5808
not your keys, not your coins!
So far, I think the process is that the seed phrase is hashed (I don't know what function is used) and it produces a private key which is attached to the public key based on ECDSA. Is that correct?
Very roughly, yes. However, the seed phrase is just a mnemonic representation of the 64-byte binary seed. Private keys are generated from that seed and not from the seed phrase.
The HMAC of the seed gives you a master private key from which you generate child private keys through hashing it with a counter.
Generating addresses from private keys is another step that is a bit more complicated than your description. You can't 'attach' keys to each other; just generate one from another based on a fixed set of rules (since those are deterministic, it basically makes the keys inherently 'attached').

It's all explained very well on learnmeabitcoin.

I want to write the code from scratch, probably in java. Do you have any good tutorials or libraries I could use? Maybe bitcoinj?
Either you use a library, or you write it yourself. If you don't care about learning how it works, you can just use bitcoinj. You may be able to learn something by reading their code and reimplementing it yourself, but a good theoretical foundation is good to have.

Sorry if I am asking quite a lot here, but googling these questions didn't actually help. I thought this place is the best for development questions.
My advice is browsing these pages:
https://learnmeabitcoin.com/
https://en.bitcoin.it/wiki/Main_Page

As well as searching Bitcointalk using ninjastic.space with appropriate filters and search terms.
https://ninjastic.space/search

If you haven't read the https://bitcoinbook.info/ yet, you can read the relevant chapters online:
Chapter 4 (Keys, Addresses): https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc
Chapter 5 (Wallets): https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch05.asciidoc
jr. member
Activity: 56
Merit: 31

This is a Work In Progress and I made it just for fun and because I wanted to educate myself in Bitcoin Wallets! Every key or address in this thread must be ignored! I just provide them to showcase how the program works! DON'T USE ANY OF THEM!



UPDATE: 2023, Jan 10th

Hello friends! So I have developed a non-deterministic wallet in JAVA, using as less external libraries as possible (obviously I used some code from other libraries).

So here is the repo link: https://bitbucket.org/vampobit/safet/src/main/

The program creates a non-deterministic wallet generating entropy * using:
  • Java's SecureRandom = 208
  • User's input = 48 bits of entropy

a runtime example is:

Code:
-------------------------
| Generating Entropy |
-------------------------
Please enter a random sequence of characters from the keyboard:
let's see how this goes... vampobit
Using user input to generate 48 bits of entropy.
Using SecureRandom to generate 204 bits of entropy.
---------------------
| Generated Keys |
---------------------
Private Key: b49bd68e4f1bd220e90871031860009b0b44654268cb1e4dcdca93743fc7961e
Private Key (WIF): L3Gnp62mS3PsmtQ3AEZveuYWywkucv787krXEXj9xDcuJAQjC4pC
Public Key: 02a16995de6cd203c0459a841752fad6941a65ca43a0cbf629f3413d64db7fb24c
Legacy Address: 15zHNp2irZGBpd4NzJ8JypsahRDyjpoa52

My latest additions have been:
  • generating QR Codes for private key and for legacy address
  • removing the initial entropy I used to get using time thanks to ETFbitcoin's indication

I have tested everything both on Test Net and the Main Net and it works pretty good (the QR codes too).

Please let me know what you think!!!!



Hello everyone! First of all, I may make mistakes in the following post, so forgive my possible ignorance. I need your help.

I want to
  • learn theoretically how a wallet works. What algorithms are used etc. It is a little opaque to me.
  • develop a simple wallet generator in JAVA


So far, I think the process is that the seed phrase is hashed (I don't know what function is used) and it produces a private key which is attached to the public key based on ECDSA. Is that correct?

I want to write the code from scratch, probably in java. Do you have any good tutorials or libraries I could use? Maybe bitcoinj?

Sorry if I am asking quite a lot here, but googling these questions didn't actually help. I thought this place is the best for development questions.
Jump to: