forked from breadwallet/breadwallet-core
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBRCryptoCoder.c
More file actions
199 lines (175 loc) · 5 KB
/
BRCryptoCoder.c
File metadata and controls
199 lines (175 loc) · 5 KB
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
//
// BRCryptoCoder.c
// BRCore
//
// Created by Michael Carrara on 9/23/19.
// Copyright © 2019 Breadwinner AG. All rights reserved.
//
// See the LICENSE file at the project root for license information.
// See the CONTRIBUTORS file at the project root for a list of contributors.
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "BRCryptoCoder.h"
#include "ethereum/util/BRUtilHex.h"
#include "support/BRBase58.h"
struct BRCryptoCoderRecord {
BRCryptoCoderType type;
BRCryptoRef ref;
};
IMPLEMENT_CRYPTO_GIVE_TAKE (BRCryptoCoder, cryptoCoder);
extern BRCryptoCoder
cryptoCoderCreate(BRCryptoCoderType type) {
BRCryptoCoder coder = NULL;
switch (type) {
case CRYPTO_CODER_HEX:
case CRYPTO_CODER_BASE58:
case CRYPTO_CODER_BASE58CHECK: {
coder = calloc (1, sizeof(struct BRCryptoCoderRecord));
coder->type = type;
coder->ref = CRYPTO_REF_ASSIGN(cryptoCoderRelease);
break;
}
default: {
assert (0);
break;
}
}
return coder;
}
static void
cryptoCoderRelease (BRCryptoCoder coder) {
memset (coder, 0, sizeof(*coder));
free (coder);
}
extern size_t
cryptoCoderEncodeLength (BRCryptoCoder coder,
const uint8_t *src,
size_t srcLen) {
// - src CANNOT be NULL (see: BRBase58Encode), even with srcLen of 0
if (NULL == src) {
assert (0);
return 0;
}
size_t length = 0;
switch (coder->type) {
case CRYPTO_CODER_HEX: {
length = encodeHexLength (srcLen);
break;
}
case CRYPTO_CODER_BASE58: {
length = BRBase58Encode (NULL, 0, src, srcLen);
break;
}
case CRYPTO_CODER_BASE58CHECK: {
length = BRBase58CheckEncode (NULL, 0, src, srcLen);
break;
}
default: {
assert (0);
break;
}
}
return length;
}
extern BRCryptoBoolean
cryptoCoderEncode (BRCryptoCoder coder,
char *dst,
size_t dstLen,
const uint8_t *src,
size_t srcLen) {
// - src CANNOT be NULL (see: BRBase58Encode), even with srcLen of 0
// - dst MUST be non-NULL and sufficiently sized
if (NULL == src ||
NULL == dst || dstLen < cryptoCoderEncodeLength (coder, src, srcLen)) {
assert (0);
return CRYPTO_FALSE;
}
BRCryptoBoolean result = CRYPTO_FALSE;
switch (coder->type) {
case CRYPTO_CODER_HEX: {
encodeHex (dst, dstLen, src, srcLen);
result = CRYPTO_TRUE;
break;
}
case CRYPTO_CODER_BASE58: {
result = AS_CRYPTO_BOOLEAN (BRBase58Encode (dst, dstLen, src, srcLen));
break;
}
case CRYPTO_CODER_BASE58CHECK: {
result = AS_CRYPTO_BOOLEAN (BRBase58CheckEncode (dst, dstLen, src, srcLen));
break;
}
default: {
assert (0);
break;
}
}
return result;
}
extern size_t
cryptoCoderDecodeLength (BRCryptoCoder coder,
const char *src) {
// - src CANNOT be NULL (see: BRBase58Decode), even with srcLen of 0
if (NULL == src) {
assert (0);
return 0;
}
size_t length = 0;
switch (coder->type) {
case CRYPTO_CODER_HEX: {
size_t strLen = strlen (src);
length = (0 == strLen % 2) ? decodeHexLength (strLen) : 0;
break;
}
case CRYPTO_CODER_BASE58: {
length = BRBase58Decode (NULL, 0, src);
break;
}
case CRYPTO_CODER_BASE58CHECK: {
length = BRBase58CheckDecode (NULL, 0, src);
break;
}
default: {
// for an unsupported algorithm, assert
assert (0);
break;
}
}
return length;
}
extern BRCryptoBoolean
cryptoCoderDecode (BRCryptoCoder coder,
uint8_t *dst,
size_t dstLen,
const char *src) {
// - src CANNOT be NULL (see: BRBase58Decode), even with srcLen of 0
// - dst MUST be non-NULL and sufficiently sized
if (NULL == src ||
NULL == dst || dstLen < cryptoCoderDecodeLength (coder, src)) {
assert (0);
return CRYPTO_FALSE;
}
BRCryptoBoolean result = CRYPTO_FALSE;
switch (coder->type) {
case CRYPTO_CODER_HEX: {
decodeHex (dst, dstLen, src, strlen (src));
result = CRYPTO_TRUE;
break;
}
case CRYPTO_CODER_BASE58: {
result = AS_CRYPTO_BOOLEAN (BRBase58Decode (dst, dstLen, src));
break;
}
case CRYPTO_CODER_BASE58CHECK: {
result = AS_CRYPTO_BOOLEAN (BRBase58CheckDecode (dst, dstLen, src));
break;
}
default: {
// for an unsupported algorithm, assert
assert (0);
break;
}
}
return result;
}