Author

Topic: Generating Address From 78 Bit Number (Read 189 times)

legendary
Activity: 1042
Merit: 2805
Bitcoin and C♯ Enthusiast
September 12, 2021, 10:49:03 PM
#12
I recommend you to look on Denovo. Coding Enthusiast must have probably implement it, it ain't difficult.
The following method contains all the subsequent methods that are called in order to create a private key from an integer of at most bitLen bits, convert to public key and finally get the corresponding address. You can find all those methods in Bitcoin.Net and see what they do.
It goes without saying that a key created this way is a weak key.
Code:
public static void CreateWeakAddress(int bitLen, out string comp, out string uncomp)
{
    if (bitLen > 256 || bitLen < 1)
        throw new ArgumentOutOfRangeException();

    // Create a random integer of at most bitLen bits
    BigInteger mod = BigInteger.One << bitLen;
    byte[] data = new byte[32];
    using SharpRandom rng = new();
    rng.GetBytes(data);
    BigInteger value = new BigInteger(data, true, true) % mod;

    // Convert to a private key (will check if in range and could throw ArgumentOutOfRangeException)
    using PrivateKey key = new(value);
    // Get pubkey and addresses
    PublicKey pub = key.ToPublicKey();
    comp = Address.GetP2pkh(pub, true);
    uncomp = Address.GetP2pkh(pub, false);

    // Other address types are possible too
    _ = Address.GetP2wpkh(pub, true);
    _ = Address.GetP2wpkh(pub, false);
    _ = Address.GetP2sh_P2wpkh(pub, true);
    _ = Address.GetP2sh_P2wpkh(pub, false);
}
hero member
Activity: 1220
Merit: 612
OGRaccoon
September 12, 2021, 06:16:27 PM
#11
78 bit into the compressed and uncompressed addresses.
78 bits is far too small for a secure private key.  You can see in threads here that people have successfully cracked keys quite a bit larger than 78 bits.

So unless you're intentionally creating an insecure key for puzzle purposes, you probably don't want to do this.

It's not for anything specific nor will it be used to store any funds just for some testing purpose.

Thanks all for the info!

staff
Activity: 4284
Merit: 8808
September 12, 2021, 05:25:39 PM
#10
78 bit into the compressed and uncompressed addresses.
78 bits is far too small for a secure private key.  You can see in threads here that people have successfully cracked keys quite a bit larger than 78 bits.

So unless you're intentionally creating an insecure key for puzzle purposes, you probably don't want to do this.
legendary
Activity: 1512
Merit: 7340
Farewell, Leo
September 12, 2021, 03:29:39 PM
#9
Forgot to say that if you want a compressed address, the process is the same except this step:
Your uncompressed public key is a prefix followed by the coordinates.
Code:
049C6ACBF20880784802DE6CB8C721F739704FB473E71FB07C33B39173FB29AC7BD50FA16FB3913615132273E723433D92CA1C2C00FB1E770227B4F6A06F6AF770

When we generate a compressed address (which is what we usually do), we hash the compressed public key instead. In this case, it's this:
Code:
029C6ACBF20880784802DE6CB8C721F739704FB473E71FB07C33B39173FB29AC7B

It turns out that you don't have to carry both x and y coordinates since y can be calculated by the following equation:

y2 = x3 + 7

Since y can give two different values, we indicate it with a prefix. If y is even we add a “02” in front of x and if it's odd a “03”. In the case above, y was even.
hero member
Activity: 1220
Merit: 612
OGRaccoon
September 12, 2021, 02:04:31 PM
#8
So you are wanting WIF plus addresses?

example:
you feed the script:
some private key, 4EF3B2767693340

and in your output file you want what??:
public keys:
uncompressed
045E498CF31DE7E9768E9D457C66222BAE9B461B96B5CFC8CE931BFF8A12430341A2D24891A1DF7 97DE32341AA57D9E95D993C45812E8442C6E5E6F16A4BF98AC4
compressed
025E498CF31DE7E9768E9D457C66222BAE9B461B96B5CFC8CE931BFF8A12430341

public address:
uncompressed
1DrKT3o3PALKNuKC3yGUxrA7WndyBQxtKU
compressed
16m928aDT71pp7qb9ZhPiNHLoBprFZ2AnY

you mentioned public key, which is not the same as public address.

And you want the WIFs as well??

Don't reinvent the wheel, use this:
https://github.com/geniusprodigy/mega-tool-pvkmassconvert/blob/master/mega-tool-pvkmassconvert.py

Mod it as needed, if you want to print the public keys as well.

Thanks @WanderingPhilospher

the code above was from another project it just so happened to spit out the WIF should be no trouble to adjust it to get what is required.

I will have a look at the tool posted above also thanks for the advice guys!

Sorry I am out of merit I own you one!

Magic
full member
Activity: 1162
Merit: 237
Shooters Shoot...
September 12, 2021, 01:39:17 PM
#7
So you are wanting WIF plus addresses?

example:
you feed the script:
some private key, 4EF3B2767693340

and in your output file you want what??:
public keys:
uncompressed
045E498CF31DE7E9768E9D457C66222BAE9B461B96B5CFC8CE931BFF8A12430341A2D24891A1DF7 97DE32341AA57D9E95D993C45812E8442C6E5E6F16A4BF98AC4
compressed
025E498CF31DE7E9768E9D457C66222BAE9B461B96B5CFC8CE931BFF8A12430341

public address:
uncompressed
1DrKT3o3PALKNuKC3yGUxrA7WndyBQxtKU
compressed
16m928aDT71pp7qb9ZhPiNHLoBprFZ2AnY

you mentioned public key, which is not the same as public address.

And you want the WIFs as well??

Don't reinvent the wheel, use this:
https://github.com/geniusprodigy/mega-tool-pvkmassconvert/blob/master/mega-tool-pvkmassconvert.py

Mod it as needed, if you want to print the public keys as well.
legendary
Activity: 1512
Merit: 7340
Farewell, Leo
September 12, 2021, 01:16:45 PM
#6
So for the Elliptic curve base points we would be looking at something like
And for the hashing side of things.
Yep. Is that a bitcoin-python library? You should confirm one of your uncompressed address' generations with this: https://gobittest.appspot.com/Address

If you use the same private key and get the same address, you're using the correct functions.

This should give the encodedWIF which can then be used to output the public addressing?
WIF stands for Wallet Import Format. The code seems a little messed up to me and I can't fully understand why they named their variables that way with a “WIF” included. But, as far as I see, it encodes it with base58 so it should be correct.

We usually refer WIF to private keys as they can have different representations. The number in our example can be represented in hexadecimal, decimal, binary.

The WIF that, once you import it in a wallet, gives you the uncompressed address we've generated is:
Code:
5K9iZnfofS1WAtmKdZd4dZoYtge7G5sY3SXyk7i9KZyGZMsncWJ

Read more about WIF here: https://learnmeabitcoin.com/technical/wif

Thanks again!
You're welcome!
hero member
Activity: 1220
Merit: 612
OGRaccoon
September 12, 2021, 12:53:34 PM
#5
 Wink

Thank you @BlackHatCoiner!!

This is exactly what I was looking for.


So for the Elliptic curve base points we would be looking at something like

Code:
def modinv(a,n=Pcurve): 
    lm, hm = 1,0
    low, high = a%n,n
    while low > 1:
        ratio = high/low
        nm, new = hm-lm*ratio, high-low*ratio
        lm, low, hm, high = nm, new, lm, low
    return lm % n

def ECadd(a,b):
    LamAdd = ((b[1]-a[1]) * modinv(b[0]-a[0],Pcurve)) % Pcurve
    x = (LamAdd*LamAdd-a[0]-b[0]) % Pcurve
    y = (LamAdd*(a[0]-x)-a[1]) % Pcurve
    return (x,y)

def ECdouble(a):
    Lam = ((3*a[0]*a[0]+Acurve) * modinv((2*a[1]),Pcurve)) % Pcurve
    x = (Lam*Lam-2*a[0]) % Pcurve
    y = (Lam*(a[0]-x)-a[1]) % Pcurve
    return (x,y)

def EccMultiply(GenPoint,ScalarHex):
    if ScalarHex == 0 or ScalarHex >= N: hashing();
    ScalarBin = str(bin(ScalarHex))[2:]
    Q=GenPoint
    for i in range (1, len(ScalarBin)):
        Q=ECdouble(Q);
        if ScalarBin[i] == "1":
            Q=ECadd(Q,GenPoint);  
    return (Q)

And for the hashing side of things.

Code:
def hashing():
global blockSize, blockNumber,y,n,x
while (x<1):
start1()
x=0
n=0
y=0
startRange = blockNumber*blockSize+1
endRange =startRange+blockSize
for key in range(startRange,endRange):
PublicKey = EccMultiply(GPoint,key)
uncompress = "04" + "%064x" % PublicKey[0] + "%064x" % PublicKey[1];
uncompressbin = str(uncompress).decode('hex')
outputsha256 = hashlib.new('sha256',uncompressbin).digest()
outputripemd160 = hashlib.new('ripemd160',outputsha256).digest()
q=outputripemd160.encode('hex')
print find(q,satoshiKeys,key)
if x>0:
keyHex = hex(key).split('x')[-1];
keyHexf = '80'+('0'*(64-len(keyHex)))+str(keyHex)
decodewin = str(keyHexf).decode('hex');
checksumSHAa = hashlib.new('sha256',decodewin).digest()
checksumSHAb = hashlib.new('sha256',checksumSHAa).digest()
checksumwin = checksumSHAb.encode('hex')
preWIF = str(keyHexf)+str(checksumwin[0:8])
decodewin2 = str(preWIF).decode('hex')
encodeWIF = base58.b58encode(decodewin2)
print encodeWIF
break
print ""



This should give the encodedWIF which can then be used to output the public addressing?

Thanks again!
legendary
Activity: 1512
Merit: 7340
Farewell, Leo
September 12, 2021, 12:40:42 PM
#4
Merited, cause I'm sure it'll bring constructive discussion.  Smiley

I do not mind coding something up but what is the exact process to go from the above to a public key.

You'll have to multiply that number with a point (G) of an elliptic curve we're following called secp256k1. Once you do that, you'll get a new point which will be your public key or dG (private key times G).

We usually represent both private keys and public keys hexadecimally, so I'll convert the number to hex to help you understand the process. Note that you can only use legacy addresses as uncompressed. Alright, so let's start.

Let's take a random number. (the one you picked is outside our curve, so you probably typed it arbitrarily)
Code:
hex: AFD0E79369D407D576D6EDE1762CEE44BD73B8758B5AD98048A396F2A6E20488
dec: 79523850969208805552503446842656968977264486959031597789767655508829511222408

We multiply it by G, which is a known point in our curve, and we get a point with these coordinates:
Code:
x: 9C6ACBF20880784802DE6CB8C721F739704FB473E71FB07C33B39173FB29AC7B
y: D50FA16FB3913615132273E723433D92CA1C2C00FB1E770227B4F6A06F6AF770

Your uncompressed public key is a prefix followed by the coordinates.
Code:
049C6ACBF20880784802DE6CB8C721F739704FB473E71FB07C33B39173FB29AC7BD50FA16FB3913615132273E723433D92CA1C2C00FB1E770227B4F6A06F6AF770

Hash the above with SHA256 and you get:
Code:
E5AECEAEC2B8A2A7237A256C9D982B356D1A00F62604E4DD88A8447121102A30

Hash the above with RIPEMD-160 and you get:
Code:
044AA0973C1944861A3A9322DF6483BA39C8AA94

Add a version byte in front of it: (it's “00” in main net)
Code:
00044AA0973C1944861A3A9322DF6483BA39C8AA94

Hash that thing with SHA256:
Code:
860C3037C4755719FB4FDE574A9E6EABE89177277E84EE5CE64E09A92A3A7A75

Again, the above with SHA256:
Code:
79A69488947664034D5A7931934D102EEE4B94E3931EAD40479B211A51D0C5EB

Take the first four bytes (in this case they're “79A69488”) and add them to the RIPEMD-160 hash we made two steps above:
Code:
00044AA0973C1944861A3A9322DF6483BA39C8AA9479A69488

Now encode this with base58 and here I present you, your uncompressed address:
Code:
1Ph6xtRCue298R7q38GZq4q6XN8xQftBR



Has anyone got a small python or C# program that I can pipe in the numbers like this and output the address.
I was working on a Bitcoin multi-toolkit project which would include this feature. If I had finished it, you could copy my source code from that part, but unfortunately I haven't.

I recommend you to look on Denovo. Coding Enthusiast must have probably implemented it, it ain't difficult.
hero member
Activity: 1220
Merit: 612
OGRaccoon
September 12, 2021, 12:24:51 PM
#3
I can create a file with the lines I want to import that should be no problem.
full member
Activity: 1162
Merit: 237
Shooters Shoot...
September 12, 2021, 12:20:02 PM
#2
Do you have a text file with specific numbers per line, or are you wanting to feed them manually?
hero member
Activity: 1220
Merit: 612
OGRaccoon
September 12, 2021, 12:17:13 PM
#1
So I was looking for a way to convert a decimal number 78 bit into the compressed and uncompressed addresses.

I would like to feed a specific set of numbers into a small program that will then generate the related compressed and uncompressed addressing for that decimal number.

What is the exact process to go from something like :

158458943549846849875450169348572156946031654895118510018735188216379120187838

Into the address format?

Has anyone got a small python or C# program that I can pipe in the numbers like this and output the address.

I do not mind coding something up but what is the exact process to go from the above to a public key.

Best regards.
Jump to: