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

Basic support for numeric keys #456

Merged
merged 11 commits into from
Jan 11, 2024

Conversation

cmickeyb
Copy link
Contributor

New stuff:

  • support for the numeric format for ecdsa keys (constructors)
  • first start at a test harness for crypto tests, greatly expanded suite of tests for ecdsa keys

Clean up:

  • "modernizing" the error handling in the ECDSA key classes
  • canonicalizing all of the types for handling smart pointers with openssl
  • consolidation of (a lot of) redundant code in the ecdsa key classes

Copy link
Member

@bvavala bvavala left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor comments -- looks good overall.

common/crypto/sig_private_key.cpp Outdated Show resolved Hide resolved
common/crypto/sig_private_key.cpp Outdated Show resolved Hide resolved
common/crypto/sig_public_key.cpp Outdated Show resolved Hide resolved
common/interpreter/wawaka_wasm/WasmCryptoExtensions.cpp Outdated Show resolved Hide resolved
common/log.cpp Show resolved Hide resolved
@cmickeyb cmickeyb force-pushed the mic.dec22.extended_keys branch from 6a583e2 to ae61eeb Compare January 6, 2024 00:17
cmickeyb and others added 11 commits January 8, 2024 16:58
Added a verbose flag to the cmake project variables in order to make
finding errors in the build output a little easier. When true (which
is the default), the setting will ensure that all warning messages are
generated. An environment variable allows for override.

Signed-off-by: Mic Bowman <mic.bowman@intel.com>
Update the default (very simple) builtin untrusted logger
to send output to stderr and then flush. This is mostly
the result of lost logging that happens when abnormal
termination occurs (precisely the time when you want
accurate and complete logs).

Signed-off-by: Mic Bowman <mic.bowman@intel.com>
Add a new contructor for the sig_private class that takes a curve
identifier and a byte array with the bignum encoding of the private
key.

Push the new constructor through to the contract interpreter. This
should enable construction of BIP32 extended keys.

Signed-off-by: Mic Bowman <mic.bowman@intel.com>
We had definitions for memory safe pointers in several files. This
moves all of those definitions into a single file.

Add a ResetKey() method for the sig_public and sig_private classes
to manage memory allocation and resetting the pointer appropriately.
Note that there is a behavior change. The key is reset prior to
attempts to update it. This means that the key will be unset if
there is, for example, an error deserializing a key. The tests must
be updated for this (they assumed that the key was still valid after
an invalid attempt to update).

Signed-off-by: Mic Bowman <mic.bowman@intel.com>
Removed/consolidated code for deserializing ecdsa public and
private keys from a string.

Simplify and consolidate the constructors.

Use the common error handling functions.  A lot of the code in the
crypto classes predates the logging and error processing functions
that were added later. This PR updates at least the ones in the crypto
signature classes.

And... this fixes a few memory leaks and potential issues with memory
corruption during creation & assignment of keys.

Removed the XY serialization functions from the sig public class.

Added a boolean operator that can be used to test whether a key is initialized.

Cleaned up a lot of the exception generation. Attempted to use MemoryError when
it appears that memory allocation failed and CryptoError any time an OpenSSL
call fails unexpectedly.

Signed-off-by: Mic Bowman <mic.bowman@intel.com>
Add constructors for public and private ECDSA keys for numeric
keys represented by octets stored in a ByteArray.

Add methods to retrieve the numeric keys from the classes.

Signed-off-by: Mic Bowman <mic.bowman@intel.com>
Moved the signature tests into a separate file. Added a bunch of new
signature tests to ensure that uninitialized keys are handled correctly.
Removed signature tests for functions that no longer exist.

Introduced some macros that make it a little easier to make writing
and intepreting test failures a little easier.

