Author

Topic: BIP38 python problem (Read 1002 times)

sr. member
Activity: 1190
Merit: 469
October 24, 2021, 03:34:30 AM
#82

One big benefit of making the source code open is that you can ask others (who are familiar with the programming language you used and the topic such as cryptography here) look at your code and help you improve or fix the bugs it contains.

Yeah there's alot of open source python packages you can install the problem is they get broken or simply don't work. And the sad truth is it's often just alot easier to code up your own thing than to try and figure out why their's is not working since alot of times, those packages had other dependancies and the errors that are being thrown have to do with those dependencies. I call that software bloat and it's ugly.

And the thing about it is, even the ones that do work, you always run the risk that something in them will break if they stop being maintained and then you have to try and figure out how to fix it or just code your own. It wouldnt be so bad if they didn't install a bazillion dependencies that are themselves complex projects in their own right when it's really not even necessary lol.

it makes me wonder if some of these programmers even really understand what they are doing. you wouldn't need to rely on other packages so heavily if you really know how to program something. not in every case. i find i am getting the best bang for my buck by building up a library of tools that don't have these huge complicated dependencies on unnecessary glitz and glamour.
 but i guess everyone can do their own thing.

this epiphany comes to me as I had tried installing and utilizing a simple passphrase generator. you would think that would be a simple thing that couldn't go wrong...
sr. member
Activity: 1190
Merit: 469
October 14, 2021, 05:28:00 AM
#81
I'm still trying to figure out one anomoly though. I can't really say more about it YET.
One big benefit of making the source code open is that you can ask others (who are familiar with the programming language you used and the topic such as cryptography here) look at your code and help you improve or fix the bugs it contains.

I woulldn't want to subject someone to have to read through my code it is surely not polished. As well, this is a very strange thing that just kind of popped up. It was very unexpected but I'm trying to take a look into it.
legendary
Activity: 3472
Merit: 10611
October 14, 2021, 12:40:47 AM
#80
I'm still trying to figure out one anomoly though. I can't really say more about it YET.
One big benefit of making the source code open is that you can ask others (who are familiar with the programming language you used and the topic such as cryptography here) look at your code and help you improve or fix the bugs it contains.
sr. member
Activity: 1190
Merit: 469
October 13, 2021, 10:32:59 PM
#79
Have you (or are you) planning on putting your Python BIP38 code up on GitHub or similar? Huh Might be useful for someone in the future if they have don't have to "reinvent the wheel" Wink

I probably should, given how helpful people have been to try and help me get it figured out. I'm still trying to figure out one anomoly though. I can't really say more about it YET. It may be nothng but it may be something. Once I learn more, I'll feel better. never used github before but it's a good resume builder I heard  Grin

HCP
legendary
Activity: 2086
Merit: 4361
October 12, 2021, 09:55:24 PM
#78
Have you (or are you) planning on putting your Python BIP38 code up on GitHub or similar? Huh Might be useful for someone in the future if they have don't have to "reinvent the wheel" Wink
sr. member
Activity: 1190
Merit: 469
October 11, 2021, 09:30:01 PM
#77
back to the topic of bip38 in python. I finally got around to trying to code up the "decoding" part of it and there was a few little things the bip38 github page didn't really make so clear about how that is done. but i figured it out. and that's working. but i had heard that you can do bip38 for bech32 addresses. but that would be non-standard, and not in accordance with the bip. so you can't do that.
sr. member
Activity: 1190
Merit: 469
October 10, 2021, 08:00:31 AM
#76

One option is Bitaddress.org (offline of course) > Paper Wallet > Hide Art > BIP38 Encrypt > Print 7 per page.
Yeah I've printed out a couple of those before but 7 per page is kind of on the low side I was hoping I could get more onto a single page. At least 30 but I'm not sure if that's really doable since I don't want to shrink them down in size.

But it's Legacy. I know there's a Segwit version of the site, but I haven't used it (and wouldn't easily trust it).

I wouldn't trust it either not after what some person experienced with using it. Granted, he was putting his private key onto their website directly rather than running it locally but still! He tried pasting in his address to sweep the funds to but then it changed the receiving address. Then he changed it back to his again and clicked submit but it still sent it to the other address! Imagine ignoring a warning like that and going ahead and losing 0.01 bitoin anyway.

it does sound like spyware but it remains unresolved to this day. as far as i can tell.

Further imagine that happening to the same person two times! I bet he runs everything locally now.  Grin probably with a subscription to malwarebytes or mcafee antivirus for good measure. Smiley

legendary
Activity: 3290
Merit: 16489
Thick-Skinned Gang Leader and Golden Feather 2021
October 10, 2021, 02:33:37 AM
#75
creating a bunch of qr codes but unfortunately i'm not sure why such a tool doesn't already exist for doing that
One option is Bitaddress.org (offline of course) > Paper Wallet > Hide Art > BIP38 Encrypt > Print 7 per page.
But it's Legacy. I know there's a Segwit version of the site, but I haven't used it (and wouldn't easily trust it).

