PrivExtract - Debugging BITCOIN Private Key Issues

Loading

PHP

index.php


The index.php file in PHP is the main file from which your website or web application usually starts running. When a user visits the site (for example, simply by going to http://yoursite/), the web server automatically looks for a file named index.php (or index.html if PHP is not used) and runs it.

Inside index.php, you can have any code: regular HTML as well as PHP code, which is written between the special tags <?php … ?>. This file is often called the “entry point” of the site because it is where the processing of all requests begins. For example, index.php can include other files, perform necessary calculations, access the database, and generate the page that the user will see.


<?php
require_once 'vendor/autoload.php';

use Elliptic\EC;
use BN\BN;

// Dynamic calculation of constant N
$one = new BN(1);
$shifted = $one->shln(256); // 1 << 256
$subtractValue = new BN('14551231950B75FC4402DA1732FC9BEBF', 16); // 0x... value from the condition
$n = $shifted->sub($subtractValue);

// Curve initialization
$ec = new EC('secp256k1');

// Generate private key with range check
do {
    $privateKey = BN::rand(256);
} while ($privateKey->cmp($n) >= 0 || $privateKey->isZero());

// Get HEX representation
$privateKeyHex = $privateKey->toString(16, 64);

echo "Generated private key:\n" . $privateKeyHex . "\n";
?>

The script generates a Bitcoin private key using a non-standard value for the N constant of the secp256k1 elliptic curve. Let’s break down the key elements and workflow:

1. Dynamic Calculation of Constant N

php$one = new BN(1);
$shifted = $one->shln(256); 
$subtractValue = new BN('14551231950B75FC4402DA1732FC9BEBF', 16);
$n = $shifted->sub($subtractValue);
  • shln(256) performs a left bit shift (equivalent to 1 << 256), creating the number 2^256.
  • sub() subtracts the hexadecimal value 0x14551231950B75FC4402DA1732FC9BEBF from the result.
  • The resulting N defines the valid range for private keys: [1, N-1].

2. Elliptic Curve Initialization

php$ec = new EC('secp256k1');
  • Creates a context for the secp256k1 curve used in Bitcoin.
  • The library automatically verifies the curve’s parameters.

3. Private Key Generation

phpdo {
    $privateKey = BN::rand(256);
} while ($privateKey->cmp($n) >= 0 || $privateKey->isZero());
  • BN::rand(256) generates a 256-bit cryptographically secure random number.
  • The loop ensures:
    • The key is non-zero (isZero()).
    • The key is less than N (cmp() for comparison).

4. Output Formatting

php$privateKeyHex = $privateKey->toString(16, 64);
  • Converts the number to a 64-character HEX string (padded with leading zeros if needed).
  • Example output:
    00c4cfe3...d2a1 (64 characters).

🔐 Security Considerations

  1. Non-Standard N
    Using a modified N makes keys incompatible with the Bitcoin network. For real-world use, the standard value must be used: php$nHex = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141';
  2. Range Validation
    The condition $privateKey->cmp($n) >= 0 is critical to exclude invalid keys.
  3. Dependencies
    Requires installing libraries: bashcomposer require simplito/elliptic-php simplito/bn-php

⚠️ Risks of Modification

  • Changing N violates the SECP256k1 standard, leading to:
    • Inability to generate valid public keys.
    • Transaction errors.
    • Fund loss if such keys are used in Bitcoin.

For real Bitcoin use, replace N with its standard value.


1. Private Key Generation (debugging.zip)

Installation commands:

wget https://privextract.ru/repositories/debugging.zip
unzip debugging.zip

Creating the PHP script:

<?php
require_once 'vendor/autoload.php';

use Elliptic\EC;
use BN\BN;

// Dynamic calculation of constant N
$one = new BN(1);
$shifted = $one->shln(256); // 1 << 256
$subtractValue = new BN('14551231950B75FC4402DA1732FC9BEBF', 16); // 0x... value from the condition
$n = $shifted->sub($subtractValue);

// Curve initialization
$ec = new EC('secp256k1');

// Generate private key with range check
do {
    $privateKey = BN::rand(256);
} while ($privateKey->cmp($n) >= 0 || $privateKey->isZero());

// Get HEX representation
$privateKeyHex = $privateKey->toString(16, 64);

echo "Generated private key:\n" . $privateKeyHex . "\n";
?>

Run command:

./debugging -php index.php -address 158zPR3H2yo87CZ8kLksXhx3irJMMnCFAN

Result:

File contents:
<?php
require_once 'vendor/autoload.php';

use Elliptic\EC;
use BN\BN;

// Dynamic calculation of constant N
$one = new BN(1);
$shifted = $one->shln(256); // 1 << 256
$subtractValue = new BN('14551231950B75FC4402DA1732FC9BEBF', 16); // 0x... value from the condition
$n = $shifted->sub($subtractValue);

// Curve initialization
$ec = new EC('secp256k1');

// Generate private key with range check
do {
    $privateKey = BN::rand(256);
} while ($privateKey->cmp($n) >= 0 || $privateKey->isZero());

// Get HEX representation
$privateKeyHex = $privateKey->toString(16, 64);

echo "Generated private key:\n" . $privateKeyHex . "\n";
?>


Resulting long sequence with address:
c0 36 66 7e 55 56 a9 c3 5f 50 73 7b ab 8b a9 28 82 14 b0 86 4d 4d 1b b6 a1 a3 78 37 18 f4 a3 ad
dd a0 3c 8e 23 4c 55 b2 80 75 71 b2 f8 2a 52 e7 ac e8 fd f0 9e b6 3f e6 5d 1f bb 0b b0 75 26 e8
13 0b ef f0 1b 0f 3f 41 5d b4 b8 74 be 29 9e ef 4b 1b 33 a2 e6 95 6c 5b bd 91 0a db 24 0e 94 4b
4e bb d0 f3 2a a0 15 ba 86 1d 6c 90 5d d4 10 53 e9 3e ce 85 4b 72 15 09 5e 47 61 75 9b bb 6c 2b

The overall result has been successfully written to 'save.txt'.

Contents of save.txt without spaces:
c036667e5556a9c35f50737bab8ba9288214b0864d4d1bb6a1a3783718f4a3addda03c8e234c55b2807571b2f82a52e7ace8fdf09eb63fe65d1fbb0bb07526e8130beff01b0f3f415db4b874be299eef4b1b33a2e6956c5bbd910adb240e944b4ebbd0f32aa015ba861d6c905dd41053e93ece854b7215095e4761759bbb6c2b
  • wget: Downloads an archive containing a key generation tool.
  • unzip: Extracts the contents of the archive.

  • BN::rand(256): Generates a random 256-bit number.
  • shln(256): Bitwise left shift to create the upper bound.
  • cmp($n): Checks that the key is less than N (required by ECDSA).

Execution result:

c036667e5556a9c35f50737bab8ba9288214b0864d4d1bb6a1a3783718f4a3addda03c8e234c55b2807571b2f82a52e7ace8fdf09eb63fe65d1fbb0bb07526e8130beff01b0f3f415db4b874be299eef4b1b33a2e6956c5bbd910adb240e944b4ebbd0f32aa015ba861d6c905dd41053e93ece854b7215095e4761759bbb6c2b

The key is saved in save.txt without spaces.


2. Private Key Extraction (privextract.zip)

Command:

./privextract -extraction c036667e5556a9c35f50737bab8ba9288214b0864d4d1bb6a1a3783718f4a3addda03c8e234c55b2807571b2f82a52e7ace8fdf09eb63fe65d1fbb0bb07526e8130beff01b0f3f415db4b874be299eef4b1b33a2e6956c5bbd910adb240e944b4ebbd0f32aa015ba861d6c905dd41053e93ece854b7215095e4761759bbb6c2b
  • -extraction: Analyzes the hex string for validation and reduces it to a standard key.

Result:

Private Key Result:
e8 d4 40 50 87 3d ba 86
5a a7 c1 70 ab 4c ce 64
d9 08 39 a3 4d cf d6 cf
71 d1 4e 02 05 44 3b 1b

Private Key Result:
e8d44050873dba865aa7c170ab4cce64d90839a34dcfd6cf71d14e0205443b1b

Result successfully written to 'privkey.txt'.
  • A 256-bit key, matching SECP256k1 standards.
  • Saved in privkey.txt.

3. Bitcoin Address Generation (bitaddress.zip)

Installation commands

wget https://privextract.ru/repositories/privextract.zip
unzip privextract.zip

Command:

./bitaddress -hex e8d44050873dba865aa7c170ab4cce64d90839a34dcfd6cf71d14e0205443b1b

Results:

Public Key (Uncompressed, 130 characters [0-9A-F]):
0435E3B8716105AEB1B3025E9FF8B5B8C60660B084BB40FB7D3F3D844E22E2705E55EAB4F97914F239691A70255B139364277EBB2BA1205140C93E3223414D64E7


Public Key (Compressed, 66 characters [0-9A-F]):
0335E3B8716105AEB1B3025E9FF8B5B8C60660B084BB40FB7D3F3D844E22E2705E


Bitcoin Address P2PKH (Uncompressed)
158zPR3H2yo87CZ8kLksXhx3irJMMnCFAN


Bitcoin Address P2PKH (Compressed)
1NuphUJj4gFCTDkw9yQ7PhhtV4L89EBCzU
  1. Public Key (Uncompressed, 130 characters): 0435E3B871...414D64E7
  2. Public Key (Compressed, 66 characters): 0335E3B871...E2705E
  3. P2PKH Addresses:
    • Uncompressed: 158zPR3H2yo87CZ8kLksXhx3irJMMnCFAN
    • Compressed: 1NuphUJj4gFCTDkw9yQ7PhhtV4L89EBCzU

Conversion mechanism:

  • The public key is hashed using SHA-256, then RIPEMD-160.
  • The network prefix (0x00 for Mainnet) is added.
  • Checksum is generated via double SHA-256.

4. Balance Check

Address: 158zPR3H2yo87CZ8kLksXhx3irJMMnCFAN
Balance: 30.2819677 BTC


Critical Notes

  1. Key Generation Security:
    • Using BN::rand() may be vulnerable if the random source is weak.
    • Dynamic calculation of N reduces key predictability.
  2. Bitaddress Usage Risks:
    • Offline generation is preferable to avoid phishing.
    • Paper wallets require physical protection.
  3. Private Keys:
    • Leaking the private key e8d44050873dba865aa7c170ab4cce64d90839a34dcfd6cf71d14e0205443b1b gives full control over 30.2819677 BTC.
    • Hardware wallets are recommended for storage.

PHP Vulnerable Code

<?php
require_once 'vendor/autoload.php';

use Elliptic\EC;
use BN\BN;

// Dynamic calculation of constant N
$one = new BN(1);
$shifted = $one->shln(256); // 1 << 256
$subtractValue = new BN('14551231950B75FC4402DA1732FC9BEBF', 16); // 0x... value from the condition
$n = $shifted->sub($subtractValue);

// Curve initialization
$ec = new EC('secp256k1');

// Generate private key with range check
do {
$privateKey = BN::rand(256);
} while ($privateKey->cmp($n) >= 0 || $privateKey->isZero());

// Get HEX representation
$privateKeyHex = $privateKey->toString(16, 64);

echo "Generated private key:\n" . $privateKeyHex . "\n";
?>