-
Notifications
You must be signed in to change notification settings - Fork 1
/
BitcoinAddress.cpp
150 lines (127 loc) · 5.51 KB
/
BitcoinAddress.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include "BitcoinAddress.h"
#include "Base58.h"
#include "RIPEMD160.h"
#include "SHA256.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#ifdef _MSC_VER // Disable the stupid ass absurd warning messages from Visual Studio telling you that using stdlib and stdio is 'not valid ANSI C'
#pragma warning(disable:4718)
#pragma warning(disable:4996)
#endif
bool bitcoinPublicKeyToAddress(const uint8_t input[65], // The 65 bytes long ECDSA public key; first byte will always be 0x4 followed by two 32 byte components
uint8_t output[25]) // A bitcoin address (in binary( is always 25 bytes long.
{
bool ret = false;
if ( input[0] == 0x04)
{
uint8_t hash1[32]; // holds the intermediate SHA256 hash computations
computeSHA256(input,65,hash1); // Compute the SHA256 hash of the input public ECSDA signature
output[0] = 0; // Store a network byte of 0 (i.e. 'main' network)
computeRIPEMD160(hash1,32,&output[1]); // Compute the RIPEMD160 (20 byte) hash of the SHA256 hash
computeSHA256(output,21,hash1); // Compute the SHA256 hash of the RIPEMD16 hash + the one byte header (for a checksum)
computeSHA256(hash1,32,hash1); // now compute the SHA256 hash of the previously computed SHA256 hash (for a checksum)
output[21] = hash1[0]; // Store the checksum in the last 4 bytes of the public key hash
output[22] = hash1[1];
output[23] = hash1[2];
output[24] = hash1[3];
ret = true;
}
return ret;
}
bool bitcoinCompressedPublicKeyToAddress(const uint8_t input[33], // The 33 byte long compressed ECDSA public key; first byte will always be 0x4 followed by the 32 byte component
uint8_t output[25]) // A bitcoin address (in binary( is always 25 bytes long.
{
bool ret = false;
if ( input[0] == 0x02 || input[0] == 0x03 )
{
uint8_t hash1[32]; // holds the intermediate SHA256 hash computations
computeSHA256(input,33,hash1); // Compute the SHA256 hash of the input public ECSDA signature
output[0] = 0; // Store a network byte of 0 (i.e. 'main' network)
computeRIPEMD160(hash1,32,&output[1]); // Compute the RIPEMD160 (20 byte) hash of the SHA256 hash
computeSHA256(output,21,hash1); // Compute the SHA256 hash of the RIPEMD16 hash + the one byte header (for a checksum)
computeSHA256(hash1,32,hash1); // now compute the SHA256 hash of the previously computed SHA256 hash (for a checksum)
output[21] = hash1[0]; // Store the checksum in the last 4 bytes of the public key hash
output[22] = hash1[1];
output[23] = hash1[2];
output[24] = hash1[3];
ret = true;
}
return ret;
}
bool bitcoinPublicKeyToAscii(const uint8_t input[65], // The 65 bytes long ECDSA public key; first byte will always be 0x4 followed by two 32 byte components
char *output, // The output ascii representation.
uint32_t maxOutputLen) // convert a binary bitcoin address into ASCII
{
bool ret = false;
output[0] = 0;
uint8_t hash2[25];
if ( bitcoinPublicKeyToAddress(input,hash2))
{
ret = encodeBase58(hash2,25,true,output,maxOutputLen);
}
return ret;
}
bool bitcoinCompressedPublicKeyToAscii(const uint8_t input[33], // The 33 bytes long ECDSA public key
char *output, // The output ascii representation.
uint32_t maxOutputLen) // convert a binary bitcoin address into ASCII
{
bool ret = false;
output[0] = 0;
uint8_t hash2[25];
if ( bitcoinCompressedPublicKeyToAddress(input,hash2))
{
ret = encodeBase58(hash2,25,true,output,maxOutputLen);
}
return ret;
}
bool bitcoinAsciiToAddress(const char *input,uint8_t output[25]) // convert an ASCII bitcoin address into binary.
{
bool ret = false;
uint32_t len = decodeBase58(input,output,25,true);
if ( len == 25 ) // the output must be *exactly* 25 bytes!
{
uint8_t checksum[32];
computeSHA256(output,21,checksum);
computeSHA256(checksum,32,checksum);
if ( output[21] == checksum[0] ||
output[22] == checksum[1] ||
output[23] == checksum[2] ||
output[24] == checksum[3] )
{
ret = true; // the cheksum matches!
}
}
return ret;
}
void bitcoinRIPEMD160ToAddress(const uint8_t ripeMD160[20],uint8_t output[25])
{
uint8_t hash1[32]; // holds the intermediate SHA256 hash computations
output[0] = 0; // Store a network byte of 0 (i.e. 'main' network)
memcpy(&output[1],ripeMD160,20); // copy the 20 byte of the public key address
computeSHA256(output,21,hash1); // Compute the SHA256 hash of the RIPEMD16 hash + the one byte header (for a checksum)
computeSHA256(hash1,32,hash1); // now compute the SHA256 hash of the previously computed SHA256 hash (for a checksum)
output[21] = hash1[0]; // Store the checksum in the last 4 bytes of the public key hash
output[22] = hash1[1];
output[23] = hash1[2];
output[24] = hash1[3];
}
void bitcoinRIPEMD160ToScriptAddress(const uint8_t ripeMD160[20],uint8_t output[25])
{
uint8_t hash1[32]; // holds the intermediate SHA256 hash computations
output[0] = 5; // Store a network byte of 0 (i.e. 'main' network)
memcpy(&output[1],ripeMD160,20); // copy the 20 byte of the public key address
computeSHA256(output,21,hash1); // Compute the SHA256 hash of the RIPEMD16 hash + the one byte header (for a checksum)
computeSHA256(hash1,32,hash1); // now compute the SHA256 hash of the previously computed SHA256 hash (for a checksum)
output[21] = hash1[0]; // Store the checksum in the last 4 bytes of the public key hash
output[22] = hash1[1];
output[23] = hash1[2];
output[24] = hash1[3];
}
bool bitcoinAddressToAscii(const uint8_t address[25],char *output,uint32_t maxOutputLen)
{
bool ret = false;
ret = encodeBase58(address,25,true,output,maxOutputLen);
return ret;
}