Quote
the big question now is how many such qrcode private key/address pairs can be fit on a single page how many pages will it take to print all 1000. obviously the less the better but can we print on both sides of a piece of paper or is only one side best?
I wouldn't go smaller than Bitaddress.org's default QR-size, and I wouldn't use both sides of the paper.
sr. member
Activity: 1190
Merit: 469
October 09, 2021, 10:53:47 PM
#74
In that case: you can still add a QR-code. My favourite is a paper wallet (don't use the site that turned into a scam) that prints the private key twice, one of them upside down. That reduces the risk of losing it if the paper gets partially damaged. You can of course easily do this manually.

No thanks for doing 1000 qrcodes manually. the chances of making a mistake would be very high plus it would take forever!

Quote
Creating 1000 individual QR-codes would be very easy to script on Linux, but a tad more work if you also want to keep track which address belongs to each QR.

I think anything you can do with linus you should be able to do with windows. especially soemthing as simple as creating a bunch of qr codes but unfortunately i'm not sure why such a tool doesn't already exist for doing that. as far as keeping track of which address belongs to which qr code that's easy you need to print a qrcode for the addresses too. at least I would want to. yes it doubles the space but its needed.

also the process of using a private key guarantees your qr code is scannable since you have to scan and decrypt it in order to be able to use it for the first time. i think if you printed the text of the qrcodes along with them you won't need to print them "twice" since the text serves as a backup in case for whatever reason the qrcode is not having a good day.

the big question now is how many such qrcode private key/address pairs can be fit on a single page how many pages will it take to print all 1000. obviously the less the better but can we print on both sides of a piece of paper or is only one side best?

legendary
Activity: 3290
Merit: 16489
Thick-Skinned Gang Leader and Golden Feather 2021
October 09, 2021, 03:53:44 AM
#73
You know that makes sense.
In that case: you can still add a QR-code. My favourite is a paper wallet (don't use the site that turned into a scam) that prints the private key twice, one of them upside down. That reduces the risk of losing it if the paper gets partially damaged. You can of course easily do this manually.
Creating 1000 individual QR-codes would be very easy to script on Linux, but a tad more work if you also want to keep track which address belongs to each QR.
sr. member
Activity: 1190
Merit: 469
October 09, 2021, 12:04:44 AM
#72
Actually what I'm trying to do is store 1000 bitcoin private keys+addresses. That takes about 90kb or so.
What's stopping you from using BIP38 on each private key?

The great benefit of printing individual private keys is that you can simply decrypt only one of them, while keeping the rest in cold storage. And you won't lose all of them if you can't read all pages.

You know that makes sense. I think that's a much better way actually than my idea of encrypting them all in one big blob.

Quote
Even better if you create all of the keys from a HD seed, and store that seed separately.

Understood. Cheesy
legendary
Activity: 3290
Merit: 16489
Thick-Skinned Gang Leader and Golden Feather 2021
October 08, 2021, 05:29:46 AM
#71
Actually what I'm trying to do is store 1000 bitcoin private keys+addresses. That takes about 90kb or so.
What's stopping you from using BIP38 on each private key?
Bitaddress.org (I only use this online legacy version for a test of course) makes that very easy if you click Bulk Wallet (Passphrase: test):
Code:
1,"1FpowQrfR2F92BARiGRNBjRw6oqHC9fRMJ","6PnTud91uBVjFJLuaZJWyRtqe3NY3sLHvVsu7U91scN34PbgnNgCFtaQCb"
2,"1KYeL3aMpi9AbUF237TmxEWoEZMAwBmG68","6PnZAadxGMjyvjYza4ngRH1Ebkf4SbPBc3xGuH58azB4idCwiLC9mYwJZg"
3,"1vNsT73PucMAPs4agU6yzy8wAQVAejv57","6PnYuCB6X685Z9P71uCFX3jv3fDRzxjkvhWMTuQjb9qxE3hLurGuffzxFK"
4,"1DSVh3mfAxC3WHdRcnTYfsn8TZMYYgAeKr","6PnZJZVTmDCo4zGig2r7fHnwhBD8S3dWShGGE8q5XEwAP6RDiXLc5qwaK4"
5,"1NLQcpGCu6zJ3nZHKd3y7jYbSpZfvKnvxc","6PnTDsf34yqTxT6afDUUh6RiXY41DEzQ4tT3BYqZQ7zpw2jvv9SQ4w8Hhe"
6,"173UmKcwUcHBMR12CtCF9ka3dD4tamLVMW","6PnViHwxzWotkCtXCVyxJm7Qnu9RCKDQshUHScxkPdkrzqa8X4Zv1jSzUk"
7,"1Pv7MYgcjRh3SgHa5Tyfna6KzL1oDoJAA1","6PnX9ZVCCPvufaPr6RBz73V5QN1DLaGvxko7FCTzRdmFt8NWDmdz3LH5Bu"
8,"1Mmn8wvCWVnh851VmAzcCVWyxfcK14SYmJ","6PnPhhWZgmZ1adDt92QqdPEDsXUGr2Yp7N58WjdsHwdue1tEiHJF7zt97G"
9,"1mShzzPuLamED4adyeYy9syBppe2V4Q1N","6PnM4Vm51rTtp3mrF2BgT9GQzPjkR7keGbP6Hyj8kRDHe9FsgsraANy54G"
10,"1CdnDEX9og5x7sU3LCCS7D4etSD9t3wPhe","6PnSj1LCZsyUt8rR91k1NfQ4hrqcMpSGueLqv2SVwPygXKboUvAw6sG7uc"
11,"1Fqtns476tPZxqXFEjULMUFw72566k9YwV","6PnXfyUXPp6ChsLKnPuGgwwNupMoeHjJXGZK6DRKFVPVfmwNRz3M6Mkrs7"
12,"19zH966iexiXwqwV1MAKft1Z8h5ceULUkS","6PnNGjsE4PprkwLkLpc8a63nhR9axmi3dznob6KnRnNquxfBXwqJAt4Y8f"
13,"1BogPV3s11ByCLVvxaeogfb576fUzvq7s3","6PnNoBS29DuJ7GtzZAjW6qT76djX8fPxU4nNmckVqacCVhNjKgBW7yyQGp"
14,"1Q4xg57HxoSkv5mptdcRVQkopCSbwgyLhJ","6PnRNxVBSwa7b4mEMtwVNeb3LFvHBAUpsJpT9hcPX1EN4nywaBF1nYy6NU"
15,"153shGpzyKaMEy5t3UTSPLCDYqskRibVjF","6PnM8dH9Z5yukPisH47cVJNSXQ7N6bC9ejg9VQ8qzsNoWvB2wT8iZxsMh4"
16,"18eHqu5px2vzpSi9WMMhNLt7Y6ivAe1tTt","6PnSDoQuGSC6dBV8dz2KUu1P66v5EHZhmyTo7o4pfb9BYDgmKdxAoHK4i2"
17,"1LF78iaRD1CjvRKo1AU39x93P2tqFviWbK","6PnPUJm4sJGaSfq6qkBe9KVdMDnbBMFPxKPKmihY5Qsh62ir9x3LyUHoFo"
18,"1JMqoANczBWvWQvUBhkYshnBPSe3rE3Pg","6PnZbDnn1Aos1Qwi67s4eZijfmgreMWtAZ5whX1m4ABWTPvn2UYe5LvRPx"
19,"1KQZpPfujmEPSiPh2W3Qxv7AUzgkoS5mVo","6PnP9rgJ1ZzYGDTLhWZJZcmhmyBM7X4FesjmhAeazR5afjxPBmNTwqhqLU"
20,"12EGj1vhHgm9kPt2Ehe2QES9rAKUbSN4T6","6PnPYhNBkqjwrymtAnawjQVMwK1yBsWMRLVDgZLS3A9ot7AA7C7XQ3XfGq"
21,"1CGHQ4XZV7b2i4dKGy5Rud18RMWAKpTx2H","6PnNyLHGiXcXPxgDEdjYveDe3tscbY3xAxQ1gRYst9F72JN3PrYwwu5q9y"
22,"16Emwo7Zm3pDPmFw8zpTEeYTEYNaMx5JwX","6PnU1ZdynFd3fpkXLMeim3wTMKHKn7DWXCesbM5TKKkKZen2GwPCnNXhv7"
23,"1JJjtDHw6Tx4tPHPc5gzFtJEE1pLqBCqfX","6PnXy1VZpNjdT9DzYrh7sqz3RkQZF2Ps4QASd8HrTgB1VGKKcPu12xTehL"
24,"1ahBTTMXc71VC7M8kASxadGesszB8Gb8n","6PnYaQKzRjDXk6TH9KbevJArKi6mq8RUL4a3GRQjA9kKTt5e5Eg1FrKTpR"
25,"1M9GAPJx3oKKeTDe2vFoCwWeryQQavGZe6","6PnWe9MYP25QfUmHyC6WcH9WFWKonbRood4HyX2hKUk9PMQfrAWxKiLUqP"
26,"1ABPXcqs1hiCP9jJzfEiSxZrR6rjCSHLDg","6PnT2SoRzLSfkstGNXRbfWv1vs7qNgPmDWBJE6ho3AcNzcLq9dnhPGkQKD"
27,"1MP5RRyUDvmEEtMGuEe3Q9ua4ZLd3mTuiN","6PnNPbu8jLMf52Ygk4V1VuZCBcGruVHinzkdeRYFsENUwVyVTTW4aVUvmh"
28,"1KJsGoAvEC2cF3Hnvf15BaUJmt1uCHLCsc","6PnXuDA5JhA32pxRbXmR1DCPEfK4voMz2R3Xv3ZxND2At66SZYPd8N8DuQ"
29,"1L38m3GyUxJUcuZtxHVLGsaUKhZfAXnPxE","6PnRh5NpQVxxjf68pFCRz7YXtYPYARRJygpJ5tRsoXKsfRQktzUxr4pSMN"
30,"18MBupBXpXoGRvrfFxPvUnPSLfQKygxgJn","6PnSkntDXRBaz7gKXy9kLWejEEDN71fsYrtnZihp4zM6AjnWKpnTdVjXrL"
31,"15dzTyoZzA3nraXwUGiY7MM2QHgcWAbd6n","6PnZbDC9vJ5yuXbWbq8MzQp8J1fPWPjZJj3Zu52Ro4JfskQgkKfVPumjRS"
32,"1M12M8Yd3ccVnu623D4uqwKRcNYjJubsRZ","6PnPAQ3rFYNPwztH1xLD4y5k9jmL5xxoBsdbriVw7hW8hQqdNFxuEvcLN6"
33,"1JLfWxS2pqjUcWDcQTLwmS4W9KHwcGsPjx","6PnX5e8vWQZjpr1U8iqiBEbdFAWjJbwQbVGSZBBN5h9biptEV4Y8bbnLAt"
34,"12kguAtR4BonNwKFxs89QRpoAH8SGGrhmd","6PnN664VcUoivVDRbEeF3dy6jm1e4rKbwctPmCsUi6s56iEn8m18CeP8n5"
35,"1DatKJPTtpTggTZm27QQc2twrvzPpghYnA","6PnWSjJvdzksx8KKJgJufg8XNQjWNcKSJVaic5yK9ecKRKeKY1VRcZG9ts"
36,"14gPFzbsedSqabh8YoG93UFX6YGBXALZ37","6PnXFX8ScfKarRxw5NJ7Ww6hZPPTuU9HK97SiowjVnZWgNBDxGWpfHhrpZ"
37,"1JS5nmAkfytVh1XAJrajfZFHVM3sBbbWoc","6PnMkFDVrmMVWoH7pSxhXzV5xga2JmxeASv9dWcKvGRRfAEgAh2KXar4kx"
38,"1LPKhb6M2QN5vGx6BE1C4k8cDcvs47nmWa","6PnY6mSQA3BVkbNNHp3E8op7JNqE7GXDtPZKjv863FuN8RkQuMwWzQ9bTP"
39,"1A6tvoukhfgwhG4KEZ7TMHnLchbLsxbjDj","6PnRnN8oBB4Zqn4GJRDUskpVqeTa9nB8WCys7eQL8NrLKb85329hPpVDxW"
40,"1BWbUnsG7VfA4EgLZGUjQFgZrqNuPTiA2j","6PnRWTW3phwMFpTuz6dxJHmUXh5xPPn7tHmeqiDeyHu5hP8SQ5zpftE6mK"
41,"1J9padjU7harD5Lz3WM7zvgbUZ6AS3kjET","6PnYgKrGBixH1hs34CvRdUzPdS81Zw5VqEjG1T8NXpguKQpw9GfPqmnGM8"
42,"19iNmiMaJpHaFaFf4ibQMPU5ismNf96NR8","6PnUUT71U1hvJ4jfp2YfQoky53GguMnVeSWKAQHNdpU5A7qi5zyRrRDYyZ"
43,"1MdUw8dhJoQwaif66VJobecS3aZustWZ1y","6PnXD6wE6jyy6kiZ8BdqzKkRrTqxqqjuJ7K1bbfWos2Zf2GFmknw3ZP4Cs"
44,"14ZjfYLAZMnAxX18uBjfKRJD4K4YwyYmVW","6PnQ3TXWZw9DHpaesX6pYFRHixXhsyLDp1KBfkBqd9G7Yj7UrfhRFQKtvC"
45,"1HrwwsUwxNsv6UEovjTthKbXubTYUYo929","6PnY5HGyqPBbUPNoteBqtR3sd9iuDsLkGc3sxaUcUjeVvNRmev4ASgK3fA"
46,"12CSz1VMf4LhchZamRXTSCWEXo849krdN4","6PnMSDRtq8FPzgrRt2sxyTiSHPDTWKS8KyfheDFgZ8weHyS28jjxfsAvxu"
47,"1Q34Jmc3Su1vJWcDfCtixx1LjiRNRTEQki","6PnNy2gJXQMM6p94GscQHhFyUKqwTKpsQjdCMZZEPzReBSY29kYei44xUU"
48,"1FVuxhkRvQkfnKzwWEjQgr9R1E13pS15vC","6PnRPNvZvjtyzcsmNKEjnj8btLxstCjcuUXHFdjDU6Egm6aSGjkV4amH3k"
49,"1LwuY5QZYeeZZDhuK6ZWGRk2Aw3kkQF8CP","6PnNiCFgac8egM7bmFesbwPRjDNh6qsPRU6RFTDwQ9wgBSvdJWFJQn9Z3T"
50,"1NtLRQavqG1Rzh6cVT3DW7VMfqtFzYZV3J","6PnV7Gwc8BS4FP6aubU3gFCsYfdCuSnXyYmEDGFQPZY7Fe2bDP8qGW9zKF"
51,"1KTeifGBDYj2FcU9wzg12uCPgaTVrCAAda","6PnYtMxzatasJCMtvLqft9NGxVNCjDvXfkBD6H9Hafy6F8HF4XyajwE8kP"
52,"1NjW8apZAZayksBTp5taJ9yj7hghTaCWB8","6PnU1Z8D83oVdjYwP7XBofY6GSJ6ywm5GMcZJZEXR6KNLaEcuebyfZy79a"
53,"1GDWNWfXZetd626v7zoK7aXNwrPv47xSy7","6PnRrVw4JU5zUWK7AkESqiy5KC3vzfSSB8qR139sbfFJYprv5rxUpj6WZN"
54,"1AKzrMm7fXUYAxqU95M1ixxZovhstszB2p","6PnYJSbaFyJdrXftVLzDxjmmvbZdQD2CFiosn1Xs8DLE4itgNJMuajHeK3"
55,"1HdYnZu81NWC5cnGB9fTUkdBsVH1YpZxkH","6PnWtQXYCPxuD4ukcduTQucpf1W8qmbfJmmczzo3DqHQW7rYtQCvgvEDTG"
56,"1CxtevUsu3V2egd5pG6ohLrGvQuLHW4Nmp","6PnSBo3FW5YtLWeJ7YLN7RuqSxTVczWu5voRpkkJPveJUMazL2kQcv8rGk"
57,"16ta5KRZ7iZ6g2K2xQBJUazuHbL6vVMNA8","6PnPbaMeJo54gUDftv3y3uE1qDL3nCBWfyh3yX7pmQT48TPCMKkkrkV8ek"
58,"1LSuTzTKKTkurJFqCYAMrBjEWHGaMGNrH9","6PnU46w7h2bx5aGFynoFeFpkVvMHso1UyaxcduSr9yBxNgZmVfGdX5o4MK"
59,"17if3omir9d6dKByKwPhB1twibY9HAggtC","6PnZ7BqMZfa97LNDH2ACvKHNbSKLPkazfnebJShasG7em8hio4czGSji8G"
60,"19qPGCGhYnY4FHC1uVjEsViRwPkVtffJ1F","6PnS7RdEuUapdVten9Boy46CpEaBRZePLivvMjHATasKd1sjXmshbyPVRn"
61,"1Egj2bUKjYT5i8t4cUB81WfDHiAuuvfF7v","6PnSWri2YeojY9X4ZBuo1GzzSGcWJBuPLnnvfpPCNXFXQcXqrQJmb4fQ82"
62,"15inAqEEUuisWGSjwqhHZijbkvxxToxMNd","6PnRATuYDwohRoPDrNJJJv8bGwzZt5SEMSWjgXBWSYb3CuMSqjuE5p5yy6"
63,"1C2iaWHbCm5jcgJmHBHPxXNV8P8MpFYGX9","6PnRBoM4Cx4NDuKvuXKjun9TZE89A633SzZGHLU5A2mMgQHUWWEtoVDqTx"
64,"1BEFmHKDjYKK1RpsuUSfV1LW78wEL76ceT","6PnXMKjxZF7fnC8pupqu5zZHYr4KW4N8U7nzho8e7Bi8FeEmKuaiech31R"
65,"1GbRWtyTkMV1eqhVJhaFxbc3o6gjkFfitr","6PnW7GyBSoK52jQnyyaisbabRsjDTrS7yeQ5hCUAgFYK35Hu7aez2iHSzP"
66,"14KB2TPk13sgDf35sMmUkB59RpqWRAg2q3","6PnNK1DnBHBaY8yfzRHDf7qJZZXd7mJB3CvyNeTgve38NTXab23qFfEtot"
67,"1ApAtHQVDSBv5eysHd3rcCuCQZC3CyMS8U","6PnWMPv1bCm74uYcg3KuoXHqWcJUsCcFjRnnzsowe3BSHSLf62vDFjwVgP"
68,"1PGzkvvsMBL9EcAZqcdeo15vyTwYS4ttBW","6PnNP3paCWPGyd2ZNiU12nFUoY4SbM97Xp9XLm6dou6K7HL4iwZ23hafDX"
69,"1UuLVtnM3nd5y1D6GLEHcAxmoFdrKrhAm","6PnZSjGEuWB9QmqMnkBG1S7FadQ6UDLWhKuoWU57TH2aBHtbprSCz7Zyon"
70,"1Fe4KM1dxcVhpEiApTDwyzdYptQBwmRLJe","6PnYZ8AZfkdwujbX4YdgXgm6hUHChUGRNrDvWWquww58rzy1wBPAFDMyQV"
71,"1zQrfonPb6GNU2YviWoFHYDsh7aE9bQ6g","6PnVrNXH2jxWtkFCqBUux7LS8LfW1Fj6GMJTXkAspRjT3UpmS1PU6uvTpF"
72,"1LBXK659QQGYVTdwchJtywYM2WDwXFP5KK","6PnWEHgRtDa4vH6wh7NnRbPyze2iKTzFDSfcJi3QwnHj8kpYj34eQnq3w1"
73,"1LSmgTHKPDYW9fvFTkt5eoqcqKLPY9BiBu","6PnPESyuCA9Bu5AM5EcV3ueJt1HQyTgqbSCnu9nsDZeffs8YDFEQavNMxG"
74,"1GPgSWgkvUZKK3SikWEbFc1GmdraEBX9SH","6PnXHW4mtSfB8GJEr9ZUe9YTh5aAVnDNCbxBKfWTSaFgg4Z6ymcCAFfK5t"
75,"15Lx5WXQx5CSZqMCnrvvGioR8s1cpxsY65","6PnNc4dh8BmM5277HfCUfdVHbvkzT3BNajeGo3sg9vgkNTFWCvuMqS38JH"
76,"12Br2mvzat6zhbz4Vkt6mXKTKcjmHcbYna","6PnSif1uKLj45ukYjR5vodD2bJvUHNEsFcT1vxm2keQpGDFKM25Bx8v4iC"
77,"16y7oveEdDSZH56b2frEfSW3ht4z8MpcSg","6PnT6WmtMSmJS8JVPPXTADxNvATwEjTEoYsx1uvj9v6396wBUdN1tVgGKj"
78,"1BRWzySVCCKXLocVudL2Avw65GBNqYD9Ee","6PnXrc2e3cUrskNBBjXiCJUCdQXe4z6tzJvrsLbbUMyiqGEL2Qc8xCNJ2u"
79,"18uvxgZxV1QiijWNNpG1zYVR8pMwUFXo9B","6PnY9iidM1P8LhkQPmcyT2zmwh6JiEVYPe26v5gPLdAtu4SHazXV78HNTA"
80,"1238SNQdivNuXhuW5P4SeUjkUgSD9eutVn","6PnYtYzHXLSy7Q241gJdf1jLb1ztyjcm62iNRnfbwLrywswyLPrydWd7fV"
81,"1Q2fAEMC73PBGdF8j2KdNFmJWj1CbA5mnu","6PnUZjcbaZkAkcRXoAjq5FRydLPK6fxgREHimwmyRDQw8fhEYnePUYsgc6"
82,"1MZSvZX8Ri9yPF3bAVyvKcgcLNNbmAyiZY","6PnUzBhmwSQn3v9wCbRLQChVaWPVEVpm1mESzAeRP29GNd7RonRgG3PMTe"
83,"193MUnSnjC3KwUiZYHQWN9zFk5Xr5DsN29","6PnZbGekkN2pTyXT9mKN5HcgyHE6VrMsuJ5DxP3PkuQBjpbFW8No4WH8Us"
84,"1DhG6DhAdZRxFYnmd5JfgFWmu25BfE6uiN","6PnYQzuAo9jExLVXqVdJkuLwsajRVxcpAodXmRXvWqFhkm4PufpR7oC4oz"
85,"1LQ6daC9hJ7Rg5S2fRjVLW4dHmEAKfVwvw","6PnNtubvJCzq1SCAtgo6bYCJ4mKqD5WWqvdEPS4vQzJACg9ELJT4SYEoa1"
86,"1MoUQMxqt9TavaEJjTHQtRFJXuaECxJ9Nf","6PnMsV92tgLw92nzSkNRzBJck4AekWJ7HPwP6JdzYCCpHtYkwmrFsJVWRy"
87,"1JbLrPKirNDAdAyuCAPFQxPQPBCmpfVpiJ","6PnTZwjkjeehYcF62VkuJduRLp3We2MPwJmyf98MwQErFVSBbs9KEfk56U"
88,"11C5nmRp4w9dPLsCC9eBBPfcWnEgUGgkd","6PnS5rZuCHr7K7PvE2Ge14QwoZewDYLhdcrBv8RwenpSapBWwdvMWuwu3H"
89,"1J86kNVvB45gusL2y6jqmtoSAGiSR8jDsC","6PnPHHkarwncch5uaURWJ8BbEzZaecxRYsP5LwYo74K6JrM8yF36UQaRsC"
90,"12XnGArqwMEagZBFtRvBJGuESdWBTMoBqL","6PnXZuXZGmEEXrmaGE8WyJXd6zuZx77NCcVwcuDb5NnaSncQBAFAukrsQY"
91,"1Mf16y6zh7VHFt5KcJQN5JJjdYkfYidqGF","6PnV91kCXn8RJHbgb4R4smLTdHv7ZPZJz2tLSYwDaYPRJjJPS3MM4Uo1JJ"
92,"14o8UMpWth3VGR9Kni1nPwV4xugJezqyBr","6PnSbcLGTDNfMNdKkN6wkLrDaDMS4nES1dBSDUiLiKzYXWwCSBvnqpjnuK"
93,"18kcAdWpoEHFGAdakjbky7QSfhQ5guGAEU","6PnWVjnVXSkKFBFfj1ChFnskBsfi6MP4A6NMM27TadvmiFC7o9X4GmenMm"
94,"1DX5m41SEQvDgj4UrHoqdrWEGKhJphRB32","6PnThDMvExNnkLMYoWiaLz7nVygomzf7kU7Za1nn5YHwQKVbr1f3VukLzM"
95,"1E6ao1brWRGXw3MU1t1Nj5Ed62f9mYV2ry","6PnUKxCiEAviU52iMBW9GhtFfxbc7roCxCUShrMhqxwZm43dF9CeVydc8z"
96,"12uTS5Z7W6UHc9Wyf6xDfMoNp3xLC4Zayi","6PnPSmAfKoVZEb6hBbesr4ioLHjhzezewiqAdBNbbwRwzSYyHtfFyM3z7F"
97,"1EKjC6AuWimfKdfGFCnLSVqYTyoibPsq89","6PnMWQj8uAyekUdybQLanAVcx5PmbfcAJKUzKgBRWXHQT7dKtSrZtANYbS"
98,"1uJp4gp9XBzPch1dT22RvosDwEz8qmUvs","6PnVvy3cz3Non5sSUzTF5mt2XJtsrZ4ngLUWgyiMVMQuYnVyrHGpaS9QJF"
99,"1DQ4nPJ6J26jykbPHcttFRTRh7REptNx7","6PnMhs26pTnRCJbUR6fSXjAHNYh243GURuL5LKTkKs9rBYtGH5dJBSgZLv"
100,"1J4gEvvcHV7V2UhsVtJ4e4rJ6BLT4gnkUm","6PnSsu3xZLSYYjxDoSV3ujDHreQidh2ZchcdWZPfwFF8pmXmxPMe9sFYZu"
The great benefit of printing individual private keys is that you can simply decrypt only one of them, while keeping the rest in cold storage. And you won't lose all of them if you can't read all pages.
Even better if you create all of the keys from a HD seed, and store that seed separately.
sr. member
Activity: 1190
Merit: 469
October 08, 2021, 05:14:52 AM
#70

What are the 1000 characters per wallet you're trying to store? There's probably a better solution, if you explain what exactly you're trying to do.
Can you start with an example: create a (throw away) Bitcoin wallet, and post everything you want to store here.

Actually what I'm trying to do is store 1000 bitcoin private keys+addresses. That takes about 90kb or so. I have the file and I want to use it as my "wallet". Instead of an HD wallet. I need to print it on paper in encrypted form and decrypt it whenever I need to access it. Which might not be that often. But still it should be rather fast. Like minutes not hours.

that's why i don't think using ocr is really feasible for this situation. but i do need to do some further teting to convince myself fully of that. I think qr codes might provide more of what I'm needing but I need to find a tool that splits up my file and creates a bunch of qrcodes out of it. because if I can't test it then I can't really know.
legendary
Activity: 3290
Merit: 16489
Thick-Skinned Gang Leader and Golden Feather 2021
October 08, 2021, 03:37:00 AM
#69
I'm thinking that a 25 page thing using ocr would not be very efficient in that regards but maybe a shorter thing like 2 or 3 pages max.
I think you should rethink this idea:
I need a way to store more information than just the seed words. For each wallet, I figure I might need upwards of 1000 characters. Possibly I'd like to store multiple wallets all at once. So looking at maybe 5000 to 10000 characters. 10 kb. I need to be able to print out an encrypted image on a piece of paper. That would be my cold storage. When I'm ready to redeem, I will scan the image back in and decrypt its contents. And recover the original text file containing all my important seed phrases.
What are the 1000 characters per wallet you're trying to store? There's probably a better solution, if you explain what exactly you're trying to do.
Can you start with an example: create a (throw away) Bitcoin wallet, and post everything you want to store here.
sr. member
Activity: 1190
Merit: 469
October 07, 2021, 10:42:00 PM
#68
I tested this large QR-code with my old QR code reader (it seems to have disappeared from the Play Store), and it worked fine.

I'm just totally confused. None of the qr code readers I tried so far work at all with that qr code. I know I tried at least 3 different ones off of google play store. They don't work with other large qr codes I made either! I'm going to try and figure out what the cutoff is because for small size qr codes they scan it fast. Something is seriously wrong. Either with my phone or with my computer disply or with these apps. Huh

Regarding my OCR scanning experiement while at first seeming promising, page 1 only had a small handful of corrections but page 2 was way more. Like 40 or 50 at least. Maybe even more. I don't really consider that acceptable. It takes way too much time to go in and try and fix everything. So I'm thinking that a 25 page thing using ocr would not be very efficient in that regards but maybe a shorter thing like 2 or 3 pages max.

So I'm thinking using qr codes instead for the 25 page document maybe. the problem is there is no software that does that. where it breaks up something into a bunch of qr codes that get spit out onto a page/pages. and there is NO WAY i am going to try and do something like that manually.
legendary
Activity: 3290
Merit: 16489
Thick-Skinned Gang Leader and Golden Feather 2021
October 07, 2021, 04:52:53 AM
#67
This QR code idea intrigues me and yet somehow I'm worried that if I tried to make some huge qr codes to backup my 100kb file (or 90ish), I might run into problems actually being able to scan it back in. You know, my android phone can't handle those because I tested it.
I tested this large QR-code with my old QR code reader (it seems to have disappeared from the Play Store), and it worked fine.
sr. member
Activity: 1190
Merit: 469
October 07, 2021, 01:34:04 AM
#66

You don't have to add 15 pages of checksums: you can also do one checksum per page. It depends on how accurate your OCR or typing skills are.

I think the OCR engine is pretty accurate. It seems to have only had a small amount of errors maybe about 4 or 5 on that single page of 3000 plus characters. I think that's acceptable but I really haven't put it to the ultimate test yet which is actually making a printout and scanning it back in. I just used a digital file with the OCR so far. I expect the results to be worse.

And maybe that one page was just a lucky one. I'll need to do alot more testing to see what the average case is. I hate typing so I need the error rate to be very low.

Quote
Error correction would be better, and that easily puts you back at QR-codes again (where you can choose the level of error correction).
Did I mention how much I hate having to do manual error correction? This QR code idea intrigues me and yet somehow I'm worried that if I tried to make some huge qr codes to backup my 100kb file (or 90ish), I might run into problems actually being able to scan it back in. You know, my android phone can't handle those because I tested it. It just wont read big ones. At all. not off my computer screen but ...


sr. member
Activity: 1190
Merit: 469
October 06, 2021, 11:57:17 PM
#65
You don't have to add 15 pages of checksums: you can also do one checksum per page. It depends on how accurate your OCR or typing skills are.

Here's the thing though. i scanned in a single page of base64 and the original had 3522 characters but the scanned file has more it has 3525. so i can't just go line by line because the lines don't correspond necessarily to the same character positions. so i can't just go by checksums alone. i have extra characters. if the character counts were the same and some characters just got read wrong to a different character then the line by line checksum method might work. but that's not the case.

legendary
Activity: 3290
Merit: 16489
Thick-Skinned Gang Leader and Golden Feather 2021
October 06, 2021, 09:47:01 AM
#64
Although you seem to forget that my file is almost 90 kilobytes. Checksums is an additional overhead and software complexity that most people probably don't have the technical ability for. But I'm intrigued.
The beauty of using an "external" checksum is that you don't have to use it: you can still type all 90,000 characters manually, but if you make a mistake, using the checksum will make it easier to find where you went wrong.

Quote
I wish I could test out this method
That's easy: print 1000 bytes, type them all, and see if they're the same.

Quote
yeah I know about md5sum but do you think that's the best type of checksum to be using? It doesn't attempt to fix any errors and it's pretty huge.  Shocked I mean my 25 page file I could legit see it balooning to 40 pages after this fiasco!
You don't have to add 15 pages of checksums: you can also do one checksum per page. It depends on how accurate your OCR or typing skills are.
Error correction would be better, and that easily puts you back at QR-codes again (where you can choose the level of error correction).

I still think printing 90,000 bytes as a backup is a terrible idea though Tongue
sr. member
Activity: 1190
Merit: 469
October 06, 2021, 08:46:22 AM
#63

If you're talking about several kB, that's going to be very annoying to do. At least add partial checksums per line or multiple lines.

Yeah maybe! Although you seem to forget that my file is almost 90 kilobytes. Checksums is an additional overhead and software complexity that most people probably don't have the technical ability for. But I'm intrigued.

Quote
This makes it much faster to check where you have a reading error.

I wish I could test out this method but I'm skeptical that it's going to be worth the additional hassle and storage space being consumed. but I could be wrong. especially with a 90,000 character string that needs to be scanned in correctly!

Quote
A simple md5sum (https://en.wikipedia.org/wiki/Md5sum) per line would be:
Code:

43dbfbbc3fe9eecccc313b5ed4707bec  -
7d2f3295028a1dfb41df0c9e696d9d9b  -
b75dbc5c69502db35d76028643314996  -
24d8f8420aaf27e25d93787cd434a7b9  -
5833cf59445a9657c2da7088ae7a4119  -
5952f16a3f33d8c87e5846605cc95cac  -
6989ed58a32c2622dda4418eab730c65  -
844a3c31527f88588c3dd7f22ccdf883  -
c5dca4c2ee7ac2d7c0c1874d267a8b7a  -
32b5dc97587bd5e7e34f58f55f90353d  -


yeah I know about md5sum but do you think that's the best type of checksum to be using? It doesn't attempt to fix any errors and it's pretty huge.  Shocked I mean my 25 page file I could legit see it balooning to 40 pages after this fiasco!

legendary
Activity: 3290
Merit: 16489
Thick-Skinned Gang Leader and Golden Feather 2021
October 06, 2021, 04:05:17 AM
#62
In short, if you preserve your data well, you might end up having to hand-type it in (or at least go through it with your own eyeball character by character to fix scanning errors) to restore the unencrypted version. Assuming you can do that and don't mind doing that then this method could possibly work.
If you're talking about several kB, that's going to be very annoying to do. At least add partial checksums per line or multiple lines.
Say this is your data (from random.org:
Code:
oKp30Otodg07mSc83Nxw
3EdM4CFypmOfSupspfcd
OO9LL0I4QEc4dx5HhdlQ
lXSDsvm17tzQNhlEwYH0
mJPcDPPE2pQaD4Q9oaBu
pFhODlJNXz8V8vAunpzn
xeRTGwg4c5jYCzLqDNJL
4eIzVtQGEUtBJzCyhGtx
q4Vw92cwd0PqsLj9sGff
Ip6y9986cNfkEg36OYs4
A simple md5sum per line would be:
Code:
43dbfbbc3fe9eecccc313b5ed4707bec  -
7d2f3295028a1dfb41df0c9e696d9d9b  -
b75dbc5c69502db35d76028643314996  -
24d8f8420aaf27e25d93787cd434a7b9  -
5833cf59445a9657c2da7088ae7a4119  -
5952f16a3f33d8c87e5846605cc95cac  -
6989ed58a32c2622dda4418eab730c65  -
844a3c31527f88588c3dd7f22ccdf883  -
c5dca4c2ee7ac2d7c0c1874d267a8b7a  -
32b5dc97587bd5e7e34f58f55f90353d  -
This makes it much faster to check where you have a reading error.

There might be but it seems like everything is gone online now. They want to let you do everything "online" through their website. I guess they hoping someone puts in their private key. Grin
There are also offline QR-code generators that replace a Bitcoin address by something else. And I wouldn't be surprised if some QR-readers do the same.
sr. member
Activity: 1190
Merit: 469
October 05, 2021, 09:18:07 PM
#61

You can encrypt the wallet with AES256, encode the wallet in BASE64 using some easy-to-parse computer font such as Courier New or System (they must be monospaced so they can be perfectly read again using OCR), and then print out the characters onto a large number of sheets of paper. Then you save the AES key and IV as qrcodes. Store all materials in a confidential place such as inside a safe.

When you want to access the file again, read the papers in with a scanner, strip all whitespace and then decode the AES256 with the key and IV you have independently scanned. Requires a lot of paper, but it works.

At first glance the above method seems to sound doable and promising however, iit does have some issues. one of the main ones is that there is no way that any piece of ocr software can "perfectly read" the characters off of a printed page.

In short, if you preserve your data well, you might end up having to hand-type it in (or at least go through it with your own eyeball character by character to fix scanning errors) to restore the unencrypted version. Assuming you can do that and don't mind doing that then this method could possibly work.

sr. member
Activity: 1190
Merit: 469
October 05, 2021, 06:46:12 AM
#60


Looking at qrencode website (https://fukuchi.org/works/qrencode/), there are windows port such as http://code.google.com/p/qrencode-win32/, but it's a bit outdated. Besides, there are lots of QR code software/library on Windows, surely there are few which support more than 1K character.

There might be but it seems like everything is gone online now. They want to let you do everything "online" through their website. I guess they hoping someone puts in their private key. Grin there's got to be a way to filter out those kind of search results.........
legendary
Activity: 3290
Merit: 16489
Thick-Skinned Gang Leader and Golden Feather 2021
October 05, 2021, 03:06:14 AM
#59
I'm still struggling to understand why you need something other than the currently available plain text encryption options. This really does seem like reinventing the wheel to me...
One reason is I'm not familiar with other encryption that I can print, but another reason is that anything non-standard makes recovery more difficult years later. I (or someone else) may not remember exactly what was used.

That's pretty amazing, the problem there is that software you mentioned is for linux. I would need a windows tool that could do the same type of thing.
Sorry, I can't help you there. You could search for the source code, but setting up a Linux system is probably easier.
sr. member
Activity: 1190
Merit: 469
October 05, 2021, 02:22:09 AM
#58

I'd love to see something similar for encrypting a 12/24 word seed. Even better if the result is just represented as a seed again: to restore, enter the encrypted seed, the password and wait a few seconds (yes, seconds!) to decrypt it. I'd feel much safer than just storing the unencrypted seed words in plain text.

I think a person can implement exactly that process in a very trivial way. For example, say you are using the bip39 english wordlist. Say your mnemonic is 24 words long. Then you need to generate 24 random integers between 1 and 2048. Those 24 integers are your passphrase. They will serve as "offsets" when they get added to the indexes of the words in your unencrypted seedphrase. The addition is modulo 2048. Done. Now you have two things to keep track of instead of one but I guess that's the price you pay for having an encrypted seedphrase. As long as someone doesn't get ahold of both of those things, they can't do anything.

Come to think of it, the passphrase could just be any random set of 24 word seed phrase taken out of the wordlist because if you think about it, their indexes in the wordlist is those 24 integers I mentioned above.

So you have to store an encrypting seed phrase and also the encrypted seed phrase, both 24 words in length. To decrypt, you just subtract the encrypting seed phrase from the encrypted seed phrase  and voila. Is that too much trouble??

I am sure there is ways to make it more userfriendly. I mean electrum could generate the encrypting and encrypted seed phrases along with the normal seed so you would be good to go off the bat! That would be amazing.
legendary
Activity: 3472
Merit: 10611
October 04, 2021, 11:14:10 PM
#57
why not just use the original seed and a strong BIP39 passphrase? Surely this ends up effectively resulting in the same thing... a mnemonic string + passphrase?
Looks are deceiving. The extra word used in BIP39 is called "passphrase" but it is not encrypting anything. It also is not providing nearly enough security as when you actually encrypt something.
Take BIP38 for example focusing on the key derivation only, you can't even begin comparing the security that scrypt provides in BIP38 with what PBKDF2 provides in BIP39! For quick comparison the recommended iteration count used in PBKDF2 for security sensitive usages is 10 million; BIP39 uses 2048! Meanwhile costparam of 16384 used in scrypt is already more than enough, not to mention there is AES256 on top of that.
sr. member
Activity: 1190
Merit: 469
October 04, 2021, 10:27:25 PM
#56
.... However you wish. I would never trust 27 pieces of paper of plain text without checksum or error correction. The probability that a corner catches some humidity and rots away or similar, is too high. There are even insects and stuff that destroy paper.

So what you're saying is AES then Base64 encode and then do some error correction processing on it? That would make the file even longer but I'm willing to consider it. But I haven't heard of people doing a triple process thing like that before. So I'm not even sure its possible.

Also, the issue I'm experiencing with Notepad++ seems to be a longstanding one: https://community.notepad-plus-plus.org/topic/18197/issue-printing-long-lines/12
They should have had time to fix that bug by now but I guess they don't care.

sr. member
Activity: 1190
Merit: 469
October 04, 2021, 10:21:47 PM
#55

This site puts the maximum at 4296 alphanumeric characters.

As a test, I took your post with 2439 characters and created this with qrencode:


That's pretty amazing, the problem there is that software you mentioned is for linux. I would need a windows tool that could do the same type of thing. The qrcode software I have was able to read your huge qrcode and decode it into text but when I tried to encode the same text into a qrcode, it wouldn't work since it only allows up to 1024 characters apparently.
hero member
Activity: 882
Merit: 5834
not your keys, not your coins!
October 04, 2021, 07:45:08 PM
#54
the big problem with qrcodes is they're only good for 1024 characters or so. at least the software I tried only let me make a text string that long but not longer. that's not good enough. I need way more than that.
This site puts the maximum at 4296 alphanumeric characters.

~
Further, you can print multiple pages if you need more data (split it up and save each chunk as a QR code) and even adjust for less pages (but more error-prone due to smaller squares) or better readability in the future, but using more pages. However you wish. I would never trust 27 pieces of paper of plain text without checksum or error correction. The probability that a corner catches some humidity and rots away or similar, is too high. There are even insects and stuff that destroy paper.
HCP
legendary
Activity: 2086
Merit: 4361
October 04, 2021, 07:05:18 PM
#53
I'd love to see something similar for encrypting a 12/24 word seed. Even better if the result is just represented as a seed again: to restore, enter the encrypted seed, the password and wait a few seconds (yes, seconds!) to decrypt it. I'd feel much safer than just storing the unencrypted seed words in plain text.
I'm still struggling to understand why you need something other than the currently available plain text encryption options. This really does seem like reinventing the wheel to me...

Is it because you want wallets to provide built in methods to encode/decode the mnemonic string? Huh Noting that if you end up with "random" text, it sort of defeats one of the core purposes of the mnemonic in the first place... ie. reduction of transcription errors.

Turning the result into another mnemonic string sounds like it should be possible... but then, why not just use the original seed and a strong BIP39 passphrase? Surely this ends up effectively resulting in the same thing... a mnemonic string + passphrase? Huh

It seems like creating a .zip file with a password and then putting that into a .rar archive with another password... or am I missing something?
legendary
Activity: 3290
Merit: 16489
Thick-Skinned Gang Leader and Golden Feather 2021
October 04, 2021, 10:42:17 AM
#52
Why would you need to waste time and effort creating a method to encrypt a seed when you already have plenty of perfectly adequate (and proven) encryption systems for encrypting "plain text"? Huh
I like BIP38 because it's so difficult to brute-force and the result can be printed. I like how it can even be used on mobile wallets.
I'd love to see something similar for encrypting a 12/24 word seed. Even better if the result is just represented as a seed again: to restore, enter the encrypted seed, the password and wait a few seconds (yes, seconds!) to decrypt it. I'd feel much safer than just storing the unencrypted seed words in plain text.

I need a way to store more information than just the seed words. For each wallet, I figure I might need upwards of 1000 characters. Possibly I'd like to store multiple wallets all at once. So looking at maybe 5000 to 10000 characters. 10 kb. I need to be able to print out an encrypted image on a piece of paper. That would be my cold storage.
Why don't you at least print each wallet separately? Adding them all together into one large encrypted and printed text (or image) creates one large point of failure: any unreadable part means you lose access to everything. If you print each wallet separately, you reduce the risk caused by a possible error.

Quote
When I'm ready to redeem, I will scan the image back in and decrypt its contents. And recover the original text file containing all my important seed phrases. I think this would be more secure than putting it on a flash drive since paper can last longer. Hundreds of years. then only problem is that you can't really use qrcodes for that. they would literally be huge.
Let's take a step back: why not use one mnemonic that can create thousands of private keys for hundreds of different coins, and save that instead?
sr. member
Activity: 1190
Merit: 469
October 04, 2021, 09:53:46 AM
#51

You can encrypt the wallet with AES256, encode the wallet in BASE64 using some easy-to-parse computer font such as Courier New or System (they must be monospaced so they can be perfectly read again using OCR), and then print out the characters onto a large number of sheets of paper. Then you save the AES key and IV as qrcodes. Store all materials in a confidential place such as inside a safe.

I tried this but my Base 64 encoded file has almost 90,000 characters in it and the software (NOTEPAD++) I was using to do this test couldn't handle that. When I printed it to a pdf file, it only printed the first 4 pages.  The OCR tool seemed to scan in those 4 pages ok but I have no idea if it really did since I can't really know until I decode the entire thing but to do that, I need the entire pdf file scanned. Not just the first 4 pages.

Quote
When you want to access the file again, read the papers in with a scanner, strip all whitespace and then decode the AES256 with the key and IV you have independently scanned. Requires a lot of paper, but it works.

If I can get to that point. But I have a feeling it's going to require 27 pages of printouts. Unless there was a way to shrink the printing size significantly.

legendary
Activity: 3290
Merit: 16489
Thick-Skinned Gang Leader and Golden Feather 2021
October 04, 2021, 08:21:20 AM
#50
the big problem with qrcodes is they're only good for 1024 characters or so. at least the software I tried only let me make a text string that long but not longer. that's not good enough. I need way more than that.
This site puts the maximum at 4296 alphanumeric characters.

As a test, I took your post with 2439 characters and created this with qrencode:
Image loading...
sr. member
Activity: 1190
Merit: 469
October 03, 2021, 10:56:03 PM
#49

In general, the idea of using QR codes is very good. Compared to plain text, they have pretty good error correction, so if the paper is partly damaged it will be still possible to decode them. They're also made specifically for scanning and reading into a computer via camera input, so you won't need to rely on the quality of an OCR software, even if those get better and better. Decoding QR via camera will be much more resilient and reliable.

I definitely agree with that, the big problem with qrcodes is they're only good for 1024 characters or so. at least the software I tried only let me make a text string that long but not longer. that's not good enough. I need way more than that.
hero member
Activity: 882
Merit: 5834
not your keys, not your coins!
October 03, 2021, 07:57:43 AM
#48
I need a way to store more information than just the seed words. For each wallet, I figure I might need upwards of 1000 characters. Possibly I'd like to store multiple wallets all at once. So looking at maybe 5000 to 10000 characters. 10 kb. I need to be able to print out an encrypted image on a piece of paper. That would be my cold storage. When I'm ready to redeem, I will scan the image back in and decrypt its contents. And recover the original text file containing all my important seed phrases. I think this would be more secure than putting it on a flash drive since paper can last longer. Hundreds of years. then only problem is that you can't really use qrcodes for that. they would literally be huge.

You can encrypt the wallet with AES256, encode the wallet in BASE64 using some easy-to-parse computer font such as Courier New or System (they must be monospaced so they can be perfectly read again using OCR), and then print out the characters onto a large number of sheets of paper. Then you save the AES key and IV as qrcodes. Store all materials in a confidential place such as inside a safe.
In general, the idea of using QR codes is very good. Compared to plain text, they have pretty good error correction, so if the paper is partly damaged it will be still possible to decode them. They're also made specifically for scanning and reading into a computer via camera input, so you won't need to rely on the quality of an OCR software, even if those get better and better. Decoding QR via camera will be much more resilient and reliable.
sr. member
Activity: 1190
Merit: 469
October 02, 2021, 09:54:19 PM
#47


You can encrypt the wallet with AES256, encode the wallet in BASE64 using some easy-to-parse computer font such as Courier New or System (they must be monospaced so they can be perfectly read again using OCR), and then print out the characters onto a large number of sheets of paper. Then you save the AES key and IV as qrcodes. Store all materials in a confidential place such as inside a safe.


That is a reasonable solution albeit a kind of expensive one in terms of materials/resources used (ink and paper and physical storage space). I think encoding into the base 64 is going to increase the filesize and increase the number of papers it takes to print the thing out. but you did say "large number of sheets of paper" and you're right about that. it's not going to give any shortcut in that area.  the other issue is there's no fault tolerance built into it. Yes presumably you would test to make sure that it scanned and decrypted fine before you put it into a confidential place (who wouldn't??) but maybe some of the characters were marginal and got corrupted over time and you would have no idea which one or ones and what they were supposed to be and you would be in big trouble.

So while your proposal seems reasonable, in some ways it is not the ideal thing. Thanks for mentioning it though.
legendary
Activity: 3472
Merit: 10611
October 01, 2021, 10:14:33 PM
#46
I don't see the point in storing a lot of private keys simply because deterministic key derivation exists. You only store the seed for that KDF and then you can always derive the same exact 1000 private keys in a second whenever you want.
I can think of a reason: convenience! It's very easy to take 1 private key from cold storage, and use it to spend funds. You might even be willing to enter it into a hot wallet.
But if you have one seed that gives access to all your private keys, you'll need a cold storage setup just to spend funds from one key.
I could see that be useful with a handful of private keys but 1000 still doesn't make sense to me. If that many keys are being used buying a hardware wallet or setting up a cold storage (DIY) makes a lot more sense than having a "book" of private keys to spend from.
legendary
Activity: 3290
Merit: 16489
Thick-Skinned Gang Leader and Golden Feather 2021
October 01, 2021, 03:46:14 AM
#45
I don't see the point in storing a lot of private keys simply because deterministic key derivation exists. You only store the seed for that KDF and then you can always derive the same exact 1000 private keys in a second whenever you want.
I can think of a reason: convenience! It's very easy to take 1 private key from cold storage, and use it to spend funds. You might even be willing to enter it into a hot wallet.
But if you have one seed that gives access to all your private keys, you'll need a cold storage setup just to spend funds from one key.
legendary
Activity: 3472
Merit: 10611
September 30, 2021, 11:44:34 PM
#44
I need a way to store more information than just the seed words. For each wallet, I figure I might need upwards of 1000 characters. Possibly I'd like to store multiple wallets all at once.

Or i might just have a need to encrypt a text file containing 1000 private keys. That might require 2 pages.
I don't see the point in storing a lot of private keys simply because deterministic key derivation exists. You only store the seed for that KDF and then you can always derive the same exact 1000 private keys in a second whenever you want.
Even if you want multiple different wallets there are still many ways to achieve this. For example BIP32 KDF uses a derivation path that looks like m/x/y/z/... and you can change those values to get a different set of keys. Or BIP39 can add a "passphrase" to derive a different seed from the mnemonic, so same words with a different extra word (ie. the passphrase) can create different wallets.
If you don't like these algorithms you can always use any KDF you like. For example use scrypt with costParam=32,768 and a fixed salt to derive keys from an initial 128 to 256 bit random entropy.
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
September 30, 2021, 09:26:33 AM
#43
I need a way to store more information than just the seed words. For each wallet, I figure I might need upwards of 1000 characters. Possibly I'd like to store multiple wallets all at once. So looking at maybe 5000 to 10000 characters. 10 kb. I need to be able to print out an encrypted image on a piece of paper. That would be my cold storage. When I'm ready to redeem, I will scan the image back in and decrypt its contents. And recover the original text file containing all my important seed phrases. I think this would be more secure than putting it on a flash drive since paper can last longer. Hundreds of years. then only problem is that you can't really use qrcodes for that. they would literally be huge.

You can encrypt the wallet with AES256, encode the wallet in BASE64 using some easy-to-parse computer font such as Courier New or System (they must be monospaced so they can be perfectly read again using OCR), and then print out the characters onto a large number of sheets of paper. Then you save the AES key and IV as qrcodes. Store all materials in a confidential place such as inside a safe.

When you want to access the file again, read the papers in with a scanner, strip all whitespace and then decode the AES256 with the key and IV you have independently scanned. Requires a lot of paper, but it works.

Or lobby the Electrum folks with a feature proposal to export wallet data to JSON so you have less data to print and scan.
legendary
Activity: 3500
Merit: 6320
Crypto Swap Exchange
September 30, 2021, 06:38:18 AM
#42

1-3. You still need to know the word list but it could be changed in a way that doesn't depend on a fixed length word list like the algorithm Electrum uses
4-6. This can also be implemented but it would increase the number of words and the result will no longer resemble a normal BIP39 mnemonic.

My idea was an attempt to end up with a result that doesn't look any different from regular seed words.

I need a way to store more information than just the seed words. For each wallet, I figure I might need upwards of 1000 characters. Possibly I'd like to store multiple wallets all at once. So looking at maybe 5000 to 10000 characters. 10 kb. I need to be able to print out an encrypted image on a piece of paper. That would be my cold storage. When I'm ready to redeem, I will scan the image back in and decrypt its contents. And recover the original text file containing all my important seed phrases. I think this would be more secure than putting it on a flash drive since paper can last longer. Hundreds of years. then only problem is that you can't really use qrcodes for that. they would literally be huge.

Or i might just have a need to encrypt a text file containing 1000 private keys. That might require 2 pages.

You would not be able to use regular steganography to do that. You can't rely on most printers and scanners to be able to detect it. You would have to store the images on usb or other digital media.

Here is a basic steganography app:

https://github.com/computationalcore/cryptosteganography

Give it a try and see what you can squeeze into an image that you can scan later.

-Dave
sr. member
Activity: 1190
Merit: 469
September 30, 2021, 06:26:19 AM
#41

1-3. You still need to know the word list but it could be changed in a way that doesn't depend on a fixed length word list like the algorithm Electrum uses
4-6. This can also be implemented but it would increase the number of words and the result will no longer resemble a normal BIP39 mnemonic.

My idea was an attempt to end up with a result that doesn't look any different from regular seed words.

I need a way to store more information than just the seed words. For each wallet, I figure I might need upwards of 1000 characters. Possibly I'd like to store multiple wallets all at once. So looking at maybe 5000 to 10000 characters. 10 kb. I need to be able to print out an encrypted image on a piece of paper. That would be my cold storage. When I'm ready to redeem, I will scan the image back in and decrypt its contents. And recover the original text file containing all my important seed phrases. I think this would be more secure than putting it on a flash drive since paper can last longer. Hundreds of years. then only problem is that you can't really use qrcodes for that. they would literally be huge.

Or i might just have a need to encrypt a text file containing 1000 private keys. That might require 2 pages.



legendary
Activity: 3472
Merit: 10611
September 27, 2021, 12:47:58 AM
#40
It requires a fixed wordlist.
Any encoding method requires a fixed (usually hard-coded) set of "digits" and if you don't know those you won't be able to decode it. For example if you don't know base16 uses 0-9, a-f you con't decode it. For base2048 you need the digits which in case of a BIP39 mnemonic or what I explained above is the word list that would be required to decode both the mnemonic and the encrypted mnemonic alike.

Quote
i'd much prefer a solution that
1)didn't require a fixed wordlist
2)allowed for variable length mnemonics
3) but still operated by changing words in to other words
4) encodes the derivation path being used so that someone can find their money
5) encodes the particular cryptocurrency that the derivation path above refers to
6) possibly allows for encoding multiple 4/5 pairs of data so that different coins can be referenced
1-3. You still need to know the word list but it could be changed in a way that doesn't depend on a fixed length word list like the algorithm Electrum uses
4-6. This can also be implemented but it would increase the number of words and the result will no longer resemble a normal BIP39 mnemonic.

My idea was an attempt to end up with a result that doesn't look any different from regular seed words.
sr. member
Activity: 1190
Merit: 469
September 27, 2021, 12:17:06 AM
#39

You have a mnemonic that is n-bits (eg. 128-bits for 12 words) take those bits and encrypt them with AES256 with a key derived from a strong passphrase and a salt derived from the address (like BIP38).
Now you get 128-bits of encrypted data (encryption without IV) which you can encode to 12 words using the same BIP39 scheme. All you have to do is write down these words as if they were your mnemonic.

To import to a wallet you just decrypt these words and convert to an un-encrypted BIP39. That is decode 12 words to get the byte[], derive the AES key from the passphrase and address like above, decrypt using AES256. Now you have un-encrypted 128-bit entropy. Encode this using BIP39 scheme and you have the original words.

that's a pretty neat idea the only potential problem I see with it is, it's not very "portable". It requires a fixed wordlist. what if there is no wordlist at all? or what if the wordlist is different than the bip39 one. that means we have to store a complete copy of whatever wordlist it is we want to use and somehow the software has to be smart enough to know what wordlist we want it to use?

i'd much prefer a solution that
1)didn't require a fixed wordlist
2)allowed for variable length mnemonics
3) but still operated by changing words in to other words
4) encodes the derivation path being used so that someone can find their money
5) encodes the particular cryptocurrency that the derivation path above refers to
6) possibly allows for encoding multiple 4/5 pairs of data so that different coins can be referenced
legendary
Activity: 3472
Merit: 10611
September 26, 2021, 04:11:08 AM
#38
any number can be encoded as a hexadecimal string. which you can think of as a text string composed of the characters 0-9,A-F. there is a 1-1 relationship between the hexadecimal text string and bitcoin private key that it represents. Or just think of 256-bit text string consisting of 0s and 1s. That's a string too. or it can be thought of as such without causing any confusion or problem.
That's true but when you enter a private key WIF (the string) it still has to be converted to bits and treated as an integer but when you enter a mnemonic (the string) is treated as a string and even decoded using UTF8 when deriving BIP32 seed from it.

You have a mnemonic that is n-bits (eg. 128-bits for 12 words) take those bits and encrypt them with AES256 with a key derived from a strong passphrase and a salt derived from the address (like BIP38).
Now you get 128-bits of encrypted data (encryption without IV) which you can encode to 12 words using the same BIP39 scheme. All you have to do is write down these words as if they were your mnemonic.

To import to a wallet you just decrypt these words and convert to an un-encrypted BIP39. That is decode 12 words to get the byte[], derive the AES key from the passphrase and address like above, decrypt using AES256. Now you have un-encrypted 128-bit entropy. Encode this using BIP39 scheme and you have the original words.
sr. member
Activity: 1190
Merit: 469
September 26, 2021, 12:47:06 AM
#37

A bitcoin private key is not plain text, it is technically a number and can easily be treated as a stream of bytes with fixed length (32 bytes). A mnemonic on the other hand is technically plain text even though it can be converted to a stream of bytes but it will have variable size.

any number can be encoded as a hexadecimal string. which you can think of as a text string composed of the characters 0-9,A-F. there is a 1-1 relationship between the hexadecimal text string and bitcoin private key that it represents. Or just think of 256-bit text string consisting of 0s and 1s. That's a string too. or it can be thought of as such without causing any confusion or problem.

Quote
With that said I'm all for a "standard" way of encrypting a mnemonic, I've already posted about what I think such a method could look like a couple of times on this forum.

Very good! Maybe I can locate them somehow. But you post so often that it might be kind of hard to dig them all up but it would be worth it I'm sure. Cheesy
legendary
Activity: 3472
Merit: 10611
September 24, 2021, 11:24:46 PM
#36
Why would you need to waste time and effort creating a method to encrypt a bitcoin private key when you already have plenty of perfectly adequate (and proven) encryption systems for encrypting "plain text"?
A bitcoin private key is not plain text, it is technically a number and can easily be treated as a stream of bytes with fixed length (32 bytes). A mnemonic on the other hand is technically plain text even though it can be converted to a stream of bytes but it will have variable size.

With that said I'm all for a "standard" way of encrypting a mnemonic, I've already posted about what I think such a method could look like a couple of times on this forum.
sr. member
Activity: 1190
Merit: 469
September 24, 2021, 08:48:28 PM
#35
Why would you need to waste time and effort creating a method to encrypt a seed when you already have plenty of perfectly adequate (and proven) encryption systems for encrypting "plain text"? Huh

You know that's a really silly question. Let me rephrase it slightly and maybe you can help answer it:

Why would you need to waste time and effort creating a method to encrypt a bitcoin private key when you already have plenty of perfectly adequate (and proven) encryption systems for encrypting "plain text"? Huh

HCP
legendary
Activity: 2086
Merit: 4361
September 24, 2021, 07:32:04 AM
#34
Why would you need to waste time and effort creating a method to encrypt a seed when you already have plenty of perfectly adequate (and proven) encryption systems for encrypting "plain text"? Huh

As for supporting Electrum... Electrum already has perfectly functional wallet file encryption. ¯\_(ツ)_/¯

I'm not sure what it is that you're attempting to achieve here? Huh
sr. member
Activity: 1190
Merit: 469
September 23, 2021, 12:47:46 AM
#33
So BIP38 would have to be changed to not encrypt and encode a private key, but instead to encrypt and encode a seed phrase instead.

At this point the scope changes completely and will require a new BIP in my opinion.

yeah that may be true but it's still a doable thing. Not sure why it hasn't been done. other than just no one caring. one thing they wuld need to make sure though is to support electrum  Grin now that i think about it though. there's no "address" that corresponds to an hd wallet so instead of the address what would you print out? the first 10 addresses?
hero member
Activity: 882
Merit: 5834
not your keys, not your coins!
September 21, 2021, 08:24:57 PM
#32
Quote
The thing is that wallets are always HD so there is little use for a single key encryption technique for them. However the method itself is still useful and will remain useful for paper wallet creation.

bip38 could be extended to allow for hd wallets i am sure. why they dont' do that is hard to understand. how long wold it take them to come up with that maybe 2 or 3 days tops, with lunch breaks?

The point about hardware wallets is that they don't just have 1 private key. They generate a seed phrase from which an infinite amount of private keys can be derived. So BIP38 would have to be changed to not encrypt and encode a private key, but instead to encrypt and encode a seed phrase instead.

At this point the scope changes completely and will require a new BIP in my opinion.
sr. member
Activity: 1190
Merit: 469
September 13, 2021, 04:15:05 AM
#31


Quote
The thing is that wallets are always HD so there is little use for a single key encryption technique for them. However the method itself is still useful and will remain useful for paper wallet creation.

bip38 could be extended to allow for hd wallets i am sure. why they dont' do that is hard to understand. how long wold it take them to come up with that maybe 2 or 3 days tops, with lunch breaks?
sr. member
Activity: 1190
Merit: 469
September 13, 2021, 03:27:56 AM
#30

Quote
Thanks for the correction, there are so many BIPs that i sometimes forget the correct number. Even so, BIP 38 is still most common option to encrypt private key, even bitaddress support it. I'm also not aware of other encryption standard solely for cryptocurrency private key.

Well I mean yeah, bitaddress does have a certain level of support for bip38 but in my limited testing, I found it failing for a certain test vector. But that's ok, the code that I have works for that test vector just fine. So I guess I'll stick to that.
legendary
Activity: 3472
Merit: 10611
September 05, 2021, 09:48:49 PM
#29
Here's a hint, if they ask you to backup 12/24 words and mention it can be recovered on most wallet, most likely it use BIP 38.
I think you may be confusing BIP-38 (Passphrase-protected private key) with BIP-39 (Mnemonic code for generating deterministic keys). The former is supported by only a handful of wallets and tools while the later is supported by almost everything. OP was talking about the former.
legendary
Activity: 2870
Merit: 7490
Crypto Swap Exchange
September 05, 2021, 04:51:43 AM
#28
Well here's the thing. BIP38 is going away. Eventually there won't be any wallets or any software that supports it.

It's literally available on many wallet, including hardware and multi-cryptocurrency wallet. Here's a hint, if they ask you to backup 12/24 words and mention it can be recovered on most wallet, most likely it use BIP 38. There are few competitor such as Electrum Seed Version System, but still can't beat BIP 38 even though it has versioning system and better security.

Lucky for me though I was able to implement it in python 3.7 so I can use bip38 as long as I want to unless python decides to bullshit its users again like they did with the 2 to 3 upgrade.
Off-topic but... Python didn't bullshit its users. There was a long transition period where both were supported, Python 3 brings many needed features to the table like typing and is generally the better programming language.

Maybe he's complaining about most linux distro had to drop lots of software which still depend on Python 2 or few software got discontinued since the author have no intention to convert it to Python 3.
hero member
Activity: 882
Merit: 5834
not your keys, not your coins!
September 04, 2021, 08:21:33 AM
#27
Lucky for me though I was able to implement it in python 3.7 so I can use bip38 as long as I want to unless python decides to bullshit its users again like they did with the 2 to 3 upgrade.
Off-topic but... Python didn't bullshit its users. There was a long transition period where both were supported, Python 3 brings many needed features to the table like typing and is generally the better programming language.
legendary
Activity: 3472
Merit: 10611
September 04, 2021, 07:55:24 AM
#26
BIP38 is going away.
No, it is not.

Quote
Eventually there won't be any wallets or any software that supports it. It never really caught on.
The thing is that wallets are always HD so there is little use for a single key encryption technique for them. However the method itself is still useful and will remain useful for paper wallet creation.

Quote
~ since all we have is a generic "protocol specification".
Which is more than enough for a developer to implement it.

Quote
The fact that you can't even find a python 3.7 implementation of it speaks volumes.
You are just not searching well enough:
A python bitcoin library:
https://github.com/1200wd/bitcoinlib/blob/c52cdfc9fe7feaedcf4dc3e43ceca4071865281b/bitcoinlib/encoding.py#L772-L845

A shitcoin wallet's library:
https://github.com/joshmcintyre/blockchainmower/blob/7457c361b5b2792e7cd3c4882713d6b71efddcda/src/electron_cash_lib/bitcoin.py#L1023

From a paper wallet builder:
https://github.com/ryanralph/DIY-Piper/blob/0df360f61707739dd7ba5b7758f79b7c8e136867/bitcoin/bip38.py#L17

A set of utilities from @darosior:
https://github.com/darosior/bitcoineasy/blob/master/bitcoineasy/bip38.py

Another paper wallet builder:
https://github.com/zobin8/PyperWallet/blob/master/pyperlib/cryptor.py

P.S. Note that I'm not endorsing any of the above links, just pointing out examples of python (mostly v3) implementation of BIP38. Aside from that there are lots of python 2 implementations that could simply be converted to python 3.
sr. member
Activity: 1190
Merit: 469
September 04, 2021, 07:39:11 AM
#25
I worked on the EC non-multiply mode. I never messed with EC multiply mode but I actually think the EC Multiply mode is the far more interesting of the two. The BIP itself is genius. Maybe a bit overly complicate for the non-multiply mode in the sense that there's probably far more simpler ways to encrypt a bitcoin private key such as just using winrar but hey...
sr. member
Activity: 1190
Merit: 469
September 04, 2021, 07:30:07 AM
#24

I would like to inform you that a BIP is a bitcoin improvement proposal, so more like a protocol specification, and does not need a reference implementation in any language, especially not in Python, since Bitcoin Core is mostly written in C and C++.
Like, do you expect for every BIP that is 'taken seriously' to have a reference implementation in all programming languages? Wink

Well here's the thing. BIP38 is going away. Eventually there won't be any wallets or any software that supports it. It never really caught on. It's kind of a shame because I do think it's a cool piece of technology but unfortunately, we've lost the knowledge on how to implement it since all we have is a generic "protocol specification". The fact that you can't even find a python 3.7 implementation of it speaks volumes. No one cares about bip38. And no one will in the future.

Lucky for me though I was able to implement it in python 3.7 so I can use bip38 as long as I want to unless python decides to bullshit its users again like they did with the 2 to 3 upgrade.

legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
September 03, 2021, 11:57:02 PM
#23
What the quote means is that you use AES with the following settings:
key size = 256 (bit) (the derived key from scrypt)
mode = ECB (each block is encrypted individually)
IV = new byte[16] (empty initialization vector)
padding = none

Yes, those settings are correct.

The AES256Encrypt function described in BIP38 doesn't chain AES blocks together, and the IV is zeroed out before using it (it's not randomized).

Since this function transforms 16 bytes of input into 16 bytes of output, no padding is needed.
legendary
Activity: 3472
Merit: 10611
September 03, 2021, 11:17:27 PM
#22
I would like to inform you that a BIP is a bitcoin improvement proposal, so more like a protocol specification, and does not need a reference implementation in any language, especially not in Python, since Bitcoin Core is mostly written in C and C++.
Like, do you expect for every BIP that is 'taken seriously' to have a reference implementation in all programming languages? Wink
You are confusing the "reference implementation of Bitcoin" with "reference implementation of BIPs" they are not the same, ergo the BIPs reference implementation doesn't have to be in C++. In fact it should be in a langauge that the author of the BIP is most familiar with so that they can write the best readable code possible without any bugs.

The other implementations in other languages are usually done by other developers doing it as volunteers to let readers of the BIP choose whatever language they like to understand the algorithm better. If a BIP doesn't have other implementations it just means there weren't any volunteers yet and you can act on it if you want to contribute.
hero member
Activity: 882
Merit: 5834
not your keys, not your coins!
September 03, 2021, 05:18:23 PM
#21
I guess the real problem and let me get on my soapbox here is that Bip38 wasn't taken very seriously and thus they don't even have a standard reference implementation for current versions of python lol.
I would like to inform you that a BIP is a bitcoin improvement proposal, so more like a protocol specification, and does not need a reference implementation in any language, especially not in Python, since Bitcoin Core is mostly written in C and C++.
Like, do you expect for every BIP that is 'taken seriously' to have a reference implementation in all programming languages? Wink
sr. member
Activity: 1190
Merit: 469
August 08, 2021, 04:42:08 AM
#20

Well that is something that someone who knows python and can see all your code can answer. I don't know python, write it in C# and show me the code and I'll tell you where you went wrong Tongue

Everything seems to be working now, including that unicode test vector. It's working ! Shocked
sr. member
Activity: 1572
Merit: 267
August 07, 2021, 12:54:01 PM
#19


\u03D2\u0301\u0000\U00010400\U0001F4A9


Superstring in the wild if you ask me.
sr. member
Activity: 1190
Merit: 469
August 07, 2021, 12:03:27 PM
#18

Break down the problem and test the Unicode NFC normalization functionality independently from the AES unit test.


The Unicode NFC normalization is handled by a python package.
sr. member
Activity: 1190
Merit: 469
August 07, 2021, 11:44:05 AM
#17

Then you should not implement it yourself. Especially given that you don't really have a clue what you are doing.


I already have implemented it myself. It's just not working with one of the test vectors that's all.

Quote

No offense here, but if you have to ask what AES means or what an initialization vector is, you shouldn't implement this yourself.
Either use an existing library or pay someone who understands what he is doing to create such a tool for you.

Yeah I know. But I'm trying to figure out what the problem is with that one test vector why it's not working while all the other ones are. And I highly suspect it has to do with the fact that the test vector uses a unicode passphrase! Here take a look:

\u03D2\u0301\u0000\U00010400\U0001F4A9


Then they even said something even more confusing which is this:

Note: The non-standard UTF-8 characters in this passphrase should be NFC normalized to result in a passphrase of 0xcf9300f0909080f09f92a9 before further processing


Whoever wrote that BIP really must have been high as a kite. Because I'm telling you, it doesn't make any sense at all. It's like they're speaking in a different language or something.

legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
August 07, 2021, 08:31:19 AM
#16
I need it to work for all possible things it's supposed to including unicode strings of arbitrary complexity.

Break down the problem and test the Unicode NFC normalization functionality independently from the AES unit test.

The AES test should not care whether the input is a valid ascii/windows-1252/latin1/UTF-8/16/32/"Unicode" (you should not call character input that) because it operates at the byte level. Therefore, it makes sense for AES test vectors to be completely random bytes.
legendary
Activity: 1624
Merit: 2481
August 07, 2021, 07:55:52 AM
#15
... maybe some people are happy enough when it works with passphrases like "satoshi" but I need it to work for all possible things it's supposed to including unicode strings of arbitrary complexity.

Then you should not implement it yourself. Especially given that you don't really have a clue what you are doing.

No offense here, but if you have to ask what AES means or what an initialization vector is, you shouldn't implement this yourself.
Either use an existing library or pay someone who understands what he is doing to create such a tool for you.
legendary
Activity: 3472
Merit: 10611
August 06, 2021, 10:48:05 PM
#14
well how come if I normalized it in nfc form and then utf-8 encoded it, it didn't work where as all the other test vectors did work?
Well that is something that someone who knows python and can see all your code can answer. I don't know python, write it in C# and show me the code and I'll tell you where you went wrong Tongue
sr. member
Activity: 1190
Merit: 469
August 06, 2021, 02:59:52 AM
#13
Once again the lack of explanation,documentation, thouroughness in things rears its ugly head. Shocked

And once again the BIP is not supposed to explain everything
, specially the basic stuff. For example it didn't explain how to do a Base58 encoding, you already knew that or if you didn't you sought the document explaining it somewhere else.
String normalization is the same. You should just google how it works, programming languages usually have an option to perform it easily for instance in c# we simply call an extension method called Normalize(mode).
https://en.wikipedia.org/wiki/Unicode_equivalence
https://stackoverflow.com/questions/47094155/how-to-normalize-python-3-unicode-string

well how come if I normalized it in nfc form and then utf-8 encoded it, it didn't work where as all the other test vectors did work? luckily they put a test vector in that used unicode otherwise i woulda thought it worked completely 100% that is until ... maybe some people are happy enough when it works with passphrases like "satoshi" but I need it to work for all possible things it's supposed to including unicode strings of arbitrary complexity.
legendary
Activity: 3472
Merit: 10611
August 05, 2021, 10:21:33 PM
#12
Once again the lack of explanation,documentation, thouroughness in things rears its ugly head. Shocked
And once again the BIP is not supposed to explain everything, specially the basic stuff. For example it didn't explain how to do a Base58 encoding, you already knew that or if you didn't you sought the document explaining it somewhere else.
String normalization is the same. You should just google how it works, programming languages usually have an option to perform it easily for instance in c# we simply call an extension method called Normalize(mode).
https://en.wikipedia.org/wiki/Unicode_equivalence
https://stackoverflow.com/questions/47094155/how-to-normalize-python-3-unicode-string
sr. member
Activity: 1190
Merit: 469
August 05, 2021, 04:14:24 AM
#11
I think it may be a bug in python  Shocked
There is no bug in python, the bug is in your usage of AES. You are using one of the modes that does not encrypt each block individually so when you encrypt the first block (first 16 bytes) you get the correct result but when you encrypt the second block (second 16 bytes) you get the wrong result. Then you concatenate the two parts and encode it with base58 so your string ends up looking like that.
Use the mode I told you above (ECB) and it should fix your issue.
Learn about AES modes here: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_(ECB)

You can see the data in your base58, the last part is the second block you encrypt which is different:
Code:
0142-c0-e957a24a-d357fafb81c71f8375a9a4d0ac02bad5-f6c87c4b459fabe34c0c314b33708ec3
0142-c0-e957a24a-d357fafb81c71f8375a9a4d0ac02bad5-30d5c2d250fed0ce62b993841bb5ccac

Good call! It was just a typo.

I did:
Do AES256Encrypt(block = bitcoinprivkey[16...31] xor derivedhalf1[0...15], key = derivedhalf2), call the 16-byte result encryptedhalf2

when it was supposed to be:
Do AES256Encrypt(block = bitcoinprivkey[16...31] xor derivedhalf1[16...31], key = derivedhalf2), call the 16-byte result encryptedhalf2







Passphrase: TestingOneTwoThree
Encrypted key: 6PRVWUbkzzsbcVac2qwfssoUJAN1Xhrg6bNk8J7Nzm5H7kxEbn2Nh2ZoGg
WIF key: 5KN7MzqK5wt2TP1fQCYyHBtDrXdJuXbUzm4A9rKAteGu3Qi5CVR
HEX key: CBF4B9F70470856BB4F40F80B87EDB90865997FFEE6DF315AB166D713AF433A5
Computed BTC address: 1Jq6MksXQVWzrznvZzxkV6oY57oWXD9TXB
Encryption steps:


1. Compute the Bitcoin address (ASCII), and take the first four bytes of SHA256(SHA256()) of it. Let's call this addresshash.
addresshash is  b'\xe9W\xa2J'

Function name: normalize_string using unicodedata.normalize package
-------------------------

2. Derive a key from the passphrase using scrypt
Parameters: passphrase is the passphrase itself encoded in UTF-8 and normalized using Unicode Normalization Form C (NFC). salt is addresshash from the earlier step, n=16384, r=8, p=8, length=64 (n, r, p are provisional and subject to consensus)
scrypt =  b'\xf8vH\xa6\xb4/\xdd\x86\xefh7\xa2I\xcd\xe1S\x18\xf2d\xd4:\x85\x9ba\x0ex\xeac\xd5\x1c\xb2\xd3\xe6\x0b\xf4K\xfb)\xd5C\xbb\xa2J\xfc\xcc\xfa\xdb\xfcn\xf91/\xcc\xcfX\x9f\xa5\xea\x13f\xec!\xe4\xc0'
scrypt_hash_hex =  f87648a6b42fdd86ef6837a249cde15318f264d43a859b610e78ea63d51cb2d3e60bf44bfb29d54 3bba24afcccfadbfc6ef9312fcccf589fa5ea1366ec21e4c0
Let's split the resulting 64 bytes in half, and call them derivedhalf1 and derivedhalf2.
derivedhalf1 =  b'\xf8vH\xa6\xb4/\xdd\x86\xefh7\xa2I\xcd\xe1S\x18\xf2d\xd4:\x85\x9ba\x0ex\xeac\xd5\x1c\xb2\xd3'
derivedhalf2 =  b'\xe6\x0b\xf4K\xfb)\xd5C\xbb\xa2J\xfc\xcc\xfa\xdb\xfcn\xf91/\xcc\xcfX\x9f\xa5\xea\x13f\xec!\xe4\xc0'

3. Do AES256Encrypt(block = bitcoinprivkey[0...15] xor derivedhalf1[0...15], key = derivedhalf2), call the 16-byte result encryptedhalf1
key =  b'\xe6\x0b\xf4K\xfb)\xd5C\xbb\xa2J\xfc\xcc\xfa\xdb\xfcn\xf91/\xcc\xcfX\x9f\xa5\xea\x13f\xec!\xe4\xc0'
data=  68470520909420510445936813703370586819
encryptedhalf1=  b'\xd3W\xfa\xfb\x81\xc7\x1f\x83u\xa9\xa4\xd0\xac\x02\xba\xd5'

4. Do AES256Encrypt(block = bitcoinprivkey[16...31] xor derivedhalf1[16...31], key = derivedhalf2), call the 16-byte result encryptedhalf2
data2=  210910838195062625062692659411739509110
enryptedhalf2=  b'\xf6\xc8|KE\x9f\xab\xe3L\x0c1K3p\x8e\xc3'

5. The encrypted private key is the Base58Check-encoded concatenation of the following, which totals 39 bytes without Base58 checksum: 0x01 0x42 + flagbyte + salt + encryptedhalf1 + encryptedhalf2
Using uncompressed address
object_id_prefix=  b'\x01B'
flagbyte_byte=  b'\xc0'
salt=addresshash= b'\xe9W\xa2J'
private_key_encrypted_bytes=  b'\x01B\xc0\xe9W\xa2J\xd3W\xfa\xfb\x81\xc7\x1f\x83u\xa9\xa4\xd0\xac\x02\xba\xd5\xf6\xc8|KE\x9f\xab\xe3L\x0c1K3p\x8e\xc3'

Base 58 encoded encrypted private key
6PRVWUbkzzsbcVac2qwfssoUJAN1Xhrg6bNk8J7Nzm5H7kxEbn2Nh2ZoGg
58

Known encrypted key
6PRVWUbkzzsbcVac2qwfssoUJAN1Xhrg6bNk8J7Nzm5H7kxEbn2Nh2ZoGg
58
SUCCESS keys match





Passphrase: TestingOneTwoThree
Encrypted key: 6PYNKZ1EAgYgmQfmNVamxyXVWHzK5s6DGhwP4J5o44cvXdoY7sRzhtpUeo
WIF key: L44B5gGEpqEDRS9vVPz7QT35jcBG2r3CZwSwQ4fCewXAhAhqGVpP
HEX key: CBF4B9F70470856BB4F40F80B87EDB90865997FFEE6DF315AB166D713AF433A5
Computed BTC address: 164MQi977u9GUteHr4EPH27VkkdxmfCvGW
Encryption steps:


1. Compute the Bitcoin address (ASCII), and take the first four bytes of SHA256(SHA256()) of it. Let's call this addresshash.
addresshash is  b'C\xbeAy'

Function name: normalize_string using unicodedata.normalize package
-------------------------

2. Derive a key from the passphrase using scrypt
Parameters: passphrase is the passphrase itself encoded in UTF-8 and normalized using Unicode Normalization Form C (NFC). salt is addresshash from the earlier step, n=16384, r=8, p=8, length=64 (n, r, p are provisional and subject to consensus)
scrypt =  b's\x1e\xf3\xc77\xb5]\xf4\x99\x8bD\xfa\x8aTz?8\xdfBM\xa2@\xde8\x9b\x11\xd1\x87[\xa4wg//\xe8\x1b\x052\xb5\x95\x0e>\xa6\xff\xf9,e\xd4g\xaa}\x05Ii\x82\x1d\xe24Oz\x86\xd4%i'
scrypt_hash_hex =  731ef3c737b55df4998b44fa8a547a3f38df424da240de389b11d1875ba477672f2fe81b0532b59 50e3ea6fff92c65d467aa7d054969821de2344f7a86d42569
Let's split the resulting 64 bytes in half, and call them derivedhalf1 and derivedhalf2.
derivedhalf1 =  b's\x1e\xf3\xc77\xb5]\xf4\x99\x8bD\xfa\x8aTz?8\xdfBM\xa2@\xde8\x9b\x11\xd1\x87[\xa4wg'
derivedhalf2 =  b'//\xe8\x1b\x052\xb5\x95\x0e>\xa6\xff\xf9,e\xd4g\xaa}\x05Ii\x82\x1d\xe24Oz\x86\xd4%i'

3. Do AES256Encrypt(block = bitcoinprivkey[0...15] xor derivedhalf1[0...15], key = derivedhalf2), call the 16-byte result encryptedhalf1
key =  b'//\xe8\x1b\x052\xb5\x95\x0e>\xa6\xff\xf9,e\xd4g\xaa}\x05Ii\x82\x1d\xe24Oz\x86\xd4%i'
data=  245794453406607058042499921876840260015
encryptedhalf1=  b'p\xe4\xa0\x80_\x15\xa7~\xfcs\x8fy@h\xd8\x83'

4. Do AES256Encrypt(block = bitcoinprivkey[16...31] xor derivedhalf1[16...31], key = derivedhalf2), call the 16-byte result encryptedhalf2
data2=  253253421257611663847159858968675763394
enryptedhalf2=  b'|)\x85\xa6\x94_\x7f\xe0\xdb?u\xdc0^\xaf|'

5. The encrypted private key is the Base58Check-encoded concatenation of the following, which totals 39 bytes without Base58 checksum: 0x01 0x42 + flagbyte + salt + encryptedhalf1 + encryptedhalf2
Using compressed address
object_id_prefix=  b'\x01B'
flagbyte_byte=  b'\xe0'
salt=addresshash= b'C\xbeAy'
private_key_encrypted_bytes=  b'\x01B\xe0C\xbeAyp\xe4\xa0\x80_\x15\xa7~\xfcs\x8fy@h\xd8\x83|)\x85\xa6\x94_\x7f\xe0\xdb?u\xdc0^\xaf|'

Base 58 encoded encrypted private key
6PYNKZ1EAgYgmQfmNVamxyXVWHzK5s6DGhwP4J5o44cvXdoY7sRzhtpUeo
58

Known encrypted key
6PYNKZ1EAgYgmQfmNVamxyXVWHzK5s6DGhwP4J5o44cvXdoY7sRzhtpUeo
58
SUCCESS keys match





The good news is i got it working with "No compression, no EC multiply" test vectors 1 and 2 as well as their related "Compression, no EC multiply" counterparts.

The bad news is it doesn't work with "No compression, no EC multiply" Test vector 3. That one uses a strange passphrase.

Passphrase ϓ␀hankey (\u03D2\u0301\u0000\U00010400\U0001F4A9; GREEK UPSILON WITH HOOK, COMBINING ACUTE ACCENT, NULL, DESERET CAPITAL LETTER LONG I, PILE OF POO)


along with the following note:

Note: The non-standard UTF-8 characters in this passphrase should be NFC normalized to result in a passphrase of 0xcf9300f0909080f09f92a9 before further processing


None of that really makes any sense to me. 0xcf9300f0909080f09f92a9 is a hexadecimal number, not a string. Once again the lack of explanation,documentation, thouroughness in things rears its ugly head. Shocked

[moderator's note: consecutive posts merged]
legendary
Activity: 3472
Merit: 10611
August 04, 2021, 11:52:13 PM
#10
I think it may be a bug in python  Shocked
There is no bug in python, the bug is in your usage of AES. You are using one of the modes that does not encrypt each block individually so when you encrypt the first block (first 16 bytes) you get the correct result but when you encrypt the second block (second 16 bytes) you get the wrong result. Then you concatenate the two parts and encode it with base58 so your string ends up looking like that.
Use the mode I told you above (ECB) and it should fix your issue.
Learn about AES modes here: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_(ECB)

You can see the data in your base58, the last part is the second block you encrypt which is different:
Code:
0142-c0-e957a24a-d357fafb81c71f8375a9a4d0ac02bad5-f6c87c4b459fabe34c0c314b33708ec3
0142-c0-e957a24a-d357fafb81c71f8375a9a4d0ac02bad5-30d5c2d250fed0ce62b993841bb5ccac
sr. member
Activity: 1190
Merit: 469
August 04, 2021, 11:24:42 PM
#9
Unfortunately, most of the test vectors I've seen don't get as finely grained as the individual steps in an algorithm... instead they'll focus on the "initial input" and the "final output" Undecided

In any case, you might want to have a look at this: https://github.com/steve-vincent/bip38

Granted, it's Python 2.7... but it's a "working" BIP38 python project and might offer some insights as a starting point.

Yeah thanks for the suggestion about trying to use an older version of python implementation, I was hoping not to have to install an old version of python just to see how thing thing works. That's a pretty sad state of affairs but at least it might yield some better insight. Sigh, I really did not want to have to install an old version of python lol.





Technically since BIP38 is just using a couple of other functions you don't need the intermediary values for each step, the initial input and final output are more than enough. This is also why there aren't that many test vectors either.

Yeah but how do you program it in python? You see python did some crazy thing where they just changed things alot and there was a version 3 and then an old version 2 and they aren't even alike and ...



What the hay, maybe I'll just write the missing test vectors myself. I don't have much else to do this week and I've also seen stuff like BIP32 & BIP39 missing test vectors for some of their steps as well so it would be beneficial for the community. I might even be able to merge these by PR into the official BIP spec.

That would be very excellent, thanks.



[moderator's note: consecutive posts merged]
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
August 04, 2021, 06:40:57 AM
#8
Unfortunately, most of the test vectors I've seen don't get as finely grained as the individual steps in an algorithm... instead they'll focus on the "initial input" and the "final output" Undecided

In any case, you might want to have a look at this: https://github.com/steve-vincent/bip38

Granted, it's Python 2.7... but it's a "working" BIP38 python project and might offer some insights as a starting point.

What the hay, maybe I'll just write the missing test vectors myself. I don't have much else to do this week and I've also seen stuff like BIP32 & BIP39 missing test vectors for some of their steps as well so it would be beneficial for the community. I might even be able to merge these by PR into the official BIP spec.
legendary
Activity: 3472
Merit: 10611
August 03, 2021, 11:19:05 PM
#7
Technically since BIP38 is just using a couple of other functions you don't need the intermediary values for each step, the initial input and final output are more than enough. This is also why there aren't that many test vectors either.

But you can always create your own test vectors if you like, just take any of the existing implementations that is tested and add break points at different lines or print the values if the language has that option, then use those values.
HCP
legendary
Activity: 2086
Merit: 4361
August 03, 2021, 07:18:52 PM
#6
Unfortunately, most of the test vectors I've seen don't get as finely grained as the individual steps in an algorithm... instead they'll focus on the "initial input" and the "final output" Undecided

In any case, you might want to have a look at this: https://github.com/steve-vincent/bip38

Granted, it's Python 2.7... but it's a "working" BIP38 python project and might offer some insights as a starting point.
sr. member
Activity: 1190
Merit: 469
July 29, 2021, 01:31:45 AM
#5
Don't try to code AES encrypt/decrypt calls on Python unless you have dozens of man-hours to spare on debugging. It's literally a pain in the !!! and I know that because I coded this sort of thing before.

Thanks for the advice but it got to me too late, I've already spent way too many hours struggling with it but the main problem I run into is there's not a single test vector I can find that shows the output from each step of the algorithm so that I can pinpoint where I'm going wrong. Can you imagine that? Not a single test vector that shows each step and its output. Bip38 is something else!

I mean the spec seems innocent enough how they listed it out step by step. Problem is, when you can't see an example it really sucks balls.

legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
July 27, 2021, 11:09:49 AM
#4
Don't try to code AES encrypt/decrypt calls on Python unless you have dozens of man-hours to spare on debugging. It's literally a pain in the !!! and I know that because I coded this sort of thing before.

First of all if you don't have a fixed-width key then you have to select a character to pad the key with since for AES256 it must be 32 chars long and then you have to somehow remove the padding when you decrypt it (impossible to do if the key text is completely random since no characters are suitable for padding in the first place, not even \x00).

Then you have the issue of serializing this to bytes() because the encryption function will choke on regular strings, and if you're not careful with coding and muck with the wrong encode() and decode() codecs you'll end up making an encrypted text that can't be decrypted by the decryption function because the some (maybe even just one) bytes are wrong.

You cannot just work with bytes because a large number of functions will not work with that type and require the str type such as input and of course padding (since you can't mix strings with bytes either!)

This is complicated even further in Python 3 where all strings are now UTF-8 encoded instead of just ASCII encoded.

Finally there are a myriad of "pycrypto" clone libraries that all conflict with each other if they are installed in the same environment causing ImportErrors and all kinds of weird bugs which forces you to make a virtualenv to do pycrypto stuff in. Though I heard that people are using "pycryptodome" package nowadays.
sr. member
Activity: 1190
Merit: 469
July 26, 2021, 03:04:42 AM
#3

What the quote means is that you use AES with the following settings:
key size = 256 (bit) (the derived key from scrypt)
mode = ECB (each block is encrypted individually)
IV = new byte[16] (empty initialization vector)
padding = none


I will definitely give that a try. Not sure why they couldn't make that more clear in the specification though I guess they expect mind readers to be looking over their docs. oh and thanks! i'll report back if i get it working.
legendary
Activity: 3472
Merit: 10611
July 25, 2021, 10:28:31 PM
#2
The problem is I don't know they mean by that.
That is probably because you don't know how AES works which means you probably shouldn't implement BIP38 yourself and try to use an existing library that is well tested even in another language.

What the quote means is that you use AES with the following settings:
key size = 256 (bit) (the derived key from scrypt)
mode = ECB (each block is encrypted individually)
IV = new byte[16] (empty initialization vector)
padding = none

When decrypting, you split the decrypted key (extracted from the base58) into 2x 16-byte parts and decrypt using the AES instance you prepared above in 2 rounds to get the 2x 16-byte chunk of the actual private key.
sr. member
Activity: 1190
Merit: 469
July 25, 2021, 09:24:01 PM
#1
I can't seem to code bip38 in python based on the formal specification: https://github.com/bitcoin/bips/blob/master/bip-0038.mediawiki

Quote
This proposal makes use of the following functions and definitions:
•AES256Encrypt, AES256Decrypt: the simple form of the well-known AES block cipher without consideration for initialization vectors or block chaining. Each of these functions takes a 256-bit key and 16 bytes of input, and deterministically yields 16 bytes of output.

The problem is I don't know they mean by that. I'm not even sure python has that. Nothing that I have tried has worked. Which is a big disappointment. I'm using Python 3.7.

I guess the real problem and let me get on my soapbox here is that Bip38 wasn't taken very seriously and thus they don't even have a standard reference implementation for current versions of python lol.
Jump to: