-
Notifications
You must be signed in to change notification settings - Fork 72
feat: Add ed25519 support #574
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
base: edge
Are you sure you want to change the base?
Changes from all commits
de0a197
12059a2
cadd5db
3240eed
0021a2b
c7e20bd
ef92568
8423d54
85b8a43
13a1556
b3f0235
e91e62a
8b022c2
09789a0
acd918b
d118eaa
21936fc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,9 +17,11 @@ new() -> | |
| new(KeyType = {KeyAlg, PublicExpnt}) when KeyType =:= {rsa, 65537} -> | ||
| {[_, Pub], [_, Pub, Priv|_]} = {[_, Pub], [_, Pub, Priv|_]} | ||
| = crypto:generate_key(KeyAlg, {4096, PublicExpnt}), | ||
| {{KeyType, Priv, Pub}, {KeyType, Pub}}; | ||
| new(KeyType = {KeyAlg, Curve}) when KeyType =:= {?EDDSA_SIGN_ALG, ed25519} -> | ||
| {Pub, Priv} = crypto:generate_key(KeyAlg, Curve), | ||
| {{KeyType, Priv, Pub}, {KeyType, Pub}}. | ||
|
|
||
|
|
||
| %% @doc Sign some data with a private key. | ||
| sign(Key, Data) -> | ||
| sign(Key, Data, sha256). | ||
|
|
@@ -36,6 +38,8 @@ sign({{rsa, PublicExpnt}, Priv, Pub}, Data, DigestType) when PublicExpnt =:= 655 | |
| privateExponent = binary:decode_unsigned(Priv) | ||
| } | ||
| ); | ||
| sign({KeyType = {KeyAlg, Curve}, Priv, _Pub}, Data, _DigestType) when KeyType =:= {?EDDSA_SIGN_ALG, ed25519} -> | ||
| crypto:sign(KeyAlg, none, Data, [Priv, Curve]); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not super familiar with crypto:sign, do you know why we aren't passing
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great question. From Google AI:
HashEdDSA can be |
||
| sign({{KeyType, Priv, Pub}, {KeyType, Pub}}, Data, DigestType) -> | ||
| sign({KeyType, Priv, Pub}, Data, DigestType). | ||
|
|
||
|
|
@@ -57,7 +61,11 @@ verify({{rsa, PublicExpnt}, Pub}, Data, Sig, DigestType) when PublicExpnt =:= 65 | |
| publicExponent = PublicExpnt, | ||
| modulus = binary:decode_unsigned(Pub) | ||
| } | ||
| ). | ||
| ); | ||
| verify({{eddsa, Curve}, Pub}, Data, Sig, _DigestType) when | ||
| byte_size(Pub) == 32 andalso byte_size(Sig) == 64 andalso Curve =:= ed25519 -> | ||
| crypto:verify(eddsa, none, Data, Sig, [Pub, Curve]). | ||
|
|
||
|
|
||
| %% @doc Find a public key from a wallet. | ||
| to_pubkey(Pubkey) -> | ||
|
|
@@ -81,7 +89,9 @@ to_address({{_, _, PubKey}, {_, PubKey}}, _) -> | |
| to_address(PubKey, {rsa, 65537}) -> | ||
| to_rsa_address(PubKey); | ||
| to_address(PubKey, {ecdsa, 256}) -> | ||
| to_ecdsa_address(PubKey). | ||
| to_ecdsa_address(PubKey); | ||
| to_address(PubKey, {eddsa, ed25519}) -> | ||
| to_eddsa_address(PubKey). | ||
|
|
||
| %% @doc Generate a new wallet public and private key, with a corresponding keyfile. | ||
| %% The provided key is used as part of the file name. | ||
|
|
@@ -230,6 +240,9 @@ hash_address(PubKey) -> | |
| to_ecdsa_address(PubKey) -> | ||
| hb_keccak:key_to_ethereum_address(PubKey). | ||
|
|
||
| to_eddsa_address(PubKey) -> | ||
| hash_address(PubKey). | ||
|
|
||
| %%%=================================================================== | ||
| %%% Private functions. | ||
| %%%=================================================================== | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might be worth adding a test which deserializes and verifies a real eddsa data item pulled from the weave. You can download the raw dataitem and stick it in the
testdirectory and then read/deserialize/verify in a test.Earlier in our ans104 support we had only these sort of circular tests (use HB to generate and verify dataitems) and they all passed. But as soon as we started pulling real data from the weave everything broke (e.g. due to the little- vs big- encoding issue, or due to slight discrepancies in how the specs are handled). We still have an open issue due to HB and Arweave implementing ECDSA differently and incompatibly. Adding one test on real data should help avoid many of these issues or future regressions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless maybe you already have that in the
hb_gateway_clienttest? I see that it is querying an ID - does it also verify the data?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first test I created, it used
1rTy7gQuK9lJydlKqCEhtGLp2WWG-GOrVo5JdiCmaxsinformation to verify the signature, but because the anchor isn't available, I provided it manually. But decided that since I was focus on testing theverify_item, I could just create a mock transaction signed with EDDSA, and it should be the same.The only reason I removed it was because of the anchor, but I can add it back by providing the anchor and calling
verify_item.The test on the
hb_gateway_clientonly checks other parameters of an ED25519 transaction, but doesn't verify it.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I think this is what is being done in
l2_dataitem_ed25519_test, @JamesPiechota . A sample (or a few) in thetest/directory and an associated eunit test sounds like a good idea in general, though.@speeddragon : I don't see a
hb_message:verifycall on that test, I think? We should verify that a few validate correctly and that at least one form of invalid signature (ex: take a valid one, modify a bit in the body) fails.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, I think I focus too much on the transaction
verifyfunction and forgot to check the support for thehb_message. I will take a look into it.The tests on
hb_gateway_clientdon't validate the message, so I didn't add it. There are tests underdev_messagethat do the validations, I will look into them.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main codec tests are in the
hb_message_test_vectorsmodule. Thedev_messageones are only really to verify that the calls to the codecs are hooked up correctly. Could you setup a new codec definition (withtype: NEW_SIG_SCHEME?) in the test vectors, then we can just check that all of those tests pass? The suite is quite exhaustive at this point.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've modified the
dev_message:verify_testto support both wallets. I don't think modifyinghb_message_test_vectorswould make sense for this case.Also added the data item of
1rTy7gQuK9lJydlKqCEhtGLp2WWG-GOrVo5JdiCmaxswhich I extracted from the bundle. This has the anchor information, and we can deserialize and verify it.