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

feat(keys): add test vectors for protobuf encoding #537

Merged
merged 6 commits into from
Aug 1, 2023

Conversation

thomaseizinger
Copy link
Contributor

@marten-seemann @MarcoPolo Would appreciate if you could cross-check these with the go implementation. Also cc @Menduist for nim-libp2p.

Here is the commit adding the tests to rust-libp2p: https://github.com/drHuangMHT/rust-libp2p/blob/92f6914bf5c6c8dc12146c64c967f407000354a0/identity/src/keypair.rs#L665-L733

Resolves #533.

@thomaseizinger thomaseizinger marked this pull request as draft April 10, 2023 09:32
@thomaseizinger
Copy link
Contributor Author

Sorry for the noise, this isn't ready yet. Just found a bug in our encoding of RSA keys.

@thomaseizinger
Copy link
Contributor Author

Okay, the first two test vectors are now ready. Could you please cross check them before we merge the PR on our end?

We've split these up into multiple PRs in rust-libp2p now so my plan is to extend this with more test cases as we go along but it would be great to already check them now that they are correct.

@marten-seemann
Copy link
Contributor

@thomaseizinger Pretty busy right now, but if you want to send us a PR for go-libp2p, would be happy to review.


| Key | bytes |
|-----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ECDSA private key | 0803128a01308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420122f33dad49e77dd1a467ac4b4b9432079d3ac0c110f9a608e86ff31a7552e55a14403420004ada418c4f1f7715ef1a365d9ae1e80f5d7069ab55ee19f1c4d77b44ea8dc9cbda558fe88dc32779c68573bf330daeeae1f44158a3b7d4b325230a8daf0d46dc5 |
Copy link
Contributor

Choose a reason for hiding this comment

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

This key is failing in nim-libp2p, here:
https://github.com/status-im/nim-libp2p/blob/a1eb53b1813df5d4fa1b343ef003ad9fb5ebb1d8/libp2p/crypto/ecnist.nim#L619-L620

I'm not familiar enough to know if it's a problem on our side or an invalid key, but can look deeper if no one knows

Copy link
Contributor

Choose a reason for hiding this comment

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

Looked a bit more into it
https://www.rfc-editor.org/rfc/rfc5915
Specificies:

   ECPrivateKey ::= SEQUENCE {
     version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
     privateKey     OCTET STRING,
     parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
     publicKey  [1] BIT STRING OPTIONAL
   }

version specifies the syntax version number of the elliptic curve
private key structure. For this version of the document, it SHALL
be set to ecPrivkeyVer1, which is of type INTEGER and whose value
is one (1).

But this key contains 0:
https://lapo.it/asn1js/#MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgEi8z2tSed90aRnrEtLlDIHnTrAwRD5pgjob_MadVLlWhRANCAAStpBjE8fdxXvGjZdmuHoD11waatV7hnxxNd7ROqNycvaVY_ojcMnecaFc78zDa7q4fRBWKO31LMlIwqNrw1G3F
(uncheck "with definitions", first integer = 0)

So unless another spec is used, this is invalid

Choose a reason for hiding this comment

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

The first integer being 0 is defined here in RFC5208

PrivateKeyInfo ::= SEQUENCE {
  version                   Version,
  privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
  privateKey                PrivateKey,
  attributes           [0]  IMPLICIT Attributes OPTIONAL 
}

version is the syntax version number, for compatibility with
future revisions of this document. It shall be 0 for this version
of the document.

as a part of PKCS#8 "header".
The 1 you are looking for is the next integer

SEQUENCE (3 elem)
  INTEGER 0 ---- Version
  SEQUENCE (2 elem) ---- PrivateKeyAlgorithmIdentifier 
    OBJECT IDENTIFIER 1.2.840.10045.2.1 ecPublicKey (ANSI X9.62 public key type)
    OBJECT IDENTIFIER 1.2.840.10045.3.1.7 prime256v1 (ANSI X9.62 named elliptic curve)
  OCTET STRING (109 byte) 306B0201010420122F33DAD… ---- PrivateKey
    SEQUENCE (3 elem)
      INTEGER 1    <<<< here
      OCTET STRING (32 byte) 122F33DAD49E77DD1A... ---- 32 bytes private key
      [1] (1 elem)
        BIT STRING (520 bit) 000001001010110110100... ---- 520 bit or 65 bytes public key

which is 1.
Additionally, the key generated by Rust implementation of secp256r1 also generates keys with first integer being 0.

Copy link

@drHuangMHT drHuangMHT May 3, 2023

Choose a reason for hiding this comment

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

The problem is I don't know what "DER-encoded PKIX" actually means. The key itself is valid, but I'm not sure whether the wrapper is correct. The spec should refer directly to RFC5208 and/or RFC5915.

Copy link
Contributor

Choose a reason for hiding this comment

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

You are right, nim-libp2p expects the PrivateKey directly. I think go-libp2p does too, since we use some test vectors generated from their lib, and they look like this:
https://lapo.it/asn1js/#MHcCAQEEID5bH-lxLmwxSUKnUL1nSF3jwe_oWxv7Ugro-a49-kpMoAoGCCqGSM49AwEHoUQDQgAE3j0wD6Nq4Oj11TCJnYOrq0Sr8xYfFipLyQHY5uzaAg6LbV-NowUl5x1oUVEMCY5cR8ZGpZf7Tc7ANOn3fECeYg

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

@thomaseizinger thomaseizinger May 3, 2023

Choose a reason for hiding this comment

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

We just have some that we generated from go-libp2p here: https://github.com/status-im/nim-libp2p/blob/a1eb53b1813df5d4fa1b343ef003ad9fb5ebb1d8/tests/testpeerid.nim

Awesome thanks!

I'll use those for this PR then!

@drHuangMHT Can you use those for our tests? We just need to rewrite them to assert against a peer ID instead of a public key.

Copy link
Contributor

Choose a reason for hiding this comment

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

Well, that sure makes my job easier :D

Choose a reason for hiding this comment

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

Failed to decode provided keys in https://github.com/status-im/nim-libp2p/blob/a1eb53b1813df5d4fa1b343ef003ad9fb5ebb1d8/tests/testpeerid.nim. However by skipping the first 4 bytes the keys can be decoded, which is the key in

You are right, nim-libp2p expects the PrivateKey directly. I think go-libp2p does too, since we use some test vectors generated from their lib, and they look like this: https://lapo.it/asn1js/#MHcCAQEEID5bH-lxLmwxSUKnUL1nSF3jwe_oWxv7Ugro-a49-kpMoAoGCCqGSM49AwEHoUQDQgAE3j0wD6Nq4Oj11TCJnYOrq0Sr8xYfFipLyQHY5uzaAg6LbV-NowUl5x1oUVEMCY5cR8ZGpZf7Tc7ANOn3fECeYg

The online decoder also can't decode those keys.

Choose a reason for hiding this comment

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

Never mind the first 4 bytes come from protobuf encoding

mxinden added a commit to mxinden/rust-libp2p that referenced this pull request Jul 20, 2023
Use test fixture from libp2p/specs#537 for ed25516 roundtrip test.
Copy link
Member

@mxinden mxinden left a comment

Choose a reason for hiding this comment

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

@thomaseizinger mind accepting the suggestion below adding an RSA fixture?

Also what is missing for this to be merged. I find it very useful.

peer-ids/peer-ids.md Show resolved Hide resolved
@thomaseizinger
Copy link
Contributor Author

@thomaseizinger mind accepting the suggestion below adding an RSA fixture?

I can't unfortunately. Can you open a PR to my fork?

Also what is missing for this to be merged. I find it very useful.

I'd like at least one other implementation to verify this before we merge here.

@mxinden
Copy link
Member

mxinden commented Jul 24, 2023

@thomaseizinger mind accepting the suggestion below adding an RSA fixture?

I can't unfortunately. Can you open a PR to my fork?

For some reason I am able to. Hope you don't mind. a5926d7

Also what is missing for this to be merged. I find it very useful.

I'd like at least one other implementation to verify this before we merge here.

@Menduist given your involvement above, would you mind using these fixtures in your CI?

mergify bot pushed a commit to libp2p/rust-libp2p that referenced this pull request Jul 29, 2023
Use test fixture from libp2p/specs#537 for ed25519 roundtrip test.

Pull-Request: #4228.
@thomaseizinger thomaseizinger marked this pull request as ready for review July 31, 2023 20:18
Copy link
Contributor

@Menduist Menduist left a comment

Choose a reason for hiding this comment

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

Green on nim-libp2p

@thomaseizinger
Copy link
Contributor Author

@mxinden do you mind approving this so we can merge it?

Copy link
Member

@mxinden mxinden left a comment

Choose a reason for hiding this comment

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

Thank you for the work here @thomaseizinger, @drHuangMHT and @Menduist.

@mxinden mxinden merged commit d2106f4 into libp2p:master Aug 1, 2023
thomaseizinger pushed a commit to libp2p/rust-libp2p that referenced this pull request Aug 20, 2023
Use test fixture from libp2p/specs#537 for ed25519 roundtrip test.

Pull-Request: #4228.
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.

Add test vectors for encoding and decoding keypairs
5 participants