Skip to content

Commit

Permalink
get bip38 flags
Browse files Browse the repository at this point in the history
  • Loading branch information
glslang authored and jgriffiths committed Oct 26, 2018
1 parent 4273afe commit 34bac73
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGES.md
Expand Up @@ -2,6 +2,9 @@

## Version 0.6.5

- BIP38_KEY_TESTNET was changed to reflect the testnet network version. BIP38 testnet keys
created with older versions of wally were not valid for testnet.

- API change of wally_tx_elements_input_init_alloc and wally_tx_add_elements_raw_input
to also include the pegin witness.

Expand Down
24 changes: 23 additions & 1 deletion include/wally_bip38.h
Expand Up @@ -9,7 +9,7 @@ extern "C" {

/** Flags for BIP38 conversion. The first 8 bits are reserved for the network */
#define BIP38_KEY_MAINNET 0 /** Address is for main network */
#define BIP38_KEY_TESTNET 7 /** Address is for test network */
#define BIP38_KEY_TESTNET 111 /** Address is for test network */
#define BIP38_KEY_COMPRESSED 256 /** Public key is compressed */
#define BIP38_KEY_EC_MULT 512 /** EC-Multiplied key (FIXME: Not implemented) */
#define BIP38_KEY_QUICK_CHECK 1024 /** Check structure only (no password required) */
Expand Down Expand Up @@ -95,6 +95,28 @@ WALLY_CORE_API int bip38_to_private_key(
unsigned char *bytes_out,
size_t len);

/**
* Get compression and/or EC mult flags.
*
* :param bytes: Raw BIP 38 address to get the flags from.
* :param bytes_len: Size of ``bytes`` in bytes. Must be ``BIP38_SERIALIZED_LEN``.
* :param written: BIP38_KEY_ flags indicating behavior.
*/
WALLY_CORE_API int bip38_raw_get_flags(
const unsigned char *bytes,
size_t bytes_len,
size_t *written);

/**
* Get compression and/or EC mult flags.
*
* :param bip38: BIP 38 address to get the flags from.
* :param written: BIP38_KEY_ flags indicating behavior.
*/
WALLY_CORE_API int bip38_get_flags(
const char *bip38,
size_t *written);

#ifdef __cplusplus
}
#endif
Expand Down
47 changes: 47 additions & 0 deletions src/bip38.c
Expand Up @@ -336,3 +336,50 @@ int bip38_to_private_key(const char *bip38,
return to_private_key(bip38, NULL, 0, pass, pass_len, flags,
bytes_out, len);
}

static int get_flags(const char *bip38,
const unsigned char *bytes, size_t bytes_len,
size_t *written)
{
struct bip38_layout_t buf;

if (!written)
return WALLY_EINVAL;

*written = 0;

if (bytes) {
if (bytes_len != BIP38_SERIALIZED_LEN)
return WALLY_EINVAL;
memcpy(&buf.prefix, bytes, BIP38_SERIALIZED_LEN);
} else {
size_t serialized_len;
int ret;
if ((ret = wally_base58_to_bytes(bip38, BASE58_FLAG_CHECKSUM, &buf.prefix,
BIP38_SERIALIZED_LEN + BASE58_CHECKSUM_LEN,
&serialized_len)))
return ret;

if (serialized_len != BIP38_SERIALIZED_LEN)
return WALLY_EINVAL;
}

*written = buf.ec_type != BIP38_NO_ECMUL ? BIP38_KEY_EC_MULT : 0;
*written |= buf.flags & BIP38_FLAG_COMPRESSED ? BIP38_KEY_COMPRESSED : 0;

wally_clear(&buf, sizeof(buf));

return WALLY_OK;
}

int bip38_raw_get_flags(const unsigned char *bytes, size_t bytes_len,
size_t *written)
{
return get_flags(NULL, bytes, bytes_len, written);
}

int bip38_get_flags(const char *bip38,
size_t *written)
{
return get_flags(bip38, NULL, 0, written);
}
2 changes: 2 additions & 0 deletions src/swig_java/swig.i
Expand Up @@ -352,6 +352,8 @@ static jbyteArray create_array(JNIEnv *jenv, const unsigned char* p, size_t len)
%returns_string(bip38_from_private_key);
%returns_array_(bip38_raw_to_private_key, 6, 7, 32);
%returns_array_(bip38_to_private_key, 5, 6, 32);
%returns_size_t(bip38_raw_get_flags);
%returns_size_t(bip38_get_flags);
%returns_string(bip39_get_languages);
%returns_struct(bip39_get_wordlist, words);
%returns_string(bip39_get_word);
Expand Down
7 changes: 7 additions & 0 deletions src/test/test_bip38.py
Expand Up @@ -92,6 +92,13 @@ def test_bip38_invalid(self):
ret, _ = self.from_priv(priv_key, passwd, K_MAIN + flags)
self.assertEqual(ret, expected)

def test_bip38_flags(self):
priv_key = "6PYTh1Jgj3caimSrFjsfR5wJ8zUgWNDiPoNVZapSy8BwkF4NaKa1R32CaN"
ret, flags = bip38_get_flags(utf8(priv_key))
self.assertEqual(ret, WALLY_OK)
flags = int(flags)
self.assertEqual(flags & 256, 256) # BIP38_COMPRESSED
self.assertEqual(flags & 512, 0) # BIP38_KEY_EC_MULT

if __name__ == '__main__':
unittest.main()
2 changes: 2 additions & 0 deletions src/test/util.py
Expand Up @@ -130,6 +130,8 @@ class wally_tx(Structure):
('bip38_from_private_key', c_int, [c_void_p, c_ulong, c_void_p, c_ulong, c_uint, c_char_p_p]),
('bip38_to_private_key', c_int, [c_char_p, c_void_p, c_ulong, c_uint, c_void_p, c_ulong]),
('bip38_raw_to_private_key', c_int, [c_void_p, c_ulong, c_void_p, c_ulong, c_uint, c_void_p, c_ulong]),
('bip38_raw_get_flags', c_int, [c_void_p, c_ulong, c_ulong_p]),
('bip38_get_flags', c_int, [c_char_p, c_ulong_p]),
('bip39_get_languages', c_int, [c_char_p_p]),
('bip39_get_wordlist', c_int, [c_char_p, POINTER(c_void_p)]),
('bip39_get_word', c_int, [c_void_p, c_ulong, c_char_p_p]),
Expand Down

0 comments on commit 34bac73

Please sign in to comment.