Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Investigate pbkdf2 #1334

Closed
fabiorigam opened this issue Sep 24, 2024 · 4 comments
Closed

Investigate pbkdf2 #1334

fabiorigam opened this issue Sep 24, 2024 · 4 comments

Comments

@fabiorigam
Copy link
Member

fabiorigam commented Sep 24, 2024

Investigate if it's possible to implement pbkdf2 (used mostly on mobile).

@lucanicoladebiasi
Copy link
Collaborator

The use of PBKDF2 derives a randomised seed from mnemonic words good enough to seed SECP256K1 key pard generation, but is not at all simpler or quicker than any other method developed in the last 20 years.

However - because implemented in many hardware - it could be convenient to have in the SDK. This is possible because the library noble-hash we use in the SDK provides the needed functionalities.

@lucanicoladebiasi
Copy link
Collaborator

I applied the blackbox approach to compare mnemonic input to wished output. @grenos instructed me 'west liberty trash promote cushion install have coast color parade receive wire should resunt in the address 0x88471b80cac83d549843ce96f20aff3a00f219b4.
Hence I worte the following snippet based of this SDK

import { Address } from '@vechain/sdk-core';
const mnemonics =
    'west liberty trash promote cushion install have coast color parade receive wire'.split(
        ' '
    );
const address = Address.ofMnemonic(mnemonics);
console.log(address.toString());

getting as result 0x88471b80CAC83d549843cE96f20afF3A00F219B4 that is the expected address.
This proves the SDK address implementation internally uses (the evolution) of the (25 years old) PDKDF2 algorithm

The chain to derive address from mnemonics is the following:

  1. mnemonics -> PDKDF2 -> pseudo-random seed (PDKDF2 is an hashing algorithm);
  2. random seed - > SECP256K1 -> private and public keys
  3. public key -> KECCAK256 -> address.

Hence, there is no need to provide PDKF2 API in the SDK because the needed functionalities are already provided by the Address class.
The Mnemonic class provided methods to derive the public key from mnemonics.

@lucanicoladebiasi
Copy link
Collaborator

lucanicoladebiasi commented Oct 2, 2024

The experiment above demonstrates long computational times experienced in some runtime are not caused by the SDK implementation.
The SDK uses the audited libraries noble-curves and noble-hash, the latter providing PBKDF2.
The named libraries delegates cryptography math to the crypto component of NodeJS runtime, the crypto component delegated the functionalities to the API of the operating system, this one provides the call to the hardware random generator.
If NodeJS runtime can't bind with crypto as expected, the SDK implements a fall back mechanism running the cryptographic math with only what JS runtime provides, this is why it's many orders of magnitude slower than the same math delegated to the hardware through the OS. Unfortunately this can be the case when the runtime is hosted by a mobile architecture.

JS React allows JS code to call a sandbox running code compiled in C/C++. Facebook uses this approach to implement PBKDF2.
I'm investigating how to plug in the https://github.com/margelo/react-native-quick-crypto/tree/main/packages/react-native-quick-crypto project the C++ PBKDF2 library to seed the C++ SECP256K1 library to input the C++ KECCK256 library to obtain the address from mnemonics. This is the Facebook suggested pattern to have cryptography safely and fast implemented.

The Bitcoin Foundation published the required C/C++ libraries I'm investigating.

@lucanicoladebiasi
Copy link
Collaborator

Experimenting with the MIT licensed C++ source code published at https://github.com/edwardstock/bip3x.
Successfully compiled for MacOS on ARM architecture thanks to https://www.jetbrains.com/clion/.

Shortcut to compile the cryptographic shared library to call from C/C++

  1. Install CMake.
brew install cmake
  1. From the directory where bip3x is installed
mkdir build & cd build
  1. Compile the library to be called from C/C++ code
cmake .. -DCMAKE_BUILD=Release -Dbip3x_BUILD_SHARED_LIBS=On -Dbip3x_BUILD_JNI_BINDINGS=Off -Dbip3x_BUILD_C_BINDINGS=On -Dbip3x_BUILD_TESTS=Off

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

When branches are created from issues, their pull requests are automatically linked.

3 participants