Signed-off-by: Mic Bowman <mic.bowman@intel.com>
Co-authored-by: Bruno Vavala <bruno.vavala@intel.com>
Signed-off-by: Mic Bowman <cmickeyb@gmail.com>
Co-authored-by: Bruno Vavala <bruno.vavala@intel.com>
Signed-off-by: Mic Bowman <cmickeyb@gmail.com>
Fix the error strings in sig_public_key.cpp to reflect
that the errors are in the public key, not the private key.

Replace the typedefs for bignumbers in the crypto extenions
with the existing definitions from the crypto library. Not
sure the shared header file should be universally visible
but it is for now.

Signed-off-by: Mic Bowman <mic.bowman@intel.com>
Signed-off-by: Mic Bowman <mic.bowman@intel.com>
@cmickeyb cmickeyb force-pushed the mic.dec22.extended_keys branch from ae61eeb to 7e5d646 Compare January 8, 2024 23:58
Copy link
Contributor

@g2flyer g2flyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Runs well and in general looks good. A few nit-picking (and somewhat debatable) comments, though.
PS: sorry for the late review. Having ancient outlook refile rules which i forgot about didn't help ;-)

common/crypto/sig.h Show resolved Hide resolved
common/log.cpp Show resolved Hide resolved
common/crypto/sig_private_key.cpp Show resolved Hide resolved
// Custom curve constructor with initial key specified as a bignum
pcrypto::sig::PrivateKey::PrivateKey(
const pcrypto::sig::SigCurve& sigCurve,
const ByteArray& numeric_key) :
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't binary_key here and in (de)serialization (as well for public key) be clearer than numeric_key as difference is really ascii (PEM) vs binary encoding of what is in both case a number (which for public keys is anyway a bit debatable at is a point which is not really an (algebraic) number?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i could go either way... its numeric to me because the code i'm writing around it is treating it as a number (hierarchical key derivation). public keys make more sense because they are compressed points.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, even the string/PEM version is still an (encoded) number? I definitely wouldn't want to veto this name but it just wasn't very intuitive for me ...

}
sigDetails_ = privateKey.sigDetails_;
} // pcrypto::sig::PrivateKey::PrivateKey (copy constructor)

// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// Move constructor
// throws RuntimeError
pcrypto::sig::PrivateKey::PrivateKey(pcrypto::sig::PrivateKey&& privateKey)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we override the move constructor, shouldn't we also define an explicit move assignment operator? (admit i'm on thin ground with my C++ knowledge and there are some implicitly defined version, so maybe C++ does do the right thing?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move for sigdetails? suggest you check with @bvavala since that's his code

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, i meant a move assignment operation for PrivateKey (& PublicKey) ....


ByteArray key(key_buffer, key_buffer + key_buffer_length);

pcrypto::sig::PrivateKey privkey(pcrypto::sig::SigCurve::SECP384R1, key);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit surprising to see a particular curve hardcoded here? Why are we not using PDO_DEFAULT_SIGCURVE here?

{
wasm_module_inst_t module_inst = wasm_runtime_get_module_inst(exec_env);
try {
pe::ThrowIf<pe::RuntimeError>(key_buffer_length != 48, "unsupported key size");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, doesn't the length depend on the curve? So hardcoding 48 here seems a bit brittle? (also, in principle the length could also be greater?)

/* ----------------------------------------------------------------- *
* NAME: ww::crypto::
* ----------------------------------------------------------------- */
bool ww::crypto::ecdsa::generate_keys(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generate to me would imply we are generating new key but we really (re)create (i.e., deserialize) existing keys?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strictly... yes. in practice, we're creating keys in a form that can be used in other operations.

const ww::types::ByteArray message(message_string.begin(), message_string.end());

// ---------- get the keys we need ----------
ww::types::ByteArray bytes(48);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again the magic 48 :-)

@g2flyer g2flyer self-requested a review January 11, 2024 18:44
@bvavala bvavala merged commit 0fc4201 into hyperledger-labs:main Jan 11, 2024
4 checks passed
@cmickeyb cmickeyb deleted the mic.dec22.extended_keys branch January 16, 2024 00:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants