exweb3 / block_keys Goto Github PK
View Code? Open in Web Editor NEWBIP32 & BIP44 Implementation in Elixir (Multi-Account Hierarchy for Deterministic Wallets)
License: Apache License 2.0
BIP32 & BIP44 Implementation in Elixir (Multi-Account Hierarchy for Deterministic Wallets)
License: Apache License 2.0
Hey,
We have started making a docker version of the code and got the following:
===> Compiling keccakf1600
make: Entering directory '/app/deps/keccakf1600/c_src'
C decaf-utils.c
In file included from /app/deps/keccakf1600/c_src/decaf-common.h:42,
from /app/deps/keccakf1600/c_src/decaf-utils.c:38:
/usr/lib/gcc/x86_64-alpine-linux-musl/9.3.0/include/stdint.h:9:26: error: no include path in which to search for stdint.h
9 | # include_next <stdint.h>
| ^
In file included from /app/deps/keccakf1600/c_src/decaf-utils.c:38:
/app/deps/keccakf1600/c_src/decaf-common.h:43:10: fatal error: sys/types.h: No such file or directory
43 | #include <sys/types.h>
| ^~~~~~~~~~~~~
compilation terminated.
make: *** [Makefile:146: /app/deps/keccakf1600/c_src/decaf-utils.o] Error 1
make: Leaving directory '/app/deps/keccakf1600/c_src'
===> Hook for compile failed!```
Hey!
I've been using this library and its great, we are testing it with testnet bitcoin, I cant seem to import the master private key on a wallet and match the generated addresses from the library, so I can’t spent.
I've tried P2PKH and derivation paths m/44'/1'/0'
, m/44'/0'/0'
, m/0'/0'
and m
.
Thanks in advance!
Recommend switching reps to
Hey,
Noticed another problem with the docker build. It turns out I can't generate the keys :(.
I am getting the following error when starting a console from the docker container:
09:37:06.739 [warn] The on_load function for module libsecp256k1 returned:
{:error, {:load_failed, 'Failed to load NIF library: \'Error loading shared library /app/_build/prod/lib/libsecp256k1/priv/libsecp256k1_nif.so: No such file or directory\''}}
Also, the following error appeared during the compilation:
make[1]: Leaving directory '/app/deps/libsecp256k1/c_src/secp256k1'
cc -I/usr/local/lib/erlang/erts-10.7.1/include -I c_src/secp256k1 -I c_src/secp256k1/src -I c_src/secp256k1/include -I../libsecp256k1/src -fPIC -shared -o priv/libsecp256k1_nif.so c_src/libsecp256k1_nif.c c_src/secp256k1/.libs/libsecp256k1.a -lgmp
c_src/libsecp256k1_nif.c: In function 'ecdsa_sign':
c_src/libsecp256k1_nif.c:494:51: warning: passing argument 2 of 'secp256k1_ecdsa_signature_serialize_der' from incompatible pointer type [-Wincompatible-pointer-types]
494 | if (secp256k1_ecdsa_signature_serialize_der(ctx, &intermediatesig, &siglen, &signature) != 1) {
| ^~~~~~~~~~~~~~~~
| |
| unsigned char (*)[74]
In file included from c_src/libsecp256k1_nif.c:9:
c_src/secp256k1/src/secp256k1.c:261:90: note: expected 'unsigned char *' but argument is of type 'unsigned char (*)[74]'
261 | int secp256k1_ecdsa_signature_serialize_der(const secp256k1_context* ctx, unsigned char *output, size_t *outputlen, const secp256k1_ecdsa_signature* sig) {
| ~~~~~~~~~~~~~~~^~~~~~
In file included from c_src/secp256k1/src/secp256k1.c:9,
from c_src/libsecp256k1_nif.c:9:
c_src/libsecp256k1_nif.c:497:64: warning: passing argument 3 of 'secp256k1_ecdsa_signature_parse_der' from incompatible pointer type [-Wincompatible-pointer-types]
497 | CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &signature, &intermediatesig, siglen) == 1);
| ^~~~~~~~~~~~~~~~
| |
| unsigned char (*)[74]
c_src/secp256k1/src/util.h:40:39: note: in definition of macro 'EXPECT'
40 | #define EXPECT(x,c) __builtin_expect((x),(c))
| ^
c_src/libsecp256k1_nif.c:497:5: note: in expansion of macro 'CHECK'
497 | CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &signature, &intermediatesig, siglen) == 1);
| ^~~~~
In file included from c_src/libsecp256k1_nif.c:9:
c_src/secp256k1/src/secp256k1.c:224:124: note: expected 'const unsigned char *' but argument is of type 'unsigned char (*)[74]'
224 | int secp256k1_ecdsa_signature_parse_der(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
| ~~~~~~~~~~~~~~~~~~~~~^~~~~
/usr/lib/gcc/x86_64-alpine-linux-musl/9.3.0/../../../../x86_64-alpine-linux-musl/bin/ld: cannot find -lgmp
collect2: error: ld returned 1 exit status
make: *** [Makefile:31: priv/libsecp256k1_nif.so] Error 1
One of the tasks I need to build is being able to generate keys from the phrases sent by clients from outside.
What I have noticed that my phrases generated by BlockKeys.Mnemonic.generate_phrase
the function would allow me to generate seeds used for keys generation.
However I am trying to understand how to validate phrases from external systems, so they can be used by us. For example:
iex(27)> phrase = BlockKeys.Mnemonic.generate_phrase
"shuffle clay veteran vicious achieve regular mammal regular pluck income crack client oxygen unaware plate client expire eager glimpse limit wonder dentist access naive"
iex(28)> BlockKeys.Mnemonic.generate_seed(phrase)
"a1425bc1452ae8a9ef9a1743daa8164657bf60003170fc32faa9b1cf34f90c52e44c6bb3da66b38b2af333d71219b1eab41c147c0b2b272f5612949e9affadb7"
Works
However when I have changed something in the phrase (e.g. I am assuming that the user have sent us something different)
# See I have replaced the first word to clay here...
iex(30)> phrase = "clay clay veteran vicious achieve regular mammal regular pluck income crack client oxygen unaware plate client expire eager glimpse limit wonder dentist access naive"
"clay clay veteran vicious achieve regular mammal regular pluck income crack client oxygen unaware plate client expire eager glimpse limit wonder dentist access naive"
iex(31)> BlockKeys.Mnemonic.generate_seed(phrase)
{:error, "Checksum is not valid"}
# See I have removed two first words here
iex(32)> phrase = "veteran vicious achieve regular mammal regular pluck income crack client oxygen unaware plate client expire eager glimpse limit wonder dentist access naive"
"veteran vicious achieve regular mammal regular pluck income crack client oxygen unaware plate client expire eager glimpse limit wonder dentist access naive"
iex(33)> BlockKeys.Mnemonic.generate_seed(phrase)
** (FunctionClauseError) no function clause matching in BlockKeys.Mnemonic.verify_checksum/1
The following arguments were given to BlockKeys.Mnemonic.verify_checksum/1:
# 1
<<243, 62, 112, 7, 90, 104, 107, 105, 169, 171, 148, 49, 197, 90, 121, 118, 58,
98, 85, 148, 26, 39, 99, 48, 63, 244, 29, 64, 21, 37>>
Attempted function clauses (showing 1 out of 1):
defp verify_checksum(<<entropy::binary()-size(32), checksum::binary()-size(1)>>)
(block_keys 0.1.5) lib/block_keys/mnemonic.ex:151: BlockKeys.Mnemonic.verify_checksum/1
(block_keys 0.1.5) lib/block_keys/mnemonic.ex:66: BlockKeys.Mnemonic.generate_seed/2
iex(33)>
Could you explain how do I understand which phrase is correct and which is not?
Currently we rely on libsecp256k1
for the tweak add and decompress operations:
It would help to eliminate that dependency and implement those operations in pure Elixir. Although this would be a performance hit, it would help when trying to use block_keys
in an embedded environment like Nerves.
One good compromise would be to have the ecc library configurable.
Looks like we've got the next problem. One of the dependencies (keccakf1600) can't be compiled on otp23, as it has a major change in erl_interface. (http://blog.erlang.org/OTP-23-Highlights/)
On the high level it looks like this:
$ mix compile
===> Compiling keccakf1600
LD keccakf1600.so
ld: library not found for -lerl_interface
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [/Users/name/proj/deps/keccakf1600/c_src/../priv/keccakf1600.so] Error 1
===> Hook for compile failed!
** (Mix) Could not compile dependency :keccakf1600, "/Users/name/.asdf/installs/elixir/1.10.3-otp-23/.mix/rebar3 bare compile --paths="/Users/name/proj/_build/dev/lib/*/ebin"" command failed. You can recompile this dependency with "mix deps.compile keccakf1600", update it with "mix deps.update keccakf1600" or clean it with "mix deps.clean keccakf1600"
The quick investigation shows that the problematic line is: https://github.com/hayesgm/erlang-keccakf1600/blob/master/c_src/Makefile#L92 and the following change fixes it:
LDLIBS += -L"$(ERL_INTERFACE_LIB_DIR)" -le
However, I have two questions:
keccakf1600
as it seems to be unrelated to generating mnemonic based keys at all and is used only in some bitcoin specific thing we don't need atm?I cloned this repository, then ran mix deps.get
and iex -S mix
:
Erlang/OTP 23 [erts-11.0.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1]
Interactive Elixir (1.10.3) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> root_key = BlockKeys.from_mnemonic("nurse grid sister metal flock choice system control about mountain sister rapid hundred render shed chicken print cover tape sister zero bronze tattoo stairs")
"xprv9s21ZrQH143K35qGjQ6GG1wGHFZP7uCZA1WBdUJA8vBZqESQXQGA4A9d4eve5JqWB5m8YTMcNe8cc7c3FVzDGNcmiabi9WQycbFeEvvJF2D"
iex(2)> BlockKeys.CKD.derive(root_key, "M/44'/60'/0'/0/0") |> BlockKeys.Ethereum.Address.from_xpub
21:58:12.955 [warn] The on_load function for module libsecp256k1 returned:
{:error, {:load_failed, 'Failed to load NIF library: \'/home/felipe/local-repositories/block_keys/_build/dev/lib/libsecp256k1/priv/libsecp256k1_nif.so: cannot open shared object file: No such file or directory\''}}
** (UndefinedFunctionError) function :libsecp256k1.ec_pubkey_create/2 is undefined (module :libsecp256k1 is not available)
(libsecp256k1 0.1.10) :libsecp256k1.ec_pubkey_create(<<52, 229, 119, 241, 177, 34, 46, 53, 218, 61, 119, 101, 81, 208, 34, 9, 178, 233, 180, 154, 141, 245, 203, 159, 179, 170, 124, 150, 195, 100, 32, 80>>, :uncompressed)
(block_keys 0.1.10) lib/block_keys/crypto.ex:26: BlockKeys.Crypto.public_key/1
(block_keys 0.1.10) lib/block_keys/ckd.ex:202: BlockKeys.CKD.put_uncompressed_parent_pub/2
(block_keys 0.1.10) lib/block_keys/ckd.ex:82: BlockKeys.CKD.child_key_private/2
(block_keys 0.1.10) lib/block_keys/ckd.ex:55: BlockKeys.CKD._derive/2
(block_keys 0.1.10) lib/block_keys/ckd.ex:28: BlockKeys.CKD.derive/2
iex(2)>
